From c022367c713d6c1bb42c02f360fddd9794f05004 Mon Sep 17 00:00:00 2001 From: Radim Mifka Date: Fri, 17 Nov 2023 02:06:44 +0100 Subject: [PATCH] Replace unnecessary ElseClauseASTNode --- include/compiler/parser/ASTNodes.h | 13 +----- src/compiler/parser/ASTNodes.c | 20 ++-------- src/compiler/parser/Parser.c | 63 +++++++++++------------------- test/compiler/parser/Parser.test.c | 30 +++++--------- 4 files changed, 39 insertions(+), 87 deletions(-) diff --git a/include/compiler/parser/ASTNodes.h b/include/compiler/parser/ASTNodes.h index afc7102..ace7516 100644 --- a/include/compiler/parser/ASTNodes.h +++ b/include/compiler/parser/ASTNodes.h @@ -28,7 +28,6 @@ enum ASTNodeType { NODE_ARGUMENT_LIST, NODE_FUNCTION_CALL, NODE_IF_STATEMENT, - NODE_ELSE_CLAUSE, NODE_PATTERN, NODE_CONDITION, NODE_OPTIONAL_BINDING_CONDITION, @@ -205,18 +204,11 @@ typedef struct ConditionASTNode { OptionalBindingConditionASTNode *optionalBindingCondition; } ConditionASTNode; -typedef struct ElseClauseASTNode { - enum ASTNodeType _type; - struct IfStatementASTNode *ifStatement; - BlockASTNode *body; - bool isElseIf; -} ElseClauseASTNode; - typedef struct IfStatementASTNode { enum ASTNodeType _type; ConditionASTNode *condition; BlockASTNode *body; - ElseClauseASTNode *elseClause; + ASTNode /* BlockASTNode | IfStatementASTNode | null */ *alternate; } IfStatementASTNode; typedef struct WhileStatementASTNode { @@ -256,8 +248,7 @@ FunctionCallASTNode* new_FunctionCallASTNode(IdentifierASTNode *id, ArgumentList PatternASTNode* new_PatternASTNode(IdentifierASTNode *id, TypeReferenceASTNode *type); OptionalBindingConditionASTNode* new_OptionalBindingConditionASTNode(PatternASTNode *pattern, ExpressionASTNode *initializer, bool isConstant); ConditionASTNode* new_ConditionASTNode(ExpressionASTNode *expression, OptionalBindingConditionASTNode *optionalBindingCondition); -ElseClauseASTNode* new_ElseClauseASTNode(IfStatementASTNode *ifStatement, BlockASTNode *body, bool isElseIf); -IfStatementASTNode* new_IfStatementASTNode(ConditionASTNode *condition, BlockASTNode *body, ElseClauseASTNode *elseClause); +IfStatementASTNode* new_IfStatementASTNode(ConditionASTNode *condition, BlockASTNode *body, ASTNode *alternate); WhileStatementASTNode* new_WhileStatementASTNode(ConditionASTNode *condition, BlockASTNode *body); AssignmentStatementASTNode* new_AssignmentStatementASTNode(IdentifierASTNode *id, ExpressionASTNode *assignment); diff --git a/src/compiler/parser/ASTNodes.c b/src/compiler/parser/ASTNodes.c index a2d54f6..02441d7 100644 --- a/src/compiler/parser/ASTNodes.c +++ b/src/compiler/parser/ASTNodes.c @@ -184,27 +184,15 @@ ConditionASTNode * new_ConditionASTNode( return node; } -ElseClauseASTNode * new_ElseClauseASTNode( - IfStatementASTNode *ifStatement, - BlockASTNode *body, - bool isElseIf -) { - prepare_node_of(ElseClauseASTNode, NODE_ELSE_CLAUSE) - node->ifStatement = ifStatement; - node->body = body; - node->isElseIf = isElseIf; - return node; -} - IfStatementASTNode * new_IfStatementASTNode( ConditionASTNode *condition, BlockASTNode *body, - ElseClauseASTNode *elseClause + ASTNode *alternate ) { prepare_node_of(IfStatementASTNode, NODE_IF_STATEMENT) node->condition = condition; node->body = body; - node->elseClause = elseClause; + node->alternate = alternate; return node; } @@ -243,12 +231,12 @@ BinaryExpressionASTNode* new_BinaryExpressionASTNode( UnaryExpressionASTNode* new_UnaryExpressionASTNode( ExpressionASTNode *argument, OperatorType operator - //bool IsPrefix + // bool IsPrefix ) { prepare_node_of(UnaryExpressionASTNode, NODE_UNARY_EXPRESSION) node->argument = argument; node->operator = operator; - //node->isPrefix = isPrefix; + // node->isPrefix = isPrefix; return node; } diff --git a/src/compiler/parser/Parser.c b/src/compiler/parser/Parser.c index 3bd735f..3855edd 100644 --- a/src/compiler/parser/Parser.c +++ b/src/compiler/parser/Parser.c @@ -21,7 +21,6 @@ ParserResult __Parser_parseFuncStatement(Parser *parser); ParserResult __Parser_parsePattern(Parser *parser); ParserResult __Parser_parseOptionalBindingCondition(Parser *parser); ParserResult __Parser_parseCondition(Parser *parser); -ParserResult __Parser_parseElseClause(Parser *parser); ParserResult __Parser_parseIfStatement(Parser *parser); ParserResult __Parser_parseWhileStatement(Parser *parser); ParserResult __Parser_parseReturnStatement(Parser *parser); @@ -506,40 +505,6 @@ ParserResult __Parser_parseCondition(Parser *parser) { return ParserSuccess(condition); } -ParserResult __Parser_parseElseClause(Parser *parser) { - assertf(parser != NULL); - - // skip else keyword - LexerResult result = Lexer_nextToken(parser->lexer); - if(!result.success) return LexerToParserError(result); - - LexerResult peek = Lexer_peekToken(parser->lexer, 1); - if(!peek.success) return LexerToParserError(peek); - - IfStatementASTNode *ifStatement = NULL; - bool isElseIf = false; - BlockASTNode *body = NULL; - - if(peek.token->kind == TOKEN_IF) { - // consume if keyword - result = Lexer_nextToken(parser->lexer); - if(!result.success) return LexerToParserError(result); - - ParserResult ifStatementResult = __Parser_parseIfStatement(parser); - if(!ifStatementResult.success) return ifStatementResult; - ifStatement = (IfStatementASTNode*)ifStatementResult.node; - isElseIf = true; - } else { - ParserResult blockResult = __Parser_parseBlock(parser, true); - if(!blockResult.success) return blockResult; - body = (BlockASTNode*)blockResult.node; - } - - ElseClauseASTNode *elseClause = new_ElseClauseASTNode(ifStatement, body, isElseIf); - - return ParserSuccess(elseClause); -} - ParserResult __Parser_parseIfStatement(Parser *parser) { assertf(parser != NULL); @@ -569,15 +534,33 @@ ParserResult __Parser_parseIfStatement(Parser *parser) { peek = Lexer_peekToken(parser->lexer, 1); if(!peek.success) return LexerToParserError(peek); - ElseClauseASTNode *elseClause = NULL; + ASTNode *alternate = NULL; if(peek.token->kind == TOKEN_ELSE) { - ParserResult elseClauseResult = __Parser_parseElseClause(parser); - if(!elseClauseResult.success) return elseClauseResult; - elseClause = (ElseClauseASTNode*)elseClauseResult.node; + // skip else keyword + LexerResult result = Lexer_nextToken(parser->lexer); + if(!result.success) return LexerToParserError(result); + + LexerResult peek = Lexer_peekToken(parser->lexer, 1); + if(!peek.success) return LexerToParserError(peek); + + if(peek.token->kind == TOKEN_IF) { + // consume if keyword + result = Lexer_nextToken(parser->lexer); + if(!result.success) return LexerToParserError(result); + + ParserResult ifStatementResult = __Parser_parseIfStatement(parser); + if(!ifStatementResult.success) return ifStatementResult; + alternate = (ASTNode*)ifStatementResult.node; + + } else { + ParserResult blockResult = __Parser_parseBlock(parser, true); + if(!blockResult.success) return blockResult; + alternate = (ASTNode*)blockResult.node; + } } - IfStatementASTNode *ifStatement = new_IfStatementASTNode((ConditionASTNode*)conditionResult.node, (BlockASTNode*)blockResult.node, (ElseClauseASTNode*)elseClause); + IfStatementASTNode *ifStatement = new_IfStatementASTNode((ConditionASTNode*)conditionResult.node, (BlockASTNode*)blockResult.node, (ASTNode*)alternate); return ParserSuccess(ifStatement); } diff --git a/test/compiler/parser/Parser.test.c b/test/compiler/parser/Parser.test.c index 83d5c6c..a9fc298 100644 --- a/test/compiler/parser/Parser.test.c +++ b/test/compiler/parser/Parser.test.c @@ -520,7 +520,7 @@ DESCRIBE(if_statement, "If statement parsing") { EXPECT_EQUAL_INT(arr->size, 0); // else - EXPECT_NULL(if_statement->elseClause); + EXPECT_NULL(if_statement->alternate); } TEST_END(); @@ -549,14 +549,9 @@ DESCRIBE(if_statement, "If statement parsing") { EXPECT_NULL(arr->data); EXPECT_EQUAL_INT(arr->size, 0); - // else - EXPECT_NOT_NULL(if_statement->elseClause); - EXPECT_FALSE(if_statement->elseClause->isElseIf); - EXPECT_NULL(if_statement->elseClause->ifStatement); - EXPECT_NOT_NULL(if_statement->elseClause->body); - // else body - body = if_statement->elseClause->body; + EXPECT_TRUE(if_statement->alternate->_type == NODE_BLOCK); + body = (BlockASTNode*)if_statement->alternate; EXPECT_NOT_NULL(body->statements); arr = body->statements; EXPECT_NULL(arr->data); @@ -602,11 +597,11 @@ DESCRIBE(if_statement, "If statement parsing") { EXPECT_EQUAL_INT(arr->size, 0); // else if - EXPECT_NOT_NULL(if_statement->elseClause); - EXPECT_TRUE(if_statement->elseClause->isElseIf); - EXPECT_NOT_NULL(if_statement->elseClause->ifStatement); + EXPECT_NOT_NULL(if_statement->alternate); + + EXPECT_TRUE(if_statement->alternate->_type == NODE_IF_STATEMENT); - IfStatementASTNode *elseif = if_statement->elseClause->ifStatement; + IfStatementASTNode *elseif = (IfStatementASTNode*)if_statement->alternate; EXPECT_NOT_NULL(elseif->condition); EXPECT_TRUE(elseif->condition->_type == NODE_CONDITION); @@ -635,14 +630,9 @@ DESCRIBE(if_statement, "If statement parsing") { EXPECT_NULL(arr->data); EXPECT_EQUAL_INT(arr->size, 0); - // else - EXPECT_NOT_NULL(elseif->elseClause); - EXPECT_FALSE(elseif->elseClause->isElseIf); - EXPECT_NULL(elseif->elseClause->ifStatement); - EXPECT_NOT_NULL(elseif->elseClause->body); - // else body - body = elseif->elseClause->body; + EXPECT_TRUE(elseif->alternate->_type == NODE_BLOCK); + body = (BlockASTNode*)elseif->alternate; EXPECT_NOT_NULL(body->statements); arr = body->statements; EXPECT_NULL(arr->data); @@ -705,7 +695,7 @@ DESCRIBE(if_statement, "If statement parsing") { EXPECT_EQUAL_INT(arr->size, 0); // else - EXPECT_NULL(if_statement->elseClause); + EXPECT_NULL(if_statement->alternate); } TEST_END(); }