* [PATCH olang] parser: conform block line feeds with the spec
@ 2024-10-08 16:33 Carlos Maniero
2024-10-08 16:33 ` [olang/patches/.build.yml] build failed builds.sr.ht
2024-10-08 18:38 ` [PATCH olang] parser: conform block line feeds with the spec Johnny Richard
0 siblings, 2 replies; 4+ messages in thread
From: Carlos Maniero @ 2024-10-08 16:33 UTC (permalink / raw)
To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero
The line feeds has been handled by the statement parser functions when
the olang spec describe this grammar rule as a block responsibility.
There was also a FIXME related to allowing line feeds in between the
if/else statement and the block start that was also addressed.
Signed-off-by: Carlos Maniero <carlos@maniero.me>
---
src/parser.c | 47 ++++++++++++++-----------
| 30 ++++++++++++++++
2 files changed, 57 insertions(+), 20 deletions(-)
create mode 100644 tests/olc/0031_else_extra_line_feeds.ol
diff --git a/src/parser.c b/src/parser.c
index d16b79d..2096129 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -70,6 +70,9 @@ parser_parse_factor(parser_t *parser);
static void
skip_line_feeds(lexer_t *lexer);
+static void
+peek_next_non_lf_token(lexer_t *lexer, token_t *token);
+
void
parser_init(parser_t *parser, lexer_t *lexer, arena_t *arena)
{
@@ -493,6 +496,12 @@ StartLoop:
return NULL;
}
+ if (!skip_expected_token(parser, TOKEN_LF)) {
+ return NULL;
+ }
+
+ skip_line_feeds(parser->lexer);
+
list_append(node_block->as_block.nodes, node);
goto StartLoop;
@@ -522,11 +531,6 @@ parser_parse_return_stmt(parser_t *parser)
ast_node_t *node_return_stmt = ast_new_node_return_stmt(parser->arena, token_ret.loc, expr);
assert(node_return_stmt);
- if (!skip_expected_token(parser, TOKEN_LF)) {
- return NULL;
- }
- skip_line_feeds(parser->lexer);
-
return node_return_stmt;
}
@@ -544,6 +548,8 @@ parser_parse_if_stmt(parser_t *parser)
return NULL;
}
+ skip_line_feeds(parser->lexer);
+
ast_node_t *then = parser_parse_block(parser);
if (then == NULL) {
@@ -553,29 +559,25 @@ parser_parse_if_stmt(parser_t *parser)
ast_node_t *_else = NULL;
token_t next_token;
- lexer_next_token(parser->lexer, &next_token);
-
- // FIXME: We are not allowing line feed right after if block statement when
- // the else branch is present. We also noticed that if has the same
- // problem which will be addressed later.
+ peek_next_non_lf_token(parser->lexer, &next_token);
if (next_token.kind == TOKEN_ELSE) {
+ skip_line_feeds(parser->lexer);
+ lexer_next_token(parser->lexer, &next_token);
+ skip_line_feeds(parser->lexer);
+
_else = parser_parse_block(parser);
if (_else == NULL) {
return NULL;
}
- } else if (!expected_token(&next_token, TOKEN_LF)) {
- return NULL;
}
ast_node_t *node_if_stmt = ast_new_node_if_stmt(parser->arena, token_if.loc, cond, then, _else);
assert(node_if_stmt);
- skip_line_feeds(parser->lexer);
-
return node_if_stmt;
}
@@ -608,8 +610,6 @@ parser_parse_var_def(parser_t *parser)
ast_node_t *var_node = ast_new_node_var_def(parser->arena, token_id.loc, token_id.value, var_type, expr);
- skip_line_feeds(parser->lexer);
-
return var_node;
}
@@ -631,10 +631,6 @@ parser_parse_var_assign_stmt(parser_t *parser)
ast_node_t *ref = ast_new_node_ref(parser->arena, token_id.loc, token_id.value);
ast_node_t *expr = parser_parse_expr(parser);
- // FIXME: The expected line feed should be parsed from parent call
- // according to the grammar rules
- skip_line_feeds(parser->lexer);
-
return ast_new_node_var_assign_stmt(parser->arena, token_eq.loc, ref, expr);
}
@@ -683,3 +679,14 @@ skip_line_feeds(lexer_t *lexer)
lexer_peek_next(lexer, &token);
}
}
+
+static void
+peek_next_non_lf_token(lexer_t *lexer, token_t *token)
+{
+ lexer_cursor_t cur = lexer->cur;
+
+ skip_line_feeds(lexer);
+ lexer_peek_next(lexer, token);
+
+ lexer->cur = cur;
+}
--git a/tests/olc/0031_else_extra_line_feeds.ol b/tests/olc/0031_else_extra_line_feeds.ol
new file mode 100644
index 0000000..bc44ccd
--- /dev/null
+++ b/tests/olc/0031_else_extra_line_feeds.ol
@@ -0,0 +1,30 @@
+# Copyright (C) 2024 olang mantainers
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+fn main(): u32
+{
+ if 0 != 0
+ {
+ return 1
+ }
+ else
+ {
+ return 0
+ }
+}
+
+# TEST test_compile(exit_code=0)
+
+# TEST test_run_binary(exit_code=0)
base-commit: 3c8975ba27c87d084187eefe622cbd783e289c99
--
2.46.0
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-10-08 22:38 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-10-08 16:33 [PATCH olang] parser: conform block line feeds with the spec Carlos Maniero
2024-10-08 16:33 ` [olang/patches/.build.yml] build failed builds.sr.ht
2024-10-08 18:38 ` [PATCH olang] parser: conform block line feeds with the spec Johnny Richard
2024-10-08 22:38 ` Carlos Maniero
Code repositories for project(s) associated with this public inbox
https://git.johnnyrichard.com/olang.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox