diff options
author | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-02-12 11:55:38 +0330 |
---|---|---|
committer | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-02-12 11:55:38 +0330 |
commit | 5c336962d3d0a885a870708076f154ee422fee12 (patch) | |
tree | 6f24bf2de914d94fd309d34c7c82e8025692154b /src/compiler | |
parent | 217b2c70adfd60756591dd6b06b60279f805a596 (diff) |
add if
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/ast-tree.c | 131 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 17 | ||||
-rw-r--r-- | src/compiler/lexer.c | 5 | ||||
-rw-r--r-- | src/compiler/lexer.h | 1 | ||||
-rw-r--r-- | src/compiler/parser.c | 125 | ||||
-rw-r--r-- | src/compiler/parser.h | 9 |
6 files changed, 269 insertions, 19 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index 4976750..f92b95c 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -211,7 +211,23 @@ void astTreePrint(const AstTree *tree, int indent) { printf(" "); } goto RETURN_SUCCESS; - + case AST_TREE_TOKEN_KEYWORD_IF: { + AstTreeIf *metadata = tree->metadata; + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("condition=\n"); + astTreePrint(metadata->condition, indent + 1); + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("body=\n"); + astTreePrint(metadata->body, indent + 1); + printf("\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + } + goto RETURN_SUCCESS; case AST_TREE_TOKEN_NONE: } @@ -313,6 +329,13 @@ void astTreeDestroy(AstTree tree) { free(metadata); } return; + case AST_TREE_TOKEN_KEYWORD_IF: { + AstTreeIf *metadata = tree.metadata; + astTreeDelete(metadata->condition); + astTreeDelete(metadata->body); + free(metadata); + } + return; case AST_TREE_TOKEN_NONE: } UNREACHABLE; @@ -582,6 +605,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { case PARSER_TOKEN_OPERATOR_DIVIDE: case PARSER_TOKEN_OPERATOR_MODULO: case PARSER_TOKEN_SYMBOL_PARENTHESIS: + case PARSER_TOKEN_KEYWORD_IF: goto AFTER_SWITCH; case PARSER_TOKEN_ROOT: case PARSER_TOKEN_TYPE_TYPE: @@ -764,8 +788,12 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) { AST_TREE_TOKEN_OPERATOR_MINUS); case PARSER_TOKEN_VARIABLE: return astTreeParseVariable(parserNode, helper); - case PARSER_TOKEN_CONSTANT: + case PARSER_TOKEN_KEYWORD_IF: + return astTreeParseIf(parserNode, helper); case PARSER_TOKEN_SYMBOL_EOL: + return astTreeParse((ParserNodeSingleChildMetadata *)parserNode->metadata, + helper); + case PARSER_TOKEN_CONSTANT: case PARSER_TOKEN_SYMBOL_PARENTHESIS: case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: case PARSER_TOKEN_SYMBOL_COMMA: @@ -848,13 +876,46 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *p_helper) { } for (size_t i = 0; i < body->size; ++i) { - ParserNode *eol = body->data[i]; - if (eol->token != PARSER_TOKEN_SYMBOL_EOL) { - printError(eol->str_begin, eol->str_end, "Unexpected %s", - PARSER_TOKEN_STRINGS[eol->token]); + ParserNode *node = body->data[i]; + switch (node->token) { + case PARSER_TOKEN_SYMBOL_EOL: + node = (ParserNodeSingleChildMetadata *)node->metadata; + goto OK_NODE; + case PARSER_TOKEN_KEYWORD_IF: + goto OK_NODE; + case PARSER_TOKEN_ROOT: + case PARSER_TOKEN_IDENTIFIER: + case PARSER_TOKEN_VALUE_U64: + case PARSER_TOKEN_VALUE_BOOL: + case PARSER_TOKEN_TYPE_TYPE: + case PARSER_TOKEN_TYPE_FUNCTION: + case PARSER_TOKEN_TYPE_VOID: + case PARSER_TOKEN_TYPE_U64: + case PARSER_TOKEN_TYPE_BOOL: + case PARSER_TOKEN_KEYWORD_PRINT_U64: + case PARSER_TOKEN_KEYWORD_RETURN: + case PARSER_TOKEN_CONSTANT: + case PARSER_TOKEN_VARIABLE: + case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: + case PARSER_TOKEN_SYMBOL_PARENTHESIS: + case PARSER_TOKEN_SYMBOL_COMMA: + case PARSER_TOKEN_OPERATOR_ASSIGN: + case PARSER_TOKEN_OPERATOR_PLUS: + case PARSER_TOKEN_OPERATOR_MINUS: + case PARSER_TOKEN_OPERATOR_SUM: + case PARSER_TOKEN_OPERATOR_SUB: + case PARSER_TOKEN_OPERATOR_MULTIPLY: + case PARSER_TOKEN_OPERATOR_DIVIDE: + case PARSER_TOKEN_OPERATOR_MODULO: + case PARSER_TOKEN_FUNCTION_DEFINITION: + case PARSER_TOKEN_FUNCTION_CALL: + printError(node->str_begin, node->str_end, "Unexpected %s", + PARSER_TOKEN_STRINGS[node->token]); goto RETURN_ERROR; + case PARSER_TOKEN_NONE: } - ParserNode *node = (ParserNodeSingleChildMetadata *)eol->metadata; + UNREACHABLE; + OK_NODE: if (node->token == PARSER_TOKEN_CONSTANT) { if (!astTreeParseConstant(node, &helper)) { @@ -1147,15 +1208,31 @@ RETURN_ERROR: return NULL; } +AstTree *astTreeParseIf(ParserNode *parserNode, AstTreeHelper *helper) { + ParserNodeIfMetadata *node_metadata = parserNode->metadata; + + AstTree *condition = astTreeParse(node_metadata->condition, helper); + if (condition == NULL) { + return NULL; + } + + AstTree *body = astTreeParse(node_metadata->body, helper); + if (body == NULL) { + return NULL; + } + + AstTreeIf *metadata = a404m_malloc(sizeof(*metadata)); + metadata->condition = condition; + metadata->body = body; + + return newAstTree(AST_TREE_TOKEN_KEYWORD_IF, metadata, NULL, + parserNode->str_begin, parserNode->str_end); +} + AstTreeFunction *getFunction(AstTree *value) { switch (value->token) { case AST_TREE_TOKEN_FUNCTION: return value->metadata; - case AST_TREE_TOKEN_FUNCTION_CALL: { - AstTreeFunctionCall *metadata = value->metadata; - AstTreeFunction *function = metadata->function->metadata; - return getFunction(function->returnType); - } case AST_TREE_TOKEN_VARIABLE: { AstTreeVariable *metadata = value->metadata; if (metadata->value->token == AST_TREE_TOKEN_FUNCTION) { @@ -1164,8 +1241,10 @@ AstTreeFunction *getFunction(AstTree *value) { return NULL; } } + case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: case AST_TREE_TOKEN_KEYWORD_RETURN: + case AST_TREE_TOKEN_KEYWORD_IF: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_VOID: @@ -1203,6 +1282,7 @@ bool isConst(AstTree *value) { return true; case AST_TREE_TOKEN_KEYWORD_PRINT_U64: case AST_TREE_TOKEN_KEYWORD_RETURN: + case AST_TREE_TOKEN_KEYWORD_IF: case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: @@ -1280,6 +1360,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_KEYWORD_IF: case AST_TREE_TOKEN_NONE: } UNREACHABLE; @@ -1290,6 +1371,7 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: case AST_TREE_TOKEN_KEYWORD_RETURN: + case AST_TREE_TOKEN_KEYWORD_IF: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_U64: case AST_TREE_TOKEN_VALUE_BOOL: @@ -1392,10 +1474,11 @@ bool isCircularDependencies(AstTreeHelper *helper, AstTreeVariable *variable, case AST_TREE_TOKEN_FUNCTION: { return false; } - case AST_TREE_TOKEN_NONE: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_VARIABLE_DEFINE: + case AST_TREE_TOKEN_KEYWORD_IF: + case AST_TREE_TOKEN_NONE: } UNREACHABLE; } @@ -1458,6 +1541,8 @@ bool setAllTypes(AstTree *tree, AstTreeFunction *function) { return setTypesOperatorInfix(tree); case AST_TREE_TOKEN_VARIABLE_DEFINE: return setTypesVariableDefine(tree); + case AST_TREE_TOKEN_KEYWORD_IF: + return setTypesIf(tree, function); case AST_TREE_TOKEN_NONE: } UNREACHABLE; @@ -1644,6 +1729,25 @@ bool setTypesAstVariable(AstTreeVariable *variable) { return true; } +bool setTypesIf(AstTree *tree, AstTreeFunction *function) { + AstTreeIf *metadata = tree->metadata; + + if (!setAllTypes(metadata->condition, function) || + !setAllTypes(metadata->body, function)) { + return false; + } + + if (!typeIsEqual(metadata->condition->type, &AST_TREE_BOOL_TYPE)) { + printError(metadata->condition->str_begin, metadata->condition->str_end, + "If condition must be boolean"); + return false; + } + + tree->type = &AST_TREE_VOID_TYPE; + + return true; +} + bool setTypesAstInfix(AstTreeInfix *infix) { return setAllTypes(&infix->left, NULL) && setAllTypes(&infix->right, NULL); } @@ -1664,6 +1768,7 @@ bool astTreeClean(AstTree *tree) { return astTreeCleanFunction(tree); case AST_TREE_TOKEN_KEYWORD_PRINT_U64: case AST_TREE_TOKEN_KEYWORD_RETURN: + case AST_TREE_TOKEN_KEYWORD_IF: 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 579d919..38a6f66 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -9,6 +9,7 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_KEYWORD_PRINT_U64, AST_TREE_TOKEN_KEYWORD_RETURN, + AST_TREE_TOKEN_KEYWORD_IF, AST_TREE_TOKEN_TYPE_TYPE, AST_TREE_TOKEN_TYPE_FUNCTION, @@ -106,6 +107,11 @@ typedef struct AstTreeReturn { AstTree *value; } AstTreeReturn; +typedef struct AstTreeIf { + AstTree *condition; + AstTree *body; +} AstTreeIf; + typedef struct AstTreeHelper { AstTreeVariables **variables; size_t variables_size; @@ -129,7 +135,8 @@ AstTreeVariables copyAstTreeVariables(AstTreeVariables variables); AstTreeRoot *makeAstTree(ParserNode *parsedRoot); -bool pushVariable(AstTreeHelper *helper,AstTreeVariables *variables, AstTreeVariable *variable); +bool pushVariable(AstTreeHelper *helper, AstTreeVariables *variables, + AstTreeVariable *variable); AstTreeVariable *getVariable(AstTreeHelper *helper, char *name_begin, char *name_end); @@ -158,14 +165,17 @@ bool astTreeParseConstant(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseVariable(ParserNode *parserNode, AstTreeHelper *helper); +AstTree *astTreeParseIf(ParserNode *parserNode, AstTreeHelper *helper); + AstTreeFunction *getFunction(AstTree *value); bool isConst(AstTree *value); AstTree *makeTypeOf(AstTree *value); bool typeIsEqual(const AstTree *type0, const AstTree *type1); -bool isCircularDependencies(AstTreeHelper *helper,AstTreeVariable *variable,AstTree *tree); +bool isCircularDependencies(AstTreeHelper *helper, AstTreeVariable *variable, + AstTree *tree); -bool setAllTypesRoot(AstTreeRoot *root,AstTreeHelper *helper); +bool setAllTypesRoot(AstTreeRoot *root, AstTreeHelper *helper); bool setAllTypes(AstTree *tree, AstTreeFunction *function); bool setTypesFunction(AstTree *tree); bool setTypesPrintU64(AstTree *tree); @@ -177,6 +187,7 @@ bool setTypesOperatorAssign(AstTree *tree); bool setTypesOperatorInfix(AstTree *tree); bool setTypesOperatorUnary(AstTree *tree); bool setTypesVariableDefine(AstTree *tree); +bool setTypesIf(AstTree *tree,AstTreeFunction *function); bool setTypesAstVariable(AstTreeVariable *variable); bool setTypesAstInfix(AstTreeInfix *infix); diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index baedf24..a61c3af 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -20,6 +20,7 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_KEYWORD_RETURN", "LEXER_TOKEN_KEYWORD_TRUE", "LEXER_TOKEN_KEYWORD_FALSE", + "LEXER_TOKEN_KEYWORD_IF", "LEXER_TOKEN_NUMBER", @@ -67,13 +68,14 @@ const size_t LEXER_SYMBOL_SIZE = sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS); const char *LEXER_KEYWORD_STRINGS[] = { - "type", "void", "u64", "bool", "print_u64", "return", "true", "false", + "type", "void", "u64", "bool", "print_u64", "return", "true", "false", "if", }; const LexerToken LEXER_KEYWORD_TOKENS[] = { LEXER_TOKEN_KEYWORD_TYPE, LEXER_TOKEN_KEYWORD_VOID, LEXER_TOKEN_KEYWORD_U64, LEXER_TOKEN_KEYWORD_BOOL, LEXER_TOKEN_KEYWORD_PRINT_U64, LEXER_TOKEN_KEYWORD_RETURN, LEXER_TOKEN_KEYWORD_TRUE, LEXER_TOKEN_KEYWORD_FALSE, + LEXER_TOKEN_KEYWORD_IF, }; const size_t LEXER_KEYWORD_SIZE = sizeof(LEXER_KEYWORD_TOKENS) / sizeof(*LEXER_KEYWORD_TOKENS); @@ -205,6 +207,7 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter, case LEXER_TOKEN_KEYWORD_RETURN: case LEXER_TOKEN_KEYWORD_TRUE: case LEXER_TOKEN_KEYWORD_FALSE: + case LEXER_TOKEN_KEYWORD_IF: case LEXER_TOKEN_NUMBER: case LEXER_TOKEN_SYMBOL_EOL: case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS: diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index bc38270..4e74d1d 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -13,6 +13,7 @@ typedef enum LexerToken { LEXER_TOKEN_KEYWORD_RETURN, LEXER_TOKEN_KEYWORD_TRUE, LEXER_TOKEN_KEYWORD_FALSE, + LEXER_TOKEN_KEYWORD_IF, LEXER_TOKEN_NUMBER, diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 9cdf141..d4364af 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -25,6 +25,7 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_KEYWORD_PRINT_U64", "PARSER_TOKEN_KEYWORD_RETURN", + "PARSER_TOKEN_KEYWORD_IF", "PARSER_TOKEN_CONSTANT", "PARSER_TOKEN_VARIABLE", @@ -101,6 +102,10 @@ static constexpr ParserOrder PARSER_ORDER[] = { .ltr = true, ORDER_ARRAY(LEXER_TOKEN_SYMBOL_EOL, LEXER_TOKEN_SYMBOL_COMMA, ), }, + { + .ltr = true, + ORDER_ARRAY(LEXER_TOKEN_KEYWORD_IF, ), + }, }; static constexpr size_t PARSER_ORDER_SIZE = @@ -282,6 +287,24 @@ void parserNodePrint(const ParserNode *node, int indent) { printf(" "); } goto RETURN_SUCCESS; + case PARSER_TOKEN_KEYWORD_IF: { + ParserNodeIfMetadata *metadata = node->metadata; + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("condition=\n"); + parserNodePrint(metadata->condition, indent + 1); + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("body=\n"); + parserNodePrint(metadata->body, indent + 1); + printf("\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + free(metadata); + } + goto RETURN_SUCCESS; case PARSER_TOKEN_NONE: } UNREACHABLE; @@ -378,6 +401,13 @@ void parserNodeDelete(ParserNode *node) { free(metadata); } goto RETURN_SUCCESS; + case PARSER_TOKEN_KEYWORD_IF: { + ParserNodeIfMetadata *metadata = node->metadata; + parserNodeDelete(metadata->condition); + parserNodeDelete(metadata->body); + free(metadata); + } + goto RETURN_SUCCESS; case PARSER_TOKEN_NONE: } UNREACHABLE; @@ -545,6 +575,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, *conti = result == NULL; return result; } + case LEXER_TOKEN_KEYWORD_IF: + return parserIf(node, end, parent); case LEXER_TOKEN_SYMBOL: case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS: case LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET: @@ -555,12 +587,35 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, } ParserNode *getUntilCommonParent(ParserNode *node, ParserNode *parent) { - while (node != NULL && node->parent != parent) { + while (node != NULL && node != parent && node->parent != parent) { node = node->parent; } return node; } +ParserNode *getNextUsingCommonParent(LexerNode *node, LexerNode *end, + ParserNode *parent) { + ParserNode *parsed = getUntilCommonParent(node->parserNode, parent); + if (parsed == NULL) { + return NULL; + } + + while (true) { + node += 1; + if (node >= end) { + return NULL; + } + + ParserNode *newParsed = getUntilCommonParent(node->parserNode, parsed); + + if (newParsed == NULL) { + return getUntilCommonParent(node->parserNode, parent); + } + } + + return NULL; +} + ParserNode *parserIdentifier(LexerNode *node, ParserNode *parent) { return node->parserNode = newParserNode(PARSER_TOKEN_IDENTIFIER, node->str_begin, @@ -854,12 +909,43 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, } ParserNodeArray *bodyArray = body->metadata; for (size_t i = 0; i < bodyArray->size; ++i) { - if (bodyArray->data[i]->token != PARSER_TOKEN_SYMBOL_EOL) { + switch (bodyArray->data[i]->token) { + case PARSER_TOKEN_SYMBOL_EOL: + case PARSER_TOKEN_KEYWORD_IF: + continue; + case PARSER_TOKEN_ROOT: + case PARSER_TOKEN_IDENTIFIER: + case PARSER_TOKEN_VALUE_U64: + case PARSER_TOKEN_VALUE_BOOL: + case PARSER_TOKEN_TYPE_TYPE: + case PARSER_TOKEN_TYPE_FUNCTION: + case PARSER_TOKEN_TYPE_VOID: + case PARSER_TOKEN_TYPE_U64: + case PARSER_TOKEN_TYPE_BOOL: + case PARSER_TOKEN_KEYWORD_PRINT_U64: + case PARSER_TOKEN_KEYWORD_RETURN: + case PARSER_TOKEN_CONSTANT: + case PARSER_TOKEN_VARIABLE: + case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: + case PARSER_TOKEN_SYMBOL_PARENTHESIS: + case PARSER_TOKEN_SYMBOL_COMMA: + case PARSER_TOKEN_OPERATOR_ASSIGN: + case PARSER_TOKEN_OPERATOR_PLUS: + case PARSER_TOKEN_OPERATOR_MINUS: + case PARSER_TOKEN_OPERATOR_SUM: + case PARSER_TOKEN_OPERATOR_SUB: + case PARSER_TOKEN_OPERATOR_MULTIPLY: + case PARSER_TOKEN_OPERATOR_DIVIDE: + case PARSER_TOKEN_OPERATOR_MODULO: + case PARSER_TOKEN_FUNCTION_DEFINITION: + case PARSER_TOKEN_FUNCTION_CALL: printError(bodyArray->data[i]->str_begin, bodyArray->data[i]->str_end, "Maybe forgot a ; with %s", PARSER_TOKEN_STRINGS[bodyArray->data[i]->token]); return NULL; + case PARSER_TOKEN_NONE: } + UNREACHABLE; } } @@ -1054,6 +1140,38 @@ ParserNode *parserBinaryOrLeftOperator(LexerNode *node, LexerNode *begin, (ParserNodeSingleChildMetadata *)right, parent); } +ParserNode *parserIf(LexerNode *node, LexerNode *end, ParserNode *parent) { + LexerNode *conditionNode = node + 1; + if (conditionNode >= end) { + printError(node->str_begin, node->str_end, "If has no condition"); + return NULL; + } + + ParserNode *condition = + getUntilCommonParent(conditionNode->parserNode, parent); + + if (condition == NULL) { + printError(conditionNode->str_begin, conditionNode->str_end, + "If has bad condition"); + return NULL; + } + + ParserNode *body = getNextUsingCommonParent(conditionNode, end, parent); + + if (body == NULL) { + printError(node->str_begin, node->str_end, "If has bad body"); + return NULL; + } + + ParserNodeIfMetadata *metadata = a404m_malloc(sizeof(*metadata)); + metadata->condition = condition; + metadata->body = body; + + return condition->parent = body->parent = node->parserNode = + newParserNode(PARSER_TOKEN_KEYWORD_IF, node->str_begin, + node->str_end, metadata, parent); +} + bool isAllArguments(const ParserNodeArray *nodes) { for (size_t i = 0; i < nodes->size; ++i) { const ParserNode *node = nodes->data[i]; @@ -1084,6 +1202,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_OPERATOR_MODULO: case PARSER_TOKEN_VALUE_U64: case PARSER_TOKEN_VALUE_BOOL: + case PARSER_TOKEN_KEYWORD_IF: return true; case PARSER_TOKEN_ROOT: case PARSER_TOKEN_TYPE_TYPE: @@ -1130,6 +1249,7 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_OPERATOR_MULTIPLY: case PARSER_TOKEN_OPERATOR_DIVIDE: case PARSER_TOKEN_OPERATOR_MODULO: + case PARSER_TOKEN_KEYWORD_IF: return false; case PARSER_TOKEN_NONE: } @@ -1155,6 +1275,7 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_TYPE_VOID: case PARSER_TOKEN_TYPE_U64: case PARSER_TOKEN_TYPE_BOOL: + case PARSER_TOKEN_KEYWORD_IF: return true; case PARSER_TOKEN_TYPE_FUNCTION: case PARSER_TOKEN_CONSTANT: diff --git a/src/compiler/parser.h b/src/compiler/parser.h index 2d57538..cb90b71 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -20,6 +20,7 @@ typedef enum ParserToken { PARSER_TOKEN_KEYWORD_PRINT_U64, PARSER_TOKEN_KEYWORD_RETURN, + PARSER_TOKEN_KEYWORD_IF, PARSER_TOKEN_CONSTANT, PARSER_TOKEN_VARIABLE, @@ -103,6 +104,11 @@ typedef struct ParserNodeReturnMetadata { typedef bool ParserNodeBoolMetadata; +typedef struct ParserNodeIfMetadata { + ParserNode *condition; + ParserNode *body; +}ParserNodeIfMetadata; + void parserNodePrint(const ParserNode *node, int indent); void parserNodeDelete(ParserNode *node); @@ -116,6 +122,7 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, ParserNode *parent, bool *conti); ParserNode *getUntilCommonParent(ParserNode *node, ParserNode *parent); +ParserNode *getNextUsingCommonParent(LexerNode *node,LexerNode *end, ParserNode *parent); ParserNode *parserIdentifier(LexerNode *node, ParserNode *parent); ParserNode *parserType(LexerNode *node, ParserNode *parent); @@ -143,6 +150,8 @@ ParserNode *parserBinaryOrLeftOperator(LexerNode *node, LexerNode *begin, LexerNode *end, ParserNode *parent, ParserToken token, LexerToken laterToken); +ParserNode *parserIf(LexerNode *node, LexerNode *end, + ParserNode *parent); bool isAllArguments(const ParserNodeArray *nodes); |