From 93e8020fff52ae89e3b4935fa45acf9c3ce36e0f Mon Sep 17 00:00:00 2001 From: Ian Piumarta Date: Tue, 28 Jan 2025 12:33:01 +0900 Subject: [PATCH] handle array indexing and integer multiplication --- Makefile | 4 +- demofiles/segmentation-fault.c | 2 +- demofiles/use-after-free.c | 2 +- main.leg | 612 +++++++++++++++++++++------------ test.txt | 7 + 5 files changed, 404 insertions(+), 223 deletions(-) diff --git a/Makefile b/Makefile index 744e7b2..b5c569c 100644 --- a/Makefile +++ b/Makefile @@ -15,10 +15,10 @@ test : main ./main -vv test.txt demo : main - for i in demofiles/*.c; do echo $$i; ./main -x < $$i; done + for i in demofiles/*.c; do echo $$i; ./main $$i; done demov : main - for i in demofiles/*.c; do echo $$i; ./main -x -vv < $$i; done + for i in demofiles/*.c; do echo $$i; ./main -vv $$i; done spotless : clean rm -rf *~ *.dSYM diff --git a/demofiles/segmentation-fault.c b/demofiles/segmentation-fault.c index 97809fe..051dd93 100644 --- a/demofiles/segmentation-fault.c +++ b/demofiles/segmentation-fault.c @@ -3,7 +3,7 @@ #include int main() { - int *ptr = NULL; + int *ptr = (void *)0; // NULL; *ptr = 42; return 0; } diff --git a/demofiles/use-after-free.c b/demofiles/use-after-free.c index 0a1dbf8..2058ffb 100644 --- a/demofiles/use-after-free.c +++ b/demofiles/use-after-free.c @@ -6,7 +6,7 @@ int main() { int *ptr = malloc(sizeof(*ptr)); - assert(ptr); + assert(ptr != 0); *ptr = 42; free(ptr); printf("%d\n", *ptr); // use after free diff --git a/main.leg b/main.leg index 0185333..9f2b6c2 100644 --- a/main.leg +++ b/main.leg @@ -1,6 +1,6 @@ # main.leg -- C parser + interpreter # -# Last edited: 2025-01-28 04:46:58 by piumarta on zora +# Last edited: 2025-01-28 12:32:11 by piumarta on zora-1043.local %{ ; @@ -56,21 +56,20 @@ typedef union Object Object, *oop; #define YYSTYPE oop -#define _do_types(_) \ - _(Undefined) _(Input) _(Integer) _(Float) _(Pointer) _(Symbol) _(Pair) _(String) _(Array) \ - _(Memory) _(Reference) _(Closure) _(Call) _(Block) \ - _(Addressof) _(Dereference) _(Sizeof) _(Unary) _(Binary) _(Assign) _(Cast) \ - _(While) _(For) _(If) _(Return) _(Continue) _(Break) \ - _(Tvoid) _(Tchar) _(Tshort) _(Tint) _(Tlong) _(Tfloat) _(Tdouble) \ - _(Tpointer) _(Tarray) _(Tstruct) _(Tfunction) _(Tetc) \ - _(Scope) _(TypeName) _(Variable) _(Constant) _(Function) _(Primitive) \ +#define _do_types(_) \ + _(Undefined) _(Input) _(Integer) _(Float) _(Pointer) _(Array) _(Symbol) _(Pair) _(String) _(List) \ + _(Memory) _(Reference) _(Closure) _(Call) _(Block) \ + _(Addressof) _(Dereference) _(Sizeof) _(Unary) _(Binary) _(Index) _(Assign) _(Cast) \ + _(While) _(For) _(If) _(Return) _(Continue) _(Break) \ + _(Tvoid) _(Tchar) _(Tshort) _(Tint) _(Tlong) _(Tfloat) _(Tdouble) \ + _(Tpointer) _(Tarray) _(Tstruct) _(Tfunction) _(Tetc) \ + _(Scope) _(TypeName) _(Variable) _(Constant) _(Function) _(Primitive) \ _(VarDecls) _(TypeDecls) #define _do_unaries(_) \ _(NEG) _(NOT) _(COM) _(PREINC) _(PREDEC) _(POSTINC) _(POSTDEC) #define _do_binaries(_) \ - _(INDEX) \ _(MUL) _(DIV) _(MOD) _(ADD) _(SUB) _(SHL) _(SHR) \ _(LT) _(LE) _(GE) _(GT) _(EQ) _(NE) \ _(BAND) _(BXOR) _(BOR) _(LAND) _(LOR) @@ -115,10 +114,11 @@ struct Input { type_t _type; char *name; FILE *file; oop next; }; struct Integer { type_t _type; long value; }; struct Float { type_t _type; double value; }; struct Pointer { type_t _type; oop type, base; int offset; }; +struct Array { type_t _type; oop type, base; int size; }; struct Symbol { type_t _type; char *name; oop value; }; struct Pair { type_t _type; oop head, tail; }; struct String { type_t _type; int size; char *elements; }; -struct Array { type_t _type; int size; oop *elements; }; +struct List { type_t _type; int size; oop *elements; }; struct Memory { type_t _type; void *base; size_t size; }; struct Reference { type_t _type; oop target; }; struct Closure { type_t _type; oop function, environment; }; @@ -129,6 +129,7 @@ struct Dereference { type_t _type; oop rhs; }; struct Sizeof { type_t _type; oop rhs, size; }; struct Unary { type_t _type; unary_t operator; oop rhs; }; struct Binary { type_t _type; binary_t operator; oop lhs, rhs; }; +struct Index { type_t _type; oop lhs, rhs; }; struct Assign { type_t _type; oop lhs, rhs; }; struct Cast { type_t _type; oop type, rhs; cvt_t converter; }; struct While { type_t _type; oop condition, expression; }; @@ -252,6 +253,15 @@ oop newPointer(oop type, oop base, int offset) return obj; } +oop newArray(oop type, oop base, int size) +{ + oop obj = new(Array); + obj->Array.type = type; + obj->Array.base = base; + obj->Array.size = size; + return obj; +} + oop newFloat(double value) { # if TAGFLOAT @@ -458,89 +468,89 @@ char *String_format(oop string, char *format, ...) return buf; } -#define Array_do(ARR, VAR) \ - for (oop do_array = (ARR), VAR = nil; do_array; do_array = 0) \ - for (int do_size = get(do_array, Array,size), do_index = 0; \ - do_index < do_size && (VAR = do_array->Array.elements[do_index]); \ +#define List_do(ARR, VAR) \ + for (oop do_list = (ARR), VAR = nil; do_list; do_list = 0) \ + for (int do_size = get(do_list, List,size), do_index = 0; \ + do_index < do_size && (VAR = do_list->List.elements[do_index]); \ ++do_index) -oop newArray(void) +oop newList(void) { - oop obj = new(Array); - obj->Array.elements = 0; // empty array - obj->Array.size = 0; + oop obj = new(List); + obj->List.elements = 0; // empty list + obj->List.size = 0; return obj; } -oop Array_append(oop array, oop element) +oop List_append(oop list, oop element) { - oop *elements = get(array, Array,elements); - int size = get(array, Array,size); + oop *elements = get(list, List,elements); + int size = get(list, List,size); elements = REALLOC(elements, sizeof(*elements) * (size + 1)); - set(array, Array,elements, elements); - set(array, Array,size, size + 1); + set(list, List,elements, elements); + set(list, List,size, size + 1); return elements[size] = element; } -oop newArray1(oop a) +oop newList1(oop a) { - oop obj = newArray(); - Array_append(obj, a); + oop obj = newList(); + List_append(obj, a); return obj; } -oop newArray2(oop a, oop b) +oop newList2(oop a, oop b) { - oop obj = newArray1(a); - Array_append(obj, b); + oop obj = newList1(a); + List_append(obj, b); return obj; } -int Array_size(oop array) +int List_size(oop list) { - return get(array, Array,size); + return get(list, List,size); } -oop Array_last(oop array) +oop List_last(oop list) { - int size = get(array, Array,size); - oop *elts = get(array, Array,elements); + int size = get(list, List,size); + oop *elts = get(list, List,elements); assert(size > 0); return elts[size - 1]; } -oop Array_popLast(oop array) +oop List_popLast(oop list) { - int size = get(array, Array,size); - oop *elts = get(array, Array,elements); + int size = get(list, List,size); + oop *elts = get(list, List,elements); assert(size > 0); oop last = elts[--size]; elts[size] = nil; - set(array, Array,size, size); + set(list, List,size, size); return last; } -oop Array_get(oop array, int index) +oop List_get(oop list, int index) { - oop *elements = get(array, Array,elements); - int size = get(array, Array,size); - if (index >= size) fatal("array index %d out of bounds %d", index, size); + oop *elements = get(list, List,elements); + int size = get(list, List,size); + if (index >= size) fatal("list index %d out of bounds %d", index, size); return elements[index]; } -oop Array_set(oop array, int index, oop element) +oop List_set(oop list, int index, oop element) { - oop *elements = get(array, Array,elements); - int size = get(array, Array,size); - if (index >= size) fatal("array index %d out of bounds %d", index, size); + oop *elements = get(list, List,elements); + int size = get(list, List,size); + if (index >= size) fatal("list index %d out of bounds %d", index, size); return elements[index] = element; } -int Array_equal(oop array, oop brray) +int List_equal(oop list, oop brray) { - if (Array_size(array) != Array_size(brray)) return 0; - Array_do(array, a) { - oop b = get(brray, Array,elements)[do_index]; + if (List_size(list) != List_size(brray)) return 0; + List_do(list, a) { + oop b = get(brray, List,elements)[do_index]; if (a != b) return 0; } return 1; @@ -550,13 +560,13 @@ struct keyval { oop key, val; }; oop newMap(void) { - return newArray(); + return newList(); } int Map_find(oop map, oop key) { - int size = get(map, Array,size) / 2; - struct keyval *kvs = (struct keyval *)get(map, Array,elements); + int size = get(map, List,size) / 2; + struct keyval *kvs = (struct keyval *)get(map, List,elements); int lo = 0, hi = size - 1; while (lo <= hi) { int mi = (lo + hi) / 2; @@ -569,8 +579,8 @@ int Map_find(oop map, oop key) oop Map_set(oop map, oop key, oop val) { - int size = get(map, Array,size) / 2; - struct keyval *kvs = (struct keyval *)get(map, Array,elements); + int size = get(map, List,size) / 2; + struct keyval *kvs = (struct keyval *)get(map, List,elements); int index = Map_find(map, key); if (index > 0) return kvs[index].val = val; index = -1 - index; @@ -586,7 +596,7 @@ oop Map_set(oop map, oop key, oop val) oop Map_get(oop map, oop key) { - struct keyval *kvs = (struct keyval *)get(map, Array,elements); + struct keyval *kvs = (struct keyval *)get(map, List,elements); int index = Map_find(map, key); if (index < 0) fatal("key not found in map"); return kvs[index].val; @@ -632,6 +642,7 @@ oop newBinary(binary_t operator, oop lhs, oop rhs) return obj; } +CTOR2(Index, lhs, rhs); CTOR2(Assign, lhs, rhs); oop newCast(oop type, oop rhs) @@ -690,27 +701,27 @@ oop t_ppchar = 0; oop newTpointer(oop target) { static oop pointers = 0; - if (!pointers) pointers = newArray(); - Array_do(pointers, t) + if (!pointers) pointers = newList(); + List_do(pointers, t) if (target == get(t, Tpointer,target)) return t; // uniqe types allow comparison by identity oop obj = new(Tpointer); obj->Tpointer.target = target; - Array_append(pointers, obj); + List_append(pointers, obj); return obj; } oop newTarray(oop target, oop size) { static oop arrays = 0; - if (!arrays) arrays = newArray(); - Array_do(arrays, t) + if (!arrays) arrays = newList(); + List_do(arrays, t) if (target == get(t, Tarray,target) && size == get(t, Tarray,size)) return t; // uniqe types allow comparison by identity oop obj = new(Tarray); obj->Tarray.target = target; obj->Tarray.size = size; - Array_append(arrays, obj); + List_append(arrays, obj); return obj; } @@ -724,26 +735,26 @@ oop newTstruct(oop tag, oop members) oop vars2types(oop vars) { - oop types = newArray(); - Array_do(vars, var) - Array_append(types, get(var, Variable,type)); + oop types = newList(); + List_do(vars, var) + List_append(types, get(var, Variable,type)); return types; } oop newTfunction(oop result, oop parameters) { static oop functions = 0; - if (!functions) functions = newArray(); - Array_do(functions, t) { + if (!functions) functions = newList(); + List_do(functions, t) { oop tres = get(t, Tfunction,result); oop tpar = get(t, Tfunction,parameters); - if (result == tres && Array_equal(parameters, tpar)) + if (result == tres && List_equal(parameters, tpar)) return t; // uniqe types allow comparison by identity } oop obj = new(Tfunction); obj->Tfunction.result = result; obj->Tfunction.parameters = parameters; - Array_append(functions, obj); + List_append(functions, obj); return obj; } @@ -752,17 +763,17 @@ CTOR0(Tetc); oop newScope(void) { oop obj = new(Scope); - obj->Scope.names = newArray(); - obj->Scope.types = newArray(); - obj->Scope.values = newArray(); + obj->Scope.names = newList(); + obj->Scope.types = newList(); + obj->Scope.values = newList(); return obj; } int Scope_find(oop scope, oop name) { oop names = get(scope, Scope,names); - int size = get(names, Array,size); - oop *elts = get(names, Array,elements); + int size = get(names, List,size); + oop *elts = get(names, List,elements); for (int i = size; i--;) // fixme: binary search if (name == elts[i]) return i; @@ -773,42 +784,42 @@ oop scopes = 0; void Scope_begin(void) { - Array_append(scopes, newScope()); + List_append(scopes, newScope()); } void Scope_end(void) { - Array_popLast(scopes); + List_popLast(scopes); } oop Scope_lookup(oop name) { - int n = get(scopes, Array,size); - oop *elts = get(scopes, Array,elements); + int n = get(scopes, List,size); + oop *elts = get(scopes, List,elements); while (n--) { oop scope = elts[n]; int i = Scope_find(scope, name); - if (i >= 0) return get(get(scope, Scope,values), Array,elements)[i]; + if (i >= 0) return get(get(scope, Scope,values), List,elements)[i]; } return 0; // NOTE: 0 means undefined (rather than nil, which means uninitialised) } oop Scope_local(oop name) { - oop scope = Array_last(scopes); + oop scope = List_last(scopes); int i = Scope_find(scope, name); - if (i >= 0) return get(get(scope, Scope,values), Array,elements)[i]; + if (i >= 0) return get(get(scope, Scope,values), List,elements)[i]; return 0; // NOTE: 0 means undefined (rather than nil, which means uninitialised) } oop Scope_redeclare(oop name, oop value) { - int n = get(scopes, Array,size); - oop *elts = get(scopes, Array,elements); + int n = get(scopes, List,size); + oop *elts = get(scopes, List,elements); while (n--) { oop scope = elts[n]; int i = Scope_find(scope, name); - if (i >= 0) return get(get(scope, Scope,values), Array,elements)[i] = value; + if (i >= 0) return get(get(scope, Scope,values), List,elements)[i] = value; } return 0; // NOTE: 0 means undefined (rather than nil, which means uninitialised) } @@ -845,6 +856,7 @@ oop makeType(oop base, oop type) switch (getType(type)) { case Undefined: return base; case Symbol: return base; + case Index: return makeType(base, get(type, Index,lhs)); case Assign: return makeType(base, get(type, Assign,lhs)); case Tpointer: return newTpointer(makeType(base, get(type, Tpointer,target))); case Tarray: return newTarray(makeType(base, get(type, Tarray,target)), @@ -861,6 +873,7 @@ oop makeName(oop decl) switch (getType(decl)) { case Undefined: case Symbol: return decl; + case Index: return makeName(get(decl, Index,lhs)); case Assign: return makeName(get(decl, Assign,lhs)); case Tpointer: return makeName(get(decl, Tpointer,target)); case Tarray: return makeName(get(decl, Tarray,target)); @@ -884,28 +897,28 @@ oop makeBaseType(oop type) void VarDecls_append(oop vds, oop decl) { - Array_append(get(vds, VarDecls,variables), decl); + List_append(get(vds, VarDecls,variables), decl); } oop newVarDecls(oop type, oop decl) { oop obj = new(VarDecls); obj->VarDecls.type = type; - obj->VarDecls.variables = newArray(); + obj->VarDecls.variables = newList(); VarDecls_append(obj, decl); return obj; } void TypeDecls_append(oop tds, oop decl) { - Array_append(get(tds, TypeDecls,typenames), decl); + List_append(get(tds, TypeDecls,typenames), decl); } oop newTypeDecls(oop type, oop decl) { oop obj = new(TypeDecls); obj->TypeDecls.type = type; - obj->TypeDecls.typenames = newArray(); + obj->TypeDecls.typenames = newList(); TypeDecls_append(obj, decl); return obj; } @@ -975,7 +988,7 @@ void declareStringOn(oop type, oop name, oop str) case Tfunction: { declareStringOn(get(type, Tfunction,result), name, str); String_append(str, '('); - Array_do(get(type, Tfunction,parameters), parameter) { + List_do(get(type, Tfunction,parameters), parameter) { if (do_index) String_appendAll(str, ", ", 2); toStringOn(parameter, str); } @@ -1024,6 +1037,25 @@ oop toStringOn(oop obj, oop str) String_format(str, "%+d>", get(obj, Pointer,offset)); break; } + case Array: { + oop base = get(obj, Array,base); + switch (getType(base)) { + case Integer: + String_format(str, "[%p", (void *)(intptr_t)_integerValue(base)); + break; + case Variable: + String_format(str, "[&%s", symbolName(get(base, Variable,name))); + break; + case Memory: + String_format(str, "[%p[%d]", get(base, Memory,base), get(base, Memory,size)); + break; + default: + fatal("cannot convert array base %s to string", toString(base)); + break; + } + String_format(str, "%+d]", get(obj, Array,size)); + break; + } case Symbol: String_format(str, "%s", get(obj, Symbol,name)); break; @@ -1079,7 +1111,6 @@ oop toStringOn(oop obj, oop str) char *lhs = toString(get(obj, Binary,lhs)); char *rhs = toString(get(obj, Binary,rhs)); switch (get(obj, Binary,operator)) { - case INDEX: String_format(str, "%s[%s]", lhs, rhs); return str; case MUL: name = "*"; break; case DIV: name = "/"; break; case MOD: name = "%"; break; @@ -1102,6 +1133,13 @@ oop toStringOn(oop obj, oop str) String_format(str, "%s %s %s", lhs, name, rhs); break; } + case Index: { + toStringOn(get(obj, Index,lhs), str); + String_append(str, '['); + toStringOn(get(obj, Index,rhs), str); + String_append(str, ']'); + break; + } case Assign: { toStringOn(get(obj, Assign,lhs), str); String_format(str, " = "); @@ -1111,7 +1149,7 @@ oop toStringOn(oop obj, oop str) case Call: { toStringOn(get(obj, Call,function), str); String_append(str, '('); - Array_do(get(obj, Call,arguments), arg) { + List_do(get(obj, Call,arguments), arg) { if (do_index) String_format(str, ", "); toStringOn(arg, str); } @@ -1161,12 +1199,21 @@ oop toStringOn(oop obj, oop str) String_append(str, '*'); break; } + case Tarray: { + oop target = get(obj, Tarray,target); + oop size = get(obj, Tarray,size); + toStringOn(target, str); + String_append(str, '['); + if (nil != size) toStringOn(size, str); + String_append(str, ']'); + break; + } case Tfunction: { oop result = get(obj, Tfunction,result); oop params = get(obj, Tfunction,parameters); toStringOn(result, str); String_append(str, '('); - Array_do(params, param) { + List_do(params, param) { if (do_index) String_appendAll(str, ", ", 2); toStringOn(param, str); } @@ -1192,7 +1239,7 @@ oop toStringOn(oop obj, oop str) toStringOn(get(obj, Function,name), str); String_append(str, '('); oop params = get(obj, Function,parameters); - Array_do(params, param) { + List_do(params, param) { if (do_index) String_appendAll(str, ", ", 2); toStringOn(param, str); } @@ -1206,7 +1253,7 @@ oop toStringOn(oop obj, oop str) case VarDecls: { oop vars = get(obj, VarDecls,variables); oop base = get(obj, VarDecls,type); - Array_do(vars, var) { + List_do(vars, var) { if (do_index) String_appendAll(str, ", ", 2); toStringOn(var, str); } @@ -1215,7 +1262,7 @@ oop toStringOn(oop obj, oop str) case TypeDecls: { oop types = get(obj, TypeDecls,typenames); oop base = get(obj, TypeDecls,type); - Array_do(types, type) { + List_do(types, type) { if (do_index) String_appendAll(str, ", ", 2); toStringOn(type, str); } @@ -1248,6 +1295,11 @@ void printiln(oop obj, int indent) printiln(get(obj, Pointer,base), indent+1); break; } + case Array: { + printf("ARRAY %s [%d]\n", toString(get(obj, Array,type)), get(obj, Array,size)); + printiln(get(obj, Array,base), indent+1); + break; + } case Symbol: printf("%s\n", symbolName (obj)); break; case Pair: { printf("PAIR\n"); @@ -1271,10 +1323,10 @@ void printiln(oop obj, int indent) printf("\"\n"); break; } - case Array: { - oop *elts = get(obj, Array,elements); - int size = get(obj, Array,size); - printf("ARRAY %d\n", size); + case List: { + oop *elts = get(obj, List,elements); + int size = get(obj, List,size); + printf("LIST %d\n", size); for (int i = 0; i < size; ++i) printiln(elts[i], indent+1); break; @@ -1341,7 +1393,6 @@ void printiln(oop obj, int indent) } case Binary: { switch (get(obj, Binary,operator)) { - case INDEX: printf("INDEX\n"); break; case MUL: printf("MUL\n"); break; case DIV: printf("DIV\n"); break; case MOD: printf("MOD\n"); break; @@ -1365,6 +1416,12 @@ void printiln(oop obj, int indent) printiln(get(obj, Binary,rhs), indent+1); break; } + case Index: { + printf("INDEX\n"); + printiln(get(obj, Index,lhs), indent+1); + printiln(get(obj, Index,rhs), indent+1); + break; + } case Assign: { printf("ASSIGN\n"); printiln(get(obj, Assign,lhs), indent+1); @@ -1457,7 +1514,7 @@ void printiln(oop obj, int indent) case Scope: { printf("SCOPE "); oop names = get(obj, Scope,names); - Array_do(names, name) printf(" %s", toString(name)); + List_do(names, name) printf(" %s", toString(name)); printf("\n"); break; } @@ -1621,10 +1678,10 @@ ddector = ( LPAREN d:decltor RPAREN | p:params { d = newTfunction(d, vars2types(p)) } )* { $$ = d } -params = LPAREN a:mkArray - ( p:pdecl { Array_append(a, p) } - ( COMMA p:pdecl { Array_append(a, p) } - )* )? ( ( COMMA ETC { Array_append(a, t_etc) } +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") } ) @@ -1633,9 +1690,9 @@ pdecl = t:tname d:decltor { $$ = newVariable(d, t, nil) } initor = agrinit | expr -agrinit = LBRACE i:mkArray - ( j:initor { Array_append(i, j) } - ( COMMA j:initor { Array_append(i, j) } +agrinit = LBRACE i:mkList + ( j:initor { List_append(i, j) } + ( COMMA j:initor { List_append(i, j) } )* COMMA? )? RBRACE { $$ = i } fundefn = t:tname d:funid @@ -1648,8 +1705,8 @@ funid = STAR d:funid { $$ = newTpointer(d) } primdef = EXTERN t:tname d:funid p:params SEMI { $$ = newPrimitive(d, t, p, 0) } -block = LBRACE b:mkArray - ( s:stmt { Array_append(b, s) } +block = LBRACE b:mkList + ( s:stmt { List_append(b, s) } )* ( RBRACE { $$ = newBlock(b) } | e:error { expected(e, "statement") } ) @@ -1737,14 +1794,14 @@ cast = LPAREN t:tnamdec tnamdec = t:tname d:decltor { $$ = makeType(t, d) } postfix = v:value ( a:args { v = newCall(v, a) } - | i:index { v = newBinary(INDEX, v, i) } + | i:index { v = newIndex(v, i) } | PPLUS { v = newUnary(POSTINC, a) } | MMINUS { v = newUnary(POSTDEC, a) } )* { $$ = v } -args = LPAREN a:mkArray - ( e:expr { Array_append(a, e) } - ( COMMA e:expr { Array_append(a, e) } +args = LPAREN a:mkList + ( e:expr { List_append(a, e) } + ( COMMA e:expr { List_append(a, e) } )* )? RPAREN { $$ = a } index = LBRAK e:expr RBRAK { $$ = e } @@ -1755,7 +1812,7 @@ value = LPAREN e:expr RPAREN { $$ = e } | string | id -mkArray = { $$ = newArray() } +mkList = { $$ = newList() } float = < [-+]? [0-9]* '.' [0-9]+ ( [eE] [-+]? [0-9]+ )? > - { $$ = newFloat(atof(yytext)) } | < [-+]? [0-9]+ '.' [0-9]* ( [eE] [-+]? [0-9]+ )? > - { $$ = newFloat(atof(yytext)) } @@ -1912,25 +1969,25 @@ oop apply(oop function, oop arguments, oop env) fatal("type %s is not callable", getTypeName(function)); } case Primitive: { - oop argv = newArray(); - Array_do(arguments, arg) Array_append(argv, eval(arg, nil)); + oop argv = newList(); + List_do(arguments, arg) List_append(argv, eval(arg, nil)); return get(function, Primitive,function) - ( get(argv, Array,size), - get(argv, Array,elements), + ( get(argv, List,size), + get(argv, List,elements), env ); } case Function: { oop parameters = get(function, Function,parameters); oop body = get(function, Function,body); int variadic = get(function, Function,variadic); - int parc = get(parameters, Array,size); - int argc = get(arguments, Array,size); + int parc = get(parameters, List,size); + int argc = get(arguments, List,size); if (argc < parc) fatal("too few arguments calling %s", toString(function)); if (argc > parc && !variadic) fatal("too many arguments calling %s", toString(function)); - oop *parv = get(parameters, Array,elements); - oop *argv = get(arguments, Array,elements); + oop *parv = get(parameters, List,elements); + oop *argv = get(arguments, List,elements); Scope_begin(); int argn = 0; while (argn < parc) { @@ -1940,8 +1997,8 @@ oop apply(oop function, oop arguments, oop env) ++argn; } if (argn < argc) { // put varargs array in local variable called "..." - oop etc = newArray(); - while (argn < argc) Array_append(etc, eval(argv[argn++], nil)); + oop etc = newList(); + while (argn < argc) List_append(etc, eval(argv[argn++], nil)); declareVariable(s_etc, t_etc, etc); } switch (nlrPush()) { // longjmp occurred @@ -1960,7 +2017,7 @@ oop apply(oop function, oop arguments, oop env) oop declare(oop name, oop value) { - oop scope = Array_last(scopes); + oop scope = List_last(scopes); int index = Scope_find(scope, name); // searches active scope only if (index >= 0) { oop old = Scope_lookup(name); assert(old); @@ -1999,8 +2056,8 @@ oop declare(oop name, oop value) } fatal("name '%s' redefined\n", get(name, Symbol,name)); } - Array_append(get(scope, Scope,names ), name ); - Array_append(get(scope, Scope,values), value); + List_append(get(scope, Scope,names ), name ); + List_append(get(scope, Scope,values), value); return value; } @@ -2070,7 +2127,13 @@ int typeSize(oop type) case Tdouble: return 8; case Tpointer: return 8; // fixme: make this a parameter case Tstruct: assert(!"unimplemented"); - case Tarray: assert(!"unimplemented"); + case Tarray: { + oop target = get(type, Tarray,target); + if (isNil(target)) fatal("cannot determine size of incomplete array type (unknown element type)"); + oop size = get(type, Tarray,size); + if (isNil(size)) fatal("cannot determine size of incomplete array type (unknown size)"); + return typeSize(target) * _integerValue(size); + } case Tfunction: assert(!"unimplemented"); default: assert(!"this cannot happen"); } @@ -2290,8 +2353,13 @@ oop typeCheck(oop exp, oop fntype) oop lhs = typeCheck(get(exp, Binary,lhs), fntype); oop rhs = typeCheck(get(exp, Binary,rhs), fntype); switch (get(exp, Binary,operator)) { - case INDEX: assert(!"unimplemented"); break; - case MUL: assert(!"unimplemented"); break; + case MUL: { + if (lhs == rhs) { + if (t_int == lhs) return lhs; + } + fatal("cannot add '%s' and '%s'", toString(lhs), toString(rhs)); + break; + } case DIV: assert(!"unimplemented"); break; case MOD: assert(!"unimplemented"); break; case ADD: { @@ -2318,6 +2386,17 @@ oop typeCheck(oop exp, oop fntype) } return nil; } + case Index: { + oop lhs = typeCheck(get(exp, Index,lhs), fntype); + oop rhs = typeCheck(get(exp, Index,rhs), fntype); + if (t_int != rhs) fatal("array index is not 'int': %s", toString(get(exp, Binary,rhs))); + switch (getType(lhs)) { + case Tpointer: assert(!"unimplemented"); + case Tarray: return get(lhs, Tarray,target); + default: fatal("'%s' is not indexable: %s", toString(lhs), toString(exp)); + } + break; + } case Assign: { oop lhs = typeCheck(get(exp, Assign,lhs), fntype); oop rhs = typeCheck(get(exp, Assign,rhs), fntype); @@ -2345,27 +2424,29 @@ oop typeCheck(oop exp, oop fntype) oop cond = get(exp, For,condition); oop step = get(exp, For,update); oop body = get(exp, For,body); + Scope_begin(); typeCheck(init, fntype); cond = typeCheck(cond, fntype); if (t_int != cond) fatal("for condition is not 'int'"); typeCheck(step, fntype); typeCheck(body, fntype); + Scope_end(); return nil; } case Primitive: { oop type = get(exp, Primitive,type ); oop name = get(exp, Primitive,name ); oop parameters = get(exp, Primitive,parameters); - oop ptypes = newArray(); + oop ptypes = newList(); oop result = makeType(type, name); name = makeName(name); set(exp, Primitive,name, name); set(exp, Primitive,type, result); - if (Array_size(parameters) && t_etc == Array_last(parameters)) { - Array_popLast(parameters); + if (List_size(parameters) && t_etc == List_last(parameters)) { + List_popLast(parameters); set(exp, Primitive,variadic, 1); } - Array_do(parameters, var) { + List_do(parameters, var) { oop ptype = makeBaseType(get(var, Variable,type)); if (t_void == ptype && (do_index || do_size > 1)) fatal("illegal void parameter"); @@ -2374,14 +2455,14 @@ oop typeCheck(oop exp, oop fntype) pname = makeName(pname); set(var, Variable,name, pname); set(var, Variable,type, ptype); - Array_append(ptypes, ptype); + List_append(ptypes, ptype); } - if (1 == Array_size(ptypes) && Array_last(ptypes) == t_void) { - Array_popLast(ptypes); - Array_popLast(parameters); + if (1 == List_size(ptypes) && List_last(ptypes) == t_void) { + List_popLast(ptypes); + List_popLast(parameters); } assert(isNil(fntype)); - if (get(exp, Primitive,variadic)) Array_append(ptypes, t_etc); + if (get(exp, Primitive,variadic)) List_append(ptypes, t_etc); fntype = newTfunction(result, ptypes); set(exp, Primitive,type, fntype); # define _(X) if (s_##X == name) set(exp, Primitive,function, prim_##X); @@ -2397,16 +2478,16 @@ oop typeCheck(oop exp, oop fntype) oop name = get(exp, Function,name ); oop parameters = get(exp, Function,parameters); oop body = get(exp, Function,body ); - oop ptypes = newArray(); + oop ptypes = newList(); oop result = makeType(type, name); name = makeName(name); set(exp, Function,name, name); set(exp, Function,type, result); - if (Array_size(parameters) && t_etc == Array_last(parameters)) { - Array_popLast(parameters); + if (List_size(parameters) && t_etc == List_last(parameters)) { + List_popLast(parameters); set(exp, Function,variadic, 1); } - Array_do(parameters, var) { + List_do(parameters, var) { oop ptype = makeBaseType(get(var, Variable,type)); if (t_void == ptype && (do_index || do_size > 1)) fatal("illegal void parameter"); @@ -2415,19 +2496,19 @@ oop typeCheck(oop exp, oop fntype) pname = makeName(pname); set(var, Variable,name, pname); set(var, Variable,type, ptype); - Array_append(ptypes, ptype); + List_append(ptypes, ptype); } - if (1 == Array_size(ptypes) && Array_last(ptypes) == t_void) { - Array_popLast(ptypes); - Array_popLast(parameters); + if (1 == List_size(ptypes) && List_last(ptypes) == t_void) { + List_popLast(ptypes); + List_popLast(parameters); } assert(isNil(fntype)); - if (get(exp, Function,variadic)) Array_append(ptypes, t_etc); + if (get(exp, Function,variadic)) List_append(ptypes, t_etc); fntype = newTfunction(result, ptypes); set(exp, Function,type, fntype); declare(name, exp); // add function to global scope so recursive calls will work Scope_begin(); // parameters - Array_do(parameters, param) declare(get(param, Variable,name), param); + List_do(parameters, param) declare(get(param, Variable,name), param); typeCheck(body, fntype); // block Scope_end(); return nil; @@ -2435,7 +2516,7 @@ oop typeCheck(oop exp, oop fntype) case Block: { Scope_begin(); oop statements = get(exp, Block,statements); - Array_do(statements, statement) typeCheck(statement, fntype); + List_do(statements, statement) typeCheck(statement, fntype); Scope_end(); return nil; } @@ -2445,10 +2526,10 @@ oop typeCheck(oop exp, oop fntype) oop tfunc = typeCheck(function, fntype); if (!is(Tfunction, tfunc)) fatal("cannot call %s", getTypeName(tfunc)); oop params = get(tfunc, Tfunction,parameters); - int argc = get(arguments, Array,size); - oop *argv = get(arguments, Array,elements); - int parc = get(params, Array,size); - oop *parv = get(params, Array,elements); + int argc = get(arguments, List,size); + oop *argv = get(arguments, List,elements); + int parc = get(params, List,size); + oop *parv = get(params, List,elements); int vararg = parc && (t_etc == parv[parc - 1]); if ((!vararg && (argc != parc)) || (vararg && (argc < parc - 1))) fatal("wrong number (%d) of arguments, expected %d", argc, parc); @@ -2481,8 +2562,8 @@ oop typeCheck(oop exp, oop fntype) case VarDecls: { oop base = makeBaseType(get(exp, VarDecls,type)); oop decls = get(exp, VarDecls,variables); - oop vars = newArray(); - Array_do(decls, decl) { + oop vars = newList(); + List_do(decls, decl) { oop init = nil; if (is(Assign, decl)) { init = get(decl, Assign,rhs); @@ -2492,8 +2573,8 @@ oop typeCheck(oop exp, oop fntype) oop vartype = makeType(base, decl); if (is(Tfunction, vartype)) { oop ptypes = get(vartype, Tfunction,parameters); - if (1 == Array_size(ptypes) && t_void == Array_last(ptypes)) { - Array_popLast(ptypes); + if (1 == List_size(ptypes) && t_void == List_last(ptypes)) { + List_popLast(ptypes); // make unique vartype = newTfunction(get(vartype, Tfunction,result), ptypes); } @@ -2526,7 +2607,7 @@ oop typeCheck(oop exp, oop fntype) } // do this now so that initialiser can refer to the new variable oop var = declareVariable(varname, vartype, init); - Array_append(vars, var); + List_append(vars, var); if (!isNil(init)) { oop initype = typeCheck(init, fntype); cvt_t cvt = converter(getType(initype), getType(vartype)); @@ -2542,14 +2623,14 @@ oop typeCheck(oop exp, oop fntype) case TypeDecls: { oop base = makeBaseType(get(exp, TypeDecls,type)); oop decls = get(exp, TypeDecls,typenames); - oop typenames = newArray(); - Array_do(decls, decl) { + oop typenames = newList(); + List_do(decls, decl) { oop name = makeName(decl); oop type = makeType(base, decl); if (is(Tfunction, type)) { oop ptypes = get(type, Tfunction,parameters); - if (1 == Array_size(ptypes) && t_void == Array_last(ptypes)) { - Array_popLast(ptypes); + if (1 == List_size(ptypes) && t_void == List_last(ptypes)) { + List_popLast(ptypes); type = newTfunction(get(type, Tfunction,result), ptypes); } } @@ -2564,7 +2645,7 @@ oop typeCheck(oop exp, oop fntype) } else { oop typename = declareType(name, type); - Array_append(typenames, typename); + List_append(typenames, typename); } } set(exp, TypeDecls,typenames, typenames); @@ -2604,8 +2685,38 @@ oop assign(oop lhs, oop rhs) } return set(lhs, Variable,value, rhs); } + case Index: { + oop ondex = eval(get(lhs, Index,rhs), nil); + if (!is(Integer, ondex)) fatal("array index is not 'int'"); + int index = _integerValue(ondex); + lhs = eval(get(lhs, Index,lhs), nil); + switch (getType(lhs)) { + case Array: { + int size = get(lhs, Array,size); + if (index < 0) fatal("array index is negative"); + if (index >= size) fatal("array index out of bounds"); + oop base = get(lhs, Array,base); + oop type = get(get(lhs, Array,type), Tarray,target); + int scale = typeSize(type); + assert(is(Memory, base)); + void *addr = get(base, Memory,base) + index * scale; + switch (getType(type)) { + case Tchar: return newInteger(*(char *)addr = _integerValue(rhs)); + case Tshort: return newInteger(*(short *)addr = _integerValue(rhs)); + case Tint: return newInteger(*(int *)addr = _integerValue(rhs)); + case Tlong: return newInteger(*(long *)addr = _integerValue(rhs)); + case Tfloat: return newFloat (*(float *)addr = _floatValue(rhs)); + case Tdouble: return newFloat (*(double *)addr = _floatValue(rhs)); + default: break; + } + fatal("cannot store '%s' into array", getTypeName(type)); + } + default: break; + } + break; + } case Dereference: { // *<&var> = rhs - lhs = eval(get(dst, Dereference,rhs), nil); + lhs = eval(get(lhs, Dereference,rhs), nil); switch (getType(lhs)) { case Pointer: { // &x oop base = get(lhs, Pointer,base); @@ -2649,7 +2760,6 @@ oop assign(oop lhs, oop rhs) else fatal("invalid rvalue '%s' assigning to: %s", toString(lhs), toString(dst)); - abort(); return 0; } @@ -2691,6 +2801,7 @@ oop eval(oop exp, oop env) case Integer: return exp; case Float: return exp; case Pointer: return exp; + case Array: return exp; case Symbol: { oop value = Scope_lookup(exp); if (!value) fatal("'%s' is undefined\n", get(exp, Symbol,name)); @@ -2705,7 +2816,7 @@ oop eval(oop exp, oop env) } case Pair: assert(!"this cannot happen"); case String: return exp; - case Array: assert(!"this cannot happen"); + case List: assert(!"this cannot happen"); case Memory: assert(!"this cannot happen"); case Primitive: return exp; case Reference: return exp; @@ -2717,8 +2828,8 @@ oop eval(oop exp, oop env) } case Block: { Object *stmts = get(exp, Block,statements); - int size = get(stmts, Array,size); - oop *elts = get(stmts, Array,elements); + int size = get(stmts, List,size); + oop *elts = get(stmts, List,elements); Object *result = nil; Scope_begin(); switch (nlrPush()) { // longjmp occurred @@ -2833,7 +2944,6 @@ oop eval(oop exp, oop env) rhs = eval(rhs, env); if (Float == getType(lhs) || Float == getType(rhs)) { // floating point result switch (get(exp, Binary,operator)) { - case INDEX: assert(!"unimplemented"); case MUL: return FBINOP(lhs, * , rhs); case DIV: return FBINOP(lhs, / , rhs); case MOD: return newFloat(fmod(floatValue(lhs), floatValue(rhs))); @@ -2857,7 +2967,6 @@ oop eval(oop exp, oop env) } else { // integer result switch (get(exp, Binary,operator)) { - case INDEX: assert("!unimplemented"); case MUL: return IBINOP(lhs, * , rhs); case DIV: return IBINOP(lhs, / , rhs); case MOD: return IBINOP(lhs, % , rhs); @@ -2884,6 +2993,36 @@ oop eval(oop exp, oop env) assert(!"this cannot happen"); break; } + case Index: { + oop ondex = eval(get(exp, Index,rhs), nil); + if (!is(Integer, ondex)) fatal("array index is not 'int'"); + int index = _integerValue(ondex); + oop lhs = eval(get(exp, Index,lhs), nil); + switch (getType(lhs)) { + case Array: { + int size = get(lhs, Array,size); + if (index < 0) fatal("array index is negative"); + if (index >= size) fatal("array index out of bounds"); + oop base = get(lhs, Array,base); + oop type = get(get(lhs, Array,type), Tarray,target); + int scale = typeSize(type); + assert(is(Memory, base)); + void *addr = get(base, Memory,base) + index * scale; + 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 read '%s' from array", getTypeName(type)); + } + default: break; + } + break; + } case Assign: { return assign(get(exp, Assign,lhs), eval(get(exp, Assign,rhs), nil)); } @@ -2913,11 +3052,21 @@ oop eval(oop exp, oop env) oop cond = get(exp, For,condition); oop step = get(exp, For,update); oop body = get(exp, For,body); + Scope_begin(); + switch (nlrPush()) { + case NLR_INIT: break; + case NLR_RETURN: nlrReturn(NLR_RETURN, nlrPop()); + case NLR_CONTINUE: goto continued; + case NLR_BREAK: goto broken; + } eval(init, nil); while (integerValue(eval(cond, nil))) { eval(body, nil); + continued: eval(step, nil); } + broken: + Scope_end(); return nil; } case If: { @@ -2954,20 +3103,43 @@ oop eval(oop exp, oop env) case Tetc: assert(!"unimplemented"); break; case VarDecls: { oop vars = get(exp, VarDecls,variables); - Array_do(vars, var) { + List_do(vars, var) { oop name = get(var, Variable,name); oop type = get(var, Variable,type); oop init = get(var, Variable,value); if (is(Tfunction, type)) continue; // function declaration // do this now so that init can refer to the new variable - oop var = declareVariable(name, type, nil); + oop valu = nil; + if (is(Tarray, type)) { + oop target = get(type, Tarray,target); + int size = _integerValue(get(type, Tarray,size)); + if (size < 0) fatal("array has negative size"); + if (size > 10*1024*1024) fatal("corwardly refusing to create array of size %d", size); + oop mem = nil; + switch (getType(target)) { + case Tchar: + case Tshort: + case Tint: + case Tlong: + case Tfloat: + case Tdouble: + case Tpointer: + case Tarray: + mem = malloc(typeSize(target) * size); + break; + default: // xxx array of array + assert(!"unimplemented"); + } + valu = newArray(type, newMemory(mem, typeSize(target) * size), size); + } + oop var = declareVariable(name, type, valu); if (!isNil(init)) assign(var, eval(init, nil)); } return nil; } case TypeDecls: { oop types = get(exp, TypeDecls,typenames); - Array_do(types, type) { + List_do(types, type) { oop name = get(type, TypeName,name); oop type = get(type, TypeName,type); declareType(name, type); @@ -2995,10 +3167,11 @@ oop preval(oop exp) case Integer: return exp; case Float: return exp; case Pointer: return exp; + case Array: return exp; case Symbol: break; case Pair: break; case String: break; - case Array: break; + case List: break; case Memory: break; case Primitive: return exp; case Reference: break; @@ -3010,6 +3183,7 @@ oop preval(oop exp) case Sizeof: return get(exp, Sizeof,size); case Unary: break; case Binary: break; + case Index: break; case Assign: break; case Cast: break; case While: break; @@ -3032,7 +3206,7 @@ oop preval(oop exp) case Tetc: break; case VarDecls: { oop vars = get(exp, VarDecls,variables); - Array_do(vars, var) { + List_do(vars, var) { assert(Scope_lookup(get(var, Variable,name))); oop init = get(var, Variable,value); if (!isNil(init)) assign(var, preval(init)); @@ -3041,7 +3215,7 @@ oop preval(oop exp) } case TypeDecls: { oop types = get(exp, TypeDecls,typenames); - Array_do(types, type) { + List_do(types, type) { assert(Scope_lookup(get(type, TypeName,name))); } return nil; @@ -3080,8 +3254,8 @@ oop stackError(char *reason) void disassemble(oop program) { - oop *code = get(program, Array,elements); - int size = get(program, Array,size); + oop *code = get(program, List,elements); + int size = get(program, List,size); int pc = 0; while (pc < size) { printf("%04d", pc); @@ -3126,7 +3300,7 @@ void disassemble(oop program) oop execute(oop program) { - oop *code = get(program, Array,elements); + oop *code = get(program, List,elements); int pc = 0; oop stack[32]; @@ -3267,8 +3441,8 @@ oop execute(oop program) Object *function = get(func, Closure,function); Object *environment = get(func, Closure,environment); Object *parameters = get(function, Function,parameters); - int parc = get(parameters, Array,size); - oop *parv = get(parameters, Array,elements); + int parc = get(parameters, List,size); + oop *parv = get(parameters, List,elements); int parn = 0; while (parn < parc && argc > 0) { environment = newPair(newPair(parv[parn++], pop()), environment); @@ -3315,7 +3489,7 @@ oop execute(oop program) return 0; } -#define EMITo(O) Array_append(program, (O)) +#define EMITo(O) List_append(program, (O)) #define EMITi(I) EMITo(newInteger(I)) #define EMIToo(O, P) (( EMITo(O), EMITo(P) )) @@ -3332,18 +3506,19 @@ void compileOn(oop exp, oop program, oop cs, oop bs) case Integer: EMITio(iPUSH, exp); return; case Float: EMITio(iPUSH, exp); return; case Pointer: assert(!"unimplemented"); + case Array: assert(!"unimplemented"); case Symbol: EMITio(iGETGVAR, exp); return; case Pair: EMITio(iPUSH, exp); return; case String: EMITio(iPUSH, exp); return; - case Array: assert(!"unimplemented"); + case List: assert(!"unimplemented"); case Memory: assert(!"unimplemented"); case Primitive: EMITio(iPUSH, exp); return; case Reference: assert(!"unimplemented"); case Closure: EMITio(iPUSH, exp); return; case Call: { Object *args = get(exp, Call,arguments); - int argc = get(args, Array,size); - oop *argv = get(args, Array,elements); + int argc = get(args, List,size); + oop *argv = get(args, List,elements); for (int n = argc; n--;) compileOn(argv[n], program, cs, bs); compileOn(get(exp, Call,function), program, cs, bs); // GETVAR print EMITii(iCALL, argc); @@ -3351,12 +3526,12 @@ void compileOn(oop exp, oop program, oop cs, oop bs) } case Block: { oop statements = get(exp, Block,statements); - int size = get(statements, Array,size); + int size = get(statements, List,size); if (0 == size) { EMITio(iPUSH, nil); return; } - oop *exps = get(statements, Array,elements); + oop *exps = get(statements, List,elements); for (int i = 0; i < size - 1; ++i) { compileOn(exps[i], program, cs, bs); EMITi(iPOP); @@ -3389,7 +3564,6 @@ void compileOn(oop exp, oop program, oop cs, oop bs) compileOn(get(exp, Binary,lhs), program, cs, bs); compileOn(get(exp, Binary,rhs), program, cs, bs); switch (get(exp, Binary,operator)) { - case INDEX: assert(!"unimplemented"); case MUL: EMITi(iMUL); return; case DIV: EMITi(iDIV); return; case MOD: EMITi(iMOD); return; @@ -3411,7 +3585,7 @@ void compileOn(oop exp, oop program, oop cs, oop bs) assert(!"unimplemented"); } } - + case Index: assert(!"unimplemented"); case Assign: { oop symbol = get(exp, Assign,lhs); oop expr = get(exp, Assign,rhs); @@ -3425,12 +3599,12 @@ void compileOn(oop exp, oop program, oop cs, oop bs) return; } -# define LABEL(NAME) int NAME = get(program, Array,size) -# define PATCH(J, L) Array_set(program, J+1, newInteger(L)) +# define LABEL(NAME) int NAME = get(program, List,size) +# define PATCH(J, L) List_set(program, J+1, newInteger(L)) case While: { - oop continues = newArray(); - oop breaks = newArray(); + oop continues = newList(); + oop breaks = newList(); oop cond = get(exp, While,condition); oop body = get(exp, While,expression); EMITio(iPUSH, nil); @@ -3443,10 +3617,10 @@ void compileOn(oop exp, oop program, oop cs, oop bs) EMITii(iJMP, L1); LABEL(L2); PATCH(J1, L2); - for (int i = get(continues, Array,size); i--;) - PATCH(_integerValue(get(continues, Array,elements)[i]), L1); - for (int i = get(breaks, Array,size); i--;) - PATCH(_integerValue(get(breaks, Array,elements)[i]), L2); + for (int i = get(continues, List,size); i--;) + PATCH(_integerValue(get(continues, List,elements)[i]), L1); + for (int i = get(breaks, List,size); i--;) + PATCH(_integerValue(get(breaks, List,elements)[i]), L2); return; } case For: { @@ -3476,7 +3650,7 @@ void compileOn(oop exp, oop program, oop cs, oop bs) EMITio(iPUSH, nil); LABEL(L1); EMITio(iJMP, nil); - Array_append(cs, newInteger(L1)); + List_append(cs, newInteger(L1)); return; } case Break: { @@ -3484,7 +3658,7 @@ void compileOn(oop exp, oop program, oop cs, oop bs) EMITio(iPUSH, nil); LABEL(L1); EMITio(iJMP, nil); - Array_append(bs, newInteger(L1)); + List_append(bs, newInteger(L1)); return; } case Tvoid: assert(!"unimplemented"); return; @@ -3508,7 +3682,7 @@ void compileOn(oop exp, oop program, oop cs, oop bs) case Function: { assert(0 == get(exp, Function,code)); oop prog2 = compileFunction(get(exp, Function,body)); - set(exp, Function,code, get(prog2, Array,elements)); + set(exp, Function,code, get(prog2, List,elements)); EMITio(iCLOSE, exp); return; } @@ -3517,7 +3691,7 @@ void compileOn(oop exp, oop program, oop cs, oop bs) oop compileFunction(oop exp) { - oop program = newArray(); + oop program = newList(); compileOn(exp, program, nil, nil); EMITi(iRETURN); if (opt_v > 2) disassemble(program); @@ -3526,7 +3700,7 @@ oop compileFunction(oop exp) oop compile(oop exp) // 6*7 { - oop program = newArray(); + oop program = newList(); compileOn(exp, program, nil, nil); EMITi(iHALT); if (opt_v > 2) disassemble(program); @@ -3553,12 +3727,12 @@ void replFile(char *name, FILE *file) case NLR_BREAK: fatal("break outside loop"); } if (opt_v > 1) printf("---------------- typecheck\n"); - assert(1 == Array_size(scopes)); + assert(1 == List_size(scopes)); typeCheck(yysval, nil); - assert(1 == Array_size(scopes)); + assert(1 == List_size(scopes)); if (opt_v > 1) printf("---------------- declare\n"); result = preval(yysval); - assert(1 == Array_size(scopes)); + assert(1 == List_size(scopes)); nlrPop(); } if (opt_v > 0) { @@ -3598,19 +3772,19 @@ int main(int argc, char **argv) t_ppchar = newTpointer(t_pchar); t_etc = newTetc(); - scopes = newArray(); + scopes = newList(); Scope_begin(); // the global scope #if 0 declarePrimitive(intern("printf"), - newTfunction(t_int, newArray2(t_pchar, t_etc)), + newTfunction(t_int, newList2(t_pchar, t_etc)), prim_printf); #endif #if 0 declarePrimitive(intern("assert"), - newTfunction(t_void, newArray1(t_etc)), + newTfunction(t_void, newList1(t_etc)), prim_assert); #endif @@ -3636,25 +3810,25 @@ int main(int argc, char **argv) if (!repls) replFile("stdin", stdin); - oop args = newArray(); - Array_append(args, newInteger(1)); - Array_append(args, newStringWith("main")); + oop args = newList(); + List_append(args, newInteger(1)); + List_append(args, newStringWith("main")); 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 (Array_size(params)) { + switch (List_size(params)) { default: fatal("main has too many parameters"); case 3: - if (Array_get(params, 2) != t_ppchar) + if (List_get(params, 2) != t_ppchar) fatal("third parameter of main should be 'char **'"); case 2: - if (Array_get(params, 1) != t_ppchar) + if (List_get(params, 1) != t_ppchar) fatal("second parameter of main should be 'char **'"); case 1: - if (Array_get(params, 0) != t_int) + if (List_get(params, 0) != t_int) fatal("first parameter of main should be 'int'"); case 0: break; @@ -3671,7 +3845,7 @@ int main(int argc, char **argv) fatal("main did not return an integer"); } - assert(1 == Array_size(scopes)); + assert(1 == List_size(scopes)); return _integerValue(result); } diff --git a/test.txt b/test.txt index 61941f2..2a606d3 100755 --- a/test.txt +++ b/test.txt @@ -30,6 +30,13 @@ int main(int argc, char **argv) while (x > 0) printf("%d ", --x); printf("\n"); printf("%d\n", sizeof(char *)); + + int array[5]; + printf("array size %d\n", sizeof(array)); + int i; + for (i = 0; i < 5; ++i) array[i] = i*i; + for (i = 0; i < 5; ++i) printf("%d\n", array[i]); + return 0; }