]> git.mdlowis.com Git - proto/obnc.git/commitdiff
added a single case of code generation for binary operators using variables
authormike lowis <mike@mdlowis.com>
Mon, 26 Apr 2021 03:36:17 +0000 (23:36 -0400)
committermike lowis <mike@mdlowis.com>
Mon, 26 Apr 2021 03:36:17 +0000 (23:36 -0400)
cerise/build.sh
cerise/cerise.h
cerise/codegen.c
cerise/oberon0/OSG.Mod
cerise/parser.c
cerise/tests/Module.m
cerise/tests/Module.s

index e0a3c86274bb38bd4637401dfdca7daf73839b7b..65e385fda6c111ac4a3688ff19c739cc661e596e 100755 (executable)
@@ -1,8 +1,8 @@
 #!/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
index d435505f4ea40e7d74795f409df73a9a44557872..c784aaf0f370bb19dfd70e83febff6357addbe9e 100644 (file)
@@ -101,10 +101,11 @@ typedef struct Symbol {
     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 {
@@ -116,7 +117,7 @@ typedef struct Module {
 
 typedef struct {
     enum {
-        ITEM_CONST, ITEM_VAR
+        ITEM_CONST, ITEM_VAR, ITEM_MVAR, ITEM_REG
     } mode;
     Type* type;
     int reg;
@@ -130,8 +131,30 @@ typedef struct {
     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);
@@ -139,19 +162,8 @@ void compile(char* fname);
 
 /* 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,
 };
 
@@ -165,7 +177,7 @@ void codegen_imports(Parser* p);
 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);
index 012eb18246abd3bb3182a2eaf40e73a73726c775..c3b1636ceee76fe59bfbc1b33edf6499ea0af9cd 100644 (file)
@@ -2,6 +2,12 @@
 #include <limits.h>
 #include <assert.h>
 
+#define MAX_REG 15
+
+/* Register Usage
+
+*/
+
 Type BoolType = {
     .form = FORM_BOOL,
     .size = sizeof(bool)
@@ -26,7 +32,7 @@ void codegen_setint(Item* item, Type* type, long long val)
 {
     item->mode  = ITEM_CONST;
     item->type  = type;
-    item->reg   = IMM;
+    item->reg   = NOREG;
     item->imm.i = val;
 }
 
@@ -34,7 +40,7 @@ void codegen_setreal(Item* item, double val)
 {
     item->mode  = ITEM_CONST;
     item->type  = &RealType;
-    item->reg   = IMM;
+    item->reg   = NOREG;
     item->imm.f = val;
 }
 
@@ -42,7 +48,7 @@ void codegen_setstr(Item* item, char* val)
 {
     item->mode  = ITEM_CONST;
     item->type  = &StringType;
-    item->reg   = IMM;
+    item->reg   = NOREG;
     item->imm.s = val;
 }
 
@@ -152,8 +158,9 @@ static void const_binop(int op, Item* a, Item* b)
     }
 }
 
-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)
@@ -186,6 +193,88 @@ static void const_unop(int op, Item* a)
     }
 }
 
+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)
@@ -238,20 +327,22 @@ void codegen_startproc(Parser* p, char* name, long long localsz)
     {
         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
     {
@@ -259,149 +350,62 @@ void codegen_unop(int op, Item* a)
     }
 }
 
-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)
-//{
-//}
-
-
index 9e4b750291e1f9d6c87a796bdef42c9b0466359f..bd64f266ded0978c2f03a7477e7943f606a6bfb6 100644 (file)
@@ -73,14 +73,20 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX  9.5.2017*)
 \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
@@ -118,24 +124,54 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX  9.5.2017*)
 \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
@@ -277,27 +313,62 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX  9.5.2017*)
   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
@@ -305,27 +376,68 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX  9.5.2017*)
   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
@@ -334,10 +446,20 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX  9.5.2017*)
   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
@@ -346,20 +468,32 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX  9.5.2017*)
     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
index 34382afc84fc3e01a775f5c6ca7493a326eacf14..a76adf4364889414ae05b5118f9de9c021283049 100644 (file)
@@ -164,7 +164,14 @@ static Symbol* symbol_get(Parser* p, int class, char* name)
  *****************************************************************************/
 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;
 }
@@ -279,6 +286,11 @@ RULE(qualident)
     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;
@@ -361,7 +373,7 @@ RULE(factor)
             consume(p);
             factor(p, item);
             check_bool(p, item);
-            codegen_unop(NOT, item);
+            codegen_unop(p, NOT, item);
             break;
 
         case IDENT:
@@ -386,12 +398,12 @@ RULE(term)
             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:
@@ -409,7 +421,7 @@ RULE(simple_expr)
         int op = consume(p); // OP
         term(p, item);
         check_num(p, item);
-        codegen_unop(op, item);
+        codegen_unop(p, op, item);
     }
     else
     {
@@ -430,7 +442,7 @@ RULE(simple_expr)
         {
             check_nums(p, item, &right);
         }
-        codegen_binop(op, item, &right);
+        codegen_binop(p, op, item, &right);
     }
 }
 
@@ -438,13 +450,14 @@ RULE(expression)
 {
     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);
     }
 }
 
@@ -464,6 +477,7 @@ RULE(var_decl)
             name = expect_text(p, IDENT);
             export = accept(p, '*');
             sym = symbol_new(p, name, SYM_VAR, export);
+            sym->global = 1;
             nsyms++;
 
             if (!accept(p, ','))
@@ -585,7 +599,7 @@ RULE(statement_seq)
 
                 expression(p, &right);
                 check_types(p, item, &right);
-                codegen_store(item, &right);
+                codegen_store(p, item, &right);
             }
             else
             {
@@ -677,7 +691,7 @@ RULE(module)
         statement_seq(p, item);
         expect(p, END);
     }
-    codegen_endproc();
+    codegen_endproc(p);
 
 //    char* ename = expect_text(p, IDENT);
 //    if (strcmp(sname, ename))
@@ -717,7 +731,8 @@ void compile(char* fname)
             .path  = fname,
             .fbeg  = fcontents,
             .fpos  = fcontents,
-        }
+        },
+        .curr_reg = 0
     };
     module(p, &(Item){0});
     codegen_main(p);
index 7699a0b6893e7588a5fd20a83a5dbaf02ea33d68..21b89db7914b19b09a17822cffdeaf98e222ad4b 100644 (file)
@@ -1,6 +1,6 @@
 module Module
 
-#import 
+#import
 #    A = Foo
 #    B = Bar
 
@@ -11,11 +11,14 @@ const
 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
index 50a2c52c16beb2b17bc36a2e32f8337d6b72862b..1f9c33192c482bc9cf54837e40123c49f43562cb 100644 (file)
@@ -1,3 +1,5 @@
+// Item M:0 R:0 
+// Item M:0 R:0 42
     .data
 Module_a:
     .zero 1
@@ -6,16 +8,33 @@ Module_a:
 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