From 734bc049e78ed4c01962ebd667c9633ad452afe2 Mon Sep 17 00:00:00 2001 From: Curle Date: Sun, 6 Mar 2022 01:52:37 +0000 Subject: [PATCH] Allow single statements in bodies of if, else, while and for --- src/Main.c | 9 ++++++++- src/Parser.c | 7 +++++++ src/Statements.c | 10 +++++----- tests/breakcontinue.er | 3 +-- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/Main.c b/src/Main.c index e17c3e8..7f4cefb 100644 --- a/src/Main.c +++ b/src/Main.c @@ -69,6 +69,9 @@ char* TokenNames[] = { "Void Type", "Function keyword", + "Break keyword", + "Continue keyword", + "Print Keyword", "If keyword", "Else keyword", @@ -77,7 +80,11 @@ char* TokenNames[] = { "Return keyword", - "Struct keyword" + "Struct keyword", + "Union keyword", + "Enum keyword", + "Alias keyword", + "Import keyword" }; char* ScopeNames[] = { diff --git a/src/Parser.c b/src/Parser.c index 995b9a2..a86d014 100644 --- a/src/Parser.c +++ b/src/Parser.c @@ -462,6 +462,8 @@ struct ASTNode* GetExpressionList() { /* * Handles parsing an individual statement. + * This has the ability to parse Compounds in the case it starts with a left brace. + * This solves the dangling else problem for the parser. * * It serves as a wrapper around: * * If Statement @@ -470,13 +472,18 @@ struct ASTNode* GetExpressionList() { * * Return Statement * * Numeric literals and variables * * Binary Expressions + * * @return the AST Node representing this single statement */ struct ASTNode* ParseStatement(void) { int Type; + struct ASTNode* Node; printf("\t\tBranch leads to here, type %s/%d\r\n", TokenNames[CurrentFile->CurrentSymbol.type], CurrentFile->CurrentSymbol.type); switch (CurrentFile->CurrentSymbol.type) { + case LI_LBRAC: + Node = ParseCompound(); + return Node; case TY_CHAR: case TY_LONG: case TY_INT: diff --git a/src/Statements.c b/src/Statements.c index 4808c23..9d39915 100644 --- a/src/Statements.c +++ b/src/Statements.c @@ -384,11 +384,11 @@ struct ASTNode* IfStatement() { VerifyToken(LI_RPARE, ")"); - True = ParseCompound(); + True = ParseStatement(); if (CurrentFile->CurrentSymbol.type == KW_ELSE) { Tokenise(); - False = ParseCompound(); + False = ParseStatement(); } return ConstructASTNode(OP_IF, RET_NONE, Condition, True, False, NULL, 0); @@ -428,14 +428,13 @@ struct ASTNode* WhileStatement() { Condition = ParsePrecedenceASTNode(0); - if (Condition->Operation < OP_EQUAL || Condition->Operation > OP_GREATE) Condition = ConstructASTBranch(OP_BOOLCONV, Condition->ExprType, Condition, NULL, 0); VerifyToken(LI_RPARE, ")"); CurrentFile->CurrentLoopDepth++; - Body = ParseCompound(); + Body = ParseStatement(); CurrentFile->CurrentLoopDepth--; return ConstructASTNode(OP_LOOP, RET_NONE, Condition, NULL, Body, NULL, 0); @@ -493,7 +492,7 @@ struct ASTNode* ForStatement() { VerifyToken(LI_RPARE, ")"); CurrentFile->CurrentLoopDepth++; - Body = ParseCompound(); + Body = ParseStatement(); CurrentFile->CurrentLoopDepth--; // We need to be able to skip over the body and the postop, so we group them together. @@ -572,6 +571,7 @@ struct ASTNode* BreakStatement() { Die("Unable to break without a loop"); Tokenise(); + Tokenise(); return ConstructASTLeaf(OP_BREAK, 0, NULL, 0); } diff --git a/tests/breakcontinue.er b/tests/breakcontinue.er index 8e08caf..9afd286 100644 --- a/tests/breakcontinue.er +++ b/tests/breakcontinue.er @@ -6,9 +6,8 @@ int :: main() { while (x < 15) { printf("%d\n", x); - if (x =? 12) { + if (x =? 12) break; - } if (x =? 10) { x = x + 2;