diff options
Diffstat (limited to 'src/compiler/ast-tree.c')
-rw-r--r-- | src/compiler/ast-tree.c | 104 |
1 files changed, 101 insertions, 3 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: } |