From 75c1e685cf53e70395c8c6cd9959f79e61ab760f Mon Sep 17 00:00:00 2001 From: mtardy Date: Tue, 4 Aug 2020 10:54:48 +0200 Subject: [PATCH] Add closure and optimize map_search for arrays --- object.c | 16 +++++++++------- parse.leg | 15 ++++++++++++--- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/object.c b/object.c index a430c9b..38dc148 100644 --- a/object.c +++ b/object.c @@ -50,6 +50,7 @@ struct Function { primitive_t primitive; oop body; oop param; + oop parentScope; }; // usefull for map's elements @@ -138,13 +139,14 @@ oop makeSymbol(char *name) return newSymb; } -oop makeFunction(primitive_t primitive, oop param, oop body) +oop makeFunction(primitive_t primitive, oop param, oop body, oop parentScope) { oop newFunc = memcheck(malloc(sizeof(union object))); newFunc->type = Function; newFunc->Function.primitive = primitive; newFunc->Function.param = param; newFunc->Function.body = body; + newFunc->Function.parentScope = parentScope; return newFunc; } @@ -178,18 +180,18 @@ ssize_t map_search(oop map, oop key) assert(is(Map, map)); assert(key); - ssize_t l = 0, r = get(map, Map, size) - 1; - /* this optimization can only work if the array is consistent - ie. doesn't start at 3 because of existing member, see map_append + ssize_t r = get(map, Map, size) - 1; + if (is(Integer, key)) { - size_t index = get(key, Integer, value); + ssize_t index = get(key, Integer, value); if (index > r) { return -1 - (r + 1); } - return + oop probe = get(map, Map, elements)[index].key; + if (key == probe) return index; } - */ + ssize_t l = 0; while (l <= r) { ssize_t mid = (l + r) / 2; int cmpres = oopcmp(get(map, Map, elements)[mid].key, key); diff --git a/parse.leg b/parse.leg index e69808d..99fb1e3 100644 --- a/parse.leg +++ b/parse.leg @@ -205,6 +205,7 @@ start = - e:exp { yylval = e } exp = VAR l:IDENT EQUAL e:exp { $$ = newDeclaration(l, e) } | VAR l:IDENT { $$ = newDeclaration(l, null) } | FUN l:IDENT p:paramList e:exp { $$ = newFunc(l, p, e) } + | FUN p:paramList e:exp { $$ = newFunc(null, p, e) } | l:IDENT EQUAL e:exp { $$ = newAssign(l, e) } | l:postfix DOT i:IDENT EQUAL e:exp { $$ = newSetMember(l, i, e) } | l:postfix LBRAC i:exp RBRAC EQUAL e:exp { $$ = newSetIndex(l, i, e) } @@ -333,7 +334,7 @@ oop eval(oop scope, oop ast) case Function: return ast; case Symbol: - return map_get(scope, ast); + return getVariable(scope, ast); } oop proto = map_get(ast, __proto___symbol); @@ -360,7 +361,11 @@ oop eval(oop scope, oop ast) oop name = map_get(ast, name_symbol); oop param = map_get(ast, param_symbol); oop body = map_get(ast, body_symbol); - return newVariable(scope, name, makeFunction(NULL, param, body)); + oop func = makeFunction(NULL, param, body, scope); + printf("funcscope\n"); + println(scope); + if (name == null) return func; + return newVariable(scope, name, func); } case t_call: { oop func = eval(scope, map_get(ast, func_symbol)); @@ -368,6 +373,10 @@ oop eval(oop scope, oop ast) if (get(func, Function, primitive) == NULL) { oop param = get(func, Function, param); oop localScope = map_fromArrays(param, args); + map_set(localScope, __proto___symbol, get(func, Function, parentScope)); + printf("localscope\n"); + println(get(func, Function, parentScope)); + println(localScope); return eval(localScope, get(func, Function, body)); } return get(func, Function, primitive)(args); @@ -456,7 +465,7 @@ int main(int argc, char **argv) symbol_table = makeMap(); globals = makeMap(); - map_set(globals, intern("exit"), makeFunction(prim_exit, null, null)); + map_set(globals, intern("exit"), makeFunction(prim_exit, null, null, globals)); #define _DO(NAME) NAME##_symbol=intern(#NAME); DO_SYMBOLS()