瀏覽代碼

Add function parameters support with simplistic local scope

master
mtardy 4 年之前
父節點
當前提交
34b33bf34b
共有 2 個檔案被更改,包括 42 行新增12 行删除
  1. +4
    -1
      object.c
  2. +38
    -11
      parse.leg

+ 4
- 1
object.c 查看文件

@ -49,6 +49,7 @@ struct Function {
type_t type; type_t type;
primitive_t primitive; primitive_t primitive;
oop body; oop body;
oop param;
}; };
// usefull for map's elements // usefull for map's elements
@ -137,11 +138,12 @@ oop makeSymbol(char *name)
return newSymb; return newSymb;
} }
oop makeFunction(primitive_t primitive, oop body)
oop makeFunction(primitive_t primitive, oop param, oop body)
{ {
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.body = body; newFunc->Function.body = body;
return newFunc; return newFunc;
} }
@ -368,3 +370,4 @@ oop intern(char *ident)
map_insert(symbol_table, symbol, null, pos); map_insert(symbol_table, symbol, null, pos);
return symbol; return symbol;
} }

+ 38
- 11
parse.leg 查看文件

@ -22,7 +22,7 @@ DO_PROTOS()
// this is the global scope // this is the global scope
oop globals; oop globals;
#define DO_SYMBOLS() DO_PROTOS() _DO(__proto__) _DO(__name__) _DO(name) _DO(body) _DO(key) _DO(value) _DO(lhs) _DO(rhs) _DO(scope) _DO(args)
#define DO_SYMBOLS() DO_PROTOS() _DO(__proto__) _DO(__name__) _DO(name) _DO(body) _DO(param) _DO(key) _DO(value) _DO(lhs) _DO(rhs) _DO(scope) _DO(args)
#define _DO(NAME) oop NAME##_symbol; #define _DO(NAME) oop NAME##_symbol;
DO_SYMBOLS() DO_SYMBOLS()
@ -145,10 +145,11 @@ oop newGetIndex(oop map, oop key)
return obj; return obj;
} }
oop newFunc(oop name, oop body)
oop newFunc(oop name, oop param, oop body)
{ {
oop func = newObject(func_proto); oop func = newObject(func_proto);
map_set(func, name_symbol, name); map_set(func, name_symbol, name);
map_set(func, param_symbol, param);
map_set(func, body_symbol, body); map_set(func, body_symbol, body);
return func; return func;
} }
@ -201,12 +202,12 @@ YYSTYPE yylval;
start = - e:exp { yylval = e } start = - e:exp { yylval = e }
exp = VAR l:IDENT EQUAL p:exp { $$ = newDeclaration(l, p) }
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 LPAREN RPAREN p:exp { $$ = newFunc(l, p) }
| l:IDENT EQUAL p:exp { $$ = newAssign(l, p) }
| l:postfix DOT i:IDENT EQUAL p:exp { $$ = newSetMember(l, i, p) }
| l:postfix LBRAC i:exp RBRAC EQUAL p:exp { $$ = newSetIndex(l, i, p) }
| FUN l:IDENT p:paramList e:exp { $$ = newFunc(l, 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) }
| s:sum { $$ = s } | s:sum { $$ = s }
sum = l:prod sum = l:prod
@ -229,6 +230,13 @@ postfix = i:value ( DOT s:IDENT a:argumentList { map_set(a, int
| LBRAC p:exp RBRAC !EQUAL { i = newGetIndex(i, p) } | LBRAC p:exp RBRAC !EQUAL { i = newGetIndex(i, p) }
| a:argumentList { i = newCall(i, a) } | a:argumentList { i = newCall(i, a) }
) * { $$ = i } ) * { $$ = i }
paramList = LPAREN m:makeMap
( i:IDENT { map_append(m, i) }
( COMMA i:IDENT { map_append(m, i) }
) *
) ?
RPAREN { $$ = m }
argumentList = LPAREN m:makeMap argumentList = LPAREN m:makeMap
( e:exp { map_append(m, e) } ( e:exp { map_append(m, e) }
@ -297,6 +305,23 @@ int getInteger(oop obj)
return get(obj, Integer, value); return get(obj, Integer, value);
} }
oop map_fromArrays(oop keys, oop values)
{
assert(is(Map, keys));
assert(is(Map, values));
int i = 0;
oop map = makeMap();
oop key, value;
oop index;
while ((index = makeInteger(i)), map_hasKey(keys, index)) {
key = map_get(keys, index);
value = map_get(values, index);
map_set(map, key, value);
i++;
}
return map;
}
oop evalArgs(oop scope, oop args); oop evalArgs(oop scope, oop args);
oop eval(oop scope, oop ast) oop eval(oop scope, oop ast)
@ -333,15 +358,17 @@ oop eval(oop scope, oop ast)
} }
case t_func: { case t_func: {
oop name = map_get(ast, name_symbol); oop name = map_get(ast, name_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, body));
return newVariable(scope, name, makeFunction(NULL, param, body));
} }
case t_call: { case t_call: {
oop func = eval(scope, map_get(ast, func_symbol)); oop func = eval(scope, map_get(ast, func_symbol));
// args should be evaluated
oop args = evalArgs(scope, map_get(ast, args_symbol)); oop args = evalArgs(scope, map_get(ast, args_symbol));
if (get(func, Function, primitive) == NULL) { if (get(func, Function, primitive) == NULL) {
return eval(scope, get(func, Function, body));
oop param = get(func, Function, param);
oop localScope = map_fromArrays(param, args);
return eval(localScope, get(func, Function, body));
} }
return get(func, Function, primitive)(args); return get(func, Function, primitive)(args);
} }
@ -429,7 +456,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));
map_set(globals, intern("exit"), makeFunction(prim_exit, null, null));
#define _DO(NAME) NAME##_symbol=intern(#NAME); #define _DO(NAME) NAME##_symbol=intern(#NAME);
DO_SYMBOLS() DO_SYMBOLS()

Loading…
取消
儲存