|
|
@ -1,6 +1,6 @@ |
|
|
|
# main.leg -- C parser + interpreter |
|
|
|
# |
|
|
|
# Last edited: 2025-01-24 16:03:00 by piumarta on zora |
|
|
|
# Last edited: 2025-01-24 20:12:04 by piumarta on zora |
|
|
|
|
|
|
|
%{ |
|
|
|
; |
|
|
@ -925,6 +925,11 @@ oop toStringOn(oop obj, oop str) |
|
|
|
toStringOn(get(obj, Cast,rhs), str); |
|
|
|
break; |
|
|
|
} |
|
|
|
case Dereference: { |
|
|
|
String_append(str, '*'); |
|
|
|
toStringOn(get(obj, Dereference,rhs), str); |
|
|
|
break; |
|
|
|
} |
|
|
|
case Unary: { |
|
|
|
char *name = 0; |
|
|
|
oop rhs = get(obj, Unary,rhs); |
|
|
@ -956,8 +961,8 @@ oop toStringOn(oop obj, oop str) |
|
|
|
case SHR: name = ">>"; break; |
|
|
|
case LT: name = "<"; break; |
|
|
|
case LE: name = "<="; break; |
|
|
|
case GE: name = ">"; break; |
|
|
|
case GT: name = ">="; break; |
|
|
|
case GE: name = ">="; break; |
|
|
|
case GT: name = ">"; break; |
|
|
|
case EQ: name = "=="; break; |
|
|
|
case NE: name = "!="; break; |
|
|
|
case BAND: name = "&"; break; |
|
|
@ -985,6 +990,13 @@ oop toStringOn(oop obj, oop str) |
|
|
|
String_append(str, ')'); |
|
|
|
break; |
|
|
|
} |
|
|
|
case While: { |
|
|
|
String_format(str, "while ("); |
|
|
|
toStringOn(get(obj, While,condition), str); |
|
|
|
String_format(str, ") "); |
|
|
|
toStringOn(get(obj, While,expression), str); |
|
|
|
break; |
|
|
|
} |
|
|
|
case For: { |
|
|
|
String_format(str, "for ("); |
|
|
|
toStringOn(get(obj, For,initialiser), str); |
|
|
@ -1450,7 +1462,7 @@ block = LBRACE b:mkArray |
|
|
|
| e:error { expected(e, "statement") } |
|
|
|
) |
|
|
|
|
|
|
|
stmt = WHILE c:cond s:stmt { $$ = newWhile(c, e) } |
|
|
|
stmt = WHILE c:cond s:stmt { $$ = newWhile(c, s) } |
|
|
|
| FOR LPAREN |
|
|
|
( i:vardecl | i:expropt SEMI ) |
|
|
|
c:expropt SEMI u:expropt RPAREN |
|
|
@ -1682,9 +1694,9 @@ oop nlrPop(void) |
|
|
|
#define FBINOP(L, OP, R) newFloat(floatValue(L) OP floatValue(R)) |
|
|
|
#define FRELOP(L, OP, R) (floatValue(L) OP floatValue(R) ? true : false) |
|
|
|
|
|
|
|
#define isNil(O) ((O) == nil) |
|
|
|
#define isFalse(O) ((O) == nil) |
|
|
|
#define isTrue(O) ((O) != nil) |
|
|
|
#define isNil(O) (nil == (O)) |
|
|
|
#define isFalse(O) (false == (O)) |
|
|
|
#define isTrue(O) (true == (O)) |
|
|
|
|
|
|
|
void declareVariable(oop name, oop type, oop value); |
|
|
|
|
|
|
@ -2860,7 +2872,7 @@ oop typeCheck(oop exp, oop fntype) |
|
|
|
case LT: return t_int; |
|
|
|
case LE: assert(!"unimplemented"); break; |
|
|
|
case GE: assert(!"unimplemented"); break; |
|
|
|
case GT: assert(!"unimplemented"); break; |
|
|
|
case GT: return t_int; |
|
|
|
case EQ: assert(!"unimplemented"); break; |
|
|
|
case NE: assert(!"unimplemented"); break; |
|
|
|
case BAND: assert(!"unimplemented"); break; |
|
|
@ -2878,6 +2890,14 @@ oop typeCheck(oop exp, oop fntype) |
|
|
|
fatal("incompatible types assigning '%s' to '%s'", toString(rhs), toString(lhs)); |
|
|
|
return lhs; |
|
|
|
} |
|
|
|
case While: { |
|
|
|
oop cond = get(exp, While,condition); |
|
|
|
oop body = get(exp, While,expression); |
|
|
|
cond = typeCheck(cond, fntype); |
|
|
|
if (t_int != cond) fatal("while condition is not 'int'"); |
|
|
|
typeCheck(body, fntype); |
|
|
|
return nil; |
|
|
|
} |
|
|
|
case For: { |
|
|
|
oop init = get(exp, For,initialiser); |
|
|
|
oop cond = get(exp, For,condition); |
|
|
@ -2971,8 +2991,9 @@ oop typeCheck(oop exp, oop fntype) |
|
|
|
oop *argv = get(arguments, Array,elements); |
|
|
|
int parc = get(params, Array,size); |
|
|
|
oop *parv = get(params, Array,elements); |
|
|
|
int vararg = parc && t_etc == parv[parc - 1]; |
|
|
|
if ((vararg && (argc < parc) && parc > 1) || (!vararg && (argc != parc))) |
|
|
|
int vararg = parc && (t_etc == parv[parc - 1]); |
|
|
|
printf("argc %d parc %d vararg %d\n", argc, parc, vararg); |
|
|
|
if ((!vararg && (argc != parc)) || (vararg && (argc < parc - 1))) |
|
|
|
fatal("wrong number (%d) of arguments, expected %d", argc, parc); |
|
|
|
for (int i = 0; i < argc; ++i) { |
|
|
|
oop part = parv[i]; |
|
|
|