#!/bin/sh
ctags -R &
cc -g -D CERISE_TESTS -Wall -Wextra --std=c99 -o cerisec-test *.c \
- && ./cerisec-test \
&& cc -g -Wall -Wextra --std=c99 -o cerisec *.c \
+ && ./cerisec-test \
&& ./cerisec tests/Module.m | tee tests/Module.s \
&& cc -o Module tests/Module.s
rm Module
enum{
SYM_CONST, SYM_VAR, SYM_TYPE, SYM_PROC
} class;
- int export;
char* name;
Type* type;
ImmValue imm;
+ int export : 1;
+ int global : 1;
} Symbol;
typedef struct Module {
typedef struct {
enum {
- ITEM_CONST, ITEM_VAR
+ ITEM_CONST, ITEM_VAR, ITEM_MVAR, ITEM_REG
} mode;
Type* type;
int reg;
Module* imports;
Symbol* scope;
char* name;
+ long curr_reg;
} Parser;
+static inline void item_dump(Item* a)
+{
+ printf("// Item M:%d R:%d ", a->mode, a->reg);
+ if (a->mode == ITEM_MVAR)
+ {
+ printf(" %s", a->imm.s);
+ }
+ else
+ {
+ if (a->type->form == FORM_INT)
+ {
+ printf("%lld", a->imm.i);
+ }
+ else if (a->type->form == FORM_REAL)
+ {
+ printf("%f", a->imm.f);
+ }
+ }
+ puts("");
+}
+
void lexfile(Parser* ctx, char* path);
void lex(Parser* ctx);
void lexprintpos(Parser* p, FILE* file, Tok* tok);
/* Code Generation
*****************************************************************************/
-/* opcodes */
-enum AsmOp {
- /* Assembly Operations */
- OP_LOAD = 0, OP_STORE, OP_MOVE,
- OP_CMP, OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD,
- OP_EQ, OP_NEQ, OP_LT, OP_GT, OP_LTEQ, OP_GTEQ,
-
- OP_CALL, OP_RET,
-};
-
enum Regs {
- IMM = 0,
- RAX, RBX, RCX, RDX, RBP, RSP, RSI, RDI,
+ NOREG, RBX, RCX, RDX, RBP, RSP, RSI, RDI,
R8, R9, R10, R11, R12, R13, R14, R15,
};
void codegen_global(Parser* p, char* name, Type* type);
void codegen_main(Parser* p);
void codegen_startproc(Parser* p, char* name, long long localsz);
-void codegen_endproc(void);
-void codegen_unop(int op, Item* a);
-void codegen_binop(int op, Item* a, Item* b);
-void codegen_store(Item* a, Item* b);
+void codegen_endproc(Parser* p);
+void codegen_unop(Parser* p, int op, Item* a);
+void codegen_binop(Parser* p, int op, Item* a, Item* b);
+void codegen_store(Parser* p, Item* a, Item* b);
#include <limits.h>
#include <assert.h>
+#define MAX_REG 15
+
+/* Register Usage
+
+*/
+
Type BoolType = {
.form = FORM_BOOL,
.size = sizeof(bool)
{
item->mode = ITEM_CONST;
item->type = type;
- item->reg = IMM;
+ item->reg = NOREG;
item->imm.i = val;
}
{
item->mode = ITEM_CONST;
item->type = &RealType;
- item->reg = IMM;
+ item->reg = NOREG;
item->imm.f = val;
}
{
item->mode = ITEM_CONST;
item->type = &StringType;
- item->reg = IMM;
+ item->reg = NOREG;
item->imm.s = val;
}
}
}
-static void const_unop(int op, Item* a)
+static void const_unop(Parser* p, int op, Item* a)
{
+ (void)p;
if (a->type->form == FORM_INT)
{
switch (op)
}
}
+static char* regname(int reg)
+{
+ static char* names[] = {
+ "%noreg", // invalid register
+ "%rdi", // 1st argument
+ "%rsi", // 2nd argument
+ "%rdx", // 3rd argument
+ "%rcx", // 4th argument
+ "%r8", // 5th argument
+ "%r9", // 6th argument
+ "%rbx", // temp register
+ "%r10", // temp register
+ "%r11", // temp register
+ "%r12", // callee saved register
+ "%r13", // callee saved register
+ "%r14", // callee saved register
+ "%r15", // callee saved register
+ "%rax", // return value
+ };
+ return names[reg];
+}
+
+static char* curr_regname(Parser* p)
+{
+ return regname(p->curr_reg);
+}
+
+static void next_reg(Parser* p)
+{
+ if (p->curr_reg < MAX_REG)
+ {
+ p->curr_reg++;
+ }
+ else
+ {
+ assert(!"register stack overflow");
+ }
+}
+
+static void load_var(Parser* p, Item* item)
+{
+ (void)p;
+ switch (item->mode)
+ {
+ case ITEM_CONST:
+ puts("BAR");
+ /* TODO: range check the constant */
+ // emit instruction
+ item->reg = p->curr_reg;
+
+ printf("movq %s, $%lld\n", curr_regname(p), item->imm.i);
+ item->reg = p->curr_reg;
+ next_reg(p);
+ break;
+
+ case ITEM_VAR:
+ break;
+
+ case ITEM_MVAR:
+// puts("MVAR");
+// printf("movq %s, $%lld\n", curr_regname(p), item->imm.i);
+
+// item_dump(item);
+
+
+ printf(" movq %s_%s(%%rip), %s\n",
+ p->name,
+ item->imm.s,
+ curr_regname(p)
+ );
+// b->imm.i, p->name, a->imm.s);
+
+ item->reg = p->curr_reg;
+ next_reg(p);
+ break;
+
+ case ITEM_REG:
+ /* nothing to do */
+ break;
+ }
+}
+
void codegen_imports(Parser* p)
{
for (Module* m = p->imports; m; m = m->next)
{
printf(" movq %%rsp, %%rbp\n\n");
}
+ p->curr_reg = 1;
}
-void codegen_endproc(void)
+void codegen_endproc(Parser* p)
{
+ (void)p;
puts("");
printf(" pop %%rbp\n");
printf(" ret\n\n");
}
-void codegen_unop(int op, Item* a)
+void codegen_unop(Parser* p, int op, Item* a)
{
if (a->mode == ITEM_CONST)
{
- const_unop(op, a);
+ const_unop(p, op, a);
}
else
{
}
}
-void codegen_binop(int op, Item* a, Item* b)
+static void imm_binop(Parser* p, int op, Item* a, Item* b)
+{
+ if (a->type->form == FORM_INT || a->type->form == FORM_BOOL)
+ {
+ switch (op)
+ {
+ case '+':
+ printf(" addq $%lld, %s\n", b->imm.i, regname(a->reg));
+ break;
+
+ default:
+ assert(!"not implemented");
+ break;
+ }
+ }
+ else
+ {
+ assert(!"not implemented");
+ }
+}
+
+void codegen_binop(Parser* p, int op, Item* a, Item* b)
{
if (items_const(a, b))
{
const_binop(op, a, b);
}
+ else if (b->mode == ITEM_CONST)
+ {
+ load_var(p, a);
+ imm_binop(p, op, a, b);
+ }
else
{
- assert(!"not supported");
+ load_var(p, a);
+ load_var(p, b);
+ // emit instruction
+ // p->topreg--;
+ // a->reg = p->topreg-1;
}
}
-/*
- PROCEDURE GetSB;
- BEGIN
- IF curSB = 1 THEN
- Put2(Ldw, SB, 0, pc-fixorgD);
- fixorgD := pc-1;
- curSB := 0
- END
- END GetSB;
-
- PROCEDURE load(VAR x: Item);
- BEGIN
- IF x.mode # Reg THEN
- IF x.mode = Var THEN
- IF x.r > 0 THEN (*local*)
- Put2(Ldw, RH, SP, x.a)
- ELSE
- GetSB;
- Put2(Ldw, RH, SB, x.a)
- END ;
- x.r := RH;
- incR
- ELSIF x.mode = Par THEN
- Put2(Ldw, RH, x.r, x.a);
- Put2(Ldw, RH, RH, 0);
- x.r := RH;
- incR
- ELSIF x.mode = Const THEN
- IF (x.a >= 10000H) OR (x.a < -10000H) THEN
- OSS.Mark("const too large")
- END ;
- Put1(Mov, RH, 0, x.a);
- x.r := RH;
- incR
- ELSIF x.mode = RegI THEN
- Put2(Ldw, x.r, x.r, x.a)
- ELSIF x.mode = Cond THEN
- Put3(2, negated(x.r), 2);
- FixLink(x.b);
- Put1(Mov, RH, 0, 1);
- Put3(2, 7, 1);
- FixLink(x.a);
- Put1(Mov, RH, 0, 0);
- x.r := RH;
- incR
- END ;
- x.mode := Reg
- END
- END load;
-
- PROCEDURE Store*(VAR x, y: Item); (* x := y *)
- BEGIN
- load(y);
- IF x.mode = Var THEN
- IF x.r > 0 THEN (*local*)
- Put2(Stw, y.r, SP, x.a)
- ELSE
- GetSB;
- Put2(Stw, y.r, SB, x.a)
- END
- ELSIF x.mode = Par THEN
- Put2(Ldw, RH, SP, x.a);
- Put2(Stw, y.r, RH, x.b)
- ELSIF x.mode = RegI THEN
- Put2(Stw, y.r, x.r, x.a);
- DEC(RH)
- ELSE
- OSS.Mark("illegal assignment")
- END ;
- DEC(RH)
- END Store;
-
-*/
-
-void codegen_store(Item* a, Item* b)
+void codegen_store(Parser* p, Item* a, Item* b)
{
- if (a->mode == ITEM_VAR && b->reg == IMM)
+ if (a->mode == ITEM_MVAR && b->reg == NOREG)
+ {
+ printf(" movq $%lld, %s_%s(%%rip)\n",
+ b->imm.i, p->name, a->imm.s);
+ }
+ else if (a->mode == ITEM_MVAR)
{
- printf(" movq $%lld, %s(%%rip)\n", b->imm.i, a->imm.s);
+ printf(" movq %s, %s_%s(%%rip)\n",
+ regname(b->reg), p->name, a->imm.s);
}
else
{
- assert(!"bad store op");
+// assert(!"bad store op");
}
}
-
-
-/*
-
-add %r10,%r11 // add r10 and r11, put result in r11
-add $5,%r10 // add 5 to r10, put result in r10
-call label // call a subroutine / function / procedure
-cmp %r10,%r11 // compare register r10 with register r11. The comparison sets flags in the processor status register which affect conditional jumps.
-cmp $99,%r11 // compare the number 99 with register r11. The comparison sets flags in the processor status register which affect conditional jumps.
-div %r10 // divide rax by the given register (r10), places quotient into rax and remainder into rdx (rdx must be zero before this instruction)
-inc %r10 // increment r10
-jmp label // jump to label
-je label // jump to label if equal
-jne label // jump to label if not equal
-jl label // jump to label if less
-jg label // jump to label if greater
-mov %r10,%r11 // move data from r10 to r11
-mov $99,%r10 // put the immediate value 99 into r10
-mov %r10,(%r11) // move data from r10 to address pointed to by r11
-mov (%r10),%r11 // move data from address pointed to by r10 to r10
-mul %r10 // multiplies rax by r10, places result in rax and overflow in rdx
-push %r10 // push r10 onto the stack
-pop %r10 // pop r10 off the stack
-ret // routine from subroutine (counterpart to call)
-syscall // invoke a syscall (in 32-bit mode, use "int $0x80" instead)
-
-*/
-
-//static void emit_op0(AsmOp op)
-//{
-//}
-//
-//static void emit_opreg1(AsmOp op, long long reg)
-//{
-//}
-//
-//static void emit_opimmi(AsmOp op, long long imm)
-//{
-//}
-//
-//static void emit_opimmf(AsmOp op, double imm)
-//{
-//}
-//
-//static void emit_opreg2(AsmOp op, int rega, int regb)
-//{
-//}
-
-
\r
PROCEDURE incR;\r
BEGIN\r
- IF RH < SB THEN INC(RH) ELSE OSS.Mark("register stack overflow") END\r
+ IF RH < SB THEN\r
+ INC(RH)\r
+ ELSE\r
+ OSS.Mark("register stack overflow")\r
+ END\r
END incR;\r
\r
PROCEDURE CheckRegs*;\r
BEGIN\r
IF RH # 0 THEN\r
- (* Texts.WriteString(W, "RegStack!"); Texts.WriteInt(W, R, 4);\r
- Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) *)\r
+ (* Texts.WriteString(W, "RegStack!");\r
+ Texts.WriteInt(W, R, 4);\r
+ Texts.WriteLn(W);\r
+ Texts.Append(Oberon.Log, W.buf) *)\r
OSS.Mark("Reg Stack"); RH := 0\r
END\r
END CheckRegs;\r
\r
PROCEDURE GetSB;\r
BEGIN\r
- IF curSB = 1 THEN Put2(Ldw, SB, 0, pc-fixorgD); fixorgD := pc-1; curSB := 0 END\r
+ IF curSB = 1 THEN\r
+ Put2(Ldw, SB, 0, pc-fixorgD);\r
+ fixorgD := pc-1;\r
+ curSB := 0\r
+ END\r
END GetSB;\r
\r
PROCEDURE load(VAR x: Item);\r
BEGIN\r
IF x.mode # Reg THEN\r
+\r
IF x.mode = Var THEN\r
- IF x.r > 0 THEN (*local*) Put2(Ldw, RH, SP, x.a) ELSE GetSB; Put2(Ldw, RH, SB, x.a) END ;\r
- x.r := RH; incR\r
- ELSIF x.mode = Par THEN Put2(Ldw, RH, x.r, x.a); Put2(Ldw, RH, RH, 0); x.r := RH; incR\r
+ IF x.r > 0 THEN (*local*)\r
+ Put2(Ldw, RH, SP, x.a)\r
+ ELSE\r
+ GetSB;\r
+ Put2(Ldw, RH, SB, x.a)\r
+ END ;\r
+ x.r := RH;\r
+ incR\r
+\r
+ ELSIF x.mode = Par THEN\r
+ Put2(Ldw, RH, x.r, x.a);\r
+ Put2(Ldw, RH, RH, 0);\r
+ x.r := RH;\r
+ incR\r
+\r
ELSIF x.mode = Const THEN\r
- IF (x.a >= 10000H) OR (x.a < -10000H) THEN OSS.Mark("const too large") END ;\r
- Put1(Mov, RH, 0, x.a); x.r := RH; incR\r
- ELSIF x.mode = RegI THEN Put2(Ldw, x.r, x.r, x.a)\r
+ IF (x.a >= 10000H) OR (x.a < -10000H) THEN\r
+ OSS.Mark("const too large")\r
+ END ;\r
+\r
+ Put1(Mov, RH, 0, x.a);\r
+ x.r := RH;\r
+ incR\r
+\r
+ ELSIF x.mode = RegI THEN\r
+ Put2(Ldw, x.r, x.r, x.a)\r
+\r
ELSIF x.mode = Cond THEN\r
Put3(2, negated(x.r), 2);\r
- FixLink(x.b); Put1(Mov, RH, 0, 1); Put3(2, 7, 1);\r
- FixLink(x.a); Put1(Mov, RH, 0, 0); x.r := RH; incR\r
+ FixLink(x.b);\r
+ Put1(Mov, RH, 0, 1);\r
+ Put3(2, 7, 1);\r
+ FixLink(x.a);\r
+ Put1(Mov, RH, 0, 0);\r
+ x.r := RH;\r
+ incR\r
END ;\r
x.mode := Reg\r
END\r
PROCEDURE AddOp*(op: LONGINT; VAR x, y: Item); (* x := x +- y *)\r
BEGIN\r
IF op = OSS.plus THEN\r
- IF (x.mode = Const) & (y.mode = Const) THEN x.a := x.a + y.a\r
- ELSIF y.mode = Const THEN load(x);\r
- IF y.a # 0 THEN Put1(Add, x.r, x.r, y.a) END\r
- ELSE load(x); load(y); Put0(Add, RH-2, x.r, y.r); DEC(RH); x.r := RH-1\r
+ IF (x.mode = Const) & (y.mode = Const) THEN\r
+ x.a := x.a + y.a\r
+\r
+ ELSIF y.mode = Const THEN\r
+ load(x);\r
+ IF y.a # 0 THEN\r
+ Put1(Add, x.r, x.r, y.a)\r
+ END\r
+\r
+ ELSE\r
+ load(x);\r
+ load(y);\r
+ Put0(Add, RH-2, x.r, y.r);\r
+ DEC(RH);\r
+ x.r := RH-1\r
END\r
+\r
ELSE (*op = OSS.minus*)\r
- IF (x.mode = Const) & (y.mode = Const) THEN x.a := x.a - y.a\r
- ELSIF y.mode = Const THEN load(x);\r
- IF y.a # 0 THEN Put1(Sub, x.r, x.r, y.a) END\r
- ELSE load(x); load(y); Put0(Sub, RH-2, x.r, y.r); DEC(RH); x.r := RH-1\r
+ IF (x.mode = Const) & (y.mode = Const) THEN\r
+ x.a := x.a - y.a\r
+ ELSIF y.mode = Const THEN\r
+ load(x);\r
+ IF y.a # 0 THEN\r
+ Put1(Sub, x.r, x.r, y.a)\r
+ END\r
+ ELSE\r
+ load(x);\r
+ load(y);\r
+ Put0(Sub, RH-2, x.r, y.r);\r
+ DEC(RH);\r
+ x.r := RH-1\r
END\r
END\r
END AddOp;\r
\r
PROCEDURE MulOp*(VAR x, y: Item); (* x := x * y *)\r
BEGIN\r
- IF (x.mode = Const) & (y.mode = Const) THEN x.a := x.a * y.a\r
- ELSIF (y.mode = Const) & (y.a = 2) THEN load(x); Put1(Lsl, x.r, x.r, 1)\r
- ELSIF y.mode = Const THEN load(x); Put1(Mul, x.r, x.r, y.a)\r
- ELSIF x.mode = Const THEN load(y); Put1(Mul, y.r, y.r, x.a); x.mode := Reg; x.r := y.r\r
- ELSE load(x); load(y); Put0(Mul, RH-2, x.r, y.r); DEC(RH); x.r := RH-1\r
+ IF (x.mode = Const) & (y.mode = Const) THEN\r
+ x.a := x.a * y.a\r
+ ELSIF (y.mode = Const) & (y.a = 2) THEN\r
+ load(x);\r
+ Put1(Lsl, x.r, x.r, 1)\r
+ ELSIF y.mode = Const THEN\r
+ load(x);\r
+ Put1(Mul, x.r, x.r, y.a)\r
+ ELSIF x.mode = Const THEN\r
+ load(y);\r
+ Put1(Mul, y.r, y.r, x.a);\r
+ x.mode := Reg;\r
+ x.r := y.r\r
+ ELSE\r
+ load(x);\r
+ load(y);\r
+ Put0(Mul, RH-2, x.r, y.r);\r
+ DEC(RH);\r
+ x.r := RH-1\r
END\r
END MulOp;\r
\r
BEGIN\r
IF op = OSS.div THEN\r
IF (x.mode = Const) & (y.mode = Const) THEN\r
- IF y.a > 0 THEN x.a := x.a DIV y.a ELSE OSS.Mark("bad divisor") END\r
- ELSIF (y.mode = Const) & (y.a = 2) THEN load(x); Put1(Asr, x.r, x.r, 1)\r
+ IF y.a > 0 THEN\r
+ x.a := x.a DIV y.a\r
+ ELSE\r
+ OSS.Mark("bad divisor")\r
+ END\r
+ ELSIF (y.mode = Const) & (y.a = 2) THEN\r
+ load(x);\r
+ Put1(Asr, x.r, x.r, 1)\r
ELSIF y.mode = Const THEN\r
- IF y.a > 0 THEN load(x); Put1(Div, x.r, x.r, y.a) ELSE OSS.Mark("bad divisor") END\r
- ELSE load(y); load(x); Put0(Div, RH-2, x.r, y.r); DEC(RH); x.r := RH-1\r
+ IF y.a > 0 THEN\r
+ load(x);\r
+ Put1(Div, x.r, x.r, y.a)\r
+ ELSE\r
+ OSS.Mark("bad divisor")\r
+ END\r
+ ELSE\r
+ load(y);\r
+ load(x);\r
+ Put0(Div, RH-2, x.r, y.r);\r
+ DEC(RH);\r
+ x.r := RH-1\r
END\r
ELSE (*op = OSS.mod*)\r
IF (x.mode = Const) & (y.mode = Const) THEN\r
- IF y.a > 0 THEN x.a := x.a MOD y.a ELSE OSS.Mark("bad modulus") END\r
- ELSIF (y.mode = Const) & (y.a = 2) THEN load(x); Put1(And, x.r, x.r, 1)\r
+ IF y.a > 0 THEN\r
+ x.a := x.a MOD y.a\r
+ ELSE\r
+ OSS.Mark("bad modulus")\r
+ END\r
+ ELSIF (y.mode = Const) & (y.a = 2) THEN\r
+ load(x);\r
+ Put1(And, x.r, x.r, 1)\r
ELSIF y.mode = Const THEN\r
- IF y.a > 0 THEN load(x); Put1(Div, x.r, x.r, y.a); Put0(Mov+U, x.r, 0, 0) ELSE OSS.Mark("bad modulus") END\r
- ELSE load(y); load(x); Put0(Div, RH-2, x.r, y.r); Put0(Mov+U, RH-2, 0, 0); DEC(RH); x.r := RH-1\r
+ IF y.a > 0 THEN\r
+ load(x);\r
+ Put1(Div, x.r, x.r, y.a);\r
+ Put0(Mov+U, x.r, 0, 0)\r
+ ELSE\r
+ OSS.Mark("bad modulus")\r
+ END\r
+ ELSE\r
+ load(y);\r
+ load(x);\r
+ Put0(Div, RH-2, x.r, y.r);\r
+ Put0(Mov+U, RH-2, 0, 0);\r
+ DEC(RH);\r
+ x.r := RH-1\r
END\r
END\r
END DivOp;\r
\r
PROCEDURE Relation*(op: INTEGER; VAR x, y: Item); (* x := x ? y *)\r
BEGIN\r
- IF y.mode = Const THEN load(x); Put1(Cmp, x.r, x.r, y.a); DEC(RH)\r
- ELSE load(x); load(y); Put0(Cmp, x.r, x.r, y.r); DEC(RH, 2)\r
+ IF y.mode = Const THEN\r
+ load(x);\r
+ Put1(Cmp, x.r, x.r, y.a);\r
+ DEC(RH)\r
+ ELSE\r
+ load(x);\r
+ load(y);\r
+ Put0(Cmp, x.r, x.r, y.r);\r
+ DEC(RH, 2)\r
END ;\r
SetCC(x, relmap[op - OSS.eql])\r
END Relation;\r
BEGIN\r
load(y);\r
IF x.mode = Var THEN\r
- IF x.r > 0 THEN (*local*) Put2(Stw, y.r, SP, x.a) ELSE GetSB; Put2(Stw, y.r, SB, x.a) END\r
- ELSIF x.mode = Par THEN Put2(Ldw, RH, SP, x.a); Put2(Stw, y.r, RH, x.b)\r
- ELSIF x.mode = RegI THEN Put2(Stw, y.r, x.r, x.a); DEC(RH)\r
- ELSE OSS.Mark("illegal assignment")\r
+ IF x.r > 0 THEN (*local*)\r
+ Put2(Stw, y.r, SP, x.a)\r
+ ELSE\r
+ GetSB;\r
+ Put2(Stw, y.r, SB, x.a)\r
+ END\r
+ ELSIF x.mode = Par THEN\r
+ Put2(Ldw, RH, SP, x.a);\r
+ Put2(Stw, y.r, RH, x.b)\r
+ ELSIF x.mode = RegI THEN\r
+ Put2(Stw, y.r, x.r, x.a);\r
+ DEC(RH)\r
+ ELSE\r
+ OSS.Mark("illegal assignment")\r
END ;\r
DEC(RH)\r
END Store;\r
VAR xmd: INTEGER;\r
BEGIN xmd := x.mode; loadAdr(x);\r
IF (ftype.form = Array) & (ftype.len < 0) THEN (*open array*)\r
- IF x.type.len >= 0 THEN Put1(Mov, RH, 0, x.type.len) ELSE Put2(Ldw, RH, SP, x.a+4) END ;\r
+ IF x.type.len >= 0 THEN\r
+ Put1(Mov, RH, 0, x.type.len)\r
+ ELSE\r
+ Put2(Ldw, RH, SP, x.a+4)\r
+ END ;\r
incR\r
ELSIF ftype.form = Record THEN\r
- IF xmd = Par THEN Put2(Ldw, RH, SP, x.a+4); incR END\r
+ IF xmd = Par THEN\r
+ Put2(Ldw, RH, SP, x.a+4);\r
+ incR\r
+ END\r
END\r
END VarParam;\r
\r
PROCEDURE ValueParam*(VAR x: Item);\r
- BEGIN load(x)\r
+ BEGIN\r
+ load(x)\r
END ValueParam;\r
\r
PROCEDURE OpenArrayParam*(VAR x: Item);\r
BEGIN loadAdr(x);\r
- IF x.type.len >= 0 THEN Put1(Mov, RH, 0, x.type.len) ELSE Put2(Ldw, RH, SP, x.a+4) END ;\r
+ IF x.type.len >= 0 THEN\r
+ Put1(Mov, RH, 0, x.type.len)\r
+ ELSE\r
+ Put2(Ldw, RH, SP, x.a+4)\r
+ END ;\r
incR\r
END OpenArrayParam;\r
\r
*****************************************************************************/
static void init_item(Item* item, Symbol* sym)
{
- item->mode = sym->class;
+ if (SYM_VAR == sym->class)
+ {
+ item->mode = (sym->global ? ITEM_MVAR : ITEM_VAR);
+ }
+ else
+ {
+ item->mode = ITEM_CONST;
+ }
item->imm = sym->imm;
item->type = sym->type;
}
char* name = expect_text(p, IDENT);
Symbol* sym = symbol_get(p, -1, name);
init_item(item, sym);
+ if (sym->class == SYM_VAR)
+ {
+ item->imm.s = sym->name;
+ }
+
// item->mode = sym->class;
// item->type = sym->type;
consume(p);
factor(p, item);
check_bool(p, item);
- codegen_unop(NOT, item);
+ codegen_unop(p, NOT, item);
break;
case IDENT:
case '/':
case '%':
check_nums(p, item, &right);
- codegen_binop(op, item, &right);
+ codegen_binop(p, op, item, &right);
break;
case AND:
check_bools(p, item, &right);
- codegen_binop(op, item, &right);
+ codegen_binop(p, op, item, &right);
break;
default:
int op = consume(p); // OP
term(p, item);
check_num(p, item);
- codegen_unop(op, item);
+ codegen_unop(p, op, item);
}
else
{
{
check_nums(p, item, &right);
}
- codegen_binop(op, item, &right);
+ codegen_binop(p, op, item, &right);
}
}
{
int ops[] = { EQ, NEQ, '<', LTEQ, '>', GTEQ, IS, 0 };
simple_expr(p, item);
+ item_dump(item);
if (matches_oneof(p, ops))
{
Item right = { 0 };
int op = consume(p);
simple_expr(p, &right);
check_nums(p, item, &right);
- codegen_binop(op, item, &right);
+ codegen_binop(p, op, item, &right);
}
}
name = expect_text(p, IDENT);
export = accept(p, '*');
sym = symbol_new(p, name, SYM_VAR, export);
+ sym->global = 1;
nsyms++;
if (!accept(p, ','))
expression(p, &right);
check_types(p, item, &right);
- codegen_store(item, &right);
+ codegen_store(p, item, &right);
}
else
{
statement_seq(p, item);
expect(p, END);
}
- codegen_endproc();
+ codegen_endproc(p);
// char* ename = expect_text(p, IDENT);
// if (strcmp(sname, ename))
.path = fname,
.fbeg = fcontents,
.fpos = fcontents,
- }
+ },
+ .curr_reg = 0
};
module(p, &(Item){0});
codegen_main(p);
module Module
-#import
+#import
# A = Foo
# B = Bar
var
a : Bool
b : Int
+ c : Int
begin
- a = true;
- a = A;
- b = 24;
- b = B;
-# c = a + b;
+ a = true;
+ a = A;
+ b = 24;
+ b = B;
+ c = b + 1;
+# c = 1 + b;
+# c = a + b;
end
+// Item M:0 R:0
+// Item M:0 R:0 42
.data
Module_a:
.zero 1
Module_b:
.zero 8
+ .data
+Module_c:
+ .zero 8
+
.text
.globl Module
Module:
pushq %rbp
movq %rsp, %rbp
- movq $1, a(%rip)
- movq $1, a(%rip)
- movq $24, b(%rip)
- movq $42, b(%rip)
+// Item M:0 R:0
+ movq $1, Module_a(%rip)
+// Item M:0 R:0
+ movq $1, Module_a(%rip)
+// Item M:0 R:0 24
+ movq $24, Module_b(%rip)
+// Item M:0 R:0 42
+ movq $42, Module_b(%rip)
+ movq Module_b(%rip), %rdi
+ addq $1, %rdi
+// Item M:2 R:1 b
+ movq %rdi, Module_c(%rip)
+BAR
+movq %rsi, $1
+ movq Module_b(%rip), %rdx
+// Item M:0 R:2 1
+ movq %rsi, Module_c(%rip)
pop %rbp
ret