#include #include "CASL.h" #include "syntax_tree.h" #include "y.tab.h" /* defined in CASL.c */ extern char *newLabel(); void label(char *); #define C0(c) C3(c, NULL, NULL, NULL) #define C1(c, op1) C3(c, op1, NULL, NULL) #define C2(c, op1, op2) C3(c, op1, op2 , NULL) extern void C3(char *, char *, char *, char *); extern char *d(int); extern void comment(char *); extern char *addStringLiteral(char *); void codeAsgn(Tree, Tree); void codeBinOp(char *, Tree, Tree); void codeBinOp2(char *, Tree, Tree); void codeRelOp(char *, Tree, Tree); void codeRelOp2(char *, Tree, Tree); void codeArrRef(Obj, Tree); void codeFuncCall(Obj, Tree); void codeVarRef(Obj); void codeExp(Tree t) { char *l1; switch (t->type) { case '=': codeAsgn(t->left, t->right); break; case '|': codeBinOp(OR, t->left, t->right); break; case '^': codeBinOp(XOR, t->left, t->right); break; case '&': codeBinOp(AND, t->left, t->right); break; case '~': codeExp(t->left); C1(POP, GR1); C2(XOR, GR1, "=#FFFF"); break; case EQEQ: codeRelOp(JZE, t->left, t->right); break; case EXEQ: codeRelOp(JNZ, t->left, t->right); break; case '<': codeRelOp(JMI, t->left, t->right); break; case LTEQ: codeRelOp2(JPL, t->left, t->right); break; case '>': codeRelOp(JPL, t->left, t->right); break; case GTEQ: codeRelOp2(JMI, t->left, t->right); break; case '+': codeBinOp(ADDA, t->left, t->right); break; case '-': codeBinOp(SUBA, t->left, t->right); break; case '*': codeBinOp2("MULT", t->left, t->right); break; case '/': codeBinOp2("DIV", t->left, t->right); break; case UMINUS: codeExp(t->left); C1(POP, GR2); C2(XOR, GR1, GR1); C2(SUBA, GR1, GR2); break; case ARR_REF: codeArrRef(t->left->obj, t->right); break; case FUNC_CALL: codeFuncCall(t->left->obj, t->right); break; case SYM: codeVarRef(t->obj); break; case NUM: C2(LAD, GR1, d(t->num)); comment("numeric literal"); break; case STR: C2(LAD, GR1, addStringLiteral(t->str)); comment(t->str); break; } C2(PUSH, d(0), GR1); } void codeAsgn(Tree dst, Tree src){ Obj ob = dst->left->obj; codeExp(src); switch (dst->type) { case SCALAR: C1(POP, GR1); switch (ob->type) { case objGVAR: C2(ST, GR1, ob->name); break; case objLVAR: C3(ST, GR1, d(ob->offset - ob->scope->size), GR7); } break; case ARRAY: codeExp(dst->right); C1(POP, GR6); C1(POP, GR1); switch (ob->type) { case objGVAR: C2(ADDL, GR6, ob->name); C3(ST, GR1, d(0), GR6); break; case objGARR: C3(ST, GR1, ob->name, GR6); break; case objLVAR: C3(ADDL, GR6, d(ob->offset - ob->scope->size), GR7); C3(ST, GR1, d(0), GR6); break; case objLARR: C2(ADDL, GR6, GR7); C3(ST, GR1, d(ob->offset - ob->scope->size), GR6); } } } void codeBinOp(char *code, Tree left, Tree right){ codeExp(right); codeExp(left); C1(POP, GR1); C1(POP, GR2); C2(code, GR1, GR2); } void codeBinOp2(char *label, Tree left, Tree right){ codeExp(right); codeExp(left); C1(POP, GR1); C1(POP, GR2); C1(CALL, label); } void codeRelOp(char *code, Tree left, Tree right){ char *l1 = newLabel(); codeExp(right); codeExp(left); C1(POP, GR1); C1(POP, GR2); C2(CPA, GR1, GR2); C2(LAD, GR1, "=#FFFF"); C1(code, l1); C2(XOR, GR1, GR1); label(l1); C1(DS, d(0)); } void codeRelOp2(char *code, Tree left, Tree right){ char *l1 = newLabel(); codeExp(right); codeExp(left); C1(POP, GR0); C1(POP, GR2); C2(XOR, GR1, GR1); C2(CPA, GR0, GR2); C1(code, l1); C2(LAD, GR1, "=#FFFF"); label(l1); C1(DS, d(0)); } void codeArrRef(Obj var, Tree right) { codeExp(right); C1(POP, GR1); switch (var->type) { case objGVAR: C2(LD, GR6, var->name); break; case objGARR: C2(LAD, GR6, var->name); break; case objLVAR: C3(LD, GR6, d(var->offset - var->scope->size), GR7); comment(var->name); break; case objLARR: C3(LAD, GR6, d(var->offset - var->scope->size), GR7); comment(var->name); } C2(ADDL, GR6, GR1); C3(LD, GR1, d(0), GR6); } void codeFuncCall(Obj func, Tree args) { int i, j; for(i=0; args!=NUL; args = args->right, i++) { codeExp(args->left); } for(j=i; j>0; j--) { C1(POP, GR1); C3(ST, GR1, d(j), GR7); } C2(LAD, GR1, d(i)); comment("number of arguments"); C1(CALL, func->name); } void codeVarRef(Obj var) { switch (var->type) { case objGVAR: C2(LD, GR1, var->name); break; case objGARR: C2(LAD, GR1, var->name); break; case objLVAR: C3(LD, GR1, d(var->offset - var->scope->size), GR7); comment(var->name); break; case objLARR: C3(LAD, GR1, d(var->offset - var->scope->size), GR7); comment(var->name); } }