diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/ast-tree.c | 104 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 22 | ||||
-rw-r--r-- | src/compiler/code-generator.c | 90 | ||||
-rw-r--r-- | src/compiler/code-generator.h | 8 | ||||
-rw-r--r-- | src/compiler/parser.c | 67 | ||||
-rw-r--r-- | src/compiler/parser.h | 9 | ||||
-rw-r--r-- | src/main.c | 141 | ||||
-rw-r--r-- | src/utils/log.h | 2 |
8 files changed, 382 insertions, 61 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index 8043561..c38a4b8 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -6,7 +6,7 @@ #include <stdlib.h> #include <string.h> -static const AstTree AST_TREE_U64_TYPE = { +const AstTree AST_TREE_U64_TYPE = { .token = AST_TREE_TOKEN_TYPE_U64, .metadata = NULL, }; @@ -26,6 +26,8 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_VARIABLE_DEFINE", "AST_TREE_TOKEN_VALUE_U64", + "AST_TREE_TOKEN_OPERATOR_ASSIGN", + "AST_TREE_TOKEN_NONE", }; @@ -132,6 +134,34 @@ void astTreePrint(const AstTree *tree, int indent) { metadata->name_begin); } goto RETURN_SUCCESS; + case AST_TREE_TOKEN_OPERATOR_ASSIGN: { + AstTreeInfix *metadata = tree->metadata; + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("left=\n"); + astTreePrint(&metadata->left, indent + 1); + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("right=\n"); + astTreePrint(&metadata->right, indent + 1); + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("leftType=\n"); + astTreePrint(&metadata->leftType, indent + 1); + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("rightType=\n"); + astTreePrint(&metadata->rightType, indent + 1); + printf("\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + } + goto RETURN_SUCCESS; + case AST_TREE_TOKEN_NONE: } @@ -208,6 +238,15 @@ void astTreeDestroy(AstTree tree) { // AstTreeIdentifier *metadata = tree.metadata; // not needed } return; + case AST_TREE_TOKEN_OPERATOR_ASSIGN: { + AstTreeInfix *metadata = tree.metadata; + astTreeDestroy(metadata->left); + astTreeDestroy(metadata->right); + astTreeDestroy(metadata->leftType); + astTreeDestroy(metadata->rightType); + free(metadata); + } + return; case AST_TREE_TOKEN_NONE: } printLog("Bad token '%d'", tree.token); @@ -347,6 +386,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { case PARSER_TOKEN_SYMBOL_PARENTHESIS: case PARSER_TOKEN_SYMBOL_COMMA: case PARSER_TOKEN_FUNCTION_CALL: + case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_NONE: printLog("Should not be here"); goto RETURN_ERROR; @@ -460,6 +500,8 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables **variables, (void *)(AstTreeU64)(ParserNodeU64Metadata)parserNode->metadata); case PARSER_TOKEN_KEYWORD_PRINT_U64: return astTreeParsePrintU64(parserNode, variables, variables_size); + case PARSER_TOKEN_OPERATOR_ASSIGN: + return astTreeParseAssign(parserNode, variables, variables_size); case PARSER_TOKEN_VARIABLE: case PARSER_TOKEN_CONSTANT: case PARSER_TOKEN_SYMBOL_EOL: @@ -694,6 +736,32 @@ AstTree *astTreeParsePrintU64(ParserNode *parserNode, (AstTreeSingleChild *)operand); } +AstTree *astTreeParseAssign(ParserNode *parserNode, + AstTreeVariables **variables, + size_t variables_size) { + ParserNodeInfixMetadata *node_metadata = parserNode->metadata; + + AstTree *left = astTreeParse(node_metadata->left, variables, variables_size); + if (left == NULL) { + return NULL; + } + AstTree *right = + astTreeParse(node_metadata->right, variables, variables_size); + if (right == NULL) { + return NULL; + } + + AstTreeInfix *metadata = a404m_malloc(sizeof(*metadata)); + + metadata->left = *left; + metadata->right = *right; + + free(left); + free(right); + + return newAstTree(AST_TREE_TOKEN_OPERATOR_ASSIGN, metadata); +} + bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables, size_t variables_size) { ParserNodeVariableMetadata *node_metadata = parserNode->metadata; @@ -800,7 +868,7 @@ bool hasTypeOf(AstTree *value, const AstTree *type) { case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VARIABLE: case AST_TREE_TOKEN_VALUE_U64: - case AST_TREE_TOKEN_VARIABLE_DEFINE: + case AST_TREE_TOKEN_VARIABLE_DEFINE: return false; case AST_TREE_TOKEN_NONE: } @@ -829,7 +897,7 @@ bool hasTypeOf(AstTree *value, const AstTree *type) { case AST_TREE_TOKEN_TYPE_U64: case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VARIABLE: - case AST_TREE_TOKEN_VARIABLE_DEFINE: + case AST_TREE_TOKEN_VARIABLE_DEFINE: return false; case AST_TREE_TOKEN_NONE: } @@ -1006,6 +1074,8 @@ bool setAllTypes(AstTree *tree) { return setTypesFunctionCall(tree); case AST_TREE_TOKEN_VARIABLE: return setTypesVariable(tree); + case AST_TREE_TOKEN_OPERATOR_ASSIGN: + return setTypesOperatorAssign(tree); case AST_TREE_TOKEN_NONE: } printLog("Bad token '%d'", tree->token); @@ -1096,6 +1166,10 @@ bool setTypesVariable(AstTree *tree) { return setTypesAstVariable(metadata); } +bool setTypesOperatorAssign(AstTree *tree) { + return setTypesAstInfix(tree->metadata); +} + bool setTypesAstVariable(AstTreeVariable *variable) { if (!setAllTypes(variable->value)) { return false; @@ -1115,6 +1189,29 @@ bool setTypesAstVariable(AstTreeVariable *variable) { } } +bool setTypesAstInfix(AstTreeInfix *infix) { + if (!setAllTypes(&infix->left) || !setAllTypes(&infix->right)) { + printLog("Type mismatch"); + return false; + } + + AstTree *lType = makeTypeOf(&infix->left); + AstTree *rType = makeTypeOf(&infix->right); + + if (!typeIsEqual(lType, rType)) { + printLog("Type mismatch"); + return false; + } + + infix->leftType = *lType; + infix->rightType = *rType; + + free(lType); + free(rType); + + return true; +} + bool astTreeCleanRoot(AstTreeRoot *root) { for (size_t i = 0; i < root->variables.size; ++i) { astTreeClean(root->variables.data[i]->value); @@ -1137,6 +1234,7 @@ bool astTreeClean(AstTree *tree) { case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VALUE_U64: case AST_TREE_TOKEN_VARIABLE_DEFINE: + case AST_TREE_TOKEN_OPERATOR_ASSIGN: return true; case AST_TREE_TOKEN_NONE: } diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index 90133a5..2e43973 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -19,15 +19,21 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_VARIABLE_DEFINE, AST_TREE_TOKEN_VALUE_U64, + AST_TREE_TOKEN_OPERATOR_ASSIGN, + AST_TREE_TOKEN_NONE, } AstTreeToken; +extern const char *AST_TREE_TOKEN_STRINGS[]; + typedef struct AstTree { AstTreeToken token; - void *metadata; bool typeChecked; + void *metadata; } AstTree; +extern const AstTree AST_TREE_U64_TYPE; + typedef struct AstTreeVariable { char *name_begin; char *name_end; @@ -73,7 +79,12 @@ typedef uint64_t AstTreeU64; typedef AstTree AstTreeSingleChild; -extern const char *AST_TREE_TOKEN_STRINGS[]; +typedef struct AstTreeInfix { + AstTree left; + AstTree right; + AstTree leftType; + AstTree rightType; +} AstTreeInfix; void astTreePrint(const AstTree *tree, int indent); void astTreeRootPrint(const AstTreeRoot *root); @@ -117,6 +128,10 @@ AstTree *astTreeParsePrintU64(ParserNode *parserNode, AstTreeVariables **variables, size_t variables_size); +AstTree *astTreeParseAssign(ParserNode *parserNode, + AstTreeVariables **variables, + size_t variables_size); + bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables, size_t variables_size); @@ -137,7 +152,10 @@ bool setTypesPrintU64(AstTree *tree); bool setTypesTypeFunction(AstTree *tree); bool setTypesFunctionCall(AstTree *tree); bool setTypesVariable(AstTree *tree); +bool setTypesOperatorAssign(AstTree *tree); + bool setTypesAstVariable(AstTreeVariable *variable); +bool setTypesAstInfix(AstTreeInfix *infix); bool astTreeCleanRoot(AstTreeRoot *root); bool astTreeClean(AstTree *tree); diff --git a/src/compiler/code-generator.c b/src/compiler/code-generator.c index b52c5d3..4ddfe94 100644 --- a/src/compiler/code-generator.c +++ b/src/compiler/code-generator.c @@ -25,6 +25,13 @@ void codeGeneratorDelete(CodeGeneratorCodes *code) { free(metadata); } continue; + case CODE_GENERATOR_INSTRUCTION_MOV_U64: { + CodeGeneratorDoubleOperand *metadata = current.metadata; + free(metadata->op0.value); + free(metadata->op1.value); + free(metadata); + } + continue; } printLog("Bad instruction %d", current.instruction); exit(1); @@ -42,6 +49,43 @@ CodeGeneratorOperand *newCodeGeneratorOperand(char *value, bool isReference) { return result; } +CodeGeneratorOperand *makeCodeGeneratorOperand(AstTree tree) { + switch (tree.token) { + case AST_TREE_TOKEN_VALUE_U64: + return newCodeGeneratorOperand(u64ToString((AstTreeU64)tree.metadata), + false); + case AST_TREE_TOKEN_VARIABLE: { + AstTreeVariable *variable = tree.metadata; + if (!typeIsEqual(variable->type, &AST_TREE_U64_TYPE)) { + UNREACHABLE; + } + if (variable->isConst) { + return newCodeGeneratorOperand( + u64ToString((AstTreeU64)variable->value->metadata), false); + } else { + char *name = a404m_malloc( + (variable->name_end - variable->name_begin + 1) * sizeof(*name)); + strncpy(name, variable->name_begin, + variable->name_end - variable->name_begin); + name[variable->name_end - variable->name_begin] = '\0'; + + return newCodeGeneratorOperand(name, true); + } + } + case AST_TREE_TOKEN_FUNCTION: + case AST_TREE_TOKEN_KEYWORD_PRINT_U64: + case AST_TREE_TOKEN_TYPE_TYPE: + case AST_TREE_TOKEN_TYPE_FUNCTION: + case AST_TREE_TOKEN_TYPE_VOID: + case AST_TREE_TOKEN_TYPE_U64: + case AST_TREE_TOKEN_FUNCTION_CALL: + case AST_TREE_TOKEN_VARIABLE_DEFINE: + case AST_TREE_TOKEN_OPERATOR_ASSIGN: + case AST_TREE_TOKEN_NONE: + } + UNREACHABLE; +} + CodeGeneratorCode createGenerateCode(char *label_begin, char *label_end, CodeGeneratorInstruction instruction, void *metadata) { @@ -183,6 +227,31 @@ bool codeGeneratorAstTreeFunction(char *label_begin, char *label_end, } } goto OK; + case AST_TREE_TOKEN_OPERATOR_ASSIGN: { + AstTreeInfix *infix = tree.metadata; + + if (infix->left.token != AST_TREE_TOKEN_VARIABLE) { + printLog("Not implemented yet"); + exit(1); + } else if (infix->leftType.token != AST_TREE_TOKEN_TYPE_U64) { + printLog("Not implemented yet"); + exit(1); + } + + CodeGeneratorDoubleOperand *operands = a404m_malloc(sizeof(*operands)); + CodeGeneratorOperand *op0 = makeCodeGeneratorOperand(infix->left); + CodeGeneratorOperand *op1 = makeCodeGeneratorOperand(infix->right); + operands->op0 = *op0; + operands->op1 = *op1; + free(op0); + free(op1); + + generateCodePushCode( + codes, + createGenerateCode(label_begin, label_end, + CODE_GENERATOR_INSTRUCTION_MOV_U64, operands)); + } + goto OK; case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_VALUE_U64: case AST_TREE_TOKEN_VARIABLE: @@ -288,6 +357,27 @@ char *codeGeneratorToFlatASM(const CodeGeneratorCodes *codes) { free(inst); } continue; + case CODE_GENERATOR_INSTRUCTION_MOV_U64: { + CodeGeneratorDoubleOperand *metadata = code.metadata; + char *inst; + if (metadata->op1.isReference) { + asprintf(&inst, "mov rax, [%s]\n", metadata->op1.value); + } else { + asprintf(&inst, "mov rax, %s\n", metadata->op1.value); + } + codeGeneratorAppendFlatASMCommand(&fasm, &fasm_size, &fasm_inserted, inst, + strlen(inst)); + free(inst); + if (metadata->op0.isReference) { + asprintf(&inst, "mov [%s], rax\n", metadata->op0.value); + } else { + UNREACHABLE; + } + codeGeneratorAppendFlatASMCommand(&fasm, &fasm_size, &fasm_inserted, inst, + strlen(inst)); + free(inst); + } + continue; } printLog("Bad instruction %d", code.instruction); } diff --git a/src/compiler/code-generator.h b/src/compiler/code-generator.h index a9c6490..ac47e76 100644 --- a/src/compiler/code-generator.h +++ b/src/compiler/code-generator.h @@ -9,6 +9,7 @@ typedef enum CodeGeneratorInstruction : uint8_t { CODE_GENERATOR_INSTRUCTION_CALL, CODE_GENERATOR_INSTRUCTION_RET, CODE_GENERATOR_INSTRUCTION_DEF_VAR64, + CODE_GENERATOR_INSTRUCTION_MOV_U64, } CodeGeneratorInstruction; typedef struct CodeGeneratorCode { @@ -28,6 +29,11 @@ typedef struct CodeGeneratorOperand { bool isReference; } CodeGeneratorOperand; +typedef struct CodeGeneratorDoubleOperand { + CodeGeneratorOperand op0; + CodeGeneratorOperand op1; +} CodeGeneratorDoubleOperand; + typedef struct CodeGeneratorCodes { CodeGeneratorCode *codes; size_t codes_size; @@ -37,6 +43,8 @@ void codeGeneratorDelete(CodeGeneratorCodes *code); CodeGeneratorOperand *newCodeGeneratorOperand(char *value, bool isReference); +CodeGeneratorOperand *makeCodeGeneratorOperand(AstTree tree); + CodeGeneratorCode createGenerateCode(char *label_begin, char *label_end, CodeGeneratorInstruction instruction, void *metadata); diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 2bdac64..7a9e0e3 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -30,6 +30,8 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_SYMBOL_PARENTHESIS", "PARSER_TOKEN_SYMBOL_COMMA", + "PARSER_TOKEN_OPERATOR_ASSIGN", + "PARSER_TOKEN_FUNCTION_DEFINITION", "PARSER_TOKEN_FUNCTION_CALL", @@ -62,6 +64,10 @@ static constexpr ParserOrder PARSER_ORDER[] = { ORDER_ARRAY(LEXER_TOKEN_SYMBOL_COLON, LEXER_TOKEN_KEYWORD_PRINT_U64, ), }, { + .ltr = false, + ORDER_ARRAY(LEXER_TOKEN_SYMBOL_ASSIGN, ), + }, + { .ltr = true, ORDER_ARRAY(LEXER_TOKEN_SYMBOL_EOL, LEXER_TOKEN_SYMBOL_COMMA, ), }, @@ -202,6 +208,23 @@ void parserNodePrint(const ParserNode *node, int indent) { printf(" "); } goto RETURN_SUCCESS; + case PARSER_TOKEN_OPERATOR_ASSIGN: { + const ParserNodeInfixMetadata *metadata = node->metadata; + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("left=\n"); + parserNodePrint(metadata->left, indent + 1); + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("right=\n"); + parserNodePrint(metadata->right, indent + 1); + printf("\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + } + goto RETURN_SUCCESS; case PARSER_TOKEN_NONE: } printLog("Bad token '%d'", node->token); @@ -275,6 +298,12 @@ void parserNodeDelete(ParserNode *node) { free(metadata); } goto RETURN_SUCCESS; + case PARSER_TOKEN_OPERATOR_ASSIGN: { + ParserNodeInfixMetadata *metadata = node->metadata; + parserNodeDelete(metadata->left); + parserNodeDelete(metadata->right); + } + goto RETURN_SUCCESS; case PARSER_TOKEN_NONE: } @@ -403,11 +432,12 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, return parserComma(node, begin, parent); case LEXER_TOKEN_NUMBER: return parserNumber(node, parent); - case LEXER_TOKEN_NONE: + case LEXER_TOKEN_SYMBOL_ASSIGN: + return parserAssign(node, begin, end, parent); case LEXER_TOKEN_SYMBOL: case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS: case LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET: - case LEXER_TOKEN_SYMBOL_ASSIGN: + case LEXER_TOKEN_NONE: } printLog("Bad token '%d'", node->token); return NULL; @@ -790,6 +820,36 @@ RETURN_ERROR: return NULL; } +ParserNode *parserAssign(LexerNode *node, LexerNode *begin, LexerNode *end, + ParserNode *parent) { + LexerNode *leftNode = node - 1; + LexerNode *rightNode = node + 1; + + if (leftNode < begin || rightNode >= end) { + printLog("Bad assign"); + return NULL; + } + + ParserNode *left = getUntilCommonParent(leftNode->parserNode, parent); + ParserNode *right = getUntilCommonParent(rightNode->parserNode, parent); + + if (left == NULL || right == NULL) { + printLog("Bad assign"); + return NULL; + } + + ParserNodeInfixMetadata *metadata = a404m_malloc(sizeof(*metadata)); + metadata->left = left; + metadata->right = right; + + return left->parent = right->parent = node->parserNode = + newParserNode(PARSER_TOKEN_OPERATOR_ASSIGN, left->str_begin, + right->str_end, metadata, parent); + + printLog("Not implemented"); + return NULL; +} + bool isAllArguments(const ParserNodeArray *nodes) { for (size_t i = 0; i < nodes->size; ++i) { const ParserNode *node = nodes->data[i]; @@ -809,6 +869,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_FUNCTION_DEFINITION: case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_KEYWORD_PRINT_U64: + case PARSER_TOKEN_OPERATOR_ASSIGN: return true; case PARSER_TOKEN_ROOT: case PARSER_TOKEN_TYPE_TYPE: @@ -845,6 +906,7 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_VALUE_U64: case PARSER_TOKEN_KEYWORD_PRINT_U64: + case PARSER_TOKEN_OPERATOR_ASSIGN: return false; case PARSER_TOKEN_NONE: } @@ -858,6 +920,7 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_VALUE_U64: case PARSER_TOKEN_IDENTIFIER: + case PARSER_TOKEN_OPERATOR_ASSIGN: return true; case PARSER_TOKEN_TYPE_FUNCTION: case PARSER_TOKEN_TYPE_TYPE: diff --git a/src/compiler/parser.h b/src/compiler/parser.h index c20fc12..ea53042 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -26,6 +26,8 @@ typedef enum ParserToken { PARSER_TOKEN_SYMBOL_PARENTHESIS, PARSER_TOKEN_SYMBOL_COMMA, + PARSER_TOKEN_OPERATOR_ASSIGN, + PARSER_TOKEN_FUNCTION_DEFINITION, PARSER_TOKEN_FUNCTION_CALL, @@ -80,6 +82,11 @@ typedef ParserNode ParserNodeSingleChildMetadata; typedef uint64_t ParserNodeU64Metadata; +typedef struct ParserNodeInfixMetadata { + ParserNode *left; + ParserNode *right; +} ParserNodeInfixMetadata; + void parserNodePrint(const ParserNode *node, int indent); void parserNodeDelete(ParserNode *node); @@ -110,6 +117,8 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, ParserNode *parent); ParserNode *parserVariable(LexerNode *node, LexerNode *begin, LexerNode *end, ParserNode *parent); +ParserNode *parserAssign(LexerNode *node, LexerNode *begin, LexerNode *end, + ParserNode *parent); bool isAllArguments(const ParserNodeArray *nodes); @@ -8,67 +8,100 @@ #include <stdlib.h> static int runWithPrint(const char *filePath, const char *outFilePath) { - int ret = 1; char *code = readWholeFile(filePath); - if (code != NULL) { - LexerNodeArray lexed = lexer(code); - if (!lexerNodeArrayIsError(lexed)) { - lexerNodeArrayPrint(lexed); - ParserNode *parsedRoot = parser(lexed); - if (parsedRoot != NULL) { - parserNodePrint(parsedRoot, 0); - AstTreeRoot *astTree = makeAstTree(parsedRoot); - if (astTree != NULL) { - astTreeRootPrint(astTree); - CodeGeneratorCodes *codes = codeGenerator(astTree); - if (codes != NULL) { - char *fasm = codeGeneratorToFlatASM(codes); - printf("%s", fasm); - if (codeGeneratorFlatASMExec(outFilePath, fasm)) { - ret = system(outFilePath); - } - free(fasm); - codeGeneratorDelete(codes); - } - astTreeRootDelete(astTree); - } - parserNodeDelete(parsedRoot); - } - lexerNodeArrayDestroy(lexed); - } - free(code); + + if (code == NULL) { + return 1; + } + + LexerNodeArray lexed = lexer(code); + if (lexerNodeArrayIsError(lexed)) { + goto RETURN_ERROR; + } + lexerNodeArrayPrint(lexed); + + ParserNode *parsedRoot = parser(lexed); + lexerNodeArrayDestroy(lexed); + if (parsedRoot == NULL) { + goto RETURN_ERROR; + } + parserNodePrint(parsedRoot, 0); + + AstTreeRoot *astTree = makeAstTree(parsedRoot); + parserNodeDelete(parsedRoot); + if (astTree == NULL) { + goto RETURN_ERROR; } - return ret; + astTreeRootPrint(astTree); + + CodeGeneratorCodes *codes = codeGenerator(astTree); + astTreeRootDelete(astTree); + if (codes == NULL) { + goto RETURN_ERROR; + } + + char *fasm = codeGeneratorToFlatASM(codes); + codeGeneratorDelete(codes); + free(code); + + printf("%s", fasm); + + if (codeGeneratorFlatASMExec(outFilePath, fasm)) { + free(fasm); + return system(outFilePath); + } + + return 1; + +RETURN_ERROR: + free(code); + return 1; } static int run(const char *filePath, const char *outFilePath) { - int ret = 1; char *code = readWholeFile(filePath); - if (code != NULL) { - LexerNodeArray lexed = lexer(code); - if (!lexerNodeArrayIsError(lexed)) { - ParserNode *parsedRoot = parser(lexed); - if (parsedRoot != NULL) { - AstTreeRoot *astTree = makeAstTree(parsedRoot); - if (astTree != NULL) { - CodeGeneratorCodes *codes = codeGenerator(astTree); - if (codes != NULL) { - char *fasm = codeGeneratorToFlatASM(codes); - if (codeGeneratorFlatASMExec(outFilePath, fasm)) { - ret = system(outFilePath); - } - free(fasm); - codeGeneratorDelete(codes); - } - astTreeRootDelete(astTree); - } - parserNodeDelete(parsedRoot); - } - lexerNodeArrayDestroy(lexed); - } - free(code); + + if (code == NULL) { + return 1; + } + + LexerNodeArray lexed = lexer(code); + if (lexerNodeArrayIsError(lexed)) { + goto RETURN_ERROR; + } + + ParserNode *parsedRoot = parser(lexed); + lexerNodeArrayDestroy(lexed); + if (parsedRoot == NULL) { + goto RETURN_ERROR; + } + + AstTreeRoot *astTree = makeAstTree(parsedRoot); + parserNodeDelete(parsedRoot); + if (astTree == NULL) { + goto RETURN_ERROR; } - return ret; + + CodeGeneratorCodes *codes = codeGenerator(astTree); + astTreeRootDelete(astTree); + if (codes == NULL) { + goto RETURN_ERROR; + } + + char *fasm = codeGeneratorToFlatASM(codes); + codeGeneratorDelete(codes); + free(code); + + if (codeGeneratorFlatASMExec(outFilePath, fasm)) { + free(fasm); + return system(outFilePath); + } + + return 1; + +RETURN_ERROR: + free(code); + return 1; } int main(int argc, char *argv[]) { diff --git a/src/utils/log.h b/src/utils/log.h index 32f6a8f..620b2a3 100644 --- a/src/utils/log.h +++ b/src/utils/log.h @@ -2,4 +2,6 @@ #define printLog(format,...) _printLogBack(format, __FILE_NAME__, __LINE__, ## __VA_ARGS__) +#define UNREACHABLE printLog("Unreachable");exit(1) + extern void _printLogBack(const char *format, const char *file, int line, ...); |