Ver a proveniência

block eval pops scopes properly during nonlocal return

master
Ian Piumarta há 5 meses
ascendente
cometimento
c220bef846
2 ficheiros alterados com 24 adições e 6 eliminações
  1. +22
    -5
      main.leg
  2. +2
    -1
      test.txt

+ 22
- 5
main.leg Ver ficheiro

@ -1,6 +1,6 @@
# main.leg -- C parser + interpreter
#
# Last edited: 2025-01-24 14:48:22 by piumarta on zora-1043.local
# Last edited: 2025-01-24 16:03:00 by piumarta on zora
%{
;
@ -1263,8 +1263,10 @@ void printiln(oop obj, int indent)
break;
}
case Scope: {
printf("SCOPE\n");
printiln(get(obj, Scope,names), indent+1);
printf("SCOPE ");
oop names = get(obj, Scope,names);
Array_do(names, name) printf(" %s", toString(name));
printf("\n");
break;
}
case TypeName: {
@ -1704,13 +1706,16 @@ oop apply(oop function, oop arguments, oop 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);
assert(get(function, Function,variadic) || (parc == argc));
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);
Scope_begin();
if (get(function, Function,variadic)) --parc;
int argn = 0;
while (argn < parc) {
oop var = parv[argn];
@ -1839,10 +1844,17 @@ oop eval(oop exp, oop env)
oop *elts = get(stmts, Array,elements);
Object *result = nil;
Scope_begin();
switch (nlrPush()) { // longjmp occurred
case NLR_INIT: break;
case NLR_RETURN: Scope_end(); return nlrPop();
case NLR_CONTINUE: Scope_end(); nlrReturn(NLR_CONTINUE, nlrPop());
case NLR_BREAK: Scope_end(); nlrReturn(NLR_BREAK, nlrPop());
}
for (int i = 0; i < size; ++i) {
result = eval(elts[i], env);
}
Scope_end();
nlrPop();
return result;
}
case Address: {
@ -3061,9 +3073,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));
typeCheck(yysval, nil);
assert(1 == Array_size(scopes));
if (opt_v > 1) printf("---------------- declare\n");
result = preval(yysval);
assert(1 == Array_size(scopes));
nlrPop();
}
if (opt_v > 0) {
@ -3172,5 +3187,7 @@ int main(int argc, char **argv)
fatal("main did not return an integer");
}
assert(1 == Array_size(scopes));
return _integerValue(result);
}

+ 2
- 1
test.txt Ver ficheiro

@ -4,7 +4,7 @@
int x = 21;
int baz(int x, ...) { return 42; }
int baz(int xx, ...) { return 42; }
int foo(void) { return x + x; }
@ -13,6 +13,7 @@ char *bar(void) { return "bye bye"; }
int main(int argc, char **argv)
{
printf("hello, world %d %s\n", foo(), bar());
printf("baz is %d %d %d\n", baz(1), baz(1, 2), baz(1, "two", 3));
int x = 42;
int *p = &x;
printf("x is %d p is %p\n", *p, p);

Carregando…
Cancelar
Guardar