Type* compileTerm2(Type* argType1) { Type* argType2; Type* resultType; switch (lookAhead->tokenType) { case SB_TIMES: eat(SB_TIMES); checkIntType(argType1); argType2 = compileFactor(); checkIntType(argType2); genML(); resultType = compileTerm2(argType1); break; case SB_SLASH: eat(SB_SLASH); checkIntType(argType1); argType2 = compileFactor(); checkIntType(argType2); genDV(); resultType = compileTerm2(argType1); break; // check the FOLLOW set case SB_PLUS: case SB_MINUS: case KW_TO: case KW_DO: case SB_RPAR: case SB_COMMA: case SB_EQ: case SB_NEQ: case SB_LE: case SB_LT: case SB_GE: case SB_GT: case SB_RSEL: case SB_SEMICOLON: case KW_END: case KW_ELSE: case KW_THEN: resultType = argType1; break; default: error(ERR_INVALID_TERM, lookAhead->lineNo, lookAhead->colNo); } return resultType; }
Type* compileExpression3(Type* argType1) { Type* argType2; Type* resultType; switch (lookAhead->tokenType) { case SB_PLUS: eat(SB_PLUS); checkIntType(argType1); argType2 = compileTerm(); checkIntType(argType2); genAD(); resultType = compileExpression3(argType1); break; case SB_MINUS: eat(SB_MINUS); checkIntType(argType1); argType2 = compileTerm(); checkIntType(argType2); genSB(); resultType = compileExpression3(argType1); break; // check the FOLLOW set case KW_TO: case KW_DO: case SB_RPAR: case SB_COMMA: case SB_EQ: case SB_NEQ: case SB_LE: case SB_LT: case SB_GE: case SB_GT: case SB_RSEL: case SB_SEMICOLON: case KW_END: case KW_ELSE: case KW_THEN: resultType = argType1; break; default: error(ERR_INVALID_EXPRESSION, lookAhead->lineNo, lookAhead->colNo); } return resultType; }
Type* compileIndexes(Type* arrayType) { // parse a sequence of indexes, check the consistency to the arrayType, and return the element type Type *idxType = NULL; Type *elmType = NULL; while (lookAhead->tokenType == SB_LSEL) { eat(SB_LSEL); // if current element is not of array type, // then the access to the next dimension is invalid checkArrayType(arrayType); idxType = compileExpression(); checkIntType(idxType); eat(SB_RSEL); // Down 1 level of dimension arrayType = arrayType->elementType; } // arrayType becomes elmType when we traverse to the last dimension elmType = arrayType; return elmType; }
Type* compileExpression3(void) { Type* type1; Type* type2; switch (lookAhead->tokenType) { case SB_PLUS: eat(SB_PLUS); type1 = compileTerm(); checkIntType(type1); type2 = compileExpression3(); if (type2 != NULL) checkIntType(type2); return type1; break; case SB_MINUS: eat(SB_MINUS); type1 = compileTerm(); checkIntType(type1); type2 = compileExpression3(); if (type2 != NULL) checkIntType(type2); return type1; break; // check the FOLLOW set case KW_TO: case KW_DO: case SB_RPAR: case SB_COMMA: case SB_EQ: case SB_NEQ: case SB_LE: case SB_LT: case SB_GE: case SB_GT: case SB_RSEL: case SB_SEMICOLON: case KW_END: case KW_ELSE: case KW_THEN: return NULL; break; default: error(ERR_INVALID_EXPRESSION, lookAhead->lineNo, lookAhead->colNo); } return NULL; }
Type* compileExpression(void) { Type* type; switch (lookAhead->tokenType) { case SB_PLUS: eat(SB_PLUS); type = compileExpression2(); checkIntType(type); break; case SB_MINUS: eat(SB_MINUS); type = compileExpression2(); checkIntType(type); break; default: type = compileExpression2(); } return type; }
void compileTerm2(void) { Type* type; switch (lookAhead->tokenType) { case SB_TIMES: eat(SB_TIMES); type = compileFactor(); checkIntType(type); compileTerm2(); return type; break; case SB_SLASH: eat(SB_SLASH); type = compileFactor(); checkIntType(type); compileTerm2(); return type; break; // check the FOLLOW set case SB_PLUS: case SB_MINUS: case KW_TO: case KW_DO: case SB_RPAR: case SB_COMMA: case SB_EQ: case SB_NEQ: case SB_LE: case SB_LT: case SB_GE: case SB_GT: case SB_RSEL: case SB_SEMICOLON: case KW_END: case KW_ELSE: case KW_THEN: return NULL; break; default: error(ERR_INVALID_TERM, lookAhead->lineNo, lookAhead->colNo); } }
Type* compileExpression(void) { // TODO: generate code for expression Type* type; switch (lookAhead->tokenType) { case SB_PLUS: eat(SB_PLUS); type = compileExpression2(); checkIntType(type); break; case SB_MINUS: eat(SB_MINUS); type = compileExpression2(); checkIntType(type); genNEG(); break; default: type = compileExpression2(); } return type; }
Type* compileIndexes(Type* arrayType) { // TODO: parse a sequence of indexes, check the consistency to the arrayType, and return the element type Type* type; while (lookAhead->tokenType == SB_LSEL) { eat(SB_LSEL); type = compileExpression(); checkIntType(type); checkArrayType(arrayType); arrayType = arrayType->elementType; eat(SB_RSEL); } checkBasicType(arrayType); return arrayType; }
Type* compileIndexes(Type* arrayType) { Type* type; while (lookAhead->tokenType == SB_LSEL) { eat(SB_LSEL); type = compileExpression(); checkIntType(type); checkArrayType(arrayType); arrayType = arrayType->elementType; eat(SB_RSEL); } checkBasicType(arrayType); return arrayType; }
Type* compileIndexes(Type* arrayType) { // TODO: Generate code for computing array element address Type* type; while (lookAhead->tokenType == SB_LSEL) { eat(SB_LSEL); type = compileExpression(); checkIntType(type); checkArrayType(arrayType); arrayType = arrayType->elementType; eat(SB_RSEL); } checkBasicType(arrayType); return arrayType; }