Преглед изворни кода

Add closure and optimize map_search for arrays

master
mtardy пре 4 година
родитељ
комит
75c1e685cf
2 измењених фајлова са 21 додато и 10 уклоњено
  1. +9
    -7
      object.c
  2. +12
    -3
      parse.leg

+ 9
- 7
object.c Прегледај датотеку

@ -50,6 +50,7 @@ struct Function {
primitive_t primitive; primitive_t primitive;
oop body; oop body;
oop param; oop param;
oop parentScope;
}; };
// usefull for map's elements // usefull for map's elements
@ -138,13 +139,14 @@ oop makeSymbol(char *name)
return newSymb; 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))); oop newFunc = memcheck(malloc(sizeof(union object)));
newFunc->type = Function; newFunc->type = Function;
newFunc->Function.primitive = primitive; newFunc->Function.primitive = primitive;
newFunc->Function.param = param; newFunc->Function.param = param;
newFunc->Function.body = body; newFunc->Function.body = body;
newFunc->Function.parentScope = parentScope;
return newFunc; return newFunc;
} }
@ -178,18 +180,18 @@ ssize_t map_search(oop map, oop key)
assert(is(Map, map)); assert(is(Map, map));
assert(key); 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)) { if (is(Integer, key)) {
size_t index = get(key, Integer, value);
ssize_t index = get(key, Integer, value);
if (index > r) { if (index > r) {
return -1 - (r + 1); 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) { while (l <= r) {
ssize_t mid = (l + r) / 2; ssize_t mid = (l + r) / 2;
int cmpres = oopcmp(get(map, Map, elements)[mid].key, key); int cmpres = oopcmp(get(map, Map, elements)[mid].key, key);

+ 12
- 3
parse.leg Прегледај датотеку

@ -205,6 +205,7 @@ start = - e:exp { yylval = e }
exp = VAR l:IDENT EQUAL e:exp { $$ = newDeclaration(l, e) } exp = VAR l:IDENT EQUAL e:exp { $$ = newDeclaration(l, e) }
| VAR l:IDENT { $$ = newDeclaration(l, null) } | VAR l:IDENT { $$ = newDeclaration(l, null) }
| FUN l:IDENT p:paramList e:exp { $$ = newFunc(l, p, e) } | 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:IDENT EQUAL e:exp { $$ = newAssign(l, e) }
| l:postfix DOT i:IDENT EQUAL e:exp { $$ = newSetMember(l, i, 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) } | 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: case Function:
return ast; return ast;
case Symbol: case Symbol:
return map_get(scope, ast);
return getVariable(scope, ast);
} }
oop proto = map_get(ast, __proto___symbol); 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 name = map_get(ast, name_symbol);
oop param = map_get(ast, param_symbol); oop param = map_get(ast, param_symbol);
oop body = map_get(ast, body_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: { case t_call: {
oop func = eval(scope, map_get(ast, func_symbol)); 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) { if (get(func, Function, primitive) == NULL) {
oop param = get(func, Function, param); oop param = get(func, Function, param);
oop localScope = map_fromArrays(param, args); 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 eval(localScope, get(func, Function, body));
} }
return get(func, Function, primitive)(args); return get(func, Function, primitive)(args);
@ -456,7 +465,7 @@ int main(int argc, char **argv)
symbol_table = makeMap(); symbol_table = makeMap();
globals = 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); #define _DO(NAME) NAME##_symbol=intern(#NAME);
DO_SYMBOLS() DO_SYMBOLS()

Loading…
Откажи
Сачувај