|
|
@ -1,6 +1,6 @@ |
|
|
|
# main.leg -- C parser + interpreter |
|
|
|
# |
|
|
|
# Last edited: 2025-01-25 08:53:25 by piumarta on m1mbp |
|
|
|
# Last edited: 2025-01-25 09:19:51 by piumarta on m1mbp |
|
|
|
|
|
|
|
%{ |
|
|
|
; |
|
|
@ -990,6 +990,17 @@ oop toStringOn(oop obj, oop str) |
|
|
|
String_append(str, ')'); |
|
|
|
break; |
|
|
|
} |
|
|
|
case If: { |
|
|
|
String_format(str, "if ("); |
|
|
|
toStringOn(get(obj, If,condition), str); |
|
|
|
String_format(str, ") "); |
|
|
|
toStringOn(get(obj, If,consequent), str); |
|
|
|
if (nil != get(obj, If,alternate)) { |
|
|
|
String_format(str, "; else "); |
|
|
|
toStringOn(get(obj, If,alternate), str); |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
case While: { |
|
|
|
String_format(str, "while ("); |
|
|
|
toStringOn(get(obj, While,condition), str); |
|
|
@ -2113,7 +2124,9 @@ oop eval(oop exp, oop env) |
|
|
|
oop cond = get(exp, If,condition); |
|
|
|
oop conseq = get(exp, If,consequent); |
|
|
|
oop altern = get(exp, If,alternate); |
|
|
|
return isTrue(eval(cond, env)) ? eval(conseq, env) : eval(altern, env); |
|
|
|
if (isTrue(eval(cond, env))) eval(conseq, env); |
|
|
|
else if (!isNil(altern)) eval(altern, env); |
|
|
|
return nil; |
|
|
|
} |
|
|
|
case Return: { |
|
|
|
nlrReturn(NLR_RETURN, eval(get(exp, Return,value), env)); |
|
|
@ -2875,7 +2888,7 @@ oop typeCheck(oop exp, oop fntype) |
|
|
|
case LE: assert(!"unimplemented"); break; |
|
|
|
case GE: assert(!"unimplemented"); break; |
|
|
|
case GT: return t_int; |
|
|
|
case EQ: assert(!"unimplemented"); break; |
|
|
|
case EQ: return t_int; |
|
|
|
case NE: assert(!"unimplemented"); break; |
|
|
|
case BAND: assert(!"unimplemented"); break; |
|
|
|
case BXOR: assert(!"unimplemented"); break; |
|
|
@ -2892,6 +2905,13 @@ oop typeCheck(oop exp, oop fntype) |
|
|
|
fatal("incompatible types assigning '%s' to '%s'", toString(rhs), toString(lhs)); |
|
|
|
return lhs; |
|
|
|
} |
|
|
|
case If: { |
|
|
|
if (t_int != typeCheck(get(exp, If,condition), fntype)) fatal("if condition is not 'int'"); |
|
|
|
typeCheck(get(exp, If,consequent), fntype); |
|
|
|
if (nil != get(exp, If,alternate)) |
|
|
|
typeCheck(get(exp, If,alternate), fntype); |
|
|
|
return nil; |
|
|
|
} |
|
|
|
case While: { |
|
|
|
oop cond = get(exp, While,condition); |
|
|
|
oop body = get(exp, While,expression); |
|
|
|