|
@ -7,7 +7,7 @@ |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
|
|
|
#define DO_PROTOS() \ |
|
|
#define DO_PROTOS() \ |
|
|
_DO(if) _DO(while) _DO(do) _DO(for) _DO(switch) _DO(call) _DO(func) _DO(block) _DO(declaration) \ |
|
|
|
|
|
|
|
|
_DO(if) _DO(while) _DO(do) _DO(for) _DO(switch) _DO(call) _DO(invoke) _DO(func) _DO(block) _DO(declaration) \ |
|
|
_DO(assign) _DO(assignAdd) _DO(assignSub) _DO(assignMul) _DO(assignDiv) _DO(assignMod) \ |
|
|
_DO(assign) _DO(assignAdd) _DO(assignSub) _DO(assignMul) _DO(assignDiv) _DO(assignMod) \ |
|
|
_DO(assignBitor) _DO(assignBitxor) _DO(assignBitand) _DO(assignShleft) _DO(assignShright) \ |
|
|
_DO(assignBitor) _DO(assignBitxor) _DO(assignBitand) _DO(assignShleft) _DO(assignShright) \ |
|
|
_DO(map) _DO(symbol) _DO(integer) _DO(string) \ |
|
|
_DO(map) _DO(symbol) _DO(integer) _DO(string) \ |
|
@ -79,7 +79,8 @@ oop globals= 0; |
|
|
#define DO_SYMBOLS() \ |
|
|
#define DO_SYMBOLS() \ |
|
|
DO_PROTOS() _DO(__proto__) _DO(__name__) _DO(__default__) \ |
|
|
DO_PROTOS() _DO(__proto__) _DO(__name__) _DO(__default__) \ |
|
|
_DO(name) _DO(body) _DO(param) _DO(key) _DO(value) _DO(condition) _DO(consequent) _DO(alternate) \ |
|
|
_DO(name) _DO(body) _DO(param) _DO(key) _DO(value) _DO(condition) _DO(consequent) _DO(alternate) \ |
|
|
_DO(lhs) _DO(rhs) _DO(scope) _DO(args) _DO(expression) _DO(labels) _DO(statements) _DO(initialise) _DO(update) |
|
|
|
|
|
|
|
|
_DO(lhs) _DO(rhs) _DO(scope) _DO(args) _DO(expression) _DO(labels) _DO(statements) _DO(initialise) \ |
|
|
|
|
|
_DO(update) _DO(this) |
|
|
|
|
|
|
|
|
#define _DO(NAME) oop NAME##_symbol; |
|
|
#define _DO(NAME) oop NAME##_symbol; |
|
|
DO_SYMBOLS() |
|
|
DO_SYMBOLS() |
|
@ -306,6 +307,15 @@ oop newCall(oop func, oop args) |
|
|
return call; |
|
|
return call; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
oop newInvoke(oop func, oop this, oop args) |
|
|
|
|
|
{ |
|
|
|
|
|
oop obj = newObject(invoke_proto); |
|
|
|
|
|
map_set(obj, func_symbol, func); |
|
|
|
|
|
map_set(obj, this_symbol, this); |
|
|
|
|
|
map_set(obj, args_symbol, args); |
|
|
|
|
|
return obj; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
oop newBlock(oop statements) |
|
|
oop newBlock(oop statements) |
|
|
{ |
|
|
{ |
|
|
oop obj = newObject(block_proto); |
|
|
oop obj = newObject(block_proto); |
|
@ -502,9 +512,9 @@ prefix = PLUS n:prefix { $$= n } |
|
|
| PLING n:prefix { $$= newUnary(not_proto, n) } |
|
|
| PLING n:prefix { $$= newUnary(not_proto, n) } |
|
|
| n:postfix { $$= n } |
|
|
| n:postfix { $$= n } |
|
|
|
|
|
|
|
|
postfix = i:value ( DOT s:IDENT a:argumentList { map_set(a, intern("this"), i); i = newCall(i, a) } |
|
|
|
|
|
| DOT s:IDENT !assignOp { i = newGetMap(getMember_proto, i, s) } |
|
|
|
|
|
| LBRAC p:exp RBRAC !assignOp { i = newGetMap(getIndex_proto, i, p) } |
|
|
|
|
|
|
|
|
postfix = i:value ( DOT s:IDENT a:argumentList { i = newInvoke(s, i, a) } |
|
|
|
|
|
| DOT s:IDENT !assignOp { i = newGetMap(getMember_proto, i, s) } |
|
|
|
|
|
| LBRAC p:exp RBRAC !assignOp { i = newGetMap(getIndex_proto, i, p) } |
|
|
| a:argumentList { i = newCall(i, a) } |
|
|
| a:argumentList { i = newCall(i, a) } |
|
|
) * { $$ = i } |
|
|
) * { $$ = i } |
|
|
|
|
|
|
|
@ -921,11 +931,12 @@ oop eval(oop scope, oop ast) |
|
|
oop body = map_get(ast, body_symbol); |
|
|
oop body = map_get(ast, body_symbol); |
|
|
oop func = makeFunction(NULL, param, body, scope); |
|
|
oop func = makeFunction(NULL, param, body, scope); |
|
|
if (opt_v) { |
|
|
if (opt_v) { |
|
|
printf("funcscope\n"); |
|
|
|
|
|
|
|
|
printf("funcscope: "); |
|
|
|
|
|
println(scope); |
|
|
|
|
|
printf("globalScope: "); |
|
|
println(scope); |
|
|
println(scope); |
|
|
} |
|
|
} |
|
|
if (name != null) newVariable(scope, name, func); |
|
|
if (name != null) newVariable(scope, name, func); |
|
|
if (opt_v) println(scope); |
|
|
|
|
|
return func; |
|
|
return func; |
|
|
} |
|
|
} |
|
|
case t_call: { |
|
|
case t_call: { |
|
@ -942,8 +953,57 @@ oop eval(oop scope, oop ast) |
|
|
oop localScope = map_zip(param, args); |
|
|
oop localScope = map_zip(param, args); |
|
|
map_set(localScope, __proto___symbol, get(func, Function, parentScope)); |
|
|
map_set(localScope, __proto___symbol, get(func, Function, parentScope)); |
|
|
if (opt_v) { |
|
|
if (opt_v) { |
|
|
printf("localscope\n"); |
|
|
|
|
|
|
|
|
printf("parentScope: "); |
|
|
|
|
|
println(get(func, Function, parentScope)); |
|
|
|
|
|
printf("localScope: "); |
|
|
|
|
|
println(localScope); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
jbRecPush(); |
|
|
|
|
|
int jbt = sigsetjmp(jbs->jb, 0); |
|
|
|
|
|
switch (jbt) { |
|
|
|
|
|
case j_return: { |
|
|
|
|
|
oop result = jbs->result; |
|
|
|
|
|
jbRecPop(); |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
case j_break: { |
|
|
|
|
|
fprintf(stderr, "\nbreak outside of a loop\n"); |
|
|
|
|
|
exit(1); |
|
|
|
|
|
} |
|
|
|
|
|
case j_continue: { |
|
|
|
|
|
fprintf(stderr, "\ncontinue outside of a loop\n"); |
|
|
|
|
|
exit(1); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
oop result = eval(localScope, get(func, Function, body)); |
|
|
|
|
|
jbRecPop(); |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
return get(func, Function, primitive)(args); |
|
|
|
|
|
} |
|
|
|
|
|
case t_invoke: { |
|
|
|
|
|
// this is what differs from t_call |
|
|
|
|
|
oop this = eval(scope, map_get(ast, this_symbol)); |
|
|
|
|
|
oop func = getVariable(this, map_get(ast, func_symbol)); |
|
|
|
|
|
if (!is(Function, func)) { |
|
|
|
|
|
printf("cannot call "); |
|
|
|
|
|
println(func); |
|
|
|
|
|
exit(1); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
oop args = evalArgs(scope, map_get(ast, args_symbol)); |
|
|
|
|
|
if (get(func, Function, primitive) == NULL) { |
|
|
|
|
|
oop param = get(func, Function, param); |
|
|
|
|
|
oop localScope = map_zip(param, args); |
|
|
|
|
|
// and set this in the local scope |
|
|
|
|
|
map_set(localScope, this_symbol, this); |
|
|
|
|
|
map_set(localScope, __proto___symbol, get(func, Function, parentScope)); |
|
|
|
|
|
if (opt_v) { |
|
|
|
|
|
printf("parentScope: "); |
|
|
println(get(func, Function, parentScope)); |
|
|
println(get(func, Function, parentScope)); |
|
|
|
|
|
printf("localScope: "); |
|
|
println(localScope); |
|
|
println(localScope); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -971,6 +1031,7 @@ oop eval(oop scope, oop ast) |
|
|
} |
|
|
} |
|
|
return get(func, Function, primitive)(args); |
|
|
return get(func, Function, primitive)(args); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
case t_return: { |
|
|
case t_return: { |
|
|
jbsCheck("return outside a function"); |
|
|
jbsCheck("return outside a function"); |
|
|
jbs->result = eval(scope, map_get(ast, value_symbol)); |
|
|
jbs->result = eval(scope, map_get(ast, value_symbol)); |
|
|