diff --git a/main.leg b/main.leg index 6d1b335..c05b534 100644 --- a/main.leg +++ b/main.leg @@ -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]; diff --git a/test.txt b/test.txt index 00efabf..533ec93 100755 --- a/test.txt +++ b/test.txt @@ -21,7 +21,10 @@ int main(int argc, char **argv) printf("x is %d %d\n", x, *p); x = 123; printf("x is %d %d\n", x, *p); - for (x = 0; x < 10; ++x) printf("%d\n", x); + for (x = 0; x < 10; ++x) printf("%d ", x); + printf("\n"); + while (x > 0) printf("%d ", --x); + printf("\n"); return 0; }