From 07634df3dced26f0c1eb3ff03cab517bd82353b1 Mon Sep 17 00:00:00 2001 From: Ian Piumarta Date: Wed, 5 Feb 2025 12:44:57 +0900 Subject: [PATCH] handle command-line arguments properly --- Makefile | 15 ++++-- main.leg | 154 +++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 110 insertions(+), 59 deletions(-) diff --git a/Makefile b/Makefile index d79b67b..aec5803 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,8 @@ -CFLAGS = -std=c99 -Werror -Wall -Wno-unused -g +CFLAGS = -std=c99 -Werror -Wall -Wno-unused -g +OFLAGS = -std=c99 -Werror -Wall -Wno-unused -DNDEBUG -O2 CPPFLAGS = -I/opt/local/include -LDFLAGS = -L/opt/local/lib -LDLIBS = -lgc -lm +LDFLAGS = -L/opt/local/lib +LDLIBS = -lgc -lm all : main @@ -11,6 +12,9 @@ all : main % : %.c $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS) +opt : main.c + $(CC) $(OFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS) + test : main ./main -vv test.txt @@ -20,10 +24,13 @@ demo : main demov : main for i in demofiles/*.c; do echo $$i; ./main -vv $$i; done +bench : opt + time ./opt bench.c 28 + spotless : clean rm -rf *~ *.dSYM clean : .FORCE - rm -f main + rm -f main opt .FORCE : diff --git a/main.leg b/main.leg index 7a335ee..7768371 100644 --- a/main.leg +++ b/main.leg @@ -1,6 +1,6 @@ # main.leg -- C parser + interpreter # -# Last edited: 2025-02-04 09:10:32 by piumarta on xubuntu +# Last edited: 2025-02-05 12:43:42 by piumarta on m1mbp %{ ; @@ -1832,12 +1832,12 @@ ddector = ( LPAREN d:decltor RPAREN )* { $$ = d } params = LPAREN a:mkList - ( p:pdecl { List_append(a, p) } - ( COMMA p:pdecl { List_append(a, p) } - )* )? ( ( COMMA ETC { List_append(a, t_etc) } - )? RPAREN { $$ = a } - | e:error { expected(e, "parameter declaration") } - ) + ( p:pdecl { List_append(a, p) } + ( COMMA p:pdecl { List_append(a, p) } + )* )? ( ( COMMA ETC { List_append(a, t_etc) } + )? RPAREN { $$ = a } + | e:error { expected(e, "parameter declaration") } + ) pdecl = t:tname d:decltor { $$ = newVariable(d, t, nil) } @@ -2699,7 +2699,22 @@ oop typeCheck(oop exp, oop fntype) toString(lhs), toString(rhs)); break; } - case SUB: assert(!"unimplemented"); break; + case SUB: { + if (lhs == rhs) { + if (t_int == lhs) return lhs; + if (t_float == lhs) return lhs; + } + if (is(Tpointer, lhs) && t_int == rhs) { + return lhs; + } + if (is(Tpointer, lhs) && is(Tpointer, rhs)) { + return t_long; + } + fatal("%scannot subtract '%s' and '%s'", + tokloc(get(exp, Binary,token)), + toString(lhs), toString(rhs)); + break; + } case SHL: assert(!"unimplemented"); break; case SHR: assert(!"unimplemented"); break; case LT: return t_int; @@ -2723,7 +2738,7 @@ oop typeCheck(oop exp, oop fntype) fatal("%sarray index is not 'int': %s", tokloc(get(exp, Index,token)), toString(get(exp, Index,rhs))); switch (getType(lhs)) { - case Tpointer: assert(!"unimplemented"); + case Tpointer: return get(lhs, Tpointer,target); case Tarray: return get(lhs, Tarray,target); default: fatal("'%s' is not indexable: %s", toString(lhs), toString(exp)); } @@ -3123,30 +3138,6 @@ oop getPointer(oop ptr) return 0; } -oop getArray(oop array, int index) -{ - int size = get(array, Array,size); - if (index < 0) fatal("array index is negative"); - if (index >= size) fatal("array index out of bounds"); - oop base = get(array, Array,base); - oop type = get(get(array, Array,type), Tarray,target); - int scale = typeSize(type); - assert(is(Memory, base)); - void *addr = get(base, Memory,base) + index * scale; - assert(addr < get(base, Memory,base) + get(base, Memory,size)); - switch (getType(type)) { - case Tchar: return newInteger(*(char *)addr); - case Tshort: return newInteger(*(short *)addr); - case Tint: return newInteger(*(int *)addr); - case Tlong: return newInteger(*(long *)addr); - case Tfloat: return newFloat (*(float *)addr); - case Tdouble: return newFloat (*(double *)addr); - default: break; - } - fatal("cannot load '%s' from array", getTypeName(type)); - return 0; -} - oop getMemory(oop memory, int offset, oop type) { int memsize = get(memory, Memory,size); @@ -3166,6 +3157,7 @@ oop getMemory(oop memory, int offset, oop type) oop target = get(type, Tpointer,target); switch (getType(target)) { case Tstruct: return newPointer(type, newMemory(value, typeSize(target)), 0); + case Tchar: return newPointer(t_pchar, newMemory(value, strlen(value)+1), 0); default: break; } fatal("cannot load pointer to '%s' from memory", getTypeName(target)); @@ -3220,7 +3212,7 @@ oop setMemory(oop memory, int offset, oop type, oop value) return 0; } -oop setArray(oop array, int index, oop value) +oop getArray(oop array, int index) { int size = get(array, Array,size); if (index < 0) fatal("array index is negative"); @@ -3231,6 +3223,36 @@ oop setArray(oop array, int index, oop value) assert(is(Memory, base)); void *addr = get(base, Memory,base) + index * scale; assert(addr < get(base, Memory,base) + get(base, Memory,size)); + switch (getType(type)) { + case Tchar: return newInteger(*(char *)addr); + case Tshort: return newInteger(*(short *)addr); + case Tint: return newInteger(*(int *)addr); + case Tlong: return newInteger(*(long *)addr); + case Tfloat: return newFloat (*(float *)addr); + case Tdouble: return newFloat (*(double *)addr); + case Tpointer: return getMemory(base, scale * index, type); + default: break; + } + fatal("cannot load '%s' from array", getTypeName(type)); + return 0; +} + +oop setArray(oop array, int index, oop value) +{ + int size = get(array, Array,size); + if (index < 0) fatal("array index is negative"); + if (index >= size) fatal("array index out of bounds"); + oop base = get(array, Array,base); + oop type = get(array, Array,type); + switch (getType(type)) { + case Tarray: type = get(type, Tarray,target); break; + case Tpointer: type = get(type, Tpointer,target); break; + default: assert(0); + } + int scale = typeSize(type); + assert(is(Memory, base)); + void *addr = get(base, Memory,base) + index * scale; + assert(addr < get(base, Memory,base) + get(base, Memory,size)); switch (getType(type)) { case Tchar: return newInteger(*(char *)addr = _integerValue(value)); case Tshort: return newInteger(*(short *)addr = _integerValue(value)); @@ -3238,6 +3260,10 @@ oop setArray(oop array, int index, oop value) case Tlong: return newInteger(*(long *)addr = _integerValue(value)); case Tfloat: return newFloat (*(float *)addr = _floatValue(value)); case Tdouble: return newFloat (*(double *)addr = _floatValue(value)); + case Tpointer: { + setMemory(base, scale * index, type, value); + return value; + } default: break; } fatal("cannot store '%s' into array", getTypeName(type)); @@ -3806,7 +3832,8 @@ oop eval(oop exp) int index = _integerValue(ondex); oop lhs = eval(get(exp, Index,lhs)); switch (getType(lhs)) { - case Array: RETURN(getArray(lhs, index)); + case Array: RETURN(getArray(lhs, index)); + case Pointer: assert(0); default: break; } println(lhs); @@ -4710,35 +4737,52 @@ int main(int argc, char **argv) Scope_begin(); // the global scope - int repls = 0; - - for (int argn = 1; argn < argc;) { - char *arg = argv[argn++]; - if (*arg != '-') { - replPath(arg); - ++repls; - } - else { - while (*++arg) { - switch (*arg) { - case 'O': ++opt_O; continue; - case 'v': ++opt_v; continue; - case 'x': ++opt_x; continue; - default: fatal("uknown option '%c'", *arg); - } + int argn = 1; + + while (argn < argc) { + char *arg = argv[argn]; + if (*arg != '-') break; + ++argn; + while (*++arg) { + switch (*arg) { + case 'O': ++opt_O; continue; + case 'v': ++opt_v; continue; + case 'x': ++opt_x; continue; + default: fatal("uknown option '%c'", *arg); } } } - if (!repls) replFile("stdin", stdin); + oop args = newList(); + if (argn == argc) fatal("no program file specified"); + + char *program = argv[argn++]; + replPath(program); + List_append(args, newStringWith(program)); + + while (argn < argc) + List_append(args, newStringWith(argv[argn++])); + + int cargs = List_size(args); + int vsize = sizeof(char *) * cargs; + oop vargs = newArray(newTarray(t_pchar, newInteger(cargs)), + newMemory(malloc(vsize), vsize), + cargs); + List_do(args, arg) { + char *elts = String_cString(arg); + oop mem = newMemory(elts, get(arg, String,size)); + setArray(vargs, do_index, newPointer(t_pchar, mem, 0)); + } - oop args = newList(); - List_append(args, newInteger(1)); - List_append(args, newStringWith("main")); + args = newList(); + List_append(args, newInteger(cargs)); + List_append(args, vargs); + List_append(args, newPointer(t_ppchar, newMemory(0, 0), 0)); oop entry = Scope_lookup(intern("main")); if (!entry || isNil(entry)) fatal("main is not defined"); if (!is(Function, entry)) fatal("main is not a function"); + oop params = get(get(entry, Function,type), Tfunction, parameters); switch (List_size(params)) { default: