From 34099f0d7752a2fab5eadccfeb578b77b292c889 Mon Sep 17 00:00:00 2001 From: A404M Date: Fri, 7 Feb 2025 22:16:18 +0330 Subject: add return --- src/compiler/ast-tree.c | 104 +++++++++++++++++++++++++++++++++++++----------- src/compiler/ast-tree.h | 11 ++++- src/compiler/parser.c | 54 ++++++++++++++++++++++++- src/compiler/parser.h | 6 +++ 4 files changed, 149 insertions(+), 26 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index 7f955ff..c51e836 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -107,6 +107,18 @@ void astTreePrint(const AstTree *tree, int indent) { astTreePrint(metadata, indent + 1); } goto RETURN_SUCCESS; + case AST_TREE_TOKEN_KEYWORD_RETURN: { + AstTreeReturn *metadata = tree->metadata; + if (metadata->value != NULL) { + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("value=\n"); + astTreePrint(metadata->value, indent + 1); + } + } + goto RETURN_SUCCESS; + case AST_TREE_TOKEN_VALUE_U64: { AstTreeU64 metadata = (AstTreeU64)tree->metadata; printf(",value=%lu", metadata); @@ -195,15 +207,6 @@ 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; @@ -234,6 +237,14 @@ void astTreeDestroy(AstTree tree) { astTreeDelete(metadata); } return; + case AST_TREE_TOKEN_KEYWORD_RETURN: { + AstTreeReturn *metadata = tree.metadata; + if (metadata->value != NULL) { + astTreeDelete(metadata->value); + } + free(metadata); + } + return; case AST_TREE_TOKEN_TYPE_FUNCTION: { AstTreeTypeFunction *metadata = tree.metadata; for (size_t i = 0; i < metadata->arguments_size; ++i) { @@ -287,6 +298,10 @@ void astTreeVariableDelete(AstTreeVariable *variable) { } void astTreeDelete(AstTree *tree) { + if (tree != &AST_TREE_TYPE_TYPE && tree != &AST_TREE_VOID_TYPE && + tree != &AST_TREE_U64_TYPE) { + return; + } astTreeDestroy(*tree); free(tree); } @@ -334,6 +349,7 @@ AstTree *copyAstTree(AstTree *tree) { case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: + case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_NONE: @@ -410,6 +426,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { case PARSER_TOKEN_TYPE_VOID: case PARSER_TOKEN_TYPE_U64: case PARSER_TOKEN_KEYWORD_PRINT_U64: + case PARSER_TOKEN_KEYWORD_RETURN: case PARSER_TOKEN_CONSTANT: case PARSER_TOKEN_VARIABLE: case PARSER_TOKEN_SYMBOL_EOL: @@ -419,9 +436,9 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { 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; + case PARSER_TOKEN_NONE: } printLog("Bad token %d", node_metadata->value->token); goto RETURN_ERROR; @@ -528,6 +545,8 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables **variables, &AST_TREE_U64_TYPE); case PARSER_TOKEN_KEYWORD_PRINT_U64: return astTreeParsePrintU64(parserNode, variables, variables_size); + case PARSER_TOKEN_KEYWORD_RETURN: + return astTreeParseReturn(parserNode, variables, variables_size); case PARSER_TOKEN_OPERATOR_ASSIGN: return astTreeParseAssign(parserNode, variables, variables_size); case PARSER_TOKEN_OPERATOR_SUM: @@ -727,12 +746,6 @@ AstTree *astTreeParseFunctionCall(ParserNode *parserNode, } 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]); - } - free(metadata->parameters); - return NULL; } AstTree *astTreeParseIdentifier(ParserNode *parserNode, @@ -761,6 +774,27 @@ AstTree *astTreeParsePrintU64(ParserNode *parserNode, (AstTreeSingleChild *)operand, NULL); } +AstTree *astTreeParseReturn(ParserNode *parserNode, + AstTreeVariables **variables, + size_t variables_size) { + ParserNodeReturnMetadata *node_metadata = parserNode->metadata; + + AstTree *value; + if (node_metadata == NULL) { + value = NULL; + } else { + value = astTreeParse(node_metadata->value, variables, variables_size); + if (value == NULL) { + return NULL; + } + } + + AstTreeReturn *metadata = a404m_malloc(sizeof(*metadata)); + metadata->value = value; + + return newAstTree(AST_TREE_TOKEN_KEYWORD_RETURN, metadata, NULL); +} + AstTree *astTreeParseAssign(ParserNode *parserNode, AstTreeVariables **variables, size_t variables_size) { @@ -917,6 +951,7 @@ AstTreeFunction *getFunction(AstTree *value) { } } case AST_TREE_TOKEN_KEYWORD_PRINT_U64: + case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_VOID: @@ -942,6 +977,7 @@ bool isConst(AstTree *value) { case AST_TREE_TOKEN_VALUE_U64: return true; case AST_TREE_TOKEN_KEYWORD_PRINT_U64: + case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: @@ -1005,6 +1041,7 @@ AstTree *makeTypeOf(AstTree *value) { } case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: + case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_NONE: } printLog("Bad token '%d'", value->token); @@ -1015,6 +1052,7 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { switch (type0->token) { case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: + case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_VALUE_U64: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: @@ -1066,7 +1104,7 @@ bool setAllTypesRoot(AstTreeRoot *root) { return true; } -bool setAllTypes(AstTree *tree) { +bool setAllTypes(AstTree *tree, AstTreeFunction *function) { if (tree->type != NULL) { return true; } @@ -1081,6 +1119,8 @@ bool setAllTypes(AstTree *tree) { return setTypesFunction(tree); case AST_TREE_TOKEN_KEYWORD_PRINT_U64: return setTypesPrintU64(tree); + case AST_TREE_TOKEN_KEYWORD_RETURN: + return setTypesReturn(tree, function); case AST_TREE_TOKEN_TYPE_FUNCTION: return setTypesTypeFunction(tree); case AST_TREE_TOKEN_FUNCTION_CALL: @@ -1105,13 +1145,13 @@ bool setTypesFunction(AstTree *tree) { return false; } - if (!setAllTypes(metadata->returnType)) { + if (!setAllTypes(metadata->returnType, NULL)) { return false; } for (size_t i = 0; i < metadata->scope.expressions_size; ++i) { AstTree *expression = &metadata->scope.expressions[i]; - if (!setAllTypes(expression)) { + if (!setAllTypes(expression, metadata)) { return false; } } @@ -1128,7 +1168,7 @@ bool setTypesFunction(AstTree *tree) { bool setTypesPrintU64(AstTree *tree) { AstTreeSingleChild *metadata = tree->metadata; - if (!setAllTypes(metadata)) { + if (!setAllTypes(metadata, NULL)) { return false; } else if (!typeIsEqual(metadata->type, &AST_TREE_U64_TYPE)) { printLog("Type mismatch"); @@ -1139,6 +1179,20 @@ bool setTypesPrintU64(AstTree *tree) { } } +bool setTypesReturn(AstTree *tree, AstTreeFunction *function) { + AstTreeReturn *metadata = tree->metadata; + if (metadata->value != NULL) { + if (!setAllTypes(metadata->value, NULL)) { + return false; + } else if (!typeIsEqual(metadata->value->type, function->returnType)) { + printLog("Type mismatch"); + return false; + } + } + tree->type = &AST_TREE_VOID_TYPE; + return true; +} + bool setTypesTypeFunction(AstTree *tree) { AstTreeTypeFunction *metadata = tree->metadata; @@ -1147,7 +1201,7 @@ bool setTypesTypeFunction(AstTree *tree) { return false; } - if (!setAllTypes(metadata->returnType)) { + if (!setAllTypes(metadata->returnType, NULL)) { return false; } else if (!typeIsEqual(metadata->returnType->type, &AST_TREE_TYPE_TYPE)) { printLog("Type mismatch"); @@ -1169,7 +1223,7 @@ bool setTypesFunctionCall(AstTree *tree) { if (metadata->function->token != AST_TREE_TOKEN_VARIABLE) { printLog("Not yet supported"); return false; - } else if (!setAllTypes(metadata->function)) { + } else if (!setAllTypes(metadata->function, NULL)) { return false; } @@ -1222,7 +1276,7 @@ bool setTypesOperatorSum(AstTree *tree) { } bool setTypesAstVariable(AstTreeVariable *variable) { - if (!setAllTypes(variable->value)) { + if (!setAllTypes(variable->value, NULL)) { return false; } else if (variable->type == NULL && (variable->type = makeTypeOf(variable->value)) == NULL) { @@ -1236,7 +1290,7 @@ bool setTypesAstVariable(AstTreeVariable *variable) { } bool setTypesAstInfix(AstTreeInfix *infix) { - return setAllTypes(&infix->left) && setAllTypes(&infix->right); + return setAllTypes(&infix->left, NULL) && setAllTypes(&infix->right, NULL); } bool astTreeCleanRoot(AstTreeRoot *root) { @@ -1254,6 +1308,7 @@ bool astTreeClean(AstTree *tree) { case AST_TREE_TOKEN_FUNCTION: return astTreeCleanFunction(tree); case AST_TREE_TOKEN_KEYWORD_PRINT_U64: + case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_VOID: @@ -1335,6 +1390,7 @@ size_t astTreeTypeSize(AstTree tree) { return 8; case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: + case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_VOID: diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index 28e74af..64068d3 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -8,6 +8,7 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_FUNCTION, AST_TREE_TOKEN_KEYWORD_PRINT_U64, + AST_TREE_TOKEN_KEYWORD_RETURN, AST_TREE_TOKEN_TYPE_TYPE, AST_TREE_TOKEN_TYPE_FUNCTION, @@ -88,6 +89,10 @@ typedef struct AstTreeInfix { AstTree right; } AstTreeInfix; +typedef struct AstTreeReturn { + AstTree *value; +} AstTreeReturn; + void astTreePrint(const AstTree *tree, int indent); void astTreeRootPrint(const AstTreeRoot *root); @@ -129,6 +134,9 @@ AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTree *astTreeParsePrintU64(ParserNode *parserNode, AstTreeVariables **variables, size_t variables_size); +AstTree *astTreeParseReturn(ParserNode *parserNode, + AstTreeVariables **variables, + size_t variables_size); AstTree *astTreeParseAssign(ParserNode *parserNode, AstTreeVariables **variables, @@ -150,9 +158,10 @@ AstTree *makeTypeOf(AstTree *value); bool typeIsEqual(const AstTree *type0, const AstTree *type1); bool setAllTypesRoot(AstTreeRoot *root); -bool setAllTypes(AstTree *tree); +bool setAllTypes(AstTree *tree,AstTreeFunction *function); bool setTypesFunction(AstTree *tree); bool setTypesPrintU64(AstTree *tree); +bool setTypesReturn(AstTree *tree,AstTreeFunction *function); bool setTypesTypeFunction(AstTree *tree); bool setTypesFunctionCall(AstTree *tree); bool setTypesVariable(AstTree *tree); diff --git a/src/compiler/parser.c b/src/compiler/parser.c index c8ad924..1aa596c 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -21,6 +21,7 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_TYPE_U64", "PARSER_TOKEN_KEYWORD_PRINT_U64", + "PARSER_TOKEN_KEYWORD_RETURN", "PARSER_TOKEN_CONSTANT", "PARSER_TOKEN_VARIABLE", @@ -66,12 +67,17 @@ static constexpr ParserOrder PARSER_ORDER[] = { }, { .ltr = true, - ORDER_ARRAY(LEXER_TOKEN_SYMBOL_COLON, LEXER_TOKEN_KEYWORD_PRINT_U64, ), + ORDER_ARRAY(LEXER_TOKEN_SYMBOL_COLON, ), }, { .ltr = false, ORDER_ARRAY(LEXER_TOKEN_SYMBOL_ASSIGN, ), }, + { + .ltr = true, + ORDER_ARRAY(LEXER_TOKEN_KEYWORD_RETURN, + LEXER_TOKEN_KEYWORD_PRINT_U64, ), + }, { .ltr = true, ORDER_ARRAY(LEXER_TOKEN_SYMBOL_EOL, LEXER_TOKEN_SYMBOL_COMMA, ), @@ -154,6 +160,18 @@ void parserNodePrint(const ParserNode *node, int indent) { printf(" "); } goto RETURN_SUCCESS; + case PARSER_TOKEN_KEYWORD_RETURN: { + const ParserNodeReturnMetadata *metadata = node->metadata; + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("value=\n"); + parserNodePrint(metadata->value, indent + 1); + printf("\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + } + goto RETURN_SUCCESS; case PARSER_TOKEN_FUNCTION_DEFINITION: { const ParserNodeFunctionDefnitionMetadata *metadata = node->metadata; printf(",\n"); @@ -278,6 +296,14 @@ void parserNodeDelete(ParserNode *node) { parserNodeDelete(metadata); } goto RETURN_SUCCESS; + case PARSER_TOKEN_KEYWORD_RETURN: { + ParserNodeReturnMetadata *metadata = node->metadata; + if (metadata->value != NULL) { + parserNodeDelete(metadata->value); + } + free(metadata); + } + goto RETURN_SUCCESS; case PARSER_TOKEN_FUNCTION_DEFINITION: { ParserNodeFunctionDefnitionMetadata *metadata = node->metadata; parserNodeDelete(metadata->arguments); @@ -425,6 +451,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, return parserU64(node, parent); case LEXER_TOKEN_KEYWORD_PRINT_U64: return parserPrintU64(node, end, parent); + case LEXER_TOKEN_KEYWORD_RETURN: + return parserReturn(node, end, parent); case LEXER_TOKEN_SYMBOL_EOL: return parserEol(node, begin, parent); case LEXER_TOKEN_SYMBOL_CLOSE_PARENTHESIS: @@ -505,6 +533,27 @@ ParserNode *parserPrintU64(LexerNode *node, LexerNode *end, (ParserNodeSingleChildMetadata *)operand, parent); } +ParserNode *parserReturn(LexerNode *node, LexerNode *end, ParserNode *parent) { + LexerNode *afterNode = node + 1; + ParserNode *operand; + if (afterNode >= end || afterNode->parserNode == NULL) { + operand = NULL; + } else { + operand = getUntilCommonParent(afterNode->parserNode, parent); + if (operand == NULL) { + printLog("No param"); + return NULL; + } + } + + ParserNodeReturnMetadata *metadata = a404m_malloc(sizeof(*metadata)); + metadata->value = operand; + + return operand->parent = node->parserNode = + newParserNode(PARSER_TOKEN_KEYWORD_RETURN, node->str_begin, + node->str_end, metadata, parent); +} + ParserNode *parserNumber(LexerNode *node, ParserNode *parent) { ParserNode *parserNode; switch (*node->str_begin) { @@ -902,6 +951,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_FUNCTION_DEFINITION: case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_KEYWORD_PRINT_U64: + case PARSER_TOKEN_KEYWORD_RETURN: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM: return true; @@ -940,6 +990,7 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_VALUE_U64: case PARSER_TOKEN_KEYWORD_PRINT_U64: + case PARSER_TOKEN_KEYWORD_RETURN: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM: return false; @@ -970,6 +1021,7 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: case PARSER_TOKEN_SYMBOL_COMMA: case PARSER_TOKEN_KEYWORD_PRINT_U64: + case PARSER_TOKEN_KEYWORD_RETURN: return false; case PARSER_TOKEN_NONE: } diff --git a/src/compiler/parser.h b/src/compiler/parser.h index abce8db..004f14f 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -17,6 +17,7 @@ typedef enum ParserToken { PARSER_TOKEN_TYPE_U64, PARSER_TOKEN_KEYWORD_PRINT_U64, + PARSER_TOKEN_KEYWORD_RETURN, PARSER_TOKEN_CONSTANT, PARSER_TOKEN_VARIABLE, @@ -88,6 +89,10 @@ typedef struct ParserNodeInfixMetadata { ParserNode *right; } ParserNodeInfixMetadata; +typedef struct ParserNodeReturnMetadata { + ParserNode *value; +} ParserNodeReturnMetadata; + void parserNodePrint(const ParserNode *node, int indent); void parserNodeDelete(ParserNode *node); @@ -107,6 +112,7 @@ ParserNode *parserType(LexerNode *node, ParserNode *parent); ParserNode *parserVoid(LexerNode *node, ParserNode *parent); ParserNode *parserU64(LexerNode *node, ParserNode *parent); ParserNode *parserPrintU64(LexerNode *node, LexerNode *end, ParserNode *parent); +ParserNode *parserReturn(LexerNode *node, LexerNode *end, ParserNode *parent); ParserNode *parserNumber(LexerNode *node, ParserNode *parent); ParserNode *parserEol(LexerNode *node, LexerNode *begin, ParserNode *parent); ParserNode *parserComma(LexerNode *node, LexerNode *begin, ParserNode *parent); -- cgit v1.2.3