mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2024-11-30 15:41:12 +00:00
New test-suite initial implementation. Just need to write some tests.
This commit is contained in:
parent
d1640f177f
commit
0dc4febb91
47 changed files with 29 additions and 527 deletions
23
Makefile
23
Makefile
|
@ -25,8 +25,8 @@ OBJ = \
|
|||
ast.o \
|
||||
ir.o \
|
||||
con.o
|
||||
OBJ_A = test/ast-test.o
|
||||
OBJ_I = test/ir-test.o
|
||||
|
||||
OBJ_T = test.o util.o con.o
|
||||
OBJ_C = main.o lexer.o parser.o
|
||||
OBJ_X = exec-standalone.o util.o con.o
|
||||
|
||||
|
@ -38,23 +38,22 @@ default: gmqcc
|
|||
exec-standalone.o: exec.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) -DQCVM_EXECUTOR=1
|
||||
|
||||
# test targets
|
||||
test_ast: $(OBJ_A) $(OBJ)
|
||||
$(CC) -o $@ $^ $(CFLAGS)
|
||||
test_ir: $(OBJ_I) $(OBJ)
|
||||
$(CC) -o $@ $^ $(CFLAGS)
|
||||
qcvm: $(OBJ_X)
|
||||
qcvm: $(OBJ_X)
|
||||
$(CC) -o $@ $^ $(CFLAGS) -lm
|
||||
test: test_ast test_ir
|
||||
|
||||
# compiler target
|
||||
gmqcc: $(OBJ_C) $(OBJ)
|
||||
$(CC) -o $@ $^ $(CFLAGS)
|
||||
|
||||
test: $(OBJ_T)
|
||||
$(CC) -o $@ $^ $(CFLAGS)
|
||||
|
||||
runtests:
|
||||
./test
|
||||
|
||||
#all target is test and all
|
||||
all: test gmqcc
|
||||
all: gmqcc qcvm test
|
||||
|
||||
clean:
|
||||
rm -f *.o gmqcc qcvm test_ast test_ir test/*.o
|
||||
rm -f *.o gmqcc qcvm test *.dat
|
||||
|
||||
|
||||
|
|
6
con.c
6
con.c
|
@ -272,7 +272,7 @@ int con_change(const char *out, const char *err) {
|
|||
con_close();
|
||||
|
||||
if (GMQCC_IS_DEFINE((FILE*)out)) {
|
||||
console.handle_out = (((FILE*)err) == stdout) ? stdout : stderr;
|
||||
console.handle_out = (((FILE*)out) == stdout) ? stdout : stderr;
|
||||
con_enablecolor();
|
||||
} else if (!(console.handle_out = fopen(out, "w"))) return 0;
|
||||
|
||||
|
@ -281,6 +281,10 @@ int con_change(const char *out, const char *err) {
|
|||
con_enablecolor();
|
||||
} else if (!(console.handle_err = fopen(err, "w"))) return 0;
|
||||
|
||||
// no buffering
|
||||
setvbuf(console.handle_out, NULL, _IONBF, 0);
|
||||
setvbuf(console.handle_err, NULL, _IONBF, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
1
gmqcc.h
1
gmqcc.h
|
@ -196,6 +196,7 @@ void util_memory_d (void *, unsigned int, const char *);
|
|||
void *util_memory_r (void *, size_t, unsigned int, const char *);
|
||||
void util_meminfo ();
|
||||
|
||||
bool util_filexists (const char *);
|
||||
bool util_strupper (const char *);
|
||||
bool util_strdigit (const char *);
|
||||
bool util_strncmpexact (const char *, const char *, size_t);
|
||||
|
|
2
ir.c
2
ir.c
|
@ -2972,7 +2972,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
|
|||
stmt.o3.u1 = 0;
|
||||
vec_push(code_statements, stmt);
|
||||
|
||||
printf("writing '%s'...\n", filename);
|
||||
con_out("writing '%s'...\n", filename);
|
||||
return code_write(filename);
|
||||
}
|
||||
|
||||
|
|
3
main.c
3
main.c
|
@ -225,6 +225,8 @@ static bool options_parse(int argc, char **argv) {
|
|||
continue;
|
||||
}
|
||||
|
||||
con_change(redirout, redirerr);
|
||||
|
||||
if (!strcmp(argv[0]+1, "debug")) {
|
||||
opts_debug = true;
|
||||
continue;
|
||||
|
@ -381,7 +383,6 @@ static bool options_parse(int argc, char **argv) {
|
|||
vec_push(items, item);
|
||||
}
|
||||
}
|
||||
con_change(redirout, redirerr);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,191 +0,0 @@
|
|||
QCC = ../gmqcc
|
||||
VM = ../qcvm
|
||||
|
||||
TESTLIST = \
|
||||
globaldefs \
|
||||
fielddefs \
|
||||
builtins \
|
||||
variadic \
|
||||
calls \
|
||||
if1 \
|
||||
loops1 \
|
||||
maths1 \
|
||||
maths2 \
|
||||
equality \
|
||||
fields1 \
|
||||
invalid-types \
|
||||
ngraphs \
|
||||
invalid-assign \
|
||||
field-parameters \
|
||||
functions-as-parameters \
|
||||
shadow-qcc shadow-gmqcc
|
||||
|
||||
.PHONY: clean test
|
||||
|
||||
clean:
|
||||
rm -f gmqcc qcvm
|
||||
rm -f */deflist */*.gm.dat */*.qcc.dat */output
|
||||
rm -rf obj
|
||||
|
||||
test: $(TESTLIST)
|
||||
|
||||
obj/%.gm.dat: %/main.qc obj
|
||||
@echo "Testing:" $(subst obj/,,$(subst .gm.dat,,$@))
|
||||
@$(QCC) -std=gmqcc -o $@ $< > $@.out 2> $@.err
|
||||
|
||||
obj/%.qcc.dat: %/main.qc obj
|
||||
@echo "Testing:" $(subst obj/,,$(subst .qcc.dat,,$@))
|
||||
@$(QCC) -std=qcc -o $@ $< > $@.out 2> $@.err
|
||||
|
||||
#######################################################################
|
||||
|
||||
# Macro which causes something to be compiled either with -std=qcc or without...
|
||||
# this may at some point be extended to also store information about the progs.dat
|
||||
# somewhere but for now we only need to build the object.
|
||||
define maketest
|
||||
$(eval $dat = obj/${1}.${2}.dat)
|
||||
$1: obj/$1.$2.dat
|
||||
endef
|
||||
|
||||
#######################################################################
|
||||
|
||||
globaldefs: obj/globaldefs.gm.dat
|
||||
@$(VM) -printdefs $< > $@/deflist
|
||||
@diff $@/deflist $@/deflist.expected
|
||||
|
||||
$(eval $(call maketest,fielddefs,gm))
|
||||
fielddefs:
|
||||
@$(VM) -printfields $< > $@/deflist
|
||||
@diff $@/deflist $@/deflist.expected
|
||||
|
||||
$(eval $(call maketest,builtins,qcc))
|
||||
builtins:
|
||||
@$(VM) -string "Hello 1" $< > $@/output
|
||||
@test "`wc -l $@/output | awk '{ print $$1 }'`" = "1"
|
||||
@grep -qE '^Hello 1$$' $@/output
|
||||
@$(VM) -string "A test message Yeah" $< > $@/output
|
||||
@test "`wc -l $@/output | awk '{ print $$1 }'`" = "1"
|
||||
@grep -qE '^A test message Yeah$$' $@/output
|
||||
|
||||
$(eval $(call maketest,variadic,qcc))
|
||||
variadic:
|
||||
@$(VM) -string "Hello 1" $< > $@/output
|
||||
@test "`wc -l $@/output | awk '{ print $$1 }'`" = "1"
|
||||
@grep -qE '^Hello 1$$' $@/output
|
||||
@$(VM) -string "A test message Yeah" $< > $@/output
|
||||
@test "`wc -l $@/output | awk '{ print $$1 }'`" = "1"
|
||||
@grep -qE '^A test message Yeah$$' $@/output
|
||||
|
||||
$(eval $(call maketest,calls,qcc))
|
||||
calls:
|
||||
@$(VM) -float 1 -float 100 -float 10000 $< > $@/output
|
||||
@grep -qE '^70907$$' $@/output
|
||||
@$(VM) -float 3 -float 201 -float 90127 $< > $@/output
|
||||
@grep -qE '^632719$$' $@/output
|
||||
|
||||
$(eval $(call maketest,if1,qcc))
|
||||
if1:
|
||||
@$(VM) -float 1 -float 100 -float 10000 $< > $@/output
|
||||
@grep -qE '^One$$' $@/output
|
||||
@$(VM) -float 2 -float 100 -float 10000 $< > $@/output
|
||||
@grep -qE '^Two$$' $@/output
|
||||
@$(VM) -float 3 -float 100 -float 10000 $< > $@/output
|
||||
@grep -qE '^Three$$' $@/output
|
||||
@$(VM) -float 4 -float 100 -float 10000 $< > $@/output
|
||||
@grep -qE '^Else$$' $@/output
|
||||
|
||||
$(eval $(call maketest,loops1,qcc))
|
||||
loops1:
|
||||
@$(VM) -float 0 $< > $@/output
|
||||
@diff $@/output $@/0.expected
|
||||
@$(VM) -float 1 $< > $@/output
|
||||
@diff $@/output $@/1.expected
|
||||
@$(VM) -float 4 $< > $@/output
|
||||
@diff $@/output $@/4.expected
|
||||
@$(VM) -float 10 $< > $@/output
|
||||
@diff $@/output $@/10.expected
|
||||
|
||||
$(eval $(call maketest,maths1,qcc))
|
||||
maths1:
|
||||
@$(VM) -float 0 -float 3 $< > $@/output
|
||||
@diff $@/output $@/0.3.expected
|
||||
@$(VM) -float 3 -float 6 $< > $@/output
|
||||
@diff $@/output $@/3.6.expected
|
||||
@$(VM) -float 0 -float 0 $< > $@/output
|
||||
@diff $@/output $@/0.0.expected
|
||||
|
||||
$(eval $(call maketest,maths2,qcc))
|
||||
maths2:
|
||||
@$(VM) -vector '1 2 3' -vector '4 5 6' $< > $@/output
|
||||
@grep -qE '^dot = 32$$' $@/output
|
||||
@$(VM) -vector '-5 12 5.5' -vector '4 -5 1' $< > $@/output
|
||||
@grep -qE '^dot = -74.5$$' $@/output
|
||||
@$(VM) -vector '-5 12 5.5' -vector '0 0 0' $< > $@/output
|
||||
@grep -qE '^dot = 0$$' $@/output
|
||||
|
||||
$(eval $(call maketest,equality,qcc))
|
||||
equality:
|
||||
@$(VM) -float 1 -float 1 $< > $@/output
|
||||
@diff $@/output $@/1.1.expected
|
||||
@$(VM) -float 1 -float 0 $< > $@/output
|
||||
@diff $@/output $@/1.0.expected
|
||||
@$(VM) -float 0 -float 1 $< > $@/output
|
||||
@diff $@/output $@/0.1.expected
|
||||
|
||||
$(eval $(call maketest,fields1,qcc))
|
||||
fields1:
|
||||
@$(VM) -vector '150 2000 150' -vector '220 1300 -200' $< > $@/output
|
||||
@diff $@/output $@/expected
|
||||
|
||||
invalid-types-ok: obj invalid-types/assign.qc invalid-types/op.qc invalid-types/call1.qc invalid-types/call2.qc invalid-types/call3.qc
|
||||
@echo "Testing: invalid-types"
|
||||
@if $(QCC) -std=qcc -o obj/invalid.dat invalid-types/op.qc > obj/invalid.out 2>&1 ; then echo "Successfully compiled a file which was supposed to fail: op.qc" ; false ; else true ; fi
|
||||
@if $(QCC) -std=qcc -o obj/invalid.dat invalid-types/call1.qc > obj/invalid.out 2>&1 ; then echo "Successfully compiled a file which was supposed to fail: call1.qc" ; false ; else true ; fi
|
||||
@if $(QCC) -std=qcc -o obj/invalid.dat invalid-types/call2.qc > obj/invalid.out 2>&1 ; then echo "Successfully compiled a file which was supposed to fail: call2.qc" ; false ; else true ; fi
|
||||
@if $(QCC) -std=qcc -o obj/invalid.dat invalid-types/call3.qc > obj/invalid.out 2>&1 ; then echo "Successfully compiled a file which was supposed to fail: call3.qc" ; false ; else true ; fi
|
||||
@if $(QCC) -std=qcc -o obj/invalid.dat invalid-types/assign.qc > obj/invalid.out 2>&1 ; then echo "Successfully compiled a file which was supposed to fail: assign.qc" ; false ; else true ; fi
|
||||
@touch obj/invalid-types-ok
|
||||
|
||||
invalid-types: invalid-types-ok
|
||||
|
||||
$(eval $(call maketest,ngraphs,qcc))
|
||||
ngraphs:
|
||||
@$(VM) $< > $@/output
|
||||
@diff $@/output $@/expected
|
||||
|
||||
invalid-assign-ok: obj invalid-assign/main.qc
|
||||
@echo "Testing: invalid-assign"
|
||||
@if $(QCC) -std=qcc -o obj/invalid.dat invalid-assign/main.qc > obj/invalid.out 2>&1 ; then echo "Successfully compiled a file which was supposed to fail: invalid-assign/main.qc" ; false ; else true ; fi
|
||||
|
||||
invalid-assign: invalid-assign-ok
|
||||
|
||||
$(eval $(call maketest,field-parameters,qcc))
|
||||
field-parameters:
|
||||
@$(VM) $< > $@/output
|
||||
@diff $@/output $@/expected
|
||||
|
||||
$(eval $(call maketest,functions-as-parameters,qcc))
|
||||
functions-as-parameters:
|
||||
@$(VM) $< > $@/output
|
||||
@diff $@/output $@/expected
|
||||
|
||||
$(eval $(call maketest,shadow-qcc,qcc))
|
||||
shadow-qcc:
|
||||
@$(VM) -vector '33 44 55' $< > $@/output
|
||||
@diff $@/output $@/expected
|
||||
|
||||
$(eval $(call maketest,shadow-gmqcc,gm))
|
||||
shadow-gmqcc:
|
||||
@$(VM) -vector '33 44 55' $< > $@/output
|
||||
@diff $@/output $@/expected
|
||||
|
||||
#######################################################################
|
||||
obj:
|
||||
mkdir obj
|
||||
|
||||
../gmqcc:
|
||||
$(MAKE) -C ..
|
||||
|
||||
../qcvm:
|
||||
$(MAKE) -C .. qcvm
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
void(string) print = #1;
|
||||
|
||||
void(string what) main = {
|
||||
print(what);
|
||||
print("\n");
|
||||
};
|
|
@ -1,14 +0,0 @@
|
|||
void(string, ...) print = #1;
|
||||
string(float) ftos = #2;
|
||||
|
||||
float(float x, float y, float z) sum = {
|
||||
return x + y + z;
|
||||
};
|
||||
|
||||
void(float a, float b, float c) main = {
|
||||
local float f;
|
||||
f = sum(sum(a, sum(a, b, c), c),
|
||||
sum(sum(sum(a, b, c), b, sum(a, b, c)), b, sum(a, b, sum(a, b, c))),
|
||||
sum(sum(a, b, c), b, c));
|
||||
print(ftos(f), "\n");
|
||||
};
|
|
@ -1,3 +0,0 @@
|
|||
ne
|
||||
lt
|
||||
le
|
|
@ -1,3 +0,0 @@
|
|||
ne
|
||||
gt
|
||||
ge
|
|
@ -1,3 +0,0 @@
|
|||
eq
|
||||
ge
|
||||
le
|
|
@ -1,11 +0,0 @@
|
|||
void(string, ...) print = #1;
|
||||
string(float) ftos = #2;
|
||||
|
||||
void(float a, float b) main = {
|
||||
if (a == b) print("eq\n");
|
||||
if (a != b) print("ne\n");
|
||||
if (a > b) print("gt\n");
|
||||
if (a < b) print("lt\n");
|
||||
if (a >= b) print("ge\n");
|
||||
if (a <= b) print("le\n");
|
||||
};
|
|
@ -1 +0,0 @@
|
|||
bar
|
|
@ -1,17 +0,0 @@
|
|||
void(string, string) print = #1;
|
||||
entity() spawn = #3;
|
||||
|
||||
.string a;
|
||||
.string b;
|
||||
|
||||
void(entity e, .string s) callout = {
|
||||
print(e.s, "\n");
|
||||
};
|
||||
|
||||
void() main = {
|
||||
local entity e;
|
||||
e = spawn();
|
||||
e.a = "foo";
|
||||
e.b = "bar";
|
||||
callout(e, b);
|
||||
};
|
|
@ -1,5 +0,0 @@
|
|||
Field: void at 0
|
||||
Field: float globf at 0
|
||||
Field: vector globv at 1
|
||||
Field: string globs at 4
|
||||
Field: function globfunc at 5
|
|
@ -1,4 +0,0 @@
|
|||
.float globf;
|
||||
.vector globv;
|
||||
.string globs;
|
||||
.void() globfunc;
|
|
@ -1,3 +0,0 @@
|
|||
spot1 = '150 2000 175'
|
||||
spot2 = '220 1300 -175'
|
||||
vis: 0
|
|
@ -1,43 +0,0 @@
|
|||
void(string, ...) print = #1;
|
||||
string(float) ftos = #2;
|
||||
entity() spawn = #3;
|
||||
string(vector) vtos = #5;
|
||||
void(string, ...) error = #6;
|
||||
|
||||
entity self;
|
||||
|
||||
.vector origin;
|
||||
.vector view;
|
||||
|
||||
entity() make = {
|
||||
local entity e;
|
||||
e = spawn();
|
||||
e.view = '0 0 25';
|
||||
return e;
|
||||
};
|
||||
|
||||
float(entity targ) visible = {
|
||||
local vector spot1, spot2;
|
||||
spot1 = self.origin + self.view;
|
||||
spot2 = targ.origin + targ.view;
|
||||
|
||||
print("spot1 = ", vtos(spot1), "\n");
|
||||
print("spot2 = ", vtos(spot2), "\n");
|
||||
// This was part of some QC code which had a bug
|
||||
// we don't actually return anything important here.
|
||||
return 0;
|
||||
};
|
||||
|
||||
void(vector a, vector b) main = {
|
||||
local entity targ;
|
||||
|
||||
self = make();
|
||||
targ = make();
|
||||
if (self == targ)
|
||||
error("ERROR, self == targ\n");
|
||||
|
||||
self.origin = a;
|
||||
targ.origin = b;
|
||||
|
||||
print("vis: ", ftos(visible(targ)), "\n");
|
||||
};
|
|
@ -1 +0,0 @@
|
|||
correct
|
|
@ -1,13 +0,0 @@
|
|||
void(string, string) print = #1;
|
||||
|
||||
string() getter = {
|
||||
return "correct";
|
||||
};
|
||||
|
||||
void(string() f) printer = {
|
||||
print(f(), "\n");
|
||||
};
|
||||
|
||||
void() main = {
|
||||
printer(getter);
|
||||
};
|
|
@ -1,5 +0,0 @@
|
|||
Global: void at 0
|
||||
Global: float globf at 28
|
||||
Global: vector globv at 29
|
||||
Global: string globs at 32
|
||||
Global: function globfunc at 33
|
|
@ -1,4 +0,0 @@
|
|||
float globf;
|
||||
vector globv;
|
||||
string globs;
|
||||
void() globfunc;
|
|
@ -1,12 +0,0 @@
|
|||
void(string, ...) print = #1;
|
||||
|
||||
void(float c) main = {
|
||||
if (c == 1)
|
||||
print("One\n");
|
||||
else if (c == 2)
|
||||
print("Two\n");
|
||||
else if (c == 3)
|
||||
print("Three\n");
|
||||
else
|
||||
print("Else\n");
|
||||
};
|
|
@ -1,4 +0,0 @@
|
|||
void() main = {
|
||||
local float x;
|
||||
x + 3 = 5;
|
||||
};
|
|
@ -1,5 +0,0 @@
|
|||
void() main = {
|
||||
local float x;
|
||||
local entity e;
|
||||
x = e;
|
||||
};
|
|
@ -1,6 +0,0 @@
|
|||
void(float, string, entity) fun = #1;
|
||||
|
||||
void() main = {
|
||||
local float x;
|
||||
fun(x, x, x);
|
||||
};
|
|
@ -1,6 +0,0 @@
|
|||
void(float, string, entity) fun = #1;
|
||||
|
||||
void() main = {
|
||||
local string x;
|
||||
fun(x, x, x);
|
||||
};
|
|
@ -1,6 +0,0 @@
|
|||
void(float, string, entity) fun = #1;
|
||||
|
||||
void() main = {
|
||||
local entity x;
|
||||
fun(x, x, x);
|
||||
};
|
|
@ -1,5 +0,0 @@
|
|||
void() main = {
|
||||
local float x, y;
|
||||
local entity e;
|
||||
x = y + e;
|
||||
};
|
|
@ -1 +0,0 @@
|
|||
do 0
|
|
@ -1,3 +0,0 @@
|
|||
for 0
|
||||
while 0
|
||||
do 0
|
|
@ -1,30 +0,0 @@
|
|||
for 0
|
||||
for 1
|
||||
for 2
|
||||
for 3
|
||||
for 4
|
||||
for 5
|
||||
for 6
|
||||
for 7
|
||||
for 8
|
||||
for 9
|
||||
while 0
|
||||
while 1
|
||||
while 2
|
||||
while 3
|
||||
while 4
|
||||
while 5
|
||||
while 6
|
||||
while 7
|
||||
while 8
|
||||
while 9
|
||||
do 0
|
||||
do 1
|
||||
do 2
|
||||
do 3
|
||||
do 4
|
||||
do 5
|
||||
do 6
|
||||
do 7
|
||||
do 8
|
||||
do 9
|
|
@ -1,12 +0,0 @@
|
|||
for 0
|
||||
for 1
|
||||
for 2
|
||||
for 3
|
||||
while 0
|
||||
while 1
|
||||
while 2
|
||||
while 3
|
||||
do 0
|
||||
do 1
|
||||
do 2
|
||||
do 3
|
|
@ -1,22 +0,0 @@
|
|||
void(string, ...) print = #1;
|
||||
string(float) ftos = #2;
|
||||
|
||||
void(float n) main = {
|
||||
local float i;
|
||||
|
||||
for (i = 0; i < n; i += 1) {
|
||||
print("for ", ftos(i), "\n");
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (i < n) {
|
||||
print("while ", ftos(i), "\n");
|
||||
i += 1;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
print("do ", ftos(i), "\n");
|
||||
i += 1;
|
||||
} while (i < n);
|
||||
};
|
|
@ -1,8 +0,0 @@
|
|||
input: 0 and 0
|
||||
+ 0
|
||||
* 0
|
||||
/ 0
|
||||
& 0
|
||||
| 0
|
||||
&& 0
|
||||
|| 0
|
|
@ -1,8 +0,0 @@
|
|||
input: 0 and 3
|
||||
+ 3
|
||||
* 0
|
||||
/ 0
|
||||
& 0
|
||||
| 3
|
||||
&& 0
|
||||
|| 1
|
|
@ -1,8 +0,0 @@
|
|||
input: 3 and 6
|
||||
+ 9
|
||||
* 18
|
||||
/ 0.5
|
||||
& 2
|
||||
| 7
|
||||
&& 1
|
||||
|| 1
|
|
@ -1,14 +0,0 @@
|
|||
void(string, ...) print = #1;
|
||||
string(float) ftos = #2;
|
||||
string(vector) vtos = #5;
|
||||
|
||||
void(float a, float b) main = {
|
||||
print("input: ", ftos(a), " and ", ftos(b), "\n");
|
||||
print("+ ", ftos(a+b), "\n");
|
||||
print("* ", ftos(a*b), "\n");
|
||||
print("/ ", ftos(a/b), "\n");
|
||||
print("& ", ftos(a&b), "\n");
|
||||
print("| ", ftos(a|b), "\n");
|
||||
print("&& ", ftos(a&&b), "\n");
|
||||
print("|| ", ftos(a||b), "\n");
|
||||
};
|
|
@ -1,6 +0,0 @@
|
|||
void(string, ...) print = #1;
|
||||
string(float) ftos = #2;
|
||||
|
||||
void(vector a, vector b) main = {
|
||||
print("dot = ", ftos(a*b), "\n");
|
||||
};
|
|
@ -1,2 +0,0 @@
|
|||
#^[]|{}~\%>
|
||||
#^[]|{}~\%>
|
|
@ -1,6 +0,0 @@
|
|||
void(string, string) print = %:1;
|
||||
|
||||
void() main = ??<
|
||||
print("??=??'??(??)??!??<??>??-??/??/%>", "??/n");
|
||||
print("#^[]|{}~\\%>", "\n");
|
||||
%>;
|
|
@ -1 +0,0 @@
|
|||
'0 0 0'
|
|
@ -1,7 +0,0 @@
|
|||
void(string, string) print = #1;
|
||||
string(vector) vtos = #5;
|
||||
|
||||
void(vector org) main = {
|
||||
local vector org;
|
||||
print(vtos(org), "\n");
|
||||
};
|
|
@ -1 +0,0 @@
|
|||
'33 44 55'
|
|
@ -1,7 +0,0 @@
|
|||
void(string, string) print = #1;
|
||||
string(vector) vtos = #5;
|
||||
|
||||
void(vector org) main = {
|
||||
local vector org;
|
||||
print(vtos(org), "\n");
|
||||
};
|
|
@ -1,5 +0,0 @@
|
|||
void(string, ...) print = #1;
|
||||
|
||||
void(string what) main = {
|
||||
print(what, "\n");
|
||||
};
|
9
util.c
9
util.c
|
@ -521,6 +521,15 @@ FILE *util_fopen(const char *filename, const char *mode)
|
|||
#endif
|
||||
}
|
||||
|
||||
bool util_filexists(const char *file) {
|
||||
FILE *fp = fopen(file, "rb");
|
||||
if (!fp) return false;
|
||||
|
||||
/* it exists */
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
void _util_vec_grow(void **a, size_t i, size_t s) {
|
||||
size_t m = *a ? 2*_vec_beg(*a)+i : i+1;
|
||||
void *p = mem_r((*a ? _vec_raw(*a) : NULL), s * m + sizeof(size_t)*2);
|
||||
|
|
Loading…
Reference in a new issue