diff options
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/ast-tree.c | 191 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 17 | ||||
-rw-r--r-- | src/compiler/lexer.c | 7 | ||||
-rw-r--r-- | src/compiler/lexer.h | 1 | ||||
-rw-r--r-- | src/compiler/parser.c | 107 | ||||
-rw-r--r-- | src/compiler/parser.h | 5 |
6 files changed, 293 insertions, 35 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index f92b95c..aeb1391 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -222,12 +222,27 @@ void astTreePrint(const AstTree *tree, int indent) { for (int i = 0; i < indent; ++i) printf(" "); printf("body=\n"); - astTreePrint(metadata->body, indent + 1); + astTreePrint(metadata->ifBody, indent + 1); printf("\n"); for (int i = 0; i < indent; ++i) printf(" "); } goto RETURN_SUCCESS; + case AST_TREE_TOKEN_SCOPE: { + AstTreeScope *metadata = tree->metadata; + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("expressions=[\n"); + for (size_t i = 0; i < metadata->expressions_size; ++i) { + astTreePrint(metadata->expressions[i], indent + 1); + printf(",\n"); + } + for (int i = 0; i < indent; ++i) + printf(" "); + printf("]"); + } + goto RETURN_SUCCESS; case AST_TREE_TOKEN_NONE: } @@ -332,10 +347,24 @@ void astTreeDestroy(AstTree tree) { case AST_TREE_TOKEN_KEYWORD_IF: { AstTreeIf *metadata = tree.metadata; astTreeDelete(metadata->condition); - astTreeDelete(metadata->body); + astTreeDelete(metadata->ifBody); + free(metadata); + } + return; + case AST_TREE_TOKEN_SCOPE: { + AstTreeScope *metadata = tree.metadata; + for (size_t i = 0; i < metadata->expressions_size; ++i) { + astTreeDelete(metadata->expressions[i]); + } + for (size_t i = 0; i < metadata->variables.size; ++i) { + astTreeVariableDelete(metadata->variables.data[i]); + } + free(metadata->expressions); + free(metadata->variables.data); free(metadata); } return; + case AST_TREE_TOKEN_NONE: } UNREACHABLE; @@ -793,9 +822,10 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) { case PARSER_TOKEN_SYMBOL_EOL: return astTreeParse((ParserNodeSingleChildMetadata *)parserNode->metadata, helper); + case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: + return astTreeParseCurlyBracket(parserNode, helper); case PARSER_TOKEN_CONSTANT: case PARSER_TOKEN_SYMBOL_PARENTHESIS: - case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: case PARSER_TOKEN_SYMBOL_COMMA: case PARSER_TOKEN_NONE: case PARSER_TOKEN_ROOT: @@ -1216,19 +1246,135 @@ AstTree *astTreeParseIf(ParserNode *parserNode, AstTreeHelper *helper) { return NULL; } - AstTree *body = astTreeParse(node_metadata->body, helper); - if (body == NULL) { + AstTree *ifBody = astTreeParse(node_metadata->ifBody, helper); + if (ifBody == NULL) { return NULL; } + AstTree *elseBody; + if(node_metadata->elseBody != NULL){ + elseBody = astTreeParse(node_metadata->elseBody, helper); + if(elseBody == NULL){ + return NULL; + } + }else{ + elseBody = NULL; + } + AstTreeIf *metadata = a404m_malloc(sizeof(*metadata)); metadata->condition = condition; - metadata->body = body; + metadata->ifBody = ifBody; + metadata->elseBody = elseBody; return newAstTree(AST_TREE_TOKEN_KEYWORD_IF, metadata, NULL, parserNode->str_begin, parserNode->str_end); } +AstTree *astTreeParseCurlyBracket(ParserNode *parserNode, + AstTreeHelper *p_helper) { + ParserNodeArray *body = parserNode->metadata; + + size_t expressions_size = 0; + + AstTreeScope *scope = a404m_malloc(sizeof(*scope)); + scope->variables.data = a404m_malloc(0); + scope->variables.size = 0; + scope->expressions = a404m_malloc(0); + scope->expressions_size = 0; + + size_t variables_size = p_helper->variables_size + 1; + AstTreeVariables *variables[variables_size]; + for (size_t i = 0; i < p_helper->variables_size; ++i) { + variables[i] = p_helper->variables[i]; + } + variables[variables_size - 1] = &scope->variables; + + AstTreeHelper helper = { + .variables = variables, + .variables_size = variables_size, + .variable = p_helper->variable, + .globalDeps = p_helper->globalDeps, + }; + + for (size_t i = 0; i < body->size; ++i) { + 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: + } + UNREACHABLE; + OK_NODE: + + if (node->token == PARSER_TOKEN_CONSTANT) { + if (!astTreeParseConstant(node, &helper)) { + goto RETURN_ERROR; + } + } else { + AstTree *tree = astTreeParse(node, &helper); + + if (tree == NULL) { + goto RETURN_ERROR; + } + + if (expressions_size == scope->expressions_size) { + expressions_size += expressions_size / 2 + 1; + scope->expressions = a404m_realloc( + scope->expressions, expressions_size * sizeof(*scope->expressions)); + } + scope->expressions[scope->expressions_size] = tree; + scope->expressions_size += 1; + } + } + + scope->expressions = + a404m_realloc(scope->expressions, + scope->expressions_size * sizeof(*scope->expressions)); + + return newAstTree(AST_TREE_TOKEN_SCOPE, scope, NULL, parserNode->str_begin, + parserNode->str_end); + +RETURN_ERROR: + for (size_t i = 0; i < scope->expressions_size; ++i) { + // astTreeDelete(scope->expressions[i]); + } + free(scope->variables.data); + free(scope->expressions); + return NULL; +} + AstTreeFunction *getFunction(AstTree *value) { switch (value->token) { case AST_TREE_TOKEN_FUNCTION: @@ -1262,6 +1408,7 @@ AstTreeFunction *getFunction(AstTree *value) { case AST_TREE_TOKEN_OPERATOR_MULTIPLY: case AST_TREE_TOKEN_OPERATOR_DIVIDE: case AST_TREE_TOKEN_OPERATOR_MODULO: + case AST_TREE_TOKEN_SCOPE: return NULL; case AST_TREE_TOKEN_NONE: } @@ -1293,6 +1440,7 @@ bool isConst(AstTree *value) { case AST_TREE_TOKEN_OPERATOR_MULTIPLY: case AST_TREE_TOKEN_OPERATOR_DIVIDE: case AST_TREE_TOKEN_OPERATOR_MODULO: + case AST_TREE_TOKEN_SCOPE: return false; case AST_TREE_TOKEN_VARIABLE: { AstTreeVariable *metadata = value->metadata; @@ -1361,6 +1509,7 @@ AstTree *makeTypeOf(AstTree *value) { case AST_TREE_TOKEN_KEYWORD_PRINT_U64: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_IF: + case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_NONE: } UNREACHABLE; @@ -1384,6 +1533,7 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_OPERATOR_MODULO: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: + case AST_TREE_TOKEN_SCOPE: return false; case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: @@ -1424,6 +1574,7 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { bool isCircularDependencies(AstTreeHelper *helper, AstTreeVariable *variable, AstTree *tree) { switch (tree->token) { + case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_VOID: @@ -1543,7 +1694,10 @@ bool setAllTypes(AstTree *tree, AstTreeFunction *function) { return setTypesVariableDefine(tree); case AST_TREE_TOKEN_KEYWORD_IF: return setTypesIf(tree, function); + case AST_TREE_TOKEN_SCOPE: + return setTypesScope(tree, function); case AST_TREE_TOKEN_NONE: + break; } UNREACHABLE; } @@ -1733,7 +1887,7 @@ bool setTypesIf(AstTree *tree, AstTreeFunction *function) { AstTreeIf *metadata = tree->metadata; if (!setAllTypes(metadata->condition, function) || - !setAllTypes(metadata->body, function)) { + !setAllTypes(metadata->ifBody, function)) { return false; } @@ -1748,6 +1902,26 @@ bool setTypesIf(AstTree *tree, AstTreeFunction *function) { return true; } +bool setTypesScope(AstTree *tree, AstTreeFunction *function) { + AstTreeScope *metadata = tree->metadata; + + tree->type = &AST_TREE_VOID_TYPE; + + for (size_t i = 0; i < metadata->expressions_size; ++i) { + if (!setAllTypes(metadata->expressions[i], function)) { + return false; + } + } + + for (size_t i = 0; i < metadata->variables.size; ++i) { + if (!setTypesAstVariable(metadata->variables.data[i])) { + return false; + } + } + + return true; +} + bool setTypesAstInfix(AstTreeInfix *infix) { return setAllTypes(&infix->left, NULL) && setAllTypes(&infix->right, NULL); } @@ -1787,8 +1961,10 @@ bool astTreeClean(AstTree *tree) { case AST_TREE_TOKEN_OPERATOR_MULTIPLY: case AST_TREE_TOKEN_OPERATOR_DIVIDE: case AST_TREE_TOKEN_OPERATOR_MODULO: + case AST_TREE_TOKEN_SCOPE: return true; case AST_TREE_TOKEN_NONE: + break; } UNREACHABLE; } @@ -1879,6 +2055,7 @@ size_t astTreeTypeSize(AstTree tree) { case AST_TREE_TOKEN_OPERATOR_MULTIPLY: case AST_TREE_TOKEN_OPERATOR_DIVIDE: case AST_TREE_TOKEN_OPERATOR_MODULO: + case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_NONE: } UNREACHABLE; diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index 38a6f66..594b213 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -33,6 +33,8 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_OPERATOR_DIVIDE, AST_TREE_TOKEN_OPERATOR_MODULO, + AST_TREE_TOKEN_SCOPE, + AST_TREE_TOKEN_NONE, } AstTreeToken; @@ -109,7 +111,8 @@ typedef struct AstTreeReturn { typedef struct AstTreeIf { AstTree *condition; - AstTree *body; + AstTree *ifBody; + AstTree *elseBody; } AstTreeIf; typedef struct AstTreeHelper { @@ -141,31 +144,22 @@ AstTreeVariable *getVariable(AstTreeHelper *helper, char *name_begin, char *name_end); AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper); - AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *helper); - AstTree *astTreeParseTypeFunction(ParserNode *parserNode, AstTreeHelper *helper); - AstTree *astTreeParseFunctionCall(ParserNode *parserNode, AstTreeHelper *helper); - AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTreeHelper *helper); - AstTree *astTreeParsePrintU64(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseReturn(ParserNode *parserNode, AstTreeHelper *helper); - AstTree *astTreeParseBinaryOperator(ParserNode *parserNode, AstTreeHelper *helper, AstTreeToken token); - AstTree *astTreeParseUnaryOperator(ParserNode *parserNode, AstTreeHelper *helper, AstTreeToken token); - bool astTreeParseConstant(ParserNode *parserNode, AstTreeHelper *helper); - AstTree *astTreeParseVariable(ParserNode *parserNode, AstTreeHelper *helper); - AstTree *astTreeParseIf(ParserNode *parserNode, AstTreeHelper *helper); +AstTree *astTreeParseCurlyBracket(ParserNode *parserNode, AstTreeHelper *helper); AstTreeFunction *getFunction(AstTree *value); bool isConst(AstTree *value); @@ -188,6 +182,7 @@ bool setTypesOperatorInfix(AstTree *tree); bool setTypesOperatorUnary(AstTree *tree); bool setTypesVariableDefine(AstTree *tree); bool setTypesIf(AstTree *tree,AstTreeFunction *function); +bool setTypesScope(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 a61c3af..1f45be0 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -21,6 +21,7 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_KEYWORD_TRUE", "LEXER_TOKEN_KEYWORD_FALSE", "LEXER_TOKEN_KEYWORD_IF", + "LEXER_TOKEN_KEYWORD_ELSE", "LEXER_TOKEN_NUMBER", @@ -68,14 +69,15 @@ 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", "if", + "type", "void", "u64", "bool", "print_u64", + "return", "true", "false", "if", "else", }; 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, + LEXER_TOKEN_KEYWORD_IF, LEXER_TOKEN_KEYWORD_ELSE, }; const size_t LEXER_KEYWORD_SIZE = sizeof(LEXER_KEYWORD_TOKENS) / sizeof(*LEXER_KEYWORD_TOKENS); @@ -208,6 +210,7 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter, case LEXER_TOKEN_KEYWORD_TRUE: case LEXER_TOKEN_KEYWORD_FALSE: case LEXER_TOKEN_KEYWORD_IF: + case LEXER_TOKEN_KEYWORD_ELSE: 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 4e74d1d..e7afd62 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -14,6 +14,7 @@ typedef enum LexerToken { LEXER_TOKEN_KEYWORD_TRUE, LEXER_TOKEN_KEYWORD_FALSE, LEXER_TOKEN_KEYWORD_IF, + LEXER_TOKEN_KEYWORD_ELSE, LEXER_TOKEN_NUMBER, diff --git a/src/compiler/parser.c b/src/compiler/parser.c index d4364af..b952dc1 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -297,8 +297,13 @@ void parserNodePrint(const ParserNode *node, int indent) { printf(",\n"); for (int i = 0; i < indent; ++i) printf(" "); - printf("body=\n"); - parserNodePrint(metadata->body, indent + 1); + printf("ifBody=\n"); + parserNodePrint(metadata->ifBody, indent + 1); + printf("\n,"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("elseBody=\n"); + parserNodePrint(metadata->elseBody, indent + 1); printf("\n"); for (int i = 0; i < indent; ++i) printf(" "); @@ -404,7 +409,8 @@ void parserNodeDelete(ParserNode *node) { case PARSER_TOKEN_KEYWORD_IF: { ParserNodeIfMetadata *metadata = node->metadata; parserNodeDelete(metadata->condition); - parserNodeDelete(metadata->body); + parserNodeDelete(metadata->ifBody); + parserNodeDelete(metadata->elseBody); free(metadata); } goto RETURN_SUCCESS; @@ -577,6 +583,7 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, } case LEXER_TOKEN_KEYWORD_IF: return parserIf(node, end, parent); + case LEXER_TOKEN_KEYWORD_ELSE: case LEXER_TOKEN_SYMBOL: case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS: case LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET: @@ -588,6 +595,23 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, ParserNode *getUntilCommonParent(ParserNode *node, ParserNode *parent) { while (node != NULL && node != parent && node->parent != parent) { + if (node == node->parent) { + return NULL; + } + + node = node->parent; + } + return node; +} + +ParserNode *getUntilCommonParents(ParserNode *node, ParserNode *parent, + ParserNode *parent2) { + while (node != NULL && node != parent && node->parent != parent && + node->parent != parent2) { + if (node == node->parent) { + return NULL; + } + node = node->parent; } return node; @@ -616,6 +640,29 @@ ParserNode *getNextUsingCommonParent(LexerNode *node, LexerNode *end, return NULL; } +LexerNode *getNextLexerNodeUsingCommonParent(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 node; + } + } + + return NULL; +} + ParserNode *parserIdentifier(LexerNode *node, ParserNode *parent) { return node->parserNode = newParserNode(PARSER_TOKEN_IDENTIFIER, node->str_begin, @@ -781,9 +828,11 @@ ParserNode *parserParenthesis(LexerNode *closing, LexerNode *begin, for (LexerNode *iter = closing - 1; iter >= begin; --iter) { if (iter->parserNode != NULL) { - ParserNode *pNode = getUntilCommonParent(iter->parserNode, parent); + ParserNode *pNode = + getUntilCommonParents(iter->parserNode, parent, parserNode); if (pNode == NULL) { printLog("Bad node", pNode->str_begin, pNode->str_end); + return NULL; } else { pNode->parent = parserNode; } @@ -850,9 +899,11 @@ ParserNode *parserCurlyBrackets(LexerNode *closing, LexerNode *begin, for (LexerNode *iter = closing - 1; iter >= begin; --iter) { if (iter->parserNode != NULL) { - ParserNode *pNode = getUntilCommonParent(iter->parserNode, parent); + ParserNode *pNode = + getUntilCommonParents(iter->parserNode, parent, parserNode); if (pNode == NULL) { - printLog("Bad node", pNode->str_begin, pNode->str_end); + printLog(iter->str_begin, iter->str_end, "Bad node"); + return NULL; } else { pNode->parent = parserNode; } @@ -868,11 +919,11 @@ ParserNode *parserCurlyBrackets(LexerNode *closing, LexerNode *begin, return NULL; } - parserNode->str_begin = opening->str_begin, + parserNode->str_begin = opening->str_begin; parserNode->str_end = closing->str_end; - opening->parserNode = parserNode; - closing->parserNode = parserNode; + opening->parserNode = closing->parserNode = parserNode; + if (parserNodeArray(opening + 1, closing, parserNode)) { return parserNode; } else { @@ -1156,7 +1207,9 @@ ParserNode *parserIf(LexerNode *node, LexerNode *end, ParserNode *parent) { return NULL; } - ParserNode *body = getNextUsingCommonParent(conditionNode, end, parent); + LexerNode *bodyNode = + getNextLexerNodeUsingCommonParent(conditionNode, end, parent); + ParserNode *body = getUntilCommonParent(bodyNode->parserNode, parent); if (body == NULL) { printError(node->str_begin, node->str_end, "If has bad body"); @@ -1165,11 +1218,37 @@ ParserNode *parserIf(LexerNode *node, LexerNode *end, ParserNode *parent) { ParserNodeIfMetadata *metadata = a404m_malloc(sizeof(*metadata)); metadata->condition = condition; - metadata->body = body; + metadata->ifBody = body; + + LexerNode *elseNode = + getNextLexerNodeUsingCommonParent(bodyNode, end, parent); + if (elseNode == NULL || elseNode->token != LEXER_TOKEN_KEYWORD_ELSE) { + metadata->elseBody = NULL; + return condition->parent = body->parent = node->parserNode = + newParserNode(PARSER_TOKEN_KEYWORD_IF, node->str_begin, + body->str_end, metadata, parent); + } + + LexerNode *elseBodyNode = elseNode + 1; + + if (elseBodyNode >= end || elseBodyNode->parserNode == NULL) { + printError(elseNode->str_begin, elseNode->str_end, "Else has bad body"); + return NULL; + } + + ParserNode *elseBody = getUntilCommonParent(elseBodyNode->parserNode, parent); + + if (elseBody == NULL) { + printError(elseNode->str_begin, elseNode->str_end, "Else has bad body"); + return NULL; + } + + metadata->elseBody = elseBody; - return condition->parent = body->parent = node->parserNode = - newParserNode(PARSER_TOKEN_KEYWORD_IF, node->str_begin, - node->str_end, metadata, parent); + return elseBody->parent = elseNode->parserNode = condition->parent = + body->parent = node->parserNode = + newParserNode(PARSER_TOKEN_KEYWORD_IF, node->str_begin, + elseBody->str_end, metadata, parent); } bool isAllArguments(const ParserNodeArray *nodes) { diff --git a/src/compiler/parser.h b/src/compiler/parser.h index cb90b71..60825a9 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -106,7 +106,8 @@ typedef bool ParserNodeBoolMetadata; typedef struct ParserNodeIfMetadata { ParserNode *condition; - ParserNode *body; + ParserNode *ifBody; + ParserNode *elseBody; }ParserNodeIfMetadata; void parserNodePrint(const ParserNode *node, int indent); @@ -122,7 +123,9 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, ParserNode *parent, bool *conti); ParserNode *getUntilCommonParent(ParserNode *node, ParserNode *parent); +ParserNode *getUntilCommonParents(ParserNode *node, ParserNode *parent,ParserNode *parent2); ParserNode *getNextUsingCommonParent(LexerNode *node,LexerNode *end, ParserNode *parent); +LexerNode *getNextLexerNodeUsingCommonParent(LexerNode *node,LexerNode *end, ParserNode *parent); ParserNode *parserIdentifier(LexerNode *node, ParserNode *parent); ParserNode *parserType(LexerNode *node, ParserNode *parent); |