void VersionCondition::addGlobalIdent(const char *ident) { checkPredefined(Loc(), ident); addPredefinedGlobalIdent(ident); }
void processOperator(SymbolTable *table, Node *ptr) { int stIndex; switch(ptr->token.tokenNumber) { case ASSIGN_OP: { Node *lhs = ptr->son, *rhs = ptr->son->next; if (lhs->noderep == NONTERM) { lvalue = 1; processOperator(table, lhs); lvalue = 0; } if (rhs->noderep == NONTERM) { processOperator(table, rhs); } else { rv_emit(table, rhs); } if (lhs->noderep == TERMINAL) { stIndex = lookup(table, lhs->token.tokenValue); if (stIndex == -1) { fprintf(stderr, "undefined variable: %s\n", lhs->token.tokenValue); return; } emit2("str", table->rows[stIndex].base, table->rows[stIndex].offset); } else { emit0("sti"); } break; } case ADD_ASSIGN: case SUB_ASSIGN: case MUL_ASSIGN: case DIV_ASSIGN: case MOD_ASSIGN: { Node *lhs = ptr->son, *rhs = ptr->son->next; int nodeNumber = ptr->token.tokenNumber; ptr->token.tokenNumber = ASSIGN_OP; if (lhs->noderep == NONTERM) { lvalue = 1; processOperator(table, lhs); lvalue = 0; } ptr->token.tokenNumber = nodeNumber; if (lhs->noderep == NONTERM) { processOperator(table, lhs); } else { rv_emit(table, lhs); } if (rhs->noderep == NONTERM) { processOperator(table, rhs); } else { rv_emit(table, rhs); } switch(ptr->token.tokenNumber) { case ADD_ASSIGN: emit0("add"); break; case SUB_ASSIGN: emit0("sub"); break; case MUL_ASSIGN: emit0("mult"); break; case DIV_ASSIGN: emit0("div"); break; case MOD_ASSIGN: emit0("mod"); break; } if (lhs->noderep == TERMINAL) { stIndex = lookup(table, lhs->token.tokenValue); if (stIndex == -1) { fprintf(file, "undefined variable: %s\n", lhs->son->token.tokenValue); return; } emit2("str", table->rows[stIndex].base, table->rows[stIndex].offset); } else { emit0("sti"); } break; } case ADD: case SUB: case MUL: case DIV: case MOD: case EQ: case NE: case GT: case LT: case GE: case LE: case LOGICAL_AND: case LOGICAL_OR: { Node *lhs = ptr->son, *rhs = ptr->son->next; if (lhs->noderep == NONTERM) { processOperator(table, lhs); } else { rv_emit(table, lhs); } if (rhs->noderep == NONTERM) { processOperator(table, rhs); } else { rv_emit(table, rhs); } switch(ptr->token.tokenNumber) { case ADD: emit0("add"); break; case SUB: emit0("sub"); break; case MUL: emit0("mult"); break; case DIV: emit0("div"); break; case MOD: emit0("mod"); break; case EQ: emit0("eq"); break; case NE: emit0("ne"); break; case GT: emit0("gt"); break; case LT: emit0("lt"); break; case GE: emit0("ge"); break; case LE: emit0("le"); break; case LOGICAL_AND: emit0("and"); break; case LOGICAL_OR: emit0("or"); break; } break; } case UNARY_MINUS: case LOGICAL_NOT: { Node *p = ptr->son; if (p->noderep == NONTERM) { processOperator(table, p); } else { rv_emit(table, p); } switch(ptr->token.tokenNumber) { case UNARY_MINUS: emit0("neg"); break; case LOGICAL_NOT: emit0("not"); break; } break; } case INDEX: { Node *indexExp = ptr->son->next; if (indexExp->noderep == NONTERM) processOperator(table, indexExp); else rv_emit(table, indexExp); stIndex = lookup(table, ptr->son->token.tokenValue); if (stIndex == -1) { fprintf(file, "undefined variable: %s\n", ptr->son->token.tokenValue); return; } emit2("lda", table->rows[stIndex].base, table->rows[stIndex].offset); emit0("add"); if (!lvalue) { emit0("ldi"); } break; } case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC: { Node *p = ptr->son; Node *q; int stIndex; int amount = 1; if (p->noderep == NONTERM) { processOperator(table, p); } else { rv_emit(table, p); } q = p; while (q->noderep != TERMINAL) { q = q->son; } if (!q || (q->token.tokenNumber != IDENT)) { fprintf(file, "increment/decrement operators can not be applied in expression\n"); return; } stIndex = lookup(table, q->token.tokenValue); if (stIndex == -1) { return; } switch(ptr->token.tokenNumber) { case PRE_INC: emit0("inc"); break; case PRE_DEC: emit0("dec"); break; case POST_INC: emit0("inc"); break; case POST_DEC: emit0("dec"); break; } if (p->noderep == TERMINAL) { stIndex = lookup(table, p->token.tokenValue); if (stIndex == -1) { return; } emit2("str", table->rows[stIndex].base, table->rows[stIndex].offset); } else if (p->token.tokenNumber == INDEX) { lvalue = 1; processOperator(table, p); lvalue = 0; emit0("swp"); emit0("sti"); } else fprintf(file, "error in increment/decrement operators\n"); break; } case CALL: { Node *p = ptr->son; char *functionName; int stIndex; int noArguments; if (checkPredefined(table, p)) { break; } functionName = p->token.tokenValue; stIndex = lookup(rootTable, functionName); if (stIndex == -1) { fprintf(file, "%s: undefined function\n", functionName); break; } noArguments = rootTable->rows[stIndex].width; emit0("ldp"); p = p->next->son; while (p) { if (p->noderep == NONTERM) { processOperator(table, p); } else { rv_emit(table, p); } noArguments--; p = p->next; } if (noArguments > 0) { fprintf(file, "%s: too few actual arguments\n", functionName); } if (noArguments < 0) { fprintf(file, "%s: too many actual arguments\n", functionName); } emitJump("call", ptr->son->token.tokenValue); break; } } }