diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/ast-tree.c | 337 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 19 | ||||
-rw-r--r-- | src/compiler/code-generator.c | 30 | ||||
-rw-r--r-- | src/compiler/code-generator.h | 1 | ||||
-rw-r--r-- | src/compiler/lexer.c | 7 | ||||
-rw-r--r-- | src/compiler/lexer.h | 2 | ||||
-rw-r--r-- | src/compiler/parser.c | 44 | ||||
-rw-r--r-- | src/compiler/parser.h | 3 | ||||
-rw-r--r-- | src/main.c | 54 | ||||
-rw-r--r-- | src/runner/runner.c | 143 | ||||
-rw-r--r-- | src/runner/runner.h | 11 | ||||
-rw-r--r-- | src/utils/log.h | 2 |
12 files changed, 453 insertions, 200 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index 7bb9f8f..7f955ff 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -6,9 +6,28 @@ #include <stdlib.h> #include <string.h> -const AstTree AST_TREE_U64_TYPE = { +AstTree AST_TREE_TYPE_TYPE = { + .token = AST_TREE_TOKEN_TYPE_TYPE, + .metadata = NULL, + .type = &AST_TREE_TYPE_TYPE, +}; + +AstTree AST_TREE_VOID_TYPE = { + .token = AST_TREE_TOKEN_TYPE_VOID, + .metadata = NULL, + .type = &AST_TREE_TYPE_TYPE, +}; + +AstTree AST_TREE_U64_TYPE = { .token = AST_TREE_TOKEN_TYPE_U64, .metadata = NULL, + .type = &AST_TREE_TYPE_TYPE, +}; + +AstTree AST_TREE_VOID_VALUE = { + .token = AST_TREE_TOKEN_NONE, + .metadata = NULL, + .type = &AST_TREE_VOID_TYPE, }; const char *AST_TREE_TOKEN_STRINGS[] = { @@ -27,6 +46,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_VALUE_U64", "AST_TREE_TOKEN_OPERATOR_ASSIGN", + "AST_TREE_TOKEN_OPERATOR_SUM", "AST_TREE_TOKEN_NONE", }; @@ -134,6 +154,7 @@ void astTreePrint(const AstTree *tree, int indent) { metadata->name_begin); } goto RETURN_SUCCESS; + case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_OPERATOR_ASSIGN: { AstTreeInfix *metadata = tree->metadata; printf(",\n"); @@ -146,16 +167,6 @@ void astTreePrint(const AstTree *tree, int indent) { 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(" "); @@ -184,6 +195,15 @@ void astTreeRootPrint(const AstTreeRoot *root) { } void astTreeDestroy(AstTree tree) { + if (tree.type != &AST_TREE_TYPE_TYPE && tree.type != &AST_TREE_VOID_TYPE && + tree.type != &AST_TREE_U64_TYPE) { + if (tree.type == NULL) { + printLog("token = %s %p %p", AST_TREE_TOKEN_STRINGS[tree.token], + tree.metadata, tree.type); + return; + } + astTreeDelete(tree.type); + } switch (tree.token) { case AST_TREE_TOKEN_FUNCTION: { AstTreeFunction *metadata = tree.metadata; @@ -238,12 +258,11 @@ void astTreeDestroy(AstTree tree) { // AstTreeIdentifier *metadata = tree.metadata; // not needed } return; + case AST_TREE_TOKEN_OPERATOR_SUM: 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; @@ -281,28 +300,40 @@ void astTreeRootDelete(AstTreeRoot *root) { free(root); } -AstTree *newAstTree(AstTreeToken token, void *metadata) { +AstTree *newAstTree(AstTreeToken token, void *metadata, AstTree *type) { AstTree *result = a404m_malloc(sizeof(*result)); result->token = token; result->metadata = metadata; - result->typeChecked = false; + result->type = type; return result; } AstTree *copyAstTree(AstTree *tree) { switch (tree->token) { case AST_TREE_TOKEN_TYPE_TYPE: + return &AST_TREE_TYPE_TYPE; case AST_TREE_TOKEN_TYPE_VOID: + return &AST_TREE_VOID_TYPE; case AST_TREE_TOKEN_TYPE_U64: - return newAstTree(tree->token, NULL); + return &AST_TREE_U64_TYPE; case AST_TREE_TOKEN_VALUE_U64: - return newAstTree(tree->token, (void *)(AstTreeU64)tree->metadata); + return newAstTree(tree->token, (void *)(AstTreeU64)tree->metadata, + &AST_TREE_U64_TYPE); case AST_TREE_TOKEN_VARIABLE: - return newAstTree(tree->token, tree->metadata); + return newAstTree(tree->token, tree->metadata, copyAstTree(tree->type)); + case AST_TREE_TOKEN_TYPE_FUNCTION: { + AstTreeTypeFunction *metadata = tree->metadata; + AstTreeTypeFunction *new_metadata = a404m_malloc(sizeof(*new_metadata)); + new_metadata->returnType = copyAstTree(metadata->returnType); + if (metadata->arguments_size != 0) { + UNREACHABLE; + } + return newAstTree(tree->token, new_metadata, copyAstTree(tree->type)); + } case AST_TREE_TOKEN_OPERATOR_ASSIGN: + case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: - case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_NONE: @@ -387,6 +418,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { case PARSER_TOKEN_SYMBOL_COMMA: case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_OPERATOR_ASSIGN: + case PARSER_TOKEN_OPERATOR_SUM: case PARSER_TOKEN_NONE: printLog("Should not be here"); goto RETURN_ERROR; @@ -408,11 +440,6 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { if (type == NULL) { goto RETURN_ERROR; } - - if (!hasTypeOf(value, type)) { - printLog("Type mismatch"); - goto RETURN_ERROR; - } } else { type = NULL; } @@ -483,13 +510,13 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables **variables, case PARSER_TOKEN_FUNCTION_DEFINITION: return astTreeParseFunction(parserNode, variables, variables_size); case PARSER_TOKEN_TYPE_TYPE: - return newAstTree(AST_TREE_TOKEN_TYPE_TYPE, NULL); + return &AST_TREE_TYPE_TYPE; case PARSER_TOKEN_TYPE_FUNCTION: return astTreeParseTypeFunction(parserNode, variables, variables_size); case PARSER_TOKEN_TYPE_VOID: - return newAstTree(AST_TREE_TOKEN_TYPE_VOID, NULL); + return &AST_TREE_VOID_TYPE; case PARSER_TOKEN_TYPE_U64: - return newAstTree(AST_TREE_TOKEN_TYPE_U64, NULL); + return &AST_TREE_U64_TYPE; case PARSER_TOKEN_FUNCTION_CALL: return astTreeParseFunctionCall(parserNode, variables, variables_size); case PARSER_TOKEN_IDENTIFIER: @@ -497,11 +524,14 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables **variables, case PARSER_TOKEN_VALUE_U64: return newAstTree( AST_TREE_TOKEN_VALUE_U64, - (void *)(AstTreeU64)(ParserNodeU64Metadata)parserNode->metadata); + (void *)(AstTreeU64)(ParserNodeU64Metadata)parserNode->metadata, + &AST_TREE_U64_TYPE); 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_OPERATOR_SUM: + return astTreeParseSum(parserNode, variables, variables_size); case PARSER_TOKEN_VARIABLE: case PARSER_TOKEN_CONSTANT: case PARSER_TOKEN_SYMBOL_EOL: @@ -611,7 +641,7 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, function->scope = scope; - AstTree *result = newAstTree(AST_TREE_TOKEN_FUNCTION, function); + AstTree *result = newAstTree(AST_TREE_TOKEN_FUNCTION, function, NULL); return result; @@ -663,7 +693,8 @@ AstTree *astTreeParseTypeFunction(ParserNode *parserNode, goto RETURN_ERROR; } - return newAstTree(AST_TREE_TOKEN_TYPE_FUNCTION, typeFunction); + return newAstTree(AST_TREE_TOKEN_TYPE_FUNCTION, typeFunction, + &AST_TREE_TYPE_TYPE); RETURN_ERROR: return NULL; @@ -693,15 +724,9 @@ AstTree *astTreeParseFunctionCall(ParserNode *parserNode, for (size_t i = 0; i < metadata->parameters_size; ++i) { printLog("Not impelemented yet"); exit(1); - if ((metadata->parameters[i] = astTreeParse(node_metadata->params->data[i], - variables, variables_size)) == - NULL || - hasTypeOf(metadata->parameters[i], function->metadata)) { - goto RETURN_ERROR; - } } - return newAstTree(AST_TREE_TOKEN_FUNCTION_CALL, metadata); + return newAstTree(AST_TREE_TOKEN_FUNCTION_CALL, metadata, NULL); RETURN_ERROR: for (size_t i = 0; i < metadata->parameters_size; ++i) { astTreeDelete(metadata->parameters[i]); @@ -719,7 +744,7 @@ AstTree *astTreeParseIdentifier(ParserNode *parserNode, printLog("Variable not found"); return NULL; } - return newAstTree(AST_TREE_TOKEN_VARIABLE, var); + return newAstTree(AST_TREE_TOKEN_VARIABLE, var, NULL); } AstTree *astTreeParsePrintU64(ParserNode *parserNode, @@ -733,7 +758,7 @@ AstTree *astTreeParsePrintU64(ParserNode *parserNode, } return newAstTree(AST_TREE_TOKEN_KEYWORD_PRINT_U64, - (AstTreeSingleChild *)operand); + (AstTreeSingleChild *)operand, NULL); } AstTree *astTreeParseAssign(ParserNode *parserNode, @@ -759,7 +784,32 @@ AstTree *astTreeParseAssign(ParserNode *parserNode, free(left); free(right); - return newAstTree(AST_TREE_TOKEN_OPERATOR_ASSIGN, metadata); + return newAstTree(AST_TREE_TOKEN_OPERATOR_ASSIGN, metadata, NULL); +} + +AstTree *astTreeParseSum(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_SUM, metadata, NULL); } bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables, @@ -844,84 +894,11 @@ AstTree *astTreeParseVariable(ParserNode *parserNode, goto RETURN_ERROR; } - return newAstTree(AST_TREE_TOKEN_VARIABLE_DEFINE, variable); + return newAstTree(AST_TREE_TOKEN_VARIABLE_DEFINE, variable, NULL); RETURN_ERROR: return NULL; } -bool hasTypeOf(AstTree *value, const AstTree *type) { - if (value->token == AST_TREE_TOKEN_VARIABLE) { - AstTreeVariable *variable = value->metadata; - return typeIsEqual(variable->type, type); - } - - switch (type->token) { - case AST_TREE_TOKEN_TYPE_TYPE: - switch (value->token) { - case AST_TREE_TOKEN_TYPE_TYPE: - case AST_TREE_TOKEN_TYPE_FUNCTION: - case AST_TREE_TOKEN_TYPE_VOID: - case AST_TREE_TOKEN_TYPE_U64: - return true; - case AST_TREE_TOKEN_FUNCTION: - case AST_TREE_TOKEN_KEYWORD_PRINT_U64: - 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_OPERATOR_ASSIGN: - return false; - case AST_TREE_TOKEN_NONE: - } - goto ERROR; - case AST_TREE_TOKEN_TYPE_FUNCTION: - AstTreeTypeFunction *typeMetadata = type->metadata; - switch (value->token) { - case AST_TREE_TOKEN_FUNCTION: { - AstTreeFunction *valueMetadata = value->metadata; - if (typeMetadata->arguments_size != valueMetadata->arguments.size) { - return false; - } - for (size_t i = 0; i < typeMetadata->arguments_size; ++i) { - if (!typeIsEqual(typeMetadata->arguments[i], - valueMetadata->arguments.data[i]->type)) { - return false; - } - } - return typeIsEqual(typeMetadata->returnType, valueMetadata->returnType); - } - case AST_TREE_TOKEN_KEYWORD_PRINT_U64: - case AST_TREE_TOKEN_VALUE_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: - case AST_TREE_TOKEN_VARIABLE_DEFINE: - case AST_TREE_TOKEN_OPERATOR_ASSIGN: - return false; - case AST_TREE_TOKEN_NONE: - } - goto ERROR; - case AST_TREE_TOKEN_TYPE_U64: - return value->token == AST_TREE_TOKEN_VALUE_U64; - case AST_TREE_TOKEN_FUNCTION: - case AST_TREE_TOKEN_TYPE_VOID: - case AST_TREE_TOKEN_FUNCTION_CALL: - case AST_TREE_TOKEN_VARIABLE: - case AST_TREE_TOKEN_KEYWORD_PRINT_U64: - case AST_TREE_TOKEN_VALUE_U64: - case AST_TREE_TOKEN_VARIABLE_DEFINE: - case AST_TREE_TOKEN_OPERATOR_ASSIGN: - return false; - case AST_TREE_TOKEN_NONE: - } -ERROR: - printLog("Bad token '%d'", type->token); - exit(1); -} - AstTreeFunction *getFunction(AstTree *value) { switch (value->token) { case AST_TREE_TOKEN_FUNCTION: @@ -933,7 +910,7 @@ AstTreeFunction *getFunction(AstTree *value) { } case AST_TREE_TOKEN_VARIABLE: { AstTreeVariable *metadata = value->metadata; - if (metadata->type->token == AST_TREE_TOKEN_TYPE_FUNCTION) { + if (metadata->value->token == AST_TREE_TOKEN_FUNCTION) { return metadata->value->metadata; } else { return NULL; @@ -947,6 +924,7 @@ AstTreeFunction *getFunction(AstTree *value) { case AST_TREE_TOKEN_VALUE_U64: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: + case AST_TREE_TOKEN_OPERATOR_SUM: return NULL; case AST_TREE_TOKEN_NONE: } @@ -967,6 +945,7 @@ bool isConst(AstTree *value) { case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: + case AST_TREE_TOKEN_OPERATOR_SUM: return false; case AST_TREE_TOKEN_VARIABLE: { AstTreeVariable *metadata = value->metadata; @@ -984,7 +963,7 @@ AstTree *makeTypeOf(AstTree *value) { case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_VOID: case AST_TREE_TOKEN_TYPE_U64: - return newAstTree(AST_TREE_TOKEN_TYPE_TYPE, NULL); + return &AST_TREE_TYPE_TYPE; case AST_TREE_TOKEN_FUNCTION_CALL: { AstTreeFunctionCall *metadata = value->metadata; AstTreeFunction *function = metadata->function->metadata; @@ -1004,17 +983,28 @@ AstTree *makeTypeOf(AstTree *value) { copyAstTree(function->arguments.data[i]->type); } - return newAstTree(AST_TREE_TOKEN_TYPE_FUNCTION, type_metadata); + return newAstTree(AST_TREE_TOKEN_TYPE_FUNCTION, type_metadata, + &AST_TREE_TYPE_TYPE); } case AST_TREE_TOKEN_VALUE_U64: - return newAstTree(AST_TREE_TOKEN_TYPE_U64, NULL); + return &AST_TREE_U64_TYPE; case AST_TREE_TOKEN_VARIABLE: { AstTreeVariable *variable = value->metadata; return copyAstTree(variable->type); } + case AST_TREE_TOKEN_OPERATOR_ASSIGN: { + AstTreeInfix *metadata = value->metadata; + return makeTypeOf(&metadata->left); + } + case AST_TREE_TOKEN_OPERATOR_SUM: { + AstTreeInfix *metadata = value->metadata; + + // TODO: find a better way + + return makeTypeOf(&metadata->left); + } case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: - case AST_TREE_TOKEN_OPERATOR_ASSIGN: case AST_TREE_TOKEN_NONE: } printLog("Bad token '%d'", value->token); @@ -1028,6 +1018,7 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_VALUE_U64: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: + case AST_TREE_TOKEN_OPERATOR_SUM: return false; case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: @@ -1037,8 +1028,20 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { if (type1->token != AST_TREE_TOKEN_TYPE_FUNCTION) { return false; } - printLog("Not implemented yet"); - exit(1); + AstTreeTypeFunction *type0_metadata = type0->metadata; + AstTreeTypeFunction *type1_metadata = type1->metadata; + if (!typeIsEqual(type0_metadata->returnType->type, + type1_metadata->returnType->type)) { + return false; + } + if (type0_metadata->arguments_size != type1_metadata->arguments_size) { + return false; + } + for (size_t i = 0; i < type0_metadata->arguments_size; ++i) { + printLog("Not implemented yet"); + exit(1); + } + return true; case AST_TREE_TOKEN_FUNCTION_CALL: printLog("Not implemented yet"); exit(1); @@ -1064,10 +1067,9 @@ bool setAllTypesRoot(AstTreeRoot *root) { } bool setAllTypes(AstTree *tree) { - if (tree->typeChecked == true) { + if (tree->type != NULL) { return true; } - tree->typeChecked = true; switch (tree->token) { case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: @@ -1087,6 +1089,8 @@ bool setAllTypes(AstTree *tree) { return setTypesVariable(tree); case AST_TREE_TOKEN_OPERATOR_ASSIGN: return setTypesOperatorAssign(tree); + case AST_TREE_TOKEN_OPERATOR_SUM: + return setTypesOperatorSum(tree); case AST_TREE_TOKEN_NONE: } printLog("Bad token '%d'", tree->token); @@ -1106,8 +1110,8 @@ bool setTypesFunction(AstTree *tree) { } for (size_t i = 0; i < metadata->scope.expressions_size; ++i) { - AstTree expression = metadata->scope.expressions[i]; - if (!setAllTypes(&expression)) { + AstTree *expression = &metadata->scope.expressions[i]; + if (!setAllTypes(expression)) { return false; } } @@ -1118,18 +1122,19 @@ bool setTypesFunction(AstTree *tree) { } } - return true; + tree->type = makeTypeOf(tree); + return tree->type != NULL; } bool setTypesPrintU64(AstTree *tree) { AstTreeSingleChild *metadata = tree->metadata; if (!setAllTypes(metadata)) { return false; - } - if (!hasTypeOf(metadata, &AST_TREE_U64_TYPE)) { + } else if (!typeIsEqual(metadata->type, &AST_TREE_U64_TYPE)) { printLog("Type mismatch"); return false; } else { + tree->type = &AST_TREE_VOID_TYPE; return true; } } @@ -1142,7 +1147,15 @@ bool setTypesTypeFunction(AstTree *tree) { return false; } - return setAllTypes(metadata->returnType); + if (!setAllTypes(metadata->returnType)) { + return false; + } else if (!typeIsEqual(metadata->returnType->type, &AST_TREE_TYPE_TYPE)) { + printLog("Type mismatch"); + return false; + } + + tree->type = &AST_TREE_TYPE_TYPE; + return true; } bool setTypesFunctionCall(AstTree *tree) { @@ -1156,10 +1169,7 @@ bool setTypesFunctionCall(AstTree *tree) { if (metadata->function->token != AST_TREE_TOKEN_VARIABLE) { printLog("Not yet supported"); return false; - } - - if (!setAllTypes(metadata->function)) { - printLog("Type mismatch"); + } else if (!setAllTypes(metadata->function)) { return false; } @@ -1168,64 +1178,65 @@ bool setTypesFunctionCall(AstTree *tree) { function->arguments.size != metadata->parameters_size) { printLog("Arguments doesn't match %ld != %ld", function->arguments.size, metadata->parameters_size); - return false; + return NULL; } + tree->type = copyAstTree(function->returnType); return true; } bool setTypesVariable(AstTree *tree) { AstTreeVariable *metadata = tree->metadata; - return setTypesAstVariable(metadata); + if (setTypesAstVariable(metadata)) { + tree->type = copyAstTree(metadata->type); + return true; + } else { + return false; + } } bool setTypesOperatorAssign(AstTree *tree) { AstTreeInfix *infix = tree->metadata; if (!setTypesAstInfix(infix)) { - return true; - } else if (!typeIsEqual(&infix->leftType, &infix->rightType)) { + return false; + } else if (!typeIsEqual(infix->left.type, infix->right.type)) { printLog("Type mismatch"); return false; } else { + tree->type = copyAstTree(infix->left.type); return true; } } -bool setTypesAstVariable(AstTreeVariable *variable) { - if (!setAllTypes(variable->value)) { +bool setTypesOperatorSum(AstTree *tree) { + AstTreeInfix *infix = tree->metadata; + if (!setTypesAstInfix(infix)) { return false; - } - - if (variable->type == NULL) { - if ((variable->type = makeTypeOf(variable->value)) == NULL) { - return false; - } - } - - if (!hasTypeOf(variable->value, variable->type)) { + } else if (!typeIsEqual(infix->left.type, infix->right.type)) { printLog("Type mismatch"); return false; } else { + tree->type = copyAstTree(infix->left.type); return true; } } -bool setTypesAstInfix(AstTreeInfix *infix) { - if (!setAllTypes(&infix->left) || !setAllTypes(&infix->right)) { +bool setTypesAstVariable(AstTreeVariable *variable) { + if (!setAllTypes(variable->value)) { + return false; + } else if (variable->type == NULL && + (variable->type = makeTypeOf(variable->value)) == NULL) { + return false; + } else if (!typeIsEqual(variable->value->type, variable->type)) { printLog("Type mismatch"); return false; + } else { + return true; } +} - AstTree *lType = makeTypeOf(&infix->left); - AstTree *rType = makeTypeOf(&infix->right); - - infix->leftType = *lType; - infix->rightType = *rType; - - free(lType); - free(rType); - - return true; +bool setTypesAstInfix(AstTreeInfix *infix) { + return setAllTypes(&infix->left) && setAllTypes(&infix->right); } bool astTreeCleanRoot(AstTreeRoot *root) { @@ -1251,6 +1262,7 @@ bool astTreeClean(AstTree *tree) { case AST_TREE_TOKEN_VALUE_U64: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: + case AST_TREE_TOKEN_OPERATOR_SUM: return true; case AST_TREE_TOKEN_NONE: } @@ -1271,8 +1283,8 @@ bool astTreeCleanFunction(AstTree *tree) { } for (size_t i = 0; i < metadata->scope.expressions_size; ++i) { - AstTree expression = metadata->scope.expressions[i]; - if (!astTreeClean(&expression)) { + AstTree *expression = &metadata->scope.expressions[i]; + if (!astTreeClean(expression)) { return false; } } @@ -1331,6 +1343,7 @@ size_t astTreeTypeSize(AstTree tree) { case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_VALUE_U64: case AST_TREE_TOKEN_OPERATOR_ASSIGN: + case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_NONE: } UNREACHABLE; diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index 1aada03..28e74af 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -20,6 +20,7 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_VALUE_U64, AST_TREE_TOKEN_OPERATOR_ASSIGN, + AST_TREE_TOKEN_OPERATOR_SUM, AST_TREE_TOKEN_NONE, } AstTreeToken; @@ -28,11 +29,14 @@ extern const char *AST_TREE_TOKEN_STRINGS[]; typedef struct AstTree { AstTreeToken token; - bool typeChecked; void *metadata; + struct AstTree *type; } AstTree; -extern const AstTree AST_TREE_U64_TYPE; +extern AstTree AST_TREE_TYPE_TYPE; +extern AstTree AST_TREE_VOID_TYPE; +extern AstTree AST_TREE_U64_TYPE; +extern AstTree AST_TREE_VOID_VALUE; typedef struct AstTreeVariable { char *name_begin; @@ -82,8 +86,6 @@ typedef AstTree AstTreeSingleChild; typedef struct AstTreeInfix { AstTree left; AstTree right; - AstTree leftType; - AstTree rightType; } AstTreeInfix; void astTreePrint(const AstTree *tree, int indent); @@ -95,7 +97,7 @@ void astTreeVariableDelete(AstTreeVariable *variable); void astTreeDelete(AstTree *tree); void astTreeRootDelete(AstTreeRoot *root); -AstTree *newAstTree(AstTreeToken token, void *metadata); +AstTree *newAstTree(AstTreeToken token, void *metadata, AstTree *type); AstTree *copyAstTree(AstTree *tree); AstTreeRoot *makeAstTree(ParserNode *parsedRoot); @@ -132,6 +134,9 @@ AstTree *astTreeParseAssign(ParserNode *parserNode, AstTreeVariables **variables, size_t variables_size); +AstTree *astTreeParseSum(ParserNode *parserNode, AstTreeVariables **variables, + size_t variables_size); + bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables, size_t variables_size); @@ -139,8 +144,7 @@ AstTree *astTreeParseVariable(ParserNode *parserNode, AstTreeVariables **variables, size_t variables_size); -bool hasTypeOf(AstTree *value, const AstTree *type); -AstTreeFunction* getFunction(AstTree *value); +AstTreeFunction *getFunction(AstTree *value); bool isConst(AstTree *value); AstTree *makeTypeOf(AstTree *value); bool typeIsEqual(const AstTree *type0, const AstTree *type1); @@ -153,6 +157,7 @@ bool setTypesTypeFunction(AstTree *tree); bool setTypesFunctionCall(AstTree *tree); bool setTypesVariable(AstTree *tree); bool setTypesOperatorAssign(AstTree *tree); +bool setTypesOperatorSum(AstTree *tree); bool setTypesAstVariable(AstTreeVariable *variable); bool setTypesAstInfix(AstTreeInfix *infix); diff --git a/src/compiler/code-generator.c b/src/compiler/code-generator.c index 6ef6807..ab7583e 100644 --- a/src/compiler/code-generator.c +++ b/src/compiler/code-generator.c @@ -132,6 +132,7 @@ CodeGeneratorOperand *newCodeGeneratorOperandFromAstTree(AstTree tree) { case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: + case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_NONE: } UNREACHABLE; @@ -232,6 +233,7 @@ CodeGeneratorCodes *codeGenerator(AstTreeRoot *astTreeRoot) { case AST_TREE_TOKEN_TYPE_U64: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: + case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_NONE: break; } @@ -325,7 +327,7 @@ bool codeGeneratorAstTreeFunction(char *name_begin, char *name_end, newCodeGeneratorOperandFromAstTree(infix->right); operands->op0 = *op0; operands->op1 = *op1; - operands->bytes = astTreeTypeSize(infix->leftType); + operands->bytes = astTreeTypeSize(*infix->left.type); free(op0); free(op1); @@ -334,6 +336,30 @@ bool codeGeneratorAstTreeFunction(char *name_begin, char *name_end, operands)); } goto OK; + case AST_TREE_TOKEN_OPERATOR_SUM: { + AstTreeInfix *infix = tree.metadata; + + if (infix->left.token != AST_TREE_TOKEN_VARIABLE) { + printLog("Not implemented yet"); + exit(1); + } + + CodeGeneratorMov *operands = a404m_malloc(sizeof(*operands)); + CodeGeneratorOperand *op0 = + newCodeGeneratorOperandFromAstTree(infix->left); + CodeGeneratorOperand *op1 = + newCodeGeneratorOperandFromAstTree(infix->right); + operands->op0 = *op0; + operands->op1 = *op1; + operands->bytes = astTreeTypeSize(*infix->left.type); + free(op0); + free(op1); + + generateCodePushCode( + codes, createGenerateCode(NULL, NULL, CODE_GENERATOR_INSTRUCTION_ADD, + operands)); + } + goto OK; case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_VALUE_U64: case AST_TREE_TOKEN_VARIABLE: @@ -488,6 +514,8 @@ char *codeGeneratorToFlatASM(const CodeGeneratorCodes *codes) { free(inst); } continue; + case CODE_GENERATOR_INSTRUCTION_ADD: { + } } UNREACHABLE; } diff --git a/src/compiler/code-generator.h b/src/compiler/code-generator.h index e4d9cac..3c3222a 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_MOV, + CODE_GENERATOR_INSTRUCTION_ADD, CODE_GENERATOR_INSTRUCTION_FUNCTION_BEGIN, CODE_GENERATOR_INSTRUCTION_FUNCTION_END, } CodeGeneratorInstruction; diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 071a2f8..fc7307f 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -15,6 +15,7 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_KEYWORD_VOID", "LEXER_TOKEN_KEYWORD_U64", "LEXER_TOKEN_KEYWORD_PRINT_U64", + "LEXER_TOKEN_KEYWORD_RETURN", "LEXER_TOKEN_NUMBER", @@ -28,12 +29,13 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_SYMBOL_COLON", "LEXER_TOKEN_SYMBOL_ASSIGN", "LEXER_TOKEN_SYMBOL_COMMA", + "LEXER_TOKEN_SYMBOL_PLUS", "LEXER_TOKEN_NONE", }; const char *LEXER_SYMBOL_STRINGS[] = { - ";", "(", ")", "{", "}", "->", ":", "=", ",", + ";", "(", ")", "{", "}", "->", ":", "=", ",", "+", }; const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_EOL, @@ -45,6 +47,7 @@ const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_COLON, LEXER_TOKEN_SYMBOL_ASSIGN, LEXER_TOKEN_SYMBOL_COMMA, + LEXER_TOKEN_SYMBOL_PLUS, }; const size_t LEXER_SYMBOL_SIZE = sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS); @@ -54,12 +57,14 @@ const char *LEXER_KEYWORD_STRINGS[] = { "void", "u64", "print_u64", + "return", }; const LexerToken LEXER_KEYWORD_TOKENS[] = { LEXER_TOKEN_KEYWORD_TYPE, LEXER_TOKEN_KEYWORD_VOID, LEXER_TOKEN_KEYWORD_U64, LEXER_TOKEN_KEYWORD_PRINT_U64, + LEXER_TOKEN_KEYWORD_RETURN, }; const size_t LEXER_KEYWORD_SIZE = sizeof(LEXER_KEYWORD_TOKENS) / sizeof(*LEXER_KEYWORD_TOKENS); diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index 41c1ab7..81d6fd5 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -9,6 +9,7 @@ typedef enum LexerToken { LEXER_TOKEN_KEYWORD_VOID, LEXER_TOKEN_KEYWORD_U64, LEXER_TOKEN_KEYWORD_PRINT_U64, + LEXER_TOKEN_KEYWORD_RETURN, LEXER_TOKEN_NUMBER, @@ -22,6 +23,7 @@ typedef enum LexerToken { LEXER_TOKEN_SYMBOL_COLON, LEXER_TOKEN_SYMBOL_ASSIGN, LEXER_TOKEN_SYMBOL_COMMA, + LEXER_TOKEN_SYMBOL_PLUS, LEXER_TOKEN_NONE, } LexerToken; diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 7a9e0e3..c8ad924 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -31,6 +31,7 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_SYMBOL_COMMA", "PARSER_TOKEN_OPERATOR_ASSIGN", + "PARSER_TOKEN_OPERATOR_SUM", "PARSER_TOKEN_FUNCTION_DEFINITION", @@ -61,6 +62,10 @@ static constexpr ParserOrder PARSER_ORDER[] = { }, { .ltr = true, + ORDER_ARRAY(LEXER_TOKEN_SYMBOL_PLUS, ), + }, + { + .ltr = true, ORDER_ARRAY(LEXER_TOKEN_SYMBOL_COLON, LEXER_TOKEN_KEYWORD_PRINT_U64, ), }, { @@ -208,7 +213,8 @@ void parserNodePrint(const ParserNode *node, int indent) { printf(" "); } goto RETURN_SUCCESS; - case PARSER_TOKEN_OPERATOR_ASSIGN: { + case PARSER_TOKEN_OPERATOR_ASSIGN: + case PARSER_TOKEN_OPERATOR_SUM: { const ParserNodeInfixMetadata *metadata = node->metadata; printf(",\n"); for (int i = 0; i < indent; ++i) @@ -298,7 +304,8 @@ void parserNodeDelete(ParserNode *node) { free(metadata); } goto RETURN_SUCCESS; - case PARSER_TOKEN_OPERATOR_ASSIGN: { + case PARSER_TOKEN_OPERATOR_ASSIGN: + case PARSER_TOKEN_OPERATOR_SUM: { ParserNodeInfixMetadata *metadata = node->metadata; parserNodeDelete(metadata->left); parserNodeDelete(metadata->right); @@ -434,6 +441,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, return parserNumber(node, parent); case LEXER_TOKEN_SYMBOL_ASSIGN: return parserAssign(node, begin, end, parent); + case LEXER_TOKEN_SYMBOL_PLUS: + return parserPlus(node, begin, end, parent); case LEXER_TOKEN_SYMBOL: case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS: case LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET: @@ -845,9 +854,33 @@ ParserNode *parserAssign(LexerNode *node, LexerNode *begin, LexerNode *end, 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; +ParserNode *parserPlus(LexerNode *node, LexerNode *begin, LexerNode *end, + ParserNode *parent) { + LexerNode *leftNode = node - 1; + LexerNode *rightNode = node + 1; + + if (leftNode < begin || rightNode >= end) { + printLog("Bad plus"); + return NULL; + } + + ParserNode *left = getUntilCommonParent(leftNode->parserNode, parent); + ParserNode *right = getUntilCommonParent(rightNode->parserNode, parent); + + if (left == NULL || right == NULL) { + printLog("Bad plus"); + 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_SUM, left->str_begin, + right->str_end, metadata, parent); } bool isAllArguments(const ParserNodeArray *nodes) { @@ -870,6 +903,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_KEYWORD_PRINT_U64: case PARSER_TOKEN_OPERATOR_ASSIGN: + case PARSER_TOKEN_OPERATOR_SUM: return true; case PARSER_TOKEN_ROOT: case PARSER_TOKEN_TYPE_TYPE: @@ -907,6 +941,7 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_VALUE_U64: case PARSER_TOKEN_KEYWORD_PRINT_U64: case PARSER_TOKEN_OPERATOR_ASSIGN: + case PARSER_TOKEN_OPERATOR_SUM: return false; case PARSER_TOKEN_NONE: } @@ -921,6 +956,7 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_VALUE_U64: case PARSER_TOKEN_IDENTIFIER: case PARSER_TOKEN_OPERATOR_ASSIGN: + case PARSER_TOKEN_OPERATOR_SUM: 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 ea53042..abce8db 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -27,6 +27,7 @@ typedef enum ParserToken { PARSER_TOKEN_SYMBOL_COMMA, PARSER_TOKEN_OPERATOR_ASSIGN, + PARSER_TOKEN_OPERATOR_SUM, PARSER_TOKEN_FUNCTION_DEFINITION, @@ -119,6 +120,8 @@ ParserNode *parserVariable(LexerNode *node, LexerNode *begin, LexerNode *end, ParserNode *parent); ParserNode *parserAssign(LexerNode *node, LexerNode *begin, LexerNode *end, ParserNode *parent); +ParserNode *parserPlus(LexerNode *node, LexerNode *begin, LexerNode *end, + ParserNode *parent); bool isAllArguments(const ParserNodeArray *nodes); @@ -2,12 +2,14 @@ #include "compiler/code-generator.h" #include "compiler/lexer.h" #include "compiler/parser.h" +#include "runner/runner.h" #include "utils/file.h" #include "utils/log.h" #include <stdio.h> #include <stdlib.h> -static int runWithPrint(const char *filePath, const char *outFilePath) { +static int compileRun(const char *filePath, const char *outFilePath, + bool print) { char *code = readWholeFile(filePath); if (code == NULL) { @@ -18,21 +20,24 @@ static int runWithPrint(const char *filePath, const char *outFilePath) { if (lexerNodeArrayIsError(lexed)) { goto RETURN_ERROR; } - lexerNodeArrayPrint(lexed); + if (print) + lexerNodeArrayPrint(lexed); ParserNode *parsedRoot = parser(lexed); lexerNodeArrayDestroy(lexed); if (parsedRoot == NULL) { goto RETURN_ERROR; } - parserNodePrint(parsedRoot, 0); + if (print) + parserNodePrint(parsedRoot, 0); AstTreeRoot *astTree = makeAstTree(parsedRoot); parserNodeDelete(parsedRoot); if (astTree == NULL) { goto RETURN_ERROR; } - astTreeRootPrint(astTree); + if (print) + astTreeRootPrint(astTree); CodeGeneratorCodes *codes = codeGenerator(astTree); astTreeRootDelete(astTree); @@ -44,7 +49,8 @@ static int runWithPrint(const char *filePath, const char *outFilePath) { codeGeneratorDelete(codes); free(code); - puts(fasm); + if (print) + puts(fasm); if (codeGeneratorFlatASMExec(outFilePath, fasm)) { free(fasm); @@ -58,7 +64,7 @@ RETURN_ERROR: return 1; } -static int run(const char *filePath, const char *outFilePath) { +static int run(const char *filePath, bool print) { char *code = readWholeFile(filePath); if (code == NULL) { @@ -69,47 +75,45 @@ static int run(const char *filePath, const char *outFilePath) { if (lexerNodeArrayIsError(lexed)) { goto RETURN_ERROR; } + if (print) + lexerNodeArrayPrint(lexed); ParserNode *parsedRoot = parser(lexed); lexerNodeArrayDestroy(lexed); if (parsedRoot == NULL) { goto RETURN_ERROR; } + if (print) + parserNodePrint(parsedRoot, 0); AstTreeRoot *astTree = makeAstTree(parsedRoot); parserNodeDelete(parsedRoot); if (astTree == NULL) { goto RETURN_ERROR; } - - 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); + if (print) + astTreeRootPrint(astTree); + + if (runAstTree(astTree)) { + astTreeRootDelete(astTree); + return 0; + } else { + astTreeRootDelete(astTree); + return 1; } - return 1; - RETURN_ERROR: free(code); return 1; } int main(int argc, char *argv[]) { - if (argc < 3) { - run("test/main.felan", "build/out"); + if (argc < 2) { + // compileRun("test/main.felan", "build/out", false); + run("test/main.felan", false); printLog("Too few args"); return 1; } - return runWithPrint(argv[1], argv[2]); + return run(argv[1], true); } diff --git a/src/runner/runner.c b/src/runner/runner.c new file mode 100644 index 0000000..790e6c5 --- /dev/null +++ b/src/runner/runner.c @@ -0,0 +1,143 @@ +#include "runner.h" +#include "compiler/ast-tree.h" +#include "utils/log.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +bool runAstTree(AstTreeRoot *root) { + constexpr char MAIN_STR[] = "main"; + constexpr size_t MAIN_STR_SIZE = + (sizeof(MAIN_STR) / sizeof(*MAIN_STR)) - sizeof(*MAIN_STR); + for (size_t i = 0; i < root->variables.size; ++i) { + AstTreeVariable *variable = root->variables.data[i]; + size_t name_size = variable->name_end - variable->name_begin; + if (name_size == MAIN_STR_SIZE && + strncmp(variable->name_begin, MAIN_STR, MAIN_STR_SIZE) == 0 && + variable->value->token == AST_TREE_TOKEN_FUNCTION) { + + AstTree *main = variable->value; + AstTreeFunction *mainFunction = main->metadata; + return runAstTreeFunction(mainFunction) == &AST_TREE_VOID_VALUE; + } + } + printLog("main function is not found"); + return false; +} + +AstTree *runAstTreeFunction(AstTreeFunction *function) { + for (size_t i = 0; i < function->scope.expressions_size; ++i) { + AstTree expr = function->scope.expressions[i]; + switch (expr.token) { + case AST_TREE_TOKEN_KEYWORD_PRINT_U64: { + AstTreeSingleChild *metadata = expr.metadata; + AstTree *tree = calcAstTreeValue(metadata); + printf("%ld", (AstTreeU64)tree->metadata); + astTreeDelete(tree); + } + continue; + case AST_TREE_TOKEN_FUNCTION_CALL: { + AstTree *ret = calcAstTreeValue(&expr); + if (ret != &AST_TREE_VOID_VALUE) { + astTreeDelete(ret); + } + } + continue; + case AST_TREE_TOKEN_OPERATOR_ASSIGN: { + AstTreeInfix *metadata = expr.metadata; + if (metadata->left.token == AST_TREE_TOKEN_VARIABLE) { + AstTreeVariable *left = metadata->left.metadata; + astTreeDelete(left->value); + left->value = calcAstTreeValue(&metadata->right); + } else { + UNREACHABLE; + } + } + continue; + case AST_TREE_TOKEN_OPERATOR_SUM: + case AST_TREE_TOKEN_FUNCTION: + 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_VARIABLE: + case AST_TREE_TOKEN_VARIABLE_DEFINE: + case AST_TREE_TOKEN_VALUE_U64: + case AST_TREE_TOKEN_NONE: + } + printLog("%d", expr.token); + UNREACHABLE; + } + + return &AST_TREE_VOID_VALUE; +} + +AstTree *calcAstTreeValue(AstTree *tree) { + switch (tree->token) { + case AST_TREE_TOKEN_VALUE_U64: { + return deepCopyAstTree(tree); + } + case AST_TREE_TOKEN_VARIABLE: { + AstTreeVariable *variable = tree->metadata; + return calcAstTreeValue(variable->value); + } + case AST_TREE_TOKEN_FUNCTION_CALL: { + AstTreeFunctionCall *metadata = tree->metadata; + if (metadata->parameters_size != 0) { + UNREACHABLE; + } else if (metadata->function->token == AST_TREE_TOKEN_VARIABLE) { + AstTreeVariable *variable = metadata->function->metadata; + return runAstTreeFunction(variable->value->metadata); + } else { + UNREACHABLE; + } + } + case AST_TREE_TOKEN_OPERATOR_SUM: { + AstTreeInfix *metadata = tree->metadata; + AstTree *left = calcAstTreeValue(&metadata->left); + AstTree *right = calcAstTreeValue(&metadata->right); + + if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) { + if (left->token == AST_TREE_TOKEN_VALUE_U64 && + right->token == AST_TREE_TOKEN_VALUE_U64) { + left->metadata = + (void *)((AstTreeU64)left->metadata + (AstTreeU64)right->metadata); + astTreeDelete(right); + return left; + } else { + UNREACHABLE; + } + } + } + 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_VARIABLE_DEFINE: + case AST_TREE_TOKEN_OPERATOR_ASSIGN: + case AST_TREE_TOKEN_NONE: + } + UNREACHABLE; +} + +AstTree *deepCopyAstTree(AstTree *tree) { + switch (tree->token) { + case AST_TREE_TOKEN_VALUE_U64: + return newAstTree(tree->token, tree->metadata, copyAstTree(tree->type)); + case AST_TREE_TOKEN_VARIABLE: + 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_OPERATOR_SUM: + case AST_TREE_TOKEN_NONE: + } + UNREACHABLE; +} diff --git a/src/runner/runner.h b/src/runner/runner.h new file mode 100644 index 0000000..f143cbc --- /dev/null +++ b/src/runner/runner.h @@ -0,0 +1,11 @@ +#pragma once + +#include "compiler/ast-tree.h" +#include <stdint.h> + +bool runAstTree(AstTreeRoot *root); + +AstTree *runAstTreeFunction(AstTreeFunction *function); + +AstTree *calcAstTreeValue(AstTree *tree); +AstTree *deepCopyAstTree(AstTree *tree); diff --git a/src/utils/log.h b/src/utils/log.h index 620b2a3..6e6bea9 100644 --- a/src/utils/log.h +++ b/src/utils/log.h @@ -1,5 +1,7 @@ #pragma once +#include <stdlib.h> + #define printLog(format,...) _printLogBack(format, __FILE_NAME__, __LINE__, ## __VA_ARGS__) #define UNREACHABLE printLog("Unreachable");exit(1) |