📄 codegenerator.c
字号:
/**************************************************************************** * File name: codeGenerator.c * * Description: codeGeneratorfor decafc * * Input: none * * Output: none * * Author: Luojian Chen * * Date: April 26, 1997 * ****************************************************************************/#include "codeGenerator.h"extern NodePtr mainMethodDecNodePtr;extern NodePtr mainClassDecNodePtr;extern NodePtr ClassNodeOfType(ElementPtr);extern ElementPtr Lookup(SymbolTablePtr, String);extern Boolean IsArrayType(ElementPtr);extern FILE *CFileFp;extern FILE *HFileFp;extern String HFileName;void GenerateCode(NodePtr);static int addressVarID = 1;// static Boolean isNewExp = FALSE;static void GenerateHeaderAndGlobalVar();static void GenerateClassCode(NodePtr);static void GenerateMainFunctionCode();static void GenerateReallocHeapCode1(int);static void GenerateReallocHeapCode2(int);static void GenerateConstructorCode(NodePtr, NodePtr);static void GenerateMethodCode(NodePtr, NodePtr);static void GenerateBlockCode(NodePtr, NodePtr);static void GenerateVarDecListCode(NodePtr, int);static void GenerateStatementListCode( NodePtr, NodePtr, SymbolTablePtr);static void GenerateStatementCode(NodePtr, NodePtr, SymbolTablePtr);static void GenerateAssignmentStatementCode(NodePtr, NodePtr, SymbolTablePtr);static Boolean GenerateExpressionCode(NodePtr, NodePtr, SymbolTablePtr);static void GenerateReadExpCode(NodePtr, NodePtr, SymbolTablePtr);static void GenerateNewExpCode(NodePtr, NodePtr, SymbolTablePtr);static Boolean GenerateUnaryExpCode(NodePtr, NodePtr, SymbolTablePtr);static void GenerateBinaryExpCode(NodePtr, NodePtr, SymbolTablePtr);static void GenerateNameCode(NodePtr, NodePtr, Boolean, SymbolTablePtr);static void GenerateIdentifierCode(NodePtr, NodePtr, Boolean, SymbolTablePtr);static void GenerateArrayAccessCode(NodePtr, NodePtr, Boolean, SymbolTablePtr);static void GenerateCheckNullCode();static void GenerateThisObjectAddressCode();static void GenerateClassVarAddressCode(int);static void GenerateLocalVarAddressCode(int);static void GenerateAssignConstCode(int, int);static void GenerateAssignVarCode(int, int);static void GenerateFunctionCallCode(NodePtr, NodePtr, SymbolTablePtr);static void GenerateMethodCallCode(NodePtr, NodePtr, Boolean, SymbolTablePtr);static void GenerateIfCode(NodePtr, NodePtr, SymbolTablePtr);static void GenerateWhileCode(NodePtr, NodePtr, SymbolTablePtr);static void GeneratePrintCode(NodePtr, NodePtr, SymbolTablePtr);static void GenerateProtectEnvCode();static void GenerateNewEnvCode(NodePtr, NodePtr, SymbolTablePtr);static void GenerateCallCode(String, String);static void GenerateSaveReturnValueCode();static void GenerateRestoreEnvCode();static void GenerateGetReturnValueCode();static void GenerateMallocEnvCode(int);// static void GenerateParameterCode(int);static void GenerateArgListCode(NodePtr, NodePtr, SymbolTablePtr);static void GenerateReturnCode(NodePtr, NodePtr, SymbolTablePtr);static Boolean GenerateKeywordCode(NodePtr);static void GenerateGetArrayLengthCode();static void GenerateCheckArrayLengthCode(int, int);static void GetNextAddressVarID();void GenerateCode(NodePtr rootNodePtr){ int i; NodePtr classNodePtr = NULL; if (rootNodePtr == NULL) { return; } GenerateHeaderAndGlobalVar(); for (i = 0; i < rootNodePtr->children[0]->numberOfChildren; i ++) { classNodePtr = rootNodePtr->children[0]->children[i]; GenerateClassCode(classNodePtr); #ifdef DEBUG printf("In SemanticGenerate, symbol table for class %s:\n", classNodePtr->children[0]->info.lexeme); DisplaySymbolTable(classNodePtr->info.symbolTablePtr); #endif } GenerateMainFunctionCode();}static void GenerateHeaderAndGlobalVar(){ int i; fprintf(CFileFp, STRING_INCLUDE_STDIO_H); fprintf(CFileFp, STRING_INCLUDE_MALLOC_H); fprintf(CFileFp, STRING_INCLUDE_H_FILE_FMT, HFileName); fprintf(CFileFp, STRING_NEW_LINE); fprintf(CFileFp, STRING_STACK_DEC); fprintf(CFileFp, STRING_STACK_SIZE_DEC); fprintf(CFileFp, STRING_NEW_LINE); fprintf(CFileFp, STRING_HEAP_DEC); fprintf(CFileFp, STRING_HEAP_SIZE_DEC); fprintf(CFileFp, STRING_HEAP_TOP_DEC); fprintf(CFileFp, STRING_NEW_LINE); fprintf(CFileFp, STRING_ENV_DEC); fprintf(CFileFp, STRING_ENV_SIZE_DEC); fprintf(CFileFp, STRING_NEW_LINE); for (i = 1; i <= MAX_ADDRESS_VAR_NUMBER; i ++) { fprintf(CFileFp, STRING_ADDRESS_DEC_FMT, i); } fprintf(CFileFp, STRING_NEW_LINE); fprintf(CFileFp, STRING_THIS_OFFSET_DEC); fprintf(CFileFp, STRING_NEW_LINE); fprintf(CFileFp, STRING_RETURN_VALUE_DEC); fprintf(CFileFp, STRING_NEW_LINE); fprintf(CFileFp, STRING_ARG_LIST_DEC); fprintf(CFileFp, STRING_NEW_LINE); fprintf(CFileFp, STRING_TMP_DEC); fprintf(CFileFp, STRING_NEW_LINE); fprintf(CFileFp, STRING_NEW_LINE);}static void GenerateClassCode(NodePtr classNodePtr){ int i; NodePtr classBodyNodePtr = NULL; NodePtr methodDecNodePtr = NULL; if (classNodePtr == NULL) { return; } classBodyNodePtr = classNodePtr->children[1]; GenerateConstructorCode(classNodePtr, classBodyNodePtr->children[1]); if (classBodyNodePtr->children[2] != NULL) { for (i = 0; i < classBodyNodePtr->children[2]->numberOfChildren; i ++) { methodDecNodePtr = classBodyNodePtr->children[2]->children[i]; GenerateMethodCode(classNodePtr, methodDecNodePtr); } }}static void GenerateMainFunctionCode(){ NodePtr varDecListNodePtr = NULL; int classVarNumber; int i; varDecListNodePtr = mainClassDecNodePtr->children[1]->children[0]; fprintf(CFileFp, STRING_MAIN_FUNCTION); fprintf(CFileFp, STRING_LEFT_CURLY_BRACKET); fprintf(CFileFp, STRING_MALLOC_HEAP); fprintf(CFileFp, STRING_INIT_HEAP_SIZE); fprintf(CFileFp, STRING_INIT_HEAP_TOP); fprintf(CFileFp, STRING_INIT_ZERO_ADDRESS); fprintf(CFileFp, STRING_MALLOC_STACK); fprintf(CFileFp, STRING_INIT_STACK_SIZE); if (varDecListNodePtr == NULL) { classVarNumber = 0; } else { classVarNumber = varDecListNodePtr->numberOfChildren; } GenerateReallocHeapCode1(classVarNumber); /* fprintf(CFileFp, STRING_UPDATE_HEAP_SIZE_FMT, classVarNumber + FIRST_CLASS_VAR_OFFSET); fprintf(CFileFp, STRING_REALLOC_HEAP); fprintf(CFileFp, STRING_INIT_HEAP_TOP); fprintf(CFileFp, STRING_INIT_OBJ_SIZE_FMT, classVarNumber + FIRST_CLASS_VAR_OFFSET); fprintf(CFileFp, STRING_INIT_OBJ_REF_CNT); for (i = 0; i < classVarNumber; i ++) { fprintf(CFileFp, STRING_INIT_CLASS_VAR_FMT, i + FIRST_CLASS_VAR_OFFSET); } */ GenerateMallocEnvCode(0); fprintf(CFileFp, STRING_MAIN_FUNCTION_CALL_FMT, mainClassDecNodePtr->children[0]->info.lexeme); fprintf(CFileFp, STRING_RIGHT_CURLY_BRACKET);}static void GenerateReallocHeapCode1(int classVarNumber){ int i; // fprintf(CFileFp, STRING_SAVE_HEAP_TOP); fprintf(CFileFp, STRING_SAVE_HEAP_SIZE); fprintf(CFileFp, STRING_UPDATE_HEAP_SIZE_1_FMT, classVarNumber + FIRST_CLASS_VAR_OFFSET); fprintf(CFileFp, STRING_REALLOC_HEAP); fprintf(CFileFp, STRING_UPDATE_HEAP_TOP); fprintf(CFileFp, STRING_INIT_OBJ_SIZE_FMT, classVarNumber + FIRST_CLASS_VAR_OFFSET); fprintf(CFileFp, STRING_INIT_OBJ_REF_CNT); for (i = 0; i < classVarNumber; i ++) { fprintf(CFileFp, STRING_INIT_CLASS_VAR_FMT, i + FIRST_CLASS_VAR_OFFSET); }}static void GenerateReallocHeapCode2(int tmpAddressVarID){ int i; fprintf(CFileFp, STRING_SAVE_HEAP_SIZE); fprintf(CFileFp, STRING_UPDATE_HEAP_SIZE_2_FMT, tmpAddressVarID); fprintf(CFileFp, STRING_REALLOC_HEAP); fprintf(CFileFp, STRING_UPDATE_HEAP_TOP); fprintf(CFileFp, STRING_INIT_OBJ_SIZE_2_FMT, tmpAddressVarID); fprintf(CFileFp, STRING_INIT_OBJ_REF_CNT); fprintf(CFileFp, STRING_INIT_ARRAY_FMT, tmpAddressVarID);}static void GenerateConstructorCode(NodePtr classNodePtr, NodePtr constructorNodePtr){ String className = NULL; if (constructorNodePtr == NULL) { return; } className = classNodePtr->children[0]->info.lexeme; fprintf(CFileFp, STRING_FUNCTION_HEADER_FMT, className, className); fprintf(HFileFp, STRING_FUNCTION_PROTOTYPE_FMT, className, className); GenerateBlockCode(classNodePtr, constructorNodePtr->children[2]);}static void GenerateMethodCode(NodePtr classNodePtr, NodePtr methodDecNodePtr){ String className = NULL; if (methodDecNodePtr == NULL) { return; } className = classNodePtr->children[0]->info.lexeme; fprintf(CFileFp, STRING_FUNCTION_HEADER_FMT, className, methodDecNodePtr->children[1]->info.lexeme); fprintf(HFileFp, STRING_FUNCTION_PROTOTYPE_FMT, className, methodDecNodePtr->children[1]->info.lexeme); #ifdef DEBUG printf("In GenerateMethodCode(), symbol table is:\n"); DisplaySymbolTable(methodDecNodePtr->info.symbolTablePtr); #endif GenerateBlockCode(classNodePtr, methodDecNodePtr->children[3]);}static void GenerateBlockCode(NodePtr classNodePtr, NodePtr blockNodePtr){ NodePtr varDecListNodePtr = NULL; ElementPtr elementPtr = NULL; int firstVarOffset; if (blockNodePtr == NULL) { return; } #ifdef DEBUG printf("In GenerateBlockCode, symbol table for block:\n"); DisplaySymbolTable(blockNodePtr->info.symbolTablePtr); #endif fprintf(CFileFp, STRING_LEFT_CURLY_BRACKET); varDecListNodePtr = blockNodePtr->children[0]; if (varDecListNodePtr != NULL) { if (varDecListNodePtr->numberOfChildren > 1) { elementPtr = Lookup( blockNodePtr->info.symbolTablePtr, varDecListNodePtr->children[1]->children[1]->info.lexeme); firstVarOffset = elementPtr->offset; GenerateVarDecListCode(varDecListNodePtr, firstVarOffset); } }; GenerateStatementListCode(classNodePtr, blockNodePtr->children[1], blockNodePtr->info.symbolTablePtr); fprintf(CFileFp, STRING_RIGHT_CURLY_BRACKET);}static void GenerateVarDecListCode(NodePtr varDecListNodePtr, int firstVarOffset){ int localVarNumber; int i; if (varDecListNodePtr == NULL) { localVarNumber = 0; } else { localVarNumber = varDecListNodePtr->numberOfChildren - 1; } #ifdef DEBUG printf("localVarNumber is %d\n", localVarNumber); #endif if (localVarNumber > 0) { fprintf(CFileFp, STRING_UPDATE_ENV_SIZE_FMT, localVarNumber); fprintf(CFileFp, STRING_MALLOC_VAR_FMT, localVarNumber); } for (i = 0; i < localVarNumber; i ++) { fprintf(CFileFp, STRING_INIT_LOCAL_VAR_FMT, firstVarOffset + i); }}static void GenerateStatementListCode( NodePtr classNodePtr, NodePtr stmtListNodePtr, SymbolTablePtr symbolTablePtr){ int i; NodePtr statementNodePtr = NULL; if (stmtListNodePtr == NULL) { return; } for (i = 0; i < stmtListNodePtr->numberOfChildren; i ++) { statementNodePtr = stmtListNodePtr->children[i]; GenerateStatementCode(classNodePtr, statementNodePtr, symbolTablePtr); }}static void GenerateStatementCode(NodePtr classNodePtr, NodePtr statementNodePtr, SymbolTablePtr symbolTablePtr){ NodePtr argListNodePtr = NULL; int i; int id; if (statementNodePtr == NULL) { return; } switch (statementNodePtr->type) { case NODE_TYPE_ASGN_STMT: GenerateAssignmentStatementCode( classNodePtr, statementNodePtr, symbolTablePtr); break; case NODE_TYPE_FUNC_STMT: GenerateFunctionCallCode( classNodePtr, statementNodePtr, symbolTablePtr); break; case NODE_TYPE_PRINT_STMT: argListNodePtr = statementNodePtr->children[0]; GeneratePrintCode(classNodePtr, argListNodePtr, symbolTablePtr); break; case NODE_TYPE_IF_STMT: GenerateIfCode(classNodePtr, statementNodePtr, symbolTablePtr); break; case NODE_TYPE_WHILE_STMT: GenerateWhileCode( classNodePtr, statementNodePtr, symbolTablePtr); break; case NODE_TYPE_RETURN_STMT: GenerateReturnCode(classNodePtr, statementNodePtr->children[0], symbolTablePtr); break; case NODE_TYPE_BLOCK_STMT: GenerateBlockCode(classNodePtr, statementNodePtr); break; default: break; }}static void GenerateAssignmentStatementCode( NodePtr classNodePtr, NodePtr statementNodePtr, SymbolTablePtr symbolTablePtr){ NodePtr nameNodePtr = NULL; NodePtr expNodePtr = NULL; int expAddressVarID; if (statementNodePtr == NULL) { return; } nameNodePtr = statementNodePtr->children[0]; // needLValue = TRUE; expNodePtr = statementNodePtr->children[1]; if (GenerateExpressionCode(classNodePtr, expNodePtr, symbolTablePtr) == TRUE) { GenerateNameCode(classNodePtr, nameNodePtr, TRUE, symbolTablePtr); GenerateAssignConstCode(addressVarID, expNodePtr->info.value); } else { expAddressVarID = addressVarID; GetNextAddressVarID(); GenerateNameCode(classNodePtr, nameNodePtr,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -