📄 codegenerator.c
字号:
addressVarID, offset);}static void GenerateLocalVarAddressCode(int offset){ fprintf(CFileFp, STRING_LOCAL_VAR_FMT, addressVarID, offset);}static void GenerateAssignConstCode( int nameAddressVarID, int expValue){ fprintf(CFileFp, STRING_ASSIGN_CONST_FMT, nameAddressVarID, expValue);}static void GenerateAssignVarCode(int nameAddressVarID, int expAddressVarID){ fprintf(CFileFp, STRING_ASSIGN_VAR_FMT, nameAddressVarID, expAddressVarID);}static void GenerateFunctionCallCode( NodePtr classNodePtr, NodePtr callNodePtr, SymbolTablePtr symbolTablePtr){ NodePtr methodNameNodePtr = NULL; GenerateMethodCallCode( classNodePtr, callNodePtr->children[0], TRUE, symbolTablePtr); GenerateProtectEnvCode(); GenerateNewEnvCode( classNodePtr, callNodePtr->children[1], symbolTablePtr); methodNameNodePtr = callNodePtr->children[0]; while (methodNameNodePtr->numberOfChildren > 1) { methodNameNodePtr = methodNameNodePtr->children[1]; } methodNameNodePtr = methodNameNodePtr->children[0]; GenerateCallCode(callNodePtr->info.lexeme, methodNameNodePtr->info.lexeme); GenerateSaveReturnValueCode(); GenerateRestoreEnvCode(); GenerateGetReturnValueCode();} static void GenerateMethodCallCode( NodePtr classNodePtr, NodePtr nameNodePtr, Boolean isTop, SymbolTablePtr symbolTablePtr){ NodePtr varNodePtr = NULL; NodePtr subClassNodePtr = NULL; if (nameNodePtr == NULL) { return; } fprintf(CFileFp, STRING_NEW_LINE); varNodePtr = nameNodePtr->children[0]; switch (varNodePtr->type) { case NODE_TYPE_KEYWORD: GenerateThisObjectAddressCode(); break; case NODE_TYPE_IDENTIFIER: if (nameNodePtr->numberOfChildren == 1) { return; } else { GenerateIdentifierCode( classNodePtr, varNodePtr, isTop, symbolTablePtr); } break; case NODE_TYPE_ARRAY_ACCESS: GenerateArrayAccessCode( classNodePtr, varNodePtr, isTop, symbolTablePtr); break; default: break; } if (nameNodePtr->numberOfChildren > 1) { subClassNodePtr = ClassNodeOfType(varNodePtr->typePtr); GenerateCheckNullCode(); GenerateMethodCallCode( subClassNodePtr, nameNodePtr->children[1], FALSE, subClassNodePtr->info.symbolTablePtr); }}/*static void GenerateMethodCallCode( NodePtr classNodePtr, NodePtr callNodePtr, SymbolTablePtr symbolTablePtr){ NodePtr methodNameNodePtr = NULL; if (callNodePtr == NULL) { return; } GenerateProtectEnvCode(); GenerateNewEnvCode( classNodePtr, callNodePtr->children[1], symbolTablePtr); methodNameNodePtr = callNodePtr->children[0]; while (methodNameNodePtr->numberOfChildren > 1) { methodNameNodePtr = methodNameNodePtr->children[1]; } methodNameNodePtr = methodNameNodePtr->children[0]; GenerateCallCode(callNodePtr->info.lexeme, methodNameNodePtr->info.lexeme); GenerateSaveReturnValueCode(); GenerateRestoreEnvCode(); GenerateGetReturnValueCode();}*/static void GenerateIfCode( NodePtr classNodePtr, NodePtr statementNodePtr, SymbolTablePtr symbolTablePtr){ int expAddressVarID; GenerateExpressionCode( classNodePtr, statementNodePtr->children[0], symbolTablePtr); expAddressVarID = addressVarID; GetNextAddressVarID(); fprintf(CFileFp, STRING_IF_TRUE_FMT, expAddressVarID); if (statementNodePtr->children[1] == NULL) { fprintf(CFileFp, STRING_EMPTY_STATEMENT); } else { fprintf(CFileFp, STRING_LEFT_CURLY_BRACKET); GenerateStatementCode( classNodePtr, statementNodePtr->children[1], symbolTablePtr); fprintf(CFileFp, STRING_RIGHT_CURLY_BRACKET); } fprintf(CFileFp, STRING_ELSE); if (statementNodePtr->children[1] == NULL) { fprintf(CFileFp, STRING_EMPTY_STATEMENT); } else { fprintf(CFileFp, STRING_LEFT_CURLY_BRACKET); GenerateStatementCode( classNodePtr, statementNodePtr->children[2], symbolTablePtr); fprintf(CFileFp, STRING_RIGHT_CURLY_BRACKET); }}static void GenerateWhileCode( NodePtr classNodePtr, NodePtr statementNodePtr, SymbolTablePtr symbolTablePtr){ int expAddressVarID; fprintf(CFileFp, STRING_DO); GenerateExpressionCode( classNodePtr, statementNodePtr->children[0], symbolTablePtr); expAddressVarID = addressVarID; GetNextAddressVarID(); fprintf(CFileFp, STRING_IF_FALSE_FMT, expAddressVarID); fprintf(CFileFp, STRING_BREAK); if (statementNodePtr->children[1] == NULL) { fprintf(CFileFp, STRING_EMPTY_STATEMENT); } else { fprintf(CFileFp, STRING_LEFT_CURLY_BRACKET); GenerateStatementCode( classNodePtr, statementNodePtr->children[1], symbolTablePtr); fprintf(CFileFp, STRING_RIGHT_CURLY_BRACKET); } fprintf(CFileFp, STRING_WHILE_1);}static void GeneratePrintCode( NodePtr classNodePtr, NodePtr argListNodePtr, SymbolTablePtr symbolTablePtr){ int i; for (i = 0; i < argListNodePtr->numberOfChildren - 2; i ++) { if (argListNodePtr->children[i] == NULL) { continue; } if (GenerateExpressionCode( classNodePtr, argListNodePtr->children[i], symbolTablePtr) == TRUE) { fprintf(CFileFp, STRING_PRINT_CONST_FMT, argListNodePtr->children[i]->info.value); } else { fprintf(CFileFp, STRING_PRINT_VAR_FMT, addressVarID); } } if (GenerateExpressionCode( classNodePtr, argListNodePtr->children[i], symbolTablePtr) == TRUE) { fprintf(CFileFp, STRING_PRINTLN_CONST_FMT, argListNodePtr->children[i]->info.value); } else { fprintf(CFileFp, STRING_PRINTLN_VAR_FMT, addressVarID); }}static void GenerateProtectEnvCode(){ fprintf(CFileFp, STRING_EXPAND_STACK_SIZE); fprintf(CFileFp, STRING_REALLOC_STACK); fprintf(CFileFp, STRING_SAVE_ENV_SIZE); fprintf(CFileFp, STRING_PUSH_ENV);}static void GenerateNewEnvCode( NodePtr classNodePtr, NodePtr argListNodePtr, SymbolTablePtr symbolTablePtr){ int i; if (argListNodePtr == NULL) { return; } /* for (i = 0; i < argListNodePtr->numberOfChildren; i ++) { if (argListNodePtr->children[i] == NULL) { continue; } GenerateExpressionCode( classNodePtr, argListNodePtr->children[i], symbolTablePtr); GenerateParameterCode(i); } */ GenerateArgListCode(classNodePtr, argListNodePtr, symbolTablePtr); GenerateMallocEnvCode(argListNodePtr->numberOfChildren - 1);}static void GenerateCallCode(String className, String methodName){ fprintf(CFileFp, STRING_FUNCTION_CALL_FMT, className, methodName);}static void GenerateSaveReturnValueCode(){ fprintf(CFileFp, STRING_SAVE_RETURN_VALUE);}static void GenerateRestoreEnvCode(){ fprintf(CFileFp, STRING_FREE_ENV); fprintf(CFileFp, STRING_POP_ENV); fprintf(CFileFp, STRING_RESTORE_ENV_SIZE); fprintf(CFileFp, STRING_SHRINK_STACK_SIZE); fprintf(CFileFp, STRING_REALLOC_STACK);}static void GenerateGetReturnValueCode(){ fprintf(CFileFp, STRING_TMP_VAR_FMT, addressVarID, addressVarID + 1); fprintf(CFileFp, STRING_GET_RETURN_VALUE_FMT, addressVarID);}static void GenerateMallocEnvCode(int argumentNumber){ int i; fprintf(CFileFp, STRING_UPDATE_ENV_SIZE_FMT, argumentNumber + FIRST_LOCAL_VAR_OFFSET); fprintf(CFileFp, STRING_MALLOC_ENV); /* fprintf(CFileFp, STRING_NEW_THIS_OBJ_ADDR_FMT, addressVarID); fprintf(CFileFp, STRING_ASSIGN_CONST_FMT, addressVarID, 1); */ fprintf(CFileFp, STRING_ASSIGN_THIS_OBJ_OFFSET); if (argumentNumber > 0) { for (i = 0; i < argumentNumber; i ++) { fprintf(CFileFp, STRING_PASS_ARGUMENT_FMT, i + FIRST_LOCAL_VAR_OFFSET, i); } fprintf(CFileFp, STRING_FREE_ARG_LIST); }}/*static void GenerateParameterCode(int parameterID){ int parameterAddressVarID; parameterAddressVarID = addressVarID; GetNextAddressVarID(); fprintf(CFileFp, STRING_LOCAL_VAR_FMT, addressVarID, parameterID + FIRST_LOCAL_VAR_OFFSET); fprintf(CFileFp, STRING_PASS_PARAMETER_FMT, addressVarID, parameterAddressVarID);}*/static void GenerateArgListCode( NodePtr classNodePtr, NodePtr argListNodePtr, SymbolTablePtr symbolTablePtr){ int argumentNumber; int i; if (argListNodePtr == NULL) { return; } argumentNumber = argListNodePtr->numberOfChildren - 1; fprintf(CFileFp, STRING_MALLOC_ARG_LIST_FMT, argumentNumber); for (i = 0; i < argumentNumber; i ++) { if (argListNodePtr->children[i] == NULL) { continue; } if (GenerateExpressionCode( classNodePtr, argListNodePtr->children[i], symbolTablePtr) == TRUE) { fprintf(CFileFp, STRING_SAVE_ARGUMENT_1_FMT, i, argListNodePtr->children[i]->info.lexeme); } else { fprintf(CFileFp, STRING_SAVE_ARGUMENT_2_FMT, i, addressVarID); } }}static void GenerateReturnCode( NodePtr classNodePtr, NodePtr expNodePtr, SymbolTablePtr symbolTablePtr){ int expAddressVarID; if (expNodePtr == NULL) { fprintf(CFileFp, STRING_RETURN); } else { if (GenerateExpressionCode(classNodePtr, expNodePtr, symbolTablePtr) == TRUE) { fprintf(CFileFp, STRING_RETURN_ADDR_FMT, addressVarID); GenerateAssignConstCode(addressVarID, expNodePtr->info.value); } else { expAddressVarID = addressVarID; GetNextAddressVarID(); fprintf(CFileFp, STRING_RETURN_ADDR_FMT, addressVarID); GenerateAssignVarCode(addressVarID, expAddressVarID); } }}static Boolean GenerateKeywordCode(NodePtr expNodePtr){ if (strcmp(expNodePtr->info.lexeme, STRING_THIS) == 0) { fprintf(CFileFp, STRING_THIS_OBJ_ADDR_FMT, addressVarID); return(FALSE); } else { free(expNodePtr->info.lexeme); expNodePtr->info.value = 0; return(TRUE); }}static void GenerateGetArrayLengthCode(){ int tmpAddressVarID; tmpAddressVarID = addressVarID; GetNextAddressVarID(); fprintf(CFileFp, STRING_TMP_VAR_FMT, addressVarID, addressVarID + 1); fprintf(CFileFp, STRING_ARRAY_LENGTH_P1_FMT, addressVarID, tmpAddressVarID); fprintf(CFileFp, STRING_ARRAY_LENGTH_P2_FMT, addressVarID, addressVarID, FIRST_CLASS_VAR_OFFSET); }static void GenerateCheckArrayLengthCode(idAddressVarID, addressVarID){ fprintf(CFileFp, SRTRING_CHECK_ARRAY_LEN_1_FMT, addressVarID); fprintf(CFileFp, SRTRING_CHECK_ARRAY_LEN_2_FMT, addressVarID, idAddressVarID);}static void GetNextAddressVarID(){ addressVarID = addressVarID % MAX_ADDRESS_VAR_NUMBER + 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -