summaryrefslogtreecommitdiff
path: root/42sh/src/parser/parser_conditionnals.c
diff options
context:
space:
mode:
authorMartial Simon <msimon_fr@hotmail.com>2025-09-15 01:07:58 +0200
committerMartial Simon <msimon_fr@hotmail.com>2025-09-15 01:07:58 +0200
commit967be9e750221ab2ab783f95df79bb26d290a45e (patch)
tree6802900a5e975f9f68b169f0f503f040056d6952 /42sh/src/parser/parser_conditionnals.c
add: added projectsHEADmain
Diffstat (limited to '42sh/src/parser/parser_conditionnals.c')
-rw-r--r--42sh/src/parser/parser_conditionnals.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/42sh/src/parser/parser_conditionnals.c b/42sh/src/parser/parser_conditionnals.c
new file mode 100644
index 0000000..ef1f67a
--- /dev/null
+++ b/42sh/src/parser/parser_conditionnals.c
@@ -0,0 +1,152 @@
+#include "parser/parser_functions.h"
+#include "parser/parser_utils.h"
+
+struct ast *parse_rule_if(struct lexer *lexer, enum parser_state *state)
+{
+ struct token next = lexer_peek(lexer);
+ // Not mandatory because we checked before going in here
+ if (next.type != TOKEN_IF)
+ {
+ QUICK_CLEANUP
+ }
+
+ struct ast *root = ast_create(AST_IF);
+
+ if (root == NULL)
+ {
+ *state = ERROR;
+ return NULL;
+ }
+
+ lexer_pop(lexer);
+
+ struct ast *cond = parse_compound_list(lexer, state);
+
+ next = lexer_peek(lexer);
+ if (error_check(root, state, next))
+ {
+ return NULL;
+ }
+
+ set_left(root, cond);
+
+ if (next.type != TOKEN_THEN)
+ {
+ cleanup(root, state);
+ return NULL;
+ }
+
+ lexer_pop(lexer);
+
+ cond = parse_compound_list(lexer, state);
+ next = lexer_peek(lexer);
+ if (error_check(root, state, next))
+ {
+ return NULL;
+ }
+
+ if (cond == NULL)
+ {
+ cleanup(root, state);
+ return NULL;
+ }
+
+ set_right(root, cond);
+
+ if (next.type != TOKEN_FI)
+ {
+ cond = parse_else_clause(lexer, state);
+ if (cond == NULL)
+ {
+ cleanup(root, state);
+ return NULL;
+ }
+ set_i(root, cond, 2);
+ }
+
+ lexer_pop(lexer);
+
+ return root;
+}
+
+struct ast *parse_else_clause(struct lexer *lexer, enum parser_state *state)
+{
+ struct token next = lexer_peek(lexer);
+ struct ast *root = NULL;
+
+ if (next.type == TOKEN_ELSE)
+ {
+ lexer_pop(lexer);
+
+ struct ast *cond = parse_compound_list(lexer, state);
+
+ if (cond == NULL)
+ {
+ cleanup(root, state);
+ return NULL;
+ }
+
+ if (error_check(cond, state, next))
+ {
+ return NULL;
+ }
+
+ return cond;
+ }
+ else if (next.type != TOKEN_ELIF)
+ {
+ cleanup(NULL, state);
+ return NULL;
+ }
+
+ lexer_pop(lexer);
+
+ // Doesn' it seems stupid to just manually re-creating the IF again?
+ // Can't I just call parse_if there ? But we won't be following the grammar
+ // This is a late-game optimization that might not be worth it
+ root = ast_create(AST_IF);
+ if (root == NULL)
+ {
+ cleanup(root, state);
+ return NULL;
+ }
+
+ struct ast *cond = parse_compound_list(lexer, state);
+ set_left(root, cond);
+
+ if (error_check(root, state, next))
+ {
+ return NULL;
+ }
+
+ next = lexer_peek(lexer);
+
+ if (next.type != TOKEN_THEN)
+ {
+ cleanup(root, state);
+ return NULL;
+ }
+
+ lexer_pop(lexer);
+
+ set_right(root, parse_compound_list(lexer, state));
+
+ if (error_check(root, state, next))
+ {
+ return NULL;
+ }
+
+ next = lexer_peek(lexer);
+
+ if (next.type == TOKEN_ELSE || next.type == TOKEN_ELIF)
+ {
+ cond = parse_else_clause(lexer, state);
+ if (error_check(root, state, next))
+ {
+ return NULL;
+ }
+ set_i(root, cond, 2);
+ }
+
+ return root;
+}