#include #include "emit.h" #include "tree.h" #include "seman.h" #define CHAR_TYPE 0 #define INTEGER_TYPE 1 #define STRING_TYPE 2 #define LABELSTACKSIZE 100 extern tree Root; int offset = 0; int LabelNum = 0; int GlobalDataSize; char VarOffset[200]; char ExpValue[200]; OPERAND op1, op2, op3; int CurrentTemp=0; int MaxTemp=(-1); int StringNum; int LabelStack[LABELSTACKSIZE]; int LabelStackTop= 0; extern tree NullExp(); extern tree intTypeT; extern tree charTypeT; extern tree booleanTypeT; extern tree stringTypeT; extern tree LeftChild(); extern tree RightChild(); extern char *getname(); extern int traceGen; /* trace execution or not */ /* label stack management */ PushLabel(label) int label; { if (traceGen) printf("Entering PushLabel\n"); if (LabelStackTop >= LABELSTACKSIZE) { printf("label stack overflow\n"); exit(0); } LabelStack[LabelStackTop++] = label; if (traceGen) printf("Leaving PushLabel\n"); } int PopLabel() { if (traceGen) printf("Entering PopLabel\n"); if (LabelStackTop <= 0) { printf("label stack underflow\n"); exit(0); } LabelStackTop--; if (traceGen) printf("Leaving PopLabel\n"); return(LabelStack[LabelStackTop]); } int TopLabel() { if (traceGen) printf("Entering TopLabel\n"); if (traceGen) printf("Leaving TopLabel\n"); return(LabelStack[LabelStackTop-1]); } /* calculate array upper bound */ UpperBound(T) tree T; { if (traceGen) printf("Entering UpperBound\n"); if (NodeKind(RightChild(T)) == NUMNode) { if (traceGen) printf("Leaving UpperBound\n"); return(IntVal(RightChild(T))); } else { if (traceGen) printf("Leaving UpperBound\n"); return(GetAttr(IntVal(RightChild(T)), VALUE_ATTR)); } } /* calculate array lower bound */ LowerBound(T) tree T; { if (traceGen) printf("Entering LowerBound\n"); if (NodeKind(LeftChild(T)) == NUMNode) { if (traceGen) printf("Leaving LowerBound\n"); return(IntVal(LeftChild(T))); } else { if (traceGen) printf("Leaving LowerBound\n"); return(GetAttr(IntVal(LeftChild(T)), VALUE_ATTR)); } } /* address calculation */ TypeSize(T) tree T; { int i,j,k; tree p, p1; int size, kind, op; if (traceGen) printf("Entering TypeSize\n"); kind = NodeKind(T); op = NodeOp1(T); switch (kind) { case INTEGERTNode: return 4; break; case CHARTNode: return 1; break; case BOOLEANTNode: return 1; break; case EXPRNode: switch (op) { case SubrangeOp: return 4; break; case ArrayTypeOp: size = 1; p = LeftChild(T); while (p!= NullExp()) { size = size * (UpperBound(RightChild(p)) - LowerBound(RightChild(p)) +1); p = LeftChild(p); } return(size * TypeSize(RightChild(T))); break; case RecompOp: size = 0; p = T; while (p!=NullExp()) { int temp; temp = TypeSize(RightChild(RightChild(p))); if (temp >1) if (size %4 != 0) size = size /4 *4 + 4; size = size + temp; p = LeftChild(p); } return(size); break; default: printf("DEBUG -- wrong NodeOp %d in TypeSize()\n", op); exit(0); } break; default: printf("DEBUG -- wrong NodeKind %d in TypeSize()\n", kind); exit(0); } if (traceGen) printf("Leaving TypeSize\n"); } /* type offset used for record type; use in doubt */ TypeOffset(T) tree T; { tree p,p1; int offset; if (traceGen) printf("Entering TypeOffset\n"); if (NodeKind(T) != EXPRNode) return(0); else if (NodeOp1(T) == ArrayTypeOp) TypeOffset(RightChild(T)); else if (NodeOp1(T) == RecompOp) { p = T; offset = 0; while (p != NullExp()) { int temp; temp = TypeSize(RightChild(RightChild(p))); if (temp > 1) if (offset % 4 != 0) offset = offset /4*4+4; if (!IsAttr(IntVal(LeftChild(RightChild(p))), OFFSET_ATTR)) SetAttr(IntVal(LeftChild(RightChild(p))), OFFSET_ATTR, offset); TypeOffset(RightChild(RightChild(p))); offset += temp; p = LeftChild(p); } } if (traceGen) printf("Leaving TypeOffset\n"); } /* argument and local variable offset */ ArgVarOffset(T) tree T; /* T pointing to proceop or funcop */ { tree specs, body; tree p,p1; int offset; int lastsize; if (traceGen) printf("Entering ArgVarOffset\n"); /* calculate argument offset */ specs = RightChild(LeftChild(T)); p = LeftChild(specs); offset = 4; while (p !=NullExp()) { int temp; if (NodeOp1(p) == VArgTypeOp) { temp = TypeSize(GetAttr(IntVal(LeftChild(LeftChild(p))), TYPE_ATTR)); if (temp < 4) temp = 4; } else temp = 4; if ((offset % 4) != 0) offset = (offset / 4) * 4 +4; if (NodeOp1(p) == VArgTypeOp) SetAttr(IntVal(LeftChild(LeftChild(p))), PLACE_ATTR, VARGUE); else SetAttr(IntVal(LeftChild(LeftChild(p))), PLACE_ATTR, RARGUE); SetAttr(IntVal(LeftChild(LeftChild(p))), OFFSET_ATTR, offset); TypeOffset(GetAttr(IntVal(LeftChild(LeftChild(p))), TYPE_ATTR)); offset += temp; p = RightChild(p); } if (offset % 4 == 0) offset = offset - 4; SetAttr(IntVal(LeftChild(LeftChild(T))), VALUE_ATTR, offset / 4); offset = 0; /* offset equal to local */ if (RightChild(T) == NullExp()) return(0); body = LeftChild(RightChild(T)); while (body != NullExp()) { p = RightChild(body); if (NodeOp1(p) == DeclOp) { while (p!=NullExp()) { int temp; temp = TypeSize(GetAttr(IntVal(LeftChild(RightChild(p))), TYPE_ATTR)); if (temp > 1) if ((offset % 4) != 0) offset = (offset /4) *4 +4; offset += temp; SetAttr(IntVal(LeftChild(RightChild(p))), PLACE_ATTR, LOCAL); SetAttr(IntVal(LeftChild(RightChild(p))), OFFSET_ATTR, -offset); TypeOffset(GetAttr(IntVal(LeftChild(RightChild(p))), TYPE_ATTR)); p = LeftChild(p); } } body = LeftChild(body); } SetAttr(IntVal(LeftChild(LeftChild(T))), OFFSET_ATTR, offset); if (traceGen) printf("Leaving ArgVarOffset\n"); } /* calculate variable offset */ DataOffset() { int offset; tree p,p1; if (traceGen) printf("Entering DataOffset\n"); offset = 0; p = LeftChild(Root); while (p != NullExp()) { p1 = RightChild(p); if (NodeOp1(p1) == DeclOp) { while (p1!=NullExp()) { int temp; temp = TypeSize(GetAttr(IntVal(LeftChild(RightChild(p1))), TYPE_ATTR)); if (temp > 1) if ((offset % 4) != 0) offset = (offset / 4) *4 +4; SetAttr(IntVal(LeftChild(RightChild(p1))), OFFSET_ATTR, offset); SetAttr(IntVal(LeftChild(RightChild(p1))), PLACE_ATTR, GLOBAL); TypeOffset(GetAttr(IntVal(LeftChild(RightChild(p1))), TYPE_ATTR)); offset += temp; p1 = LeftChild(p1); } } else if ((NodeOp1(p1) == ProceOp) || (NodeOp1(p1) == FuncOp)) ArgVarOffset(p1); p = LeftChild(p); } GlobalDataSize = offset; if (traceGen) printf("Leaving DataOffset\n"); } /* code generation */ tree GetVarType(T) tree T; /* pointing to formal parameter */ { tree p; tree pp1,pp2,pp3, pp4,pp5; if (traceGen) printf("Entering GetVarType\n"); if (NodeKind(T) == EXPRNode) { if (NodeOp1(T) == VarOp) { p = LeftChild(T); if (!IsAttr(IntVal(p), TYPE_ATTR)) { printf("funny\n");return(false);} pp1 = RightChild(T); pp3 = (tree)GetAttr(IntVal(p), TYPE_ATTR); while ( pp1 != NullExp()) { if (NodeKind(pp3) != EXPRNode) { printf("DEBUG!!!!!\n"); exit(0); } if (NodeOp1(pp3) == ArrayTypeOp) pp2 = RightChild(pp3); else if ((NodeOp1(pp3) == RecompOp) && (NodeOp1(LeftChild(pp1)) == FieldOp)) { int ii; ii=1; pp4 = pp3; while ((pp4 != NullExp()) && ii) { pp5 = LeftChild(RightChild(pp4)); if (strcmp(getname(GetAttr(IntVal(pp5), NAME_ATTR)), getname(GetAttr(IntVal(LeftChild(LeftChild (pp1))), NAME_ATTR))) == 0) { ii=0; pp2 = RightChild(RightChild(pp4)); } pp4 = LeftChild(pp4); } if (ii) { printf("DEBUG!!!!!\n"); exit(0); } } else {printf("DEBUG!!!!!!\n"); exit(0);} pp3 = pp2; pp1 = RightChild(pp1); } return(pp3); } } printf("DEBUG--not suppose to reach here\n"); exit(0); if (traceGen) printf("Leaving GetVarType\n"); } /* find out type for the parameter */ int GetType(T) tree T; { tree p; tree p1; if (traceGen) printf("Entering GetType\n"); if (T == NullExp()) return(INTEGER_TYPE); if (T == intTypeT) return(INTEGER_TYPE); if (T == charTypeT) return(CHAR_TYPE); if (NodeKind(T) == CHARNode) return(CHAR_TYPE); if (NodeKind(T) == NUMNode) return(INTEGER_TYPE); if (NodeKind(T) == STRINGNode) return(STRING_TYPE); if (NodeKind(T) == STNode) { if (strcmp(getname(GetAttr(IntVal(T), NAME_ATTR)), "CHAR") == 0) return(CHAR_TYPE); else if (strcmp(getname(GetAttr(IntVal(T), NAME_ATTR)), "INTEGER") == 0) return(INTEGER_TYPE); else { printf("DEBUG--not any more \n"); return(INTEGER_TYPE); } } if (NodeKind(T) != EXPRNode) { printf("DEBUG;;;;;;;;;;;\n"); printtree(T, 0); exit(0); } if (NodeOp1(T) == RoutineCallOp) { p = (tree) GetAttr(IntVal(LeftChild(T)), TYPE_ATTR); return(GetType(RightChild(RightChild(LeftChild(p))))); } if (NodeOp1(T) != VarOp) return(INTEGER_TYPE); p = (tree)GetAttr(IntVal(LeftChild(T)), TYPE_ATTR); if (RightChild(T) == NullExp()) { if (p == charTypeT) return(CHAR_TYPE); else if (p== intTypeT) return(INTEGER_TYPE); else if (NodeOp1(p) == SubrangeOp) return(INTEGER_TYPE); else return(STRING_TYPE); /* maybe changed here */ } else { p1 = RightChild(T); while (p1 != NullExp()) { if (NodeOp1(LeftChild(p1)) == IndexOp) p = RightChild(p); else if (NodeOp1(LeftChild(p1)) == FieldOp) p = (tree)GetAttr(IntVal(LeftChild(LeftChild(p1))), TYPE_ATTR); p1 = RightChild(p1); } if (p == charTypeT) { if (traceGen) printf("Leaving GetType\n"); return(CHAR_TYPE); } else if (p == intTypeT) { if (traceGen) printf("Leaving GetType\n"); return(INTEGER_TYPE); } else { if (traceGen) printf("Leaving GetType\n"); return(STRING_TYPE); } } } GenBlockAssign(dest, source, size) char *dest, *source; int size; { char temp[20], temp1[20], temp2[20]; if (traceGen) printf("Entering GenBlockAssign\n"); op1.mode = NUM_CONST; op1.num_const = 0; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp, "T%d", CurrentTemp+2); op2.ident = temp; } CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, 'l', 1); } emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum++); if (*dest == 'R') sprintf(temp1, "(%s)", dest); else sprintf(temp1, "@%s", dest); if (*source == 'R') sprintf(temp2, "(%s)", source); else sprintf(temp2, "@%s", source); op1.mode = IDENTIFIER; op1.ident = temp2; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'b', 2, op1, op2, op3); op1.mode = NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = dest; emit_most(ADD, 'l', 2, op1, op2, op3); op1.mode = NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = source; emit_most(ADD, 'l', 2, op1, op2, op3); op1.mode = NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp; emit_most(ADD, 'l', 2, op1, op2, op3); op1.mode = IDENTIFIER; op1.ident = temp; op2.mode = NUM_CONST; op2.num_const = size; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BGEQ, LabelNum++); emit_goto(JMP, LabelNum -2); emit_label(LabelNum-1); CurrentTemp--; if (traceGen) printf("Leaving GenBlockAssign\n"); } GenBlockPush(source, size) char *source; int size; { char temp[20], temp1[20], temp2[20]; if (traceGen) printf("Entering GenBlockPush\n"); op1.mode = NUM_CONST; op1.num_const = 0; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp, "T%d", CurrentTemp+2); op2.ident = temp; } CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, 'l', 1); } emit_most(MOV, 'l', 2, op1, op2, op3); op1.mode = NUM_CONST; op1.num_const = size*4-1; op2.mode = IDENTIFIER; op2.ident = source; op3.mode = IDENTIFIER; op3.ident = source; emit_most(ADD, 'l', 3, op1, op2, op3); if (*source == 'R') sprintf(temp1, "\tMOVB\t(%s),\t-(SP)", source); else sprintf(temp1, "@%s", source); op1.mode = IDENTIFIER; op1.ident = temp1; emit_label(LabelNum++); emit_idiot(temp1); op1.mode = NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = source; emit_most(SUB, 'l', 2, op1, op2, op3); op1.mode = NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp; emit_most(ADD, 'l', 2, op1, op2, op3); op1.mode = IDENTIFIER; op1.ident = temp; op2.mode = NUM_CONST; op2.num_const = size*4; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BGEQ, LabelNum++); emit_goto(JMP, LabelNum -2); emit_label(LabelNum-1); CurrentTemp--; if (traceGen) printf("Leaving GenBlockPush\n"); } int GenPushArg(T, type) tree T, type; { tree p, p1; int i; int return_value; int size; char temp[20], temp1[20]; if (traceGen) printf("Entering GenPushArg\n"); if (T==NullExp()) { if (traceGen) printf("Leaving GenPushArg\n"); return(0); } return_value = GenPushArg(RightChild(T), RightChild(type)); if (NodeOp1(type) == RArgTypeOp) { GenVarAddr(LeftChild(T)); op1.mode = IDENTIFIER; op1.ident = VarOffset; if ((VarOffset[0] =='T') || (VarOffset[0] == 'R')){ emit_most(PUSH, 'l', 1, op1, op2, op3); CurrentTemp--; } else emit_most(PUSHA, 'l', 1, op1, op2, op3); } else { /* var type */ p1 = (tree) GetAttr(IntVal(LeftChild(LeftChild(type))), TYPE_ATTR); i = GetType(LeftChild(T)); if ((i==INTEGER_TYPE) || (i==CHAR_TYPE)){ GenValueExp(LeftChild(T)); op1.mode = IDENTIFIER; op1.ident = ExpValue; emit_most(PUSH, 'l', 1, op1, op2, op3); if ((ExpValue[0]=='R') || (ExpValue[0]=='T') || (ExpValue[0]=='(') || (ExpValue[0]=='@')) CurrentTemp--; } else { if ((NodeKind(LeftChild(T)) != STRINGNode) && ((NodeKind(LeftChild(T)) != EXPRNode) || (NodeOp1(LeftChild(T)) != VarOp))){ printf("SEMANTIC ERROR, TYPE incompatibal\n"); exit(0); } GenVarAddr(LeftChild(T)); if ((VarOffset[0] != 'R') && (VarOffset[0] != 'T')) { op1.mode = IDENTIFIER; op1.ident = VarOffset; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, 'l', 1); } emit_most(MOVA, 'l', 2, op1, op2, op3); } else strcpy(temp1, VarOffset); size = TypeSize(p1); if (size % 4 != 0) size = size /4 * 4 + 4; GenBlockPush(temp1, size / 4); if ((temp1[0] == 'R') || (temp1[0] == 'T')) CurrentTemp--; } } if (traceGen) printf("Leaving GenPushArg\n"); return(return_value+1); } GenSingleStmt(T) tree T; { char name[50]; tree p, p1; tree type, arg; char temp[20], temp1[20]; int i,j,k; int size; if (traceGen) printf("Entering GenSingleStmt\n"); if (T == NullExp()) return(0); switch(NodeOp1(T)) { case IfElseOp : GenIfStmt(T); break; case ExitOp : emit_call("EXIT", 0); break; case ReturnOp : if (LeftChild(T) == NullExp()) emit_idiot("\tRET"); else { GenValueExp(LeftChild(T)); op1.mode = IDENTIFIER; op1.ident = ExpValue; op2.mode = REGISTER; op2.reg = 0; if ((ExpValue[0] =='R') || (ExpValue[0] == 'T') || (ExpValue[0] =='(') || (ExpValue[0] == '@')) CurrentTemp--; emit_most(MOV, 'l', 2, op1, op2, op3); emit_idiot("\tRET"); } break; case LoopOp : GenLoopStmt(T); break; case AssignOp : if ((GetType(RightChild(LeftChild(T))) == CHAR_TYPE) || (GetType(RightChild(LeftChild(T))) == INTEGER_TYPE)) { p = LeftChild(T); GenValueExp(RightChild(T)); strcpy(temp, ExpValue); while (p!= NullExp()) { GenVarAddr(RightChild(p)); if (VarOffset[0]=='R'){ sprintf(temp1, "(%s)", VarOffset); CurrentTemp--; } else if (VarOffset[0] == 'T'){ sprintf(temp1, "@%s", VarOffset); CurrentTemp--; } else strcpy(temp1, VarOffset); op1.mode = IDENTIFIER; op1.ident = temp; op2.mode = IDENTIFIER; op2.ident = temp1; if (GetType(RightChild(p)) == CHAR_TYPE) emit_most(MOV, 'b', 2, op1, op2, op3); else if (GetType(RightChild(p)) == INTEGER_TYPE) emit_most(MOV, 'l', 2, op1, op2, op3); else {printf("Type incompatible\n"), exit(0);} p = LeftChild(p); } if ((temp[0]=='R') || (temp[0] == 'T') || (temp[0]=='(') || (temp[0]=='@')) CurrentTemp--; } else { char blocktemp1[20], blcoktemp2[20]; char blocktemp[20]; char source[20], dest[20]; char dest1[20], source1[20]; /* caution mark, check again */ p = LeftChild(T); GenVarAddr(RightChild(T)); strcpy(source, VarOffset); strcpy(source1, VarOffset); if ((source[0] != 'R') && (source[0] != 'T')) { op1.mode = IDENTIFIER; op1.ident = VarOffset; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(blocktemp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(blocktemp1, "T%d", CurrentTemp+2); op2.ident = blocktemp1; } CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(blocktemp, "T%d", MaxTemp+1); emit_data(blocktemp, 'l', 1); } emit_most(MOVA, 'l', 2, op1, op2, op3); strcpy(source, blocktemp1); } while (p != NullExp()) { GenVarAddr(RightChild(p)); strcpy(dest, VarOffset); if ((dest[0] != 'R') && (dest[0] != 'T')) { op1.mode = IDENTIFIER; op1.ident = VarOffset; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(blocktemp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(blocktemp1, "T%d", CurrentTemp+2); op2.ident = blocktemp1; } CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(blocktemp, "T%d", MaxTemp+1); emit_data(blocktemp, 'l', 1); } emit_most(MOVA, 'l', 2, op1, op2, op3); strcpy(dest, blocktemp1); } size = TypeSize(GetVarType(RightChild(p))); GenBlockAssign(dest, source, size); if ((dest[0] == 'R') || (dest[0] == 'T')) CurrentTemp--; p = LeftChild(p); } if ((source[0] =='R') || (source[0] == 'T')) CurrentTemp--; } break; case RoutineCallOp : if (GetAttr(IntVal(LeftChild(T)), PREDE_ATTR) == true) { strcpy(name, getname(GetAttr(IntVal(LeftChild(T)), NAME_ATTR))); /* deal with it right now, got to expand */ if (strcmp("READ", name) == 0) { p = RightChild(T); p1 = LeftChild(p); while (p!=NullExp()) { p1 = LeftChild(p); if (NodeOp1(p1) != VarOp) { printf("wrong read format \n"); exit(0); } GenVarAddr(p1); op1.mode = IDENTIFIER; op1.ident = VarOffset; if ((VarOffset[0] == 'R') || (VarOffset[0] == 'T')) { emit_most(PUSH, 'l', 1, op1, op2, op3); CurrentTemp--; } else emit_most(PUSHA, 'l', 1, op1,op2,op3); switch (GetType(p1)) { case CHAR_TYPE : emit_call("readchar", 1); break; case INTEGER_TYPE : emit_call("readnum", 1); break; case STRING_TYPE : emit_call("readstr", 1); break; } p = RightChild(p); } } else if (strcmp("WRITE", name) == 0) { p = RightChild(T); while (p!=NullExp()) { p1 = LeftChild(p); if ((GetType(p1) != STRING_TYPE) || (NodeKind(p1) != EXPRNode) || (NodeOp1(p1) != VarOp)) { GenValueExp(p1); op1.mode = IDENTIFIER; op1.ident = ExpValue; if ( (ExpValue[0]=='R') || (ExpValue[0]=='T') || (ExpValue[0] == '@') || (ExpValue[0] == '(')) CurrentTemp--; } switch (GetType(p1)) { case CHAR_TYPE : emit_most(PUSH, 'l', 1, op1,op2,op3); emit_call("printchar", 1); break; case INTEGER_TYPE : emit_most(PUSH, 'l', 1, op1,op2,op3); emit_call("printnum", 1); break; case STRING_TYPE : if ((NodeKind(p1) == EXPRNode) && (NodeOp1(p1) == VarOp)){ GenVarAddr(p1); op1.mode = IDENTIFIER; op1.ident = VarOffset; if ((VarOffset[0] == 'T') || (VarOffset[0] == 'R')) { CurrentTemp--; emit_most(PUSH, 'l', 1, op1, op2, op3); } else emit_most(PUSHA, 'l', 1, op1, op2, op3); } else emit_most(PUSHA, 'l', 1, op1, op2, op3); emit_call("printstr", 1); break; default : printf("Not here, type\n"); exit(0); } p = RightChild(p); } } else if (strcmp("CHR", name) == 0) { int tempnum; char aa[50]; tempnum = CurrentTemp; for (i= tempnum-1; i>=0; i--) { if(i > 9) sprintf(aa, "\tPUSHL T%d", i+2); else sprintf(aa, "\tPUSHL R%d", i+2); emit_idiot(aa); } GenValueExp(LeftChild(RightChild(T))); op1.mode = IDENTIFIER; op1.ident = ExpValue; emit_most(PUSH, 'l', 1, op1, op2, op3); emit_call("CHR", 1); for (i=0; i9) sprintf(aa, "\tMOVL (SP)+, T%d", i+2); else sprintf(aa, "\tMOVL (SP)+, R%d", i+2); emit_idiot(aa); } if ( (ExpValue[0]=='R') || (ExpValue[0]=='T') || (ExpValue[0] == '@') || (ExpValue[0] == '(')) CurrentTemp--; }else if (strcmp("ORD", name) == 0) { int tempnum; char aa[50]; tempnum = CurrentTemp; for (i= tempnum-1; i>=0; i--) { if(i > 9) sprintf(aa, "\tPUSHL T%d", i+2); else sprintf(aa, "\tPUSHL R%d", i+2); emit_idiot(aa); } GenValueExp(LeftChild(RightChild(T))); op1.mode = IDENTIFIER; op1.ident = ExpValue; emit_most(PUSH, 'l', 1, op1, op2, op3); emit_call("ORD", 1); for (i=0; i9) sprintf(aa, "\tMOVL (SP)+, T%d", i+2); else sprintf(aa, "\tMOVL (SP)+, R%d", i+2); emit_idiot(aa); } if ( (ExpValue[0]=='R') || (ExpValue[0]=='T') || (ExpValue[0] == '@') || (ExpValue[0] == '(')) CurrentTemp--; }else if (strcmp("EOF", name) == 0) { int tempnum; char aa[50]; tempnum = CurrentTemp; for (i= tempnum-1; i>=0; i--) { if(i > 9) sprintf(aa, "\tPUSHL T%d", i+2); else sprintf(aa, "\tPUSHL R%d", i+2); emit_idiot(aa); } emit_call("EOF", 0); for (i=0; i9) sprintf(aa, "\tMOVL (SP)+, T%d", i+2); else sprintf(aa, "\tMOVL (SP)+, R%d", i+2); emit_idiot(aa); } } else {printf("DEBUG--not predefined\n"); exit(0); } } else { /* function call */ int count; type = (tree) GetAttr(IntVal(LeftChild(T)), TYPE_ATTR); if (RightChild(LeftChild(type)) == NullExp()) { emit_call(getname(GetAttr(IntVal(LeftChild (LeftChild(type))), NAME_ATTR)), 0); } else { arg = LeftChild(RightChild(LeftChild(type))); p = RightChild(T); if (arg == NullExp()) emit_call(getname(GetAttr(IntVal(LeftChild (LeftChild(type))), NAME_ATTR)), 0); else { /* pushing parameter */ count = GenPushArg(p, arg); emit_call(getname(GetAttr(IntVal(LeftChild(T)), NAME_ATTR)), GetAttr(IntVal(LeftChild(T)), VALUE_ATTR)); } } } break; default : printf("DEBUG--do't want to come to here\n"); exit(0); } } GenStmts(T) tree T; { if (traceGen) printf("Entering GenStmts\n"); if (T==NullExp()) return; GenStmts(LeftChild(T)); GenSingleStmt(RightChild(T)); if (traceGen) printf("Leaving GenSingleStmt\n"); } GenFun(T) tree T; { tree p, p1; char temp[80]; if (traceGen) printf("Entering GenFun\n"); if (RightChild(T) == NullExp()) return(0); p = LeftChild(LeftChild(T)); sprintf(temp, "\t.ENTRY %s, 0", getname(GetAttr(IntVal(p), NAME_ATTR))); emit_idiot(temp); op1.mode= NUM_CONST; op1.num_const = GetAttr(IntVal(p), OFFSET_ATTR); op2.mode = REGISTER; op2.reg = SP; emit_most(SUB, 'l', 2, op1, op2, op3); GenStmts(RightChild(RightChild(T))); emit_idiot("\tRET"); if (traceGen) printf("Leaving GenFun\n"); } GenAll() /* generate codes */ { tree p, p1; if (traceGen) printf("Entering GenAll\n"); emit_data("DATA", 'b', GlobalDataSize); p = LeftChild(Root); while(p != NullExp()) { if ((NodeOp1(RightChild(p)) == ProceOp) || (NodeOp1(RightChild(p)) == FuncOp)) GenFun(RightChild(p)); p = LeftChild(p); } /* gen code for main */ emit_entry("Main"); GenStmts(RightChild(Root)); emit_idiot("\tRET"); emit_idiot("\t.END MAIN"); if (traceGen) printf("Leaving GenAll\n"); } int GetConstValue(s) char *s; { int temp; char *p; if (traceGen) printf("Entering GetConstValue\n"); if ((s[1]>='0') && (s[1]<='9')){ p=s+1; temp = 0; while ((*p >='0') && (*p <= '9')) { temp = temp*10+(*p)-'0'; p++; } } else temp = (int)s[5]; if (traceGen) printf("Leaving GetConstValue\n"); return(temp); } GenValueExp(T) tree T; { char temp1[20]; char temp2[20]; char temp3[20]; char temp[20]; char ch; if (traceGen) printf("Entering GenValueExp\n"); ExpValue[0] = '\0'; if (NodeKind(T) == NUMNode) { sprintf(temp2, "#%d", IntVal(T)); strcpy(ExpValue, temp2); return(0); } else if (NodeKind(T) == CHARNode) { if (isprint(IntVal(T))) sprintf(temp2, "#^A/%c/", IntVal(T)); else sprintf(temp2, "#%d", IntVal(T)); strcpy(ExpValue, temp2); return(0); } else if (NodeKind(T) == STRINGNode) { sprintf(temp1, "s%d", StringNum++); emit_str(temp1, getname(IntVal(T))); sprintf(temp2, "%s", temp1); strcpy(ExpValue, temp2); return(0); } else if (NodeOp1(T) == VarOp) { int i; i = IntVal(LeftChild(T)); if (GetAttr(i, KIND_ATTR) == CONSTANT) { if ((tree)GetAttr(i, TYPE_ATTR) == intTypeT){ sprintf(ExpValue, "#%d", GetAttr(i, VALUE_ATTR)); return(0); } else if ((tree)GetAttr(i, TYPE_ATTR) == charTypeT) { if (isprint(GetAttr(i, VALUE_ATTR))) sprintf(ExpValue, "#^A/%c/", GetAttr(i, VALUE_ATTR)); else sprintf(ExpValue, "#%d", GetAttr(i, VALUE_ATTR)); return(0); } else { if (!IsAttr(i, OFFSET_ATTR)) { emit_str(getname(GetAttr(i, NAME_ATTR)), getname(GetAttr(i, VALUE_ATTR))); SetAttr(i, OFFSET_ATTR, 0); } sprintf(ExpValue, "%s", getname(GetAttr(i, NAME_ATTR))); return(0); } } GenVarAddr(T); if ((VarOffset[0]=='R')) sprintf(ExpValue, "(%s)", VarOffset); else if ((VarOffset[0] == 'T')) sprintf(ExpValue, "@T%d", VarOffset); else strcpy(ExpValue, VarOffset); return(0); } else if (NodeOp1(T) == RoutineCallOp) { int count; tree type, arg, p; int tempnum; int i; char aa[80]; /* save temp first */ tempnum = CurrentTemp; for (i= tempnum-1; i>=0; i--) { if(i > 9) sprintf(aa, "\tPUSHL T%d", i+2); else sprintf(aa, "\tPUSHL R%d", i+2); emit_idiot(aa); } type = (tree) GetAttr(IntVal(LeftChild(T)), TYPE_ATTR); if (RightChild(LeftChild(type)) == NullExp()) { emit_call(getname(GetAttr(IntVal(LeftChild (LeftChild(type))), NAME_ATTR)), GetAttr(IntVal(LeftChild(T)), VALUE_ATTR)); for (i=0; i9) sprintf(aa, "\tMOVL (SP)+, T%d", i+2); else sprintf(aa, "\tMOVL (SP)+, R%d", i+2); emit_idiot(aa); } } else { arg = LeftChild(RightChild(LeftChild(type))); p = RightChild(T); if (arg == NullExp()) emit_call(getname(GetAttr(IntVal(LeftChild (LeftChild(type))), NAME_ATTR)), GetAttr(IntVal(LeftChild(T)), VALUE_ATTR)); else { /* push parameters */ count = GenPushArg(p, arg); emit_call(getname(GetAttr(IntVal(LeftChild(T)), NAME_ATTR)), GetAttr(IntVal(LeftChild(T)), VALUE_ATTR)); } for (i=0; i9) sprintf(aa, "\tMOVL (SP)+, T%d", i+2); else sprintf(aa, "\tMOVL (SP)+, R%d", i+2); emit_idiot(aa); } op1.mode = REGISTER; op1.reg = R0; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, 'l', 2, op1, op2, op3); CurrentTemp++; strcpy(ExpValue, temp1); return(0); } } else { /* all operation */ if ((GetType(LeftChild(T)) == CHAR_TYPE) && (GetType(RightChild(T)) == CHAR_TYPE)) ch = 'b'; else ch = 'l'; if (NodeOp1(T) == AddOp) { GenValueExp(LeftChild(T)); strcpy(temp1, ExpValue); if ((temp1[0]!='#') && (temp1[0]!='R') && (temp1[0]!='T')){ if ((temp1[0]=='(') || (temp1[0]=='@')) CurrentTemp--; strcpy(temp, temp1); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", CurrentTemp+1); emit_data(temp, 'l', 1); } } GenValueExp(RightChild(T)); strcpy(temp2, ExpValue); if ((temp1[0] == '#') && (temp2[0] == '#')) { /* constant unfolded */ sprintf(ExpValue, "#%d", GetConstValue(temp1)+ GetConstValue(temp2)); return(0); } else if (temp1[0]!= '#') { op1.mode = IDENTIFIER; op1.ident = temp2; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(ADD, 'l', 2, op1, op2, op3); if ((temp2[0]=='R') || (temp2[0]=='T') || (temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp--; strcpy(ExpValue, temp1); return(0); } else if (temp2[1]!= '#') { if ((temp2[0]!='R') && (temp2[0]!='T')) { if ((temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp--; strcpy(temp, temp2); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp2, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp2, "T%d", CurrentTemp+2); op2.ident = temp2; } emit_most(MOV, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", CurrentTemp+1); emit_data(temp, 'l', 1); } } op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = IDENTIFIER; op2.ident = temp2; op3.mode = IDENTIFIER; op3.ident = temp2; emit_most(ADD, 'l', 3, op1, op2, op3); strcpy(ExpValue, temp2); return(0); } } else if (NodeOp1(T) == SubOp) { GenValueExp(LeftChild(T)); strcpy(temp1, ExpValue); if ((temp1[0]!='#') && (temp1[0]!='R') && (temp1[0]!='T')){ if ((temp1[0]=='(') || (temp1[0]=='@')) CurrentTemp--; strcpy(temp, temp1); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", CurrentTemp+1); emit_data(temp, 'l', 1); } } GenValueExp(RightChild(T)); strcpy(temp2, ExpValue); if ((temp1[0] == '#') && (temp2[0] == '#')) { /* constant unfolded */ sprintf(ExpValue, "#%d", GetConstValue(temp1)- GetConstValue(temp2)); return(0); } else if (temp1[0]!= '#') { op1.mode = IDENTIFIER; op1.ident = temp2; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(SUB, 'l', 2, op1, op2, op3); if ((temp2[0]=='R') || (temp2[0]=='T') || (temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp--; strcpy(ExpValue, temp1); return(0); } else if (temp2[1]!= '#') { if ((temp2[0]!='R') && (temp2[0]!='T')) { if ((temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp--; strcpy(temp, temp2); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp2, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp2, "T%d", CurrentTemp+2); op2.ident = temp2; } emit_most(MOV, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", CurrentTemp+1); emit_data(temp, 'l', 1); } } op1.mode = IDENTIFIER; op1.ident = temp2; op2.mode = IDENTIFIER; op2.ident = temp1; op3.mode = IDENTIFIER; op3.ident = temp2; emit_most(SUB, 'l', 3, op1, op2, op3); strcpy(ExpValue, temp2); return(0); } }else if (NodeOp1(T) == MultOp) { GenValueExp(LeftChild(T)); strcpy(temp1, ExpValue); if ((temp1[0]!='#') && (temp1[0]!='R') && (temp1[0]!='T')){ if ((temp1[0]=='(') || (temp1[0]=='@')) CurrentTemp--; strcpy(temp, temp1); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", CurrentTemp+1); emit_data(temp, 'l', 1); } } GenValueExp(RightChild(T)); strcpy(temp2, ExpValue); if ((temp1[0] == '#') && (temp2[0] == '#')) { /* constant unfolded */ sprintf(ExpValue, "#%d", GetConstValue(temp1)* GetConstValue(temp2)); return(0); } else if (temp1[0]!= '#') { op1.mode = IDENTIFIER; op1.ident = temp2; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MUL, 'l', 2, op1, op2, op3); if ((temp2[0]=='R') || (temp2[0]=='T') || (temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp--; strcpy(ExpValue, temp1); return(0); } else if (temp2[1]!= '#') { if ((temp2[0]!='R') && (temp2[0]!='T')) { if ((temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp --; strcpy(temp, temp2); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp2, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp2, "T%d", CurrentTemp+2); op2.ident = temp2; } emit_most(MOV, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", CurrentTemp+1); emit_data(temp, 'l', 1); } } op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = IDENTIFIER; op2.ident = temp2; op3.mode = IDENTIFIER; op3.ident = temp2; emit_most(MUL, 'l', 3, op1, op2, op3); strcpy(ExpValue, temp2); return(0); } }else if (NodeOp1(T) == DivOp) { GenValueExp(LeftChild(T)); strcpy(temp1, ExpValue); if ((temp1[0]!='#') && (temp1[0]!='R') && (temp1[0]!='T')){ if ((temp1[0]=='(') || (temp1[0]=='@')) CurrentTemp--; strcpy(temp, temp1); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, 'l', 1); } } GenValueExp(RightChild(T)); strcpy(temp2, ExpValue); if ((temp1[0] == '#') && (temp2[0] == '#')) { /* constant unfolded */ if (GetConstValue(temp2) == 0) { printf("Divided by zero\n"); exit(0); } sprintf(ExpValue, "#%d", GetConstValue(temp1)/ GetConstValue(temp2)); return(0); } else if (temp1[0]!= '#') { op1.mode = IDENTIFIER; op1.ident = temp2; op2.mode = NUM_CONST; op2.num_const = 0; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BNEQ, LabelNum++); emit_call("ZERO_DIV", 0); emit_label(LabelNum-1); op1.mode = IDENTIFIER; op1.ident = temp2; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(DIV, 'l', 2, op1, op2, op3); if ((temp2[0]=='R') || (temp2[0]=='T') || (temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp--; strcpy(ExpValue, temp1); return(0); } else if (temp2[1]!= '#') { if ((temp2[0]!='R') && (temp2[0]!='T')) { if ((temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp--; strcpy(temp, temp2); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp2, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp2, "T%d", CurrentTemp+2); op2.ident = temp2; } emit_most(MOV, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, 'l', 1); } } op1.mode = IDENTIFIER; op1.ident = temp2; op2.mode = IDENTIFIER; op2.ident = temp1; op3.mode = IDENTIFIER; op3.ident = temp2; emit_most(DIV, 'l', 3, op1, op2, op3); strcpy(ExpValue, temp2); return(0); } }else if (NodeOp1(T) == LTOp) { GenValueExp(LeftChild(T)); strcpy(temp1, ExpValue); if ((temp1[0]!='#') && (temp1[0]!='R') && (temp1[0]!='T')){ if ((temp1[0]=='(') || (temp1[0]=='@')) CurrentTemp--; strcpy(temp, temp1); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, ch, 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, ch , 1); } } GenValueExp(RightChild(T)); strcpy(temp2, ExpValue); if ((temp1[0] == '#') && (temp2[0] == '#')) { /* constant unfolded */ if (GetConstValue(temp1) < GetConstValue(temp2)) sprintf(ExpValue, "#1"); else sprintf(ExpValue, "#0"); return(0); } else if (temp1[0]!= '#') { op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(CMP, ch, 2, op1, op2, op3); emit_goto(BLSS, LabelNum++); op1.mode=NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode=NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); if ((temp2[0]=='R') || (temp2[0]=='T') || (temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp--; strcpy(ExpValue, temp1); return(0); } else if (temp2[1]!= '#') { if ((temp2[0]!='R') && (temp2[0]!='T')) { if ((temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp --; strcpy(temp, temp2); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp2, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp2, "T%d", CurrentTemp+2); op2.ident = temp2; } emit_most(MOV, ch, 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, ch, 1); } } op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(CMP, ch, 2, op1, op2, op3); emit_goto(BLSS, LabelNum++); op1.mode=NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode=NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); strcpy(ExpValue, temp2); return(0); } }else if (NodeOp1(T) == GTOp) { GenValueExp(LeftChild(T)); strcpy(temp1, ExpValue); if ((temp1[0]!='#') && (temp1[0]!='R') && (temp1[0]!='T')){ if ((temp1[0]=='(') || (temp1[0]=='@')) CurrentTemp--; strcpy(temp, temp1); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, ch, 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, ch, 1); } } GenValueExp(RightChild(T)); strcpy(temp2, ExpValue); if ((temp1[0] == '#') && (temp2[0] == '#')) { /* constant unfolded */ if (GetConstValue(temp1) > GetConstValue(temp2)) sprintf(ExpValue, "#1"); else sprintf(ExpValue, "#0"); return(0); } else if (temp1[0]!= '#') { op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(CMP, ch, 2, op1, op2, op3); emit_goto(BGTR, LabelNum++); op1.mode=NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode=NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); if ((temp2[0]=='R') || (temp2[0]=='T') || (temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp--; strcpy(ExpValue, temp1); return(0); } else if (temp2[1]!= '#') { if ((temp2[0]!='R') && (temp2[0]!='T')) { if ((temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp --; strcpy(temp, temp2); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp2, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp2, "T%d", CurrentTemp+2); op2.ident = temp2; } emit_most(MOV, ch, 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, ch, 1); } } op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(CMP, ch, 2, op1, op2, op3); emit_goto(BGTR, LabelNum++); op1.mode=NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode=NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); strcpy(ExpValue, temp2); return(0); } } else if (NodeOp1(T) == EQOp) { GenValueExp(LeftChild(T)); strcpy(temp1, ExpValue); if ((temp1[0]!='#') && (temp1[0]!='R') && (temp1[0]!='T')){ if ((temp1[0]=='(') || (temp1[0]=='@')) CurrentTemp--; strcpy(temp, temp1); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, ch, 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, ch, 1); } } GenValueExp(RightChild(T)); strcpy(temp2, ExpValue); if ((temp1[0] == '#') && (temp2[0] == '#')) { /* constant unfolded */ if (GetConstValue(temp1) == GetConstValue(temp2)) sprintf(ExpValue, "#1"); else sprintf(ExpValue, "#0"); return(0); } else if (temp1[0]!= '#') { op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(CMP, ch, 2, op1, op2, op3); emit_goto(BEQL, LabelNum++); op1.mode=NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode=NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); if ((temp2[0]=='R') || (temp2[0]=='T') || (temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp--; strcpy(ExpValue, temp1); return(0); } else if (temp2[1]!= '#') { if ((temp2[0]!='R') && (temp2[0]!='T')){ if ((temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp --; strcpy(temp, temp2); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp2, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp2, "T%d", CurrentTemp+2); op2.ident = temp2; } emit_most(MOV, ch, 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, ch, 1); } } op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(CMP, ch, 2, op1, op2, op3); emit_goto(BEQL, LabelNum++); op1.mode=NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode=NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); strcpy(ExpValue, temp2); return(0); } }else if (NodeOp1(T) == NEOp) { GenValueExp(LeftChild(T)); strcpy(temp1, ExpValue); if ((temp1[0]!='#') && (temp1[0]!='R') && (temp1[0]!='T')){ if ((temp1[0]=='(') || (temp1[0]=='@')) CurrentTemp--; strcpy(temp, temp1); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, ch, 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, ch, 1); } } GenValueExp(RightChild(T)); strcpy(temp2, ExpValue); if ((temp1[0] == '#') && (temp2[0] == '#')) { /* constant unfolded */ if (GetConstValue(temp1) != GetConstValue(temp2)) sprintf(ExpValue, "#1"); else sprintf(ExpValue, "#0"); return(0); } else if (temp1[0]!= '#') { op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(CMP, ch, 2, op1, op2, op3); emit_goto(BNEQ, LabelNum++); op1.mode=NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode=NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); if ((temp2[0]=='R') || (temp2[0]=='T') || (temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp--; strcpy(ExpValue, temp1); return(0); } else if (temp2[1]!= '#') { if ((temp2[0]!='R') && (temp2[0]!='T')){ if ((temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp --; strcpy(temp, temp2); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp2, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp2, "T%d", CurrentTemp+2); op2.ident = temp2; } emit_most(MOV, ch, 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, ch, 1); } } op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(CMP, ch, 2, op1, op2, op3); emit_goto(BNEQ, LabelNum++); op1.mode=NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode=NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); strcpy(ExpValue, temp2); return(0); } }else if (NodeOp1(T) == LEOp) { GenValueExp(LeftChild(T)); strcpy(temp1, ExpValue); if ((temp1[0]!='#') && (temp1[0]!='R') && (temp1[0]!='T')) { if ((temp1[0]=='(') || (temp1[0]=='@')) CurrentTemp--; strcpy(temp, temp1); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, ch, 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, ch, 1); } } GenValueExp(RightChild(T)); strcpy(temp2, ExpValue); if ((temp1[0] == '#') && (temp2[0] == '#')) { /* constant unfolded */ if (GetConstValue(temp1) <= GetConstValue(temp2)) sprintf(ExpValue, "#1"); else sprintf(ExpValue, "#0"); return(0); } else if (temp1[0]!= '#') { op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(CMP, ch, 2, op1, op2, op3); emit_goto(BLEQ, LabelNum++); op1.mode=NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode=NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); if ((temp2[0]=='R') || (temp2[0]=='T') || (temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp--; strcpy(ExpValue, temp1); return(0); } else if (temp2[1]!= '#') { if ((temp2[0]!='R') && (temp2[0]!='T')) { if ((temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp --; strcpy(temp, temp2); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp2, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp2, "T%d", CurrentTemp+2); op2.ident = temp2; } emit_most(MOV, ch, 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, ch, 1); } } op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(CMP, ch, 2, op1, op2, op3); emit_goto(BLEQ, LabelNum++); op1.mode=NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode=NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); strcpy(ExpValue, temp2); return(0); } }else if (NodeOp1(T) == GEOp) { GenValueExp(LeftChild(T)); strcpy(temp1, ExpValue); if ((temp1[0]!='#') && (temp1[0]!='R') && (temp1[0]!='T')) { if ((temp1[0]=='(') || (temp1[0]=='@')) CurrentTemp--; strcpy(temp, temp1); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, ch, 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, ch, 1); } } GenValueExp(RightChild(T)); strcpy(temp2, ExpValue); if ((temp1[0] == '#') && (temp2[0] == '#')) { /* constant unfolded */ if (GetConstValue(temp1) >= GetConstValue(temp2)) sprintf(ExpValue, "#1"); else sprintf(ExpValue, "#0"); return(0); } else if (temp1[0]!= '#') { op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(CMP, ch, 2, op1, op2, op3); emit_goto(BGEQ, LabelNum++); op1.mode=NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode=NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); if ((temp2[0]=='R') || (temp2[0]=='T') || (temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp--; strcpy(ExpValue, temp1); return(0); } else if (temp2[1]!= '#') { if ((temp2[0]!='R') && (temp2[0]!='T')) { if ((temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp --; strcpy(temp, temp2); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp2, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp2, "T%d", CurrentTemp+2); op2.ident = temp2; } emit_most(MOV, ch, 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, ch, 1); } } op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(CMP, ch, 2, op1, op2, op3); emit_goto(BGEQ, LabelNum++); op1.mode=NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode=NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); strcpy(ExpValue, temp2); return(0); } }else if (NodeOp1(T) == AndOp) { GenValueExp(LeftChild(T)); strcpy(temp1, ExpValue); if ((temp1[0]!='#') && (temp1[0]!='R') && (temp1[0]!='T')) { if ((temp1[0]=='(') || (temp1[0]=='@')) CurrentTemp--; strcpy(temp, temp1); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, 'l', 1); } } GenValueExp(RightChild(T)); strcpy(temp2, ExpValue); if ((temp1[0] == '#') && (temp2[0] == '#')) { /* constant unfolded */ if ((GetConstValue(temp1) != 0) && ( GetConstValue(temp2) != 0)) sprintf(ExpValue, "#1"); else sprintf(ExpValue, "#0"); return(0); } else if (temp1[0]!= '#') { op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = NUM_CONST; op2.num_const = 0; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BEQL, LabelNum++); op1.mode=IDENTIFIER; op1.ident = temp2; op2.mode = NUM_CONST; op2.num_const = 0; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BEQL, LabelNum-1); op1.mode=NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode=NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); if ((temp2[0]=='R') || (temp2[0]=='T') || (temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp--; strcpy(ExpValue, temp1); return(0); } else if (temp2[1]!= '#') { if ((temp2[0]!='R') && (temp2[0]!='T')){ if ((temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp --; strcpy(temp, temp2); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp2, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp2, "T%d", CurrentTemp+2); op2.ident = temp2; } emit_most(MOV, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, 'l', 1); } } op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = NUM_CONST; op2.num_const = 0; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BEQL, LabelNum++); op1.mode=IDENTIFIER; op1.ident = temp2; op2.mode = NUM_CONST; op2.num_const = 0; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BEQL, LabelNum-1); op1.mode=NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode=NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); strcpy(ExpValue, temp2); return(0); } }else if (NodeOp1(T) == OrOp) { GenValueExp(LeftChild(T)); strcpy(temp1, ExpValue); if ((temp1[0]!='#') && (temp1[0]!='R') && (temp1[0]!='T')) { if ((temp1[0]=='(') || (temp1[0]=='@')) CurrentTemp--; strcpy(temp, temp1); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, 'l', 1); } } GenValueExp(RightChild(T)); strcpy(temp2, ExpValue); if ((temp1[0] == '#') && (temp2[0] == '#')){ /* constant unfolded */ if ((GetConstValue(temp1) == 0) && ( GetConstValue(temp2) == 0)) sprintf(ExpValue, "#0"); else sprintf(ExpValue, "#1"); return(0); } else if (temp1[0]!= '#') { op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = NUM_CONST; op2.num_const = 0; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BNEQ, LabelNum++); op1.mode=IDENTIFIER; op1.ident = temp2; op2.mode = NUM_CONST; op2.num_const = 0; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BNEQ, LabelNum-1); op1.mode=NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode=NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); if ((temp2[0]=='R') || (temp2[0]=='T') || (temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp--; strcpy(ExpValue, temp1); return(0); } else if (temp2[1]!= '#') { if ((temp2[0]!='R') && (temp2[0]!='T')) { if ((temp2[0]=='(') || (temp2[0]=='@')) CurrentTemp --; strcpy(temp, temp2); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp2, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp2, "T%d", CurrentTemp+2); op2.ident = temp2; } emit_most(MOV, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, 'l', 1); } } op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = NUM_CONST; op2.num_const = 0; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BNEQ, LabelNum++); op1.mode=IDENTIFIER; op1.ident = temp2; op2.mode = NUM_CONST; op2.num_const = 0; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BNEQ, LabelNum-1); op1.mode=NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode=NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); strcpy(ExpValue, temp2); return(0); } } else if (NodeOp1(T) == UnaryNegOp) { GenValueExp(LeftChild(T)); strcpy(temp1, ExpValue); if ((temp1[0]!='#') && (temp1[0]!='R') && (temp1[0]!='T') ){ if ((temp1[0]=='(') || (temp1[0]=='@')) CurrentTemp--; strcpy(temp, temp1); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, 'l', 1); } } if (temp1[0] == '#') { /* constant unfolded */ sprintf(ExpValue, "#%d", 0-GetConstValue(temp1)); return(0); } else { op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = NUM_CONST; op2.num_const = 0; op3.mode = IDENTIFIER; op3.ident = temp1; emit_most(SUB, 'l', 3, op1, op2, op3); strcpy(ExpValue, temp1); return(0); } } else if (NodeOp1(T) == NotOp) { GenValueExp(LeftChild(T)); strcpy(temp1, ExpValue); if ((temp1[0]!='#') && (temp1[0]!='R') && (temp1[0]!='T')) { if ((temp1[0]=='(') || (temp1[0]=='@')) CurrentTemp--; strcpy(temp, temp1); op1.mode = IDENTIFIER; op1.ident = temp; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", MaxTemp+1); emit_data(temp, 'l', 1); } } if (temp1[0] == '#') { /* constant unfolded */ if (GetConstValue(temp1) != 0) sprintf(ExpValue, "#0"); else sprintf(ExpValue, "#1"); return(0); } else { op1.mode = NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BEQL, LabelNum++); op1.mode = NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); op1.mode = NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum-1); strcpy(ExpValue, temp1); return(0); } } else { printf("DEBUG--wrong exp\n"); exit(0); } } if (traceGen) printf("Leaving GenValueExp\n"); } /* get the lower bound for bound checking and code gen */ int GetLowerBound(T, index) tree T; int index; { int count; tree p; int i,j; if (traceGen) printf("Entering GetLowerBound\n"); p = LeftChild(T); count = 0; while (p!=NullExp()) { count ++; p = LeftChild(p); } p = LeftChild(T); for (i=0; i10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", CurrentTemp+1); emit_data(temp, 'l', 1); } } else if (location == VARGUE) sprintf(temp, "%d(AP)", offset); else sprintf(temp, "%d(FP)", offset); strcpy(VarOffset, temp); } else { p = RightChild(T); temp1[0] = '\0'; while (p != NullExp()) { /* calculate the address */ p1 = LeftChild(p); if (NodeOp1(p1) ==IndexOp) { index = 1; GenValueExp(LeftChild(p1)); if (ExpValue[0] != '#'){ tag = 1; /* checking the boundory */ op1.mode = NUM_CONST; op1.num_const = GetLowerBound(type, index); op2.mode = IDENTIFIER; op2.ident = ExpValue; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BLEQ, LabelNum++); emit_call("ARRAY_BOUND", 0); emit_label(LabelNum -1); op1.mode = NUM_CONST; op1.num_const = GetUpperBound(type, index); /* op2 the same */ emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BGEQ, LabelNum++); emit_call("ARRAY_BOUND", 0); emit_label(LabelNum-1); if ((ExpValue[0] == 'R') || (ExpValue[0] =='T')) { op1.mode = NUM_CONST; op1.num_const = GetLowerBound(type, index); op2.mode = IDENTIFIER; op2.ident = ExpValue; emit_most(SUB, 'l', 2, op1, op2, op3); strcpy(temp1, ExpValue); } else { /* get a now tempary */ op1.mode = IDENTIFIER; op1.ident = ExpValue; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, 'l', 2, op1, op2, op3); op1.mode = NUM_CONST; op1.num_const = GetLowerBound(type, index); /* op2 does not change */ emit_most(SUB, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", CurrentTemp+1); emit_data(temp, 'l', 1); } } } else { sprintf(temp1, "#%d", GetConstValue(ExpValue)- GetLowerBound(type, index)); } p2 = RightChild(p1); index ++; while(p2!=NullExp()) { GenValueExp(LeftChild(p2)); if (ExpValue[0] != '#') tag = 1; if (!tag) sprintf(temp1, "#%d",GetConstValue(temp1)* (GetUpperBound(type, index) - GetLowerBound(type, index)+1) + GetConstValue(ExpValue)); if (tag) { /* gen code to calculate the index */ if (temp1[0]=='#') /*** changed ***/ sprintf(temp1, "#%d", GetConstValue(temp1)* (GetUpperBound(type, index)- GetLowerBound(type, index)+1)); else { op1.mode = NUM_CONST; op1.num_const = GetUpperBound(type, index)- GetLowerBound(type, index)+1; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(MUL, 'l', 2, op1, op2, op3); } if (ExpValue[0]!='#') { op1.mode = NUM_CONST; op1.num_const = GetLowerBound(type, index); op2.mode = IDENTIFIER; op2.ident = ExpValue; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BLEQ, LabelNum++); emit_call("ARRAY_BOUND", 0); emit_label(LabelNum -1); op1.mode = NUM_CONST; op1.num_const = GetUpperBound(type, index); /* op2 the same */ emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BGEQ, LabelNum++); emit_call("ARRAY_BOUND", 0); emit_label(LabelNum-1); } if (temp1[0] != '#'){ op1.mode = IDENTIFIER; op1.ident = ExpValue; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(ADD, 'l', 2, op1, op2, op3); if ( (ExpValue[0] =='R') || (ExpValue[0]=='T')) CurrentTemp --; /* temp1 is still the same */ } else { if ((ExpValue[0] == 'R') || (ExpValue[0] =='T')) { op1.mode = NUM_CONST; op1.num_const = GetConstValue(temp1); op2.mode = IDENTIFIER; op2.ident = ExpValue; emit_most(ADD, 'l', 2, op1, op2, op3); strcpy(temp1, ExpValue); } else { /* get a now tempary */ op1.mode = IDENTIFIER; op1.ident = ExpValue; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op2.ident = temp1; } emit_most(MOV, 'l', 2, op1, op2, op3); op1.mode = NUM_CONST; op1.num_const = GetLowerBound(type, index); /* op2 does not change */ emit_most(ADD, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", CurrentTemp+1); emit_data(temp, 'l', 1); } } } } p2 = RightChild(p2); index ++; } type = RightChild(type); if (temp1[0] == '#') sprintf(temp1, "#%d", GetConstValue(temp1) * TypeSize(type)); else if (temp1[0] != '\0') { op1.mode = NUM_CONST; op1.num_const = TypeSize(type); op2.mode= IDENTIFIER; op2.ident = temp1; emit_most(MUL, 'l', 2, op1, op2, op3); } } else if (NodeOp1(p1) == FieldOp) { if (temp1[0] == '\0') sprintf(temp1, "#%d", GetAttr(IntVal(LeftChild(p1)), OFFSET_ATTR)); if (temp1[0] == '#') sprintf(temp1, "#%d", GetConstValue(temp1)+ GetAttr(IntVal(LeftChild(p1)), OFFSET_ATTR)); else { op1.mode = NUM_CONST; op1.num_const = GetAttr(IntVal(LeftChild(p1)), OFFSET_ATTR); op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(ADD, 'l', 2, op1, op2, op3); } type = (tree) GetAttr(IntVal(LeftChild(p1)), TYPE_ATTR); } p = RightChild(p); } if (location == GLOBAL) { if (temp1[0] =='#') sprintf(temp1, "DATA+%d", offset+GetConstValue(temp1)); else { op1.mode= IDENTIFIER; sprintf(temp2, "DATA+%d", offset); op1.ident = temp2; if (CurrentTemp < 10) { op2.mode = REGISTER; op2.reg = CurrentTemp+2; sprintf(temp, "R%d", CurrentTemp+2); } else { op2.mode = IDENTIFIER; sprintf(temp, "T%d", CurrentTemp+2); op2.ident = temp; } emit_most(MOVA, 'l', 2, op1, op2, op3); op1.mode = IDENTIFIER; op1.ident = temp; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(ADD, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", CurrentTemp+1); emit_data(temp, 'l', 1); } CurrentTemp--; } } else if (location == RARGUE){ /* will change here */ if (temp1[0] == '#') { sprintf(temp, "%d(AP)", offset); op1.mode = IDENTIFIER; op1.ident = temp; op2.mode = NUM_CONST; op2.num_const = GetConstValue(temp1); if (CurrentTemp < 10) { op3.mode = REGISTER; op3.reg = CurrentTemp+2; sprintf(temp1, "R%d", CurrentTemp+2); } else { op3.mode = IDENTIFIER; sprintf(temp1, "T%d", CurrentTemp+2); op3.ident = temp1; } emit_most(ADD, 'l', 3, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", CurrentTemp+1); emit_data(temp, 'l', 1); } } else { sprintf(temp, "%d(AP)", offset); op1.mode = IDENTIFIER; op1.ident = temp; op2.mode = IDENTIFIER; op2.ident = temp1; if ((temp1[0] == 'R') || (temp1[0] =='T') || (temp1[0] == '(') || (temp1[0] =='@')) CurrentTemp--; if (CurrentTemp < 10) { op3.mode = REGISTER; op3.reg = CurrentTemp+2; sprintf(temp2, "R%d", CurrentTemp+2); } else { op3.mode = IDENTIFIER; sprintf(temp2, "T%d", CurrentTemp+2); op3.ident = temp2; } emit_most(ADD, 'l', 3, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", CurrentTemp+1); emit_data(temp, 'l', 1); } strcpy(temp1, temp2); } } else if (location == VARGUE) { if (temp1[0] =='#') sprintf(temp1, "%d(AP)", offset+GetConstValue(temp1)); else { op1.mode = REGISTER; op1.reg = AP; op2.mode = NUM_CONST; op2.num_const = offset; if (CurrentTemp < 10) { op3.mode = REGISTER; op3.reg = CurrentTemp+2; sprintf(temp, "R%d", CurrentTemp+2); } else { op3.mode = IDENTIFIER; sprintf(temp, "T%d", CurrentTemp+2); op3.ident = temp; } emit_most(ADD, 'l', 3, op1, op2, op3); op1.mode = IDENTIFIER; op1.ident = temp; op2.mode = IDENTIFIER; op2.ident = temp1; /* might change here */ emit_most(ADD, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", CurrentTemp+1); emit_data(temp, 'l', 1); } CurrentTemp--; } } else { if (temp1[0] =='#') sprintf(temp1, "%d(FP)", offset+GetConstValue(temp1)); else { op1.mode = REGISTER; op1.reg = FP; op2.mode = NUM_CONST; op2.num_const = offset; if (CurrentTemp < 10) { op3.mode = REGISTER; op3.reg = CurrentTemp+2; sprintf(temp, "R%d", CurrentTemp+2); } else { op3.mode = IDENTIFIER; sprintf(temp, "T%d", CurrentTemp+2); op3.ident = temp; } emit_most(ADD, 'l', 3, op1, op2, op3); op1.mode = IDENTIFIER; op1.ident = temp; op2.mode = IDENTIFIER; op2.ident = temp1; emit_most(ADD, 'l', 2, op1, op2, op3); CurrentTemp++; if ((CurrentTemp>10) && (CurrentTemp+1 > MaxTemp)) { MaxTemp = CurrentTemp+1; sprintf(temp, "T%d", CurrentTemp+1); emit_data(temp, 'l', 1); } CurrentTemp--; } } strcpy(VarOffset, temp1); } if (traceGen) printf("Leaving GenVarAddr\n"); } /* gen if statement */ int GenIfStmt(T) tree T; { int tag; int i,j,k; tree p, p1; if (traceGen) printf("Entering GenIfStmt\n"); if (T == NullExp()) { if (traceGen) printf("Leaving GenIfStmt\n"); return(1); } tag = GenIfStmt(LeftChild(T)); if (!tag) emit_label(PopLabel()); else PushLabel(LabelNum++); /* for the end of the if loop */ p = RightChild(T); if (p == NullExp()) emit_label(PopLabel()); else if ((NodeKind(p) == EXPRNode) && (NodeOp1(p)!=CommaOp)) { /* for the files not if */ GenStmts(p); emit_label(PopLabel()); } else { /* for the ifels */ GenValueExp(LeftChild(p)); op1.mode = NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = ExpValue; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BNEQ, LabelNum++); emit_goto(JMP, LabelNum++); PushLabel(LabelNum-1); emit_label(LabelNum-2); if ((ExpValue[0] == 'R') || (ExpValue[0] == 'T') || (ExpValue[0] == '(') || (ExpValue[0] == '@')) CurrentTemp--; GenStmts(RightChild(p)); i = PopLabel(); emit_goto(JMP, TopLabel()); PushLabel(i); } if (traceGen) printf("Leaving GenIfStmt\n"); return(0); } /* generated code for loop statement */ GenLoopStmt(T) tree T; { tree p, p1; char temp1[20]; char temp2[20]; char temp3[20]; int i,j,k; int location; if (traceGen) printf("Entering GenLoopStmt\n"); p = LeftChild(T); if (p == NullExp()) { /* empty repeat */ emit_label(LabelNum++); GenValueExp(RightChild(T)); if ((ExpValue[0] == 'R') || (ExpValue[0] == 'T') || (ExpValue[0] == '(') || (ExpValue[0] == '@')) CurrentTemp--; op1.mode= NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = ExpValue; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BEQL, LabelNum++); emit_goto(JMP, LabelNum-2); emit_label(LabelNum-1); } else if ((NodeKind(p) == EXPRNode) && (NodeOp1(p) == StmtOp)) { emit_label(LabelNum++); PushLabel(LabelNum-1); GenStmts(p); GenValueExp(RightChild(T)); if ((ExpValue[0] == 'R') || (ExpValue[0] == 'T') || (ExpValue[0] == '(') || (ExpValue[0] == '@')) CurrentTemp--; op1.mode= NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = ExpValue; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BNEQ, LabelNum++); emit_goto(JMP, PopLabel()); emit_label(LabelNum-1); } else if ((NodeKind(p) == EXPRNode) && (NodeOp1(p) != CommaOp)) { emit_label(LabelNum++); PushLabel(LabelNum-1); GenValueExp(p); if ((ExpValue[0] == 'R') || (ExpValue[0] == 'T') || (ExpValue[0] == '(') || (ExpValue[0] == '@')) CurrentTemp--; op1.mode= NUM_CONST; op1.num_const = 0; op2.mode = IDENTIFIER; op2.ident = ExpValue; emit_most(CMP, 'l', 2, op1, op2, op3); emit_goto(BNEQ, LabelNum++); emit_goto(JMP, LabelNum++); emit_label(LabelNum-2); PushLabel(LabelNum-1); GenStmts(RightChild(T)); i = PopLabel(); emit_goto(JMP, PopLabel()); emit_label(i); } else { /* for loop */ p1 = RightChild(p); if (NodeOp1(p1) == ToOp) { GenValueExp(LeftChild(p1)); strcpy(temp1, ExpValue); if ((temp1[0] == 'R') || (temp1[0] == 'T') || (temp1[0] == '(') || (temp1[0] == '@')) CurrentTemp--; location = GetAttr(IntVal(LeftChild(p)), PLACE_ATTR); if (location == GLOBAL) sprintf(VarOffset, "DATA+%d", GetAttr(IntVal(LeftChild(p)), OFFSET_ATTR)); else if (location == LOCAL) sprintf(VarOffset, "%d(FP)", GetAttr(IntVal(LeftChild(p)), OFFSET_ATTR)); else sprintf(VarOffset, "%d(AP)", GetAttr(IntVal(LeftChild(p)), OFFSET_ATTR)); strcpy(temp2, VarOffset); op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum++); PushLabel(LabelNum-1); GenValueExp(RightChild(p1)); strcpy(temp3, ExpValue); op1.mode = IDENTIFIER; op1.ident = temp2; op2.mode = IDENTIFIER; op2.ident = temp3; emit_most(CMP, 'l', 2, op1, op2, op3); if ((temp3[0] == 'R') || (temp3[0] == 'T') || (temp3[0] == '(') || (temp3[0] == '@')) CurrentTemp--; emit_goto(BLEQ, LabelNum++); emit_goto(JMP, LabelNum++); PushLabel(LabelNum-1); emit_label(LabelNum-2); GenStmts(RightChild(T)); op1.mode = NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(ADD, 'l', 2, op1, op2,op3); i = PopLabel(); emit_goto(JMP, PopLabel()); emit_label(i); } else { /* downto */ GenValueExp(LeftChild(p1)); strcpy(temp1, ExpValue); if ((temp1[0] == 'R') || (temp1[0] == 'T') || (temp1[0] == '(') || (temp1[0] == '@')) CurrentTemp--; location = GetAttr(IntVal(LeftChild(p)), PLACE_ATTR); if (location == GLOBAL) sprintf(VarOffset, "DATA+%d", GetAttr(IntVal(LeftChild(p)), OFFSET_ATTR)); else if (location == LOCAL) sprintf(VarOffset, "%d(FP)", GetAttr(IntVal(LeftChild(p)), OFFSET_ATTR)); else sprintf(VarOffset, "%d(AP)", GetAttr(IntVal(LeftChild(p)), OFFSET_ATTR)); strcpy(temp2, VarOffset); op1.mode = IDENTIFIER; op1.ident = temp1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(MOV, 'l', 2, op1, op2, op3); emit_label(LabelNum++); PushLabel(LabelNum-1); GenValueExp(RightChild(p1)); strcpy(temp3, ExpValue); op1.mode = IDENTIFIER; op1.ident = temp2; op2.mode = IDENTIFIER; op2.ident = temp3; emit_most(CMP, 'l', 2, op1, op2, op3); if ((temp3[0] == 'R') || (temp3[0] == 'T') || (temp3[0] == '(') || (temp3[0] == '@')) CurrentTemp--; emit_goto(BGEQ, LabelNum++); emit_goto(JMP, LabelNum++); PushLabel(LabelNum-1); emit_label(LabelNum-2); GenStmts(RightChild(T)); op1.mode = NUM_CONST; op1.num_const = 1; op2.mode = IDENTIFIER; op2.ident = temp2; emit_most(SUB, 'l', 2, op1, op2,op3); i = PopLabel(); emit_goto(JMP, PopLabel()); emit_label(i); } } if (traceGen) printf("Leaving GenLoopStmt\n"); }