瀏覽代碼

handle while

master
Ian Piumarta 5 月之前
父節點
當前提交
cb668afe92
共有 2 個檔案被更改,包括 35 行新增11 行删除
  1. +31
    -10
      main.leg
  2. +4
    -1
      test.txt

+ 31
- 10
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];

+ 4
- 1
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;
}

Loading…
取消
儲存