Type* duplicateType(Type* type) { Type* resultType = (Type*) malloc(sizeof(Type)); resultType->typeClass = type->typeClass; if (type->typeClass == TP_ARRAY) { resultType->arraySize = type->arraySize; resultType->elementType = duplicateType(type->elementType); } return resultType; }
Type* compileType(void) { Type* type; Type* elementType; int arraySize; Object* obj; switch (lookAhead->tokenType) { case KW_INTEGER: eat(KW_INTEGER); type = makeIntType(); break; case KW_CHAR: eat(KW_CHAR); type = makeCharType(); break; case KW_STRING: eat(KW_STRING); type=makeStringType(); break; case KW_FLOAT: eat(KW_FLOAT); type=makeFloatType(); break; case KW_ARRAY: eat(KW_ARRAY); eat(SB_LSEL); eat(TK_NUMBER); arraySize = currentToken->value; eat(SB_RSEL); eat(KW_OF); elementType = compileType(); type = makeArrayType(arraySize, elementType); break; case TK_IDENT: eat(TK_IDENT); obj = checkDeclaredType(currentToken->string); type = duplicateType(obj->typeAttrs->actualType); break; default: error(ERR_INVALID_TYPE, lookAhead->lineNo, lookAhead->colNo); break; } return type; }
Type* compileType(void) { // TODO: create and return a type Type* type = NULL; switch (lookAhead->tokenType) { case KW_INTEGER: eat(KW_INTEGER); type = (Type*) malloc(sizeof(Type)); type->typeClass = TP_INT; break; case KW_CHAR: eat(KW_CHAR); type = (Type*) malloc(sizeof(Type)); type->typeClass = TP_CHAR; break; case KW_ARRAY: type = (Type*) malloc(sizeof(Type)); type->typeClass = TP_ARRAY; eat(KW_ARRAY); eat(SB_LSEL); eat(TK_NUMBER); type->arraySize = currentToken->value; eat(SB_RSEL); eat(KW_OF); type->elementType = compileType(); break; case TK_IDENT: eat(TK_IDENT); Object* obj = lookupObject(currentToken->string); if (obj == NULL) { error(ERR_UNDECLARED_TYPE, currentToken->lineNo, currentToken->colNo); } else if (obj->kind != OBJ_TYPE) { error(ERR_INVALID_TYPE, currentToken->lineNo, currentToken->colNo); } type = duplicateType(obj->typeAttrs->actualType); break; default: error(ERR_INVALID_TYPE, lookAhead->lineNo, lookAhead->colNo); break; } return type; }
Type* compileType(void) { Type* type; Type* elementType; int arraySize; Object* obj; switch (lookAhead->tokenType) { case KW_INTEGER: eat(KW_INTEGER); type = makeIntType(); break; case KW_CHAR: eat(KW_CHAR); type = makeCharType(); break; case KW_ARRAY: eat(KW_ARRAY); eat(SB_LSEL); eat(TK_NUMBER); arraySize = currentToken->value; eat(SB_RSEL); eat(KW_OF); elementType = compileType(); type = makeArrayType(arraySize, elementType); break; case TK_IDENT: eat(TK_IDENT); // check if the type identifier is declared and get its actual type obj = checkDeclaredType(currentToken->string); if (obj != NULL) type = duplicateType(obj->typeAttrs->actualType); else error(ERR_UNDECLARED_TYPE, currentToken->colNo, currentToken->lineNo); break; default: error(ERR_INVALID_TYPE, lookAhead->lineNo, lookAhead->colNo); break; } return type; }