void compileFactor(void) { Object* obj; switch (lookAhead->tokenType) { case TK_NUMBER: eat(TK_NUMBER); break; case TK_CHAR: eat(TK_CHAR); break; case TK_IDENT: eat(TK_IDENT); // check if the identifier is declared obj = checkDeclaredIdent(currentToken->string); switch (obj->kind) { case OBJ_CONSTANT: break; case OBJ_VARIABLE: compileIndexes(); break; case OBJ_PARAMETER: break; case OBJ_FUNCTION: compileArguments(); break; default: error(ERR_INVALID_FACTOR,currentToken->lineNo, currentToken->colNo); break; } break; default: error(ERR_INVALID_FACTOR, lookAhead->lineNo, lookAhead->colNo); } }
Type* compileFactor(void) { // DONE: parse a factor and return the factor's type Object* obj; Type* type; switch (lookAhead->tokenType) { case TK_NUMBER: eat(TK_NUMBER); type = intType; break; case TK_CHAR: eat(TK_CHAR); type = charType; break; case TK_IDENT: eat(TK_IDENT); // check if the identifier is declared obj = checkDeclaredIdent(currentToken->string); switch (obj->kind) { case OBJ_CONSTANT: switch (obj->constAttrs->value->type) { case TP_INT: type = intType; break; case TP_CHAR: type = charType; break; default: break; } break; case OBJ_VARIABLE: if (obj->varAttrs->type->typeClass == TP_ARRAY) { type = compileIndexes(obj->varAttrs->type); } else { type = obj->varAttrs->type; } break; case OBJ_PARAMETER: type = obj->paramAttrs->type; break; case OBJ_FUNCTION: compileArguments(obj->funcAttrs->paramList); type = obj->funcAttrs->returnType; break; default: error(ERR_INVALID_FACTOR,currentToken->lineNo, currentToken->colNo); break; } break; default: error(ERR_INVALID_FACTOR, lookAhead->lineNo, lookAhead->colNo); } return type; }
Type* compileFactor(void) { // parse a factor and return the factor's type Object* obj = NULL; Type* type = NULL; switch (lookAhead->tokenType) { case TK_NUMBER: eat(TK_NUMBER); type = makeIntType(); break; case TK_CHAR: eat(TK_CHAR); type = makeCharType(); break; case TK_IDENT: eat(TK_IDENT); // check if the identifier is declared obj = checkDeclaredIdent(currentToken->string); switch (obj->kind) { case OBJ_CONSTANT: // use as an empty type type = makeIntType(); // assign the type of the constant type->typeClass = obj->constAttrs->value->type; break; case OBJ_VARIABLE: if (obj->varAttrs->type->typeClass != TP_ARRAY) type = obj->varAttrs->type; else type = compileIndexes(obj->varAttrs->type); break; case OBJ_PARAMETER: type = obj->paramAttrs->type; break; case OBJ_FUNCTION: type = obj->funcAttrs->returnType; compileArguments(obj->funcAttrs->paramList); break; default: error(ERR_INVALID_FACTOR,currentToken->lineNo, currentToken->colNo); break; } break; default: error(ERR_INVALID_FACTOR, lookAhead->lineNo, lookAhead->colNo); } return type; }
Type* compileFactor(void) { Type* type; Object* obj; switch (lookAhead->tokenType) { case TK_NUMBER: eat(TK_NUMBER); type = intType; genLC(currentToken->value); break; case TK_CHAR: eat(TK_CHAR); type = charType; genLC(currentToken->value); break; case TK_IDENT: eat(TK_IDENT); obj = checkDeclaredIdent(currentToken->string); switch (obj->kind) { case OBJ_CONSTANT: switch (obj->constAttrs->value->type) { case TP_INT: type = intType; genLC(obj->constAttrs->value->intValue); break; case TP_CHAR: type = charType; genLC(obj->constAttrs->value->charValue); break; default: break; } break; case OBJ_VARIABLE: if (obj->varAttrs->type->typeClass == TP_ARRAY) { genVariableAddress(obj); type = compileIndexes(obj->varAttrs->type); genLI(); } else { type = obj->varAttrs->type; genVariableValue(obj); } break; case OBJ_PARAMETER: // TODO: push parameter's value onto the stack type = obj->paramAttrs->type; break; case OBJ_FUNCTION: // TODO: generate function call if (isPredefinedFunction(obj)) { compileArguments(obj->funcAttrs->paramList); genPredefinedFunctionCall(obj); } else { compileArguments(obj->funcAttrs->paramList); } type = obj->funcAttrs->returnType; break; default: error(ERR_INVALID_FACTOR,currentToken->lineNo, currentToken->colNo); break; } break; case SB_LPAR: eat(SB_LPAR); type = compileExpression(); eat(SB_RPAR); break; default: error(ERR_INVALID_FACTOR, lookAhead->lineNo, lookAhead->colNo); } return type; }