printf(" return _T%d;\n", item->reg);
}
}
+
+void codegen_rangecheck(Parser* p, long length, Item* index)
+{
+// codegen_binop(p, '*', index, base);
+ if (index->mode == ITEM_CONST)
+ {
+ if (index->type->form != FORM_INT)
+ {
+ error(p, "array indexes must be of integral type");
+ }
+ else if (index->imm.i >= length)
+ {
+ error(p, "array index out of bounds");
+ }
+ }
+}
{
(void)p, (void)item;
}
+
+void codegen_rangecheck(Parser* p, long length, Item* index)
+{
+ (void)p, (void)length, (void)index;
+}
{
(void)p, (void)item;
}
+
+void codegen_rangecheck(Parser* p, long length, Item* index)
+{
+ (void)p, (void)length, (void)index;
+}
Symbol* sym;
Type* type;
int reg;
+ int offset;
ImmValue imm;
} Item;
void codegen_call(Parser* p, Item* item, Item* args);
void codegen_setarg(Parser* p, Item* item, bool firstarg);
void codegen_return(Parser* p, Item* item);
+void codegen_rangecheck(Parser* p, long length, Item* index);
/*
END CheckRegs;\r
\r
PROCEDURE SetCC(VAR x: Item; n: LONGINT);\r
- BEGIN x.mode := Cond; x.a := 0; x.b := 0; x.r := n\r
+ BEGIN\r
+ x.mode := Cond;\r
+ x.a := 0;\r
+ x.b := 0;\r
+ x.r := n\r
END SetCC;\r
\r
PROCEDURE TestRange(x: LONGINT);\r
PROCEDURE loadAdr(VAR x: Item);\r
BEGIN\r
IF x.mode = Var THEN\r
- IF x.r > 0 THEN (*local*) Put1(Add, RH, SP, x.a); x.r := RH ELSE GetSB; Put1(Add, RH, SB, x.a) END ;\r
+ IF x.r > 0 THEN (*local*)\r
+ Put1(Add, RH, SP, x.a);\r
+ x.r := RH\r
+ ELSE\r
+ GetSB;\r
+ Put1(Add, RH, SB, x.a)\r
+ END ;\r
+ incR\r
+ ELSIF x.mode = Par THEN\r
+ Put2(Ldw, RH, SP, x.a);\r
+ Put1(Add, RH, RH, x.b);\r
+ x.r := RH;\r
incR\r
- ELSIF x.mode = Par THEN Put2(Ldw, RH, SP, x.a); Put1(Add, RH, RH, x.b); x.r := RH; incR\r
- ELSIF (x.mode = RegI) & (x.a # 0) THEN Put1(Add, x.r, x.r, x.a)\r
- ELSE OSS.Mark("address error")\r
+ ELSIF (x.mode = RegI) & (x.a # 0) THEN\r
+ Put1(Add, x.r, x.r, x.a)\r
+ ELSE\r
+ OSS.Mark("address error")\r
END ;\r
x.mode := Reg\r
END loadAdr;\r
PROCEDURE loadCond(VAR x: Item);\r
BEGIN\r
IF x.type.form = Boolean THEN\r
- IF x.mode = Const THEN x.r := 15 - x.a*8 ELSE load(x); Put1(Cmp, x.r, x.r, 0); x.r := NE; DEC(RH) END ;\r
- x.mode := Cond; x.a := 0; x.b := 0\r
- ELSE OSS.Mark("not Boolean")\r
+ IF x.mode = Const THEN\r
+ x.r := 15 - x.a*8\r
+ ELSE\r
+ load(x);\r
+ Put1(Cmp, x.r, x.r, 0);\r
+ x.r := NE;\r
+ DEC(RH)\r
+ END ;\r
+ x.mode := Cond;\r
+ x.a := 0;\r
+ x.b := 0\r
+ ELSE\r
+ OSS.Mark("not Boolean")\r
END\r
END loadCond;\r
\r
BEGIN\r
IF L0 # 0 THEN\r
L3 := L0;\r
- REPEAT L2 := L3; L3 := code[L2] MOD 40000H UNTIL L3 = 0;\r
- code[L2] := code[L2] + L1; L1 := L0\r
+ REPEAT\r
+ L2 := L3;\r
+ L3 := code[L2] MOD 40000H\r
+ UNTIL L3 = 0;\r
+ code[L2] := code[L2] + L1;\r
+ L1 := L0\r
END ;\r
RETURN L1\r
END merged;\r
(*-----------------------------------------------*)\r
\r
PROCEDURE IncLevel*(n: INTEGER);\r
- BEGIN curlev := curlev + n\r
+ BEGIN\r
+ curlev := curlev + n\r
END IncLevel;\r
\r
PROCEDURE MakeConstItem*(VAR x: Item; typ: Type; val: LONGINT);\r
\r
PROCEDURE Field*(VAR x: Item; y: Object); (* x := x.y *)\r
BEGIN\r
- IF (x.mode = Var) OR (x.mode = RegI) THEN x.a := x.a + y.val\r
- ELSIF x.mode = Par THEN Put2(Ldw, RH, x.r, x.a); x.mode := RegI; x.r := RH; x.a := y.val; incR\r
+ IF (x.mode = Var) OR (x.mode = RegI) THEN\r
+ x.a := x.a + y.val\r
+ ELSIF x.mode = Par THEN\r
+ Put2(Ldw, RH, x.r, x.a);\r
+ x.mode := RegI;\r
+ x.r := RH;\r
+ x.a := y.val;\r
+ incR\r
END\r
END Field;\r
\r
VAR s: LONGINT;\r
BEGIN\r
IF y.mode = Const THEN\r
- IF (y.a < 0) OR (y.a >= x.type.len) THEN OSS.Mark("bad index") END ;\r
- IF x.mode = Par THEN Put2(Ldw, RH, x.r, x.a); x.mode := RegI; x.a := 0 END ;\r
+ IF (y.a < 0) OR (y.a >= x.type.len) THEN\r
+ OSS.Mark("bad index")\r
+ END ;\r
+ IF x.mode = Par THEN\r
+ Put2(Ldw, RH, x.r, x.a);\r
+ x.mode := RegI;\r
+ x.a := 0\r
+ END ;\r
x.a := x.a + y.a * x.type.base.size\r
- ELSE s := x.type.base.size;\r
- IF y.mode # Reg THEN load(y) END ;\r
- IF s = 4 THEN Put1(Lsl, y.r, y.r, 2) ELSE Put1(Mul, y.r, y.r, s) END ;\r
+ ELSE\r
+ s := x.type.base.size;\r
+ IF y.mode # Reg THEN\r
+ load(y)\r
+ END ;\r
+ IF s = 4 THEN\r
+ Put1(Lsl, y.r, y.r, 2)\r
+ ELSE\r
+ Put1(Mul, y.r, y.r, s)\r
+ END ;\r
IF x.mode = Var THEN\r
- IF x.r > 0 THEN Put0(Add, y.r, SP, y.r) ELSE GetSB; Put0(Add, y.r, SB, y.r) END ;\r
- x.mode := RegI; x.r := y.r\r
+ IF x.r > 0 THEN\r
+ Put0(Add, y.r, SP, y.r)\r
+ ELSE\r
+ GetSB;\r
+ Put0(Add, y.r, SB, y.r)\r
+ END ;\r
+ x.mode := RegI;\r
+ x.r := y.r\r
ELSIF x.mode = Par THEN\r
- Put2(Ldw, RH, SP, x.a); Put0(Add, y.r, RH, y.r); x.mode := RegI; x.r := y.r\r
- ELSIF x.mode = RegI THEN Put0(Add, x.r, x.r, y.r); DEC(RH)\r
+ Put2(Ldw, RH, SP, x.a);\r
+ Put0(Add, y.r, RH, y.r);\r
+ x.mode := RegI;\r
+ x.r := y.r\r
+ ELSIF x.mode = RegI THEN\r
+ Put0(Add, x.r, x.r, y.r);\r
+ DEC(RH)\r
END\r
END\r
END Index;\r
VAR y: OSG.Item; obj: OSG.Object;\r
BEGIN\r
WHILE (sym = OSS.lbrak) OR (sym = OSS.period) DO\r
-\r
IF sym = OSS.lbrak THEN\r
- OSS.Get(sym); expression(y);\r
+ OSS.Get(sym);\r
+ expression(y);\r
IF x.type.form = OSG.Array THEN\r
- CheckInt(y); OSG.Index(x, y); x.type := x.type.base\r
- ELSE OSS.Mark("not an array")\r
+ CheckInt(y);\r
+ OSG.Index(x, y);\r
+ x.type := x.type.base\r
+ ELSE\r
+ OSS.Mark("not an array")\r
END ;\r
Check(OSS.rbrak, "no ]")\r
\r
BEGIN\r
IF sym = OSS.lparen THEN\r
OSS.Get(sym);\r
- IF fctno = 0 THEN (*ORD*) expression(x); OSG.Ord(x)\r
- ELSIF fctno = 1 THEN (*eot*) OSG.eot(x)\r
- ELSE (*fctno = 2*) OSG.Switch(x)\r
+ IF fctno = 0 THEN (*ORD*)\r
+ expression(x);\r
+ OSG.Ord(x)\r
+ ELSIF fctno = 1 THEN (*eot*)\r
+ OSG.eot(x)\r
+ ELSE (*fctno = 2*)\r
+ OSG.Switch(x)\r
END ;\r
- IF sym = OSS.rparen THEN OSS.Get(sym) ELSE OSS.Mark("rparen expected") END\r
- ELSE OSS.Mark("param missing"); OSG.MakeConstItem(x, OSG.intType, 0)\r
+ IF sym = OSS.rparen THEN\r
+ OSS.Get(sym)\r
+ ELSE\r
+ OSS.Mark("rparen expected")\r
+ END\r
+ ELSE\r
+ OSS.Mark("param missing");\r
+ OSG.MakeConstItem(x, OSG.intType, 0)\r
END\r
END StandF\unc;\r
\r
PROCEDURE StandProc(pno: LONGINT);\r
VAR x, y: OSG.Item;\r
BEGIN\r
- IF pno = 0 THEN OSG.OpenInput\r
+ IF pno = 0 THEN\r
+ OSG.OpenInput\r
ELSIF pno IN {1, 2, 3, 5} THEN\r
- IF sym = OSS.lparen THEN OSS.Get(sym); expression(x);\r
- IF pno = 1 THEN OSG.ReadInt(x);\r
+ IF sym = OSS.lparen THEN\r
+ OSS.Get(sym);\r
+ expression(x);\r
+ IF pno = 1 THEN\r
+ OSG.ReadInt(x);\r
ELSIF pno = 2 THEN\r
- IF sym = OSS.comma THEN OSS.Get(sym); expression(y); OSG.WriteInt(x, y) ELSE OSS.Mark("no comma") END\r
- ELSIF pno = 3 THEN OSG.WriteChar(x)\r
- ELSIF pno = 5 THEN OSG.LED(x)\r
- END ;\r
- IF sym = OSS.rparen THEN OSS.Get(sym) ELSE OSS.Mark("no rparen") END\r
- ELSE OSS.Mark(" missing lparen")\r
+ IF sym = OSS.comma THEN\r
+ OSS.Get(sym);\r
+ expression(y);\r
+ OSG.WriteInt(x, y)\r
+ ELSE\r
+ OSS.Mark("no comma")\r
END\r
- ELSIF pno = 4 THEN OSG.WriteLn\r
- ELSE OSS.Mark("undef proc")\r
+ ELSIF pno = 3 THEN\r
+ OSG.WriteChar(x)\r
+ ELSIF pno = 5 THEN\r
+ OSG.LED(x)\r
+ END ;\r
+ IF sym = OSS.rparen THEN\r
+ OSS.Get(sym)\r
+ ELSE\r
+ OSS.Mark("no rparen")\r
+ END\r
+ ELSE\r
+ OSS.Mark(" missing lparen")\r
+ END\r
+ ELSIF pno = 4 THEN\r
+ OSG.WriteLn\r
+ ELSE\r
+ OSS.Mark("undef proc")\r
END\r
END StandProc;\r
\r
Check(OSS.then, "no THEN");\r
StatSequence;\r
L := 0;\r
+\r
WHILE sym = OSS.elsif DO\r
OSS.Get(sym);\r
OSG.FJump(L);\r
END ;\r
StatSequence\r
END ;\r
+\r
IF sym = OSS.else THEN\r
OSS.Get(sym);\r
OSG.FJump(L);\r
ELSE\r
OSG.FixLink(x.a)\r
END ;\r
+\r
OSG.FixLink(L);\r
+\r
IF sym = OSS.end THEN\r
OSS.Get(sym)\r
ELSE\r
OSS.Get(sym)\r
END\r
END ;\r
+\r
OSG.CheckRegs;\r
+\r
IF sym = OSS.semicolon THEN\r
OSS.Get(sym)\r
ELSIF sym < OSS.semicolon THEN\r
// case '.':
// expect(p, IDENT);
// break;
-//
+
case '[':
{
expect(p, '[');
Type* type = item->type;
- while (type && type->form == FORM_ARRAY)
- {
- Item expr = {0};
- expression(p, &expr);
- check_int(p, &expr);
- type = type->base;
- if (type->form == FORM_ARRAY)
- {
- expect(p, ',');
- }
- }
+ Item index = {0};
+ expression(p, &index);
+ codegen_rangecheck(p, item->type->size, &index);
+ //codegen_binop(p, '*', &index, &base);
+ item->type = item->type->base;
expect(p, ']');
break;
}
{
do
{
- if (matches(p, IDENT))
- {
- Item right = { 0 };
- char* text = expect_text(p, IDENT);
- if (accept(p, '='))
- {
- Symbol* sym = symbol_get(p, SYM_VAR, text);
- init_item(item, sym);
- item->imm.s = sym->name;
-
- expression(p, &right);
- check_types(p, item, &right);
- codegen_store(p, item, &right);
- }
- else
- {
- /* TODO: add function calls and other complex stuff */
- error(p, "expected assignment");
- }
- expect(p, ';');
- }
- else if (matches(p, IF))
+// if (matches(p, IDENT))
+// {
+// Item right = { 0 };
+// char* text = expect_text(p, IDENT);
+// if (accept(p, '='))
+// {
+// Symbol* sym = symbol_get(p, SYM_VAR, text);
+// init_item(item, sym);
+// item->imm.s = sym->name;
+//
+// expression(p, &right);
+// check_types(p, item, &right);
+// codegen_store(p, item, &right);
+// }
+// else
+// {
+// /* TODO: add function calls and other complex stuff */
+// error(p, "expected assignment");
+// }
+// expect(p, ';');
+// }
+// else
+ if (matches(p, IF))
{
expect(p, IF);
expression(p, item);
codegen_endif(p, elsifs, item);
expect(p, END);
}
- else
+ else /* assignments/expressions */
{
- error(p, "expected a statement");
+ expression(p, item);
+ if (accept(p, '='))
+ {
+ Item right = { 0 };
+ expression(p, &right);
+ check_types(p, item, &right);
+ codegen_store(p, item, &right);
+ }
+ expect(p, ';');
}
}
while (!matches(p, END) && !matches(p, ELSE) && !matches(p, ELSIF) && !matches(p, RETURN));
{
check_bools(p, a, b);
}
+// else if (a->type->form == FORM_ARRAY)
+// {
+// }
else
{
error(p, "type mismatch");
#
# Function calls
# c = Foo(1,2);
+# e[0] = 1;
+# Foo(1,2);
e[0] = 1;
end