Esempio n. 1
0
void VersionCondition::addGlobalIdent(const char *ident)
{
    checkPredefined(Loc(), ident);
    addPredefinedGlobalIdent(ident);
}
Esempio n. 2
0
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;
        }
    }
}