summaryrefslogtreecommitdiff
path: root/42sh/src/parser/parser_operators.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_operators.c
add: added projectsHEADmain
Diffstat (limited to '42sh/src/parser/parser_operators.c')
-rw-r--r--42sh/src/parser/parser_operators.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/42sh/src/parser/parser_operators.c b/42sh/src/parser/parser_operators.c
new file mode 100644
index 0000000..31cebbb
--- /dev/null
+++ b/42sh/src/parser/parser_operators.c
@@ -0,0 +1,122 @@
+#include "parser/parser_functions.h"
+#include "parser/parser_utils.h"
+
+struct ast *parse_and_or(struct lexer *lexer, enum parser_state *state)
+{
+ struct ast *node = parse_pipeline(lexer, state);
+ struct token next = lexer_peek(lexer);
+
+ if (error_check(node, state, next))
+ {
+ QUICK_CLEANUP
+ }
+
+ while (next.type == TOKEN_AND || next.type == TOKEN_OR)
+ {
+ struct ast *logical = ast_create(AST_LOGICAL);
+ if (logical == NULL)
+ {
+ cleanup(node, state);
+ return NULL;
+ }
+
+ ((struct ast_logical *)logical)->type = next.type;
+
+ lexer_pop(lexer);
+ next = lexer_peek(lexer);
+
+ while (next.type == TOKEN_NEWLINE)
+ {
+ lexer_pop(lexer);
+ next = lexer_peek(lexer);
+ }
+
+ set_left(logical, node);
+
+ struct ast *right = parse_pipeline(lexer, state);
+
+ // So it's ready for next iteration + usable in error_check()
+ next = lexer_peek(lexer);
+
+ // If there IS an error, then it MUST have returned NULL
+ // So no need to free 'right'
+ if (error_check(logical, state, next))
+ {
+ return NULL;
+ }
+
+ set_right(logical, right);
+ node = logical;
+ }
+ return node;
+}
+
+struct ast *parse_pipeline(struct lexer *lexer, enum parser_state *state)
+{
+ struct ast *negation = NULL;
+ struct token next = lexer_peek(lexer);
+
+ if (next.type == TOKEN_NEG)
+ {
+ negation = ast_create(AST_LOGICAL);
+ if (negation == NULL)
+ {
+ QUICK_CLEANUP
+ }
+
+ union ast_caster cast;
+ cast.ast = negation;
+ cast.ast_lo->type = next.type;
+
+ lexer_pop(lexer);
+ next = lexer_peek(lexer);
+ }
+
+ struct ast *node = parse_command(lexer, state);
+ next = lexer_peek(lexer);
+
+ if (negation != NULL)
+ {
+ set_left(negation, node);
+ node = negation;
+ }
+
+ // If there is an error here (aka node failed), just negation is alloc'ed
+ if (error_check(negation, state, next))
+ {
+ return NULL;
+ }
+
+ while (next.type == TOKEN_PIPE)
+ {
+ lexer_pop(lexer);
+ struct ast *pipe = ast_create(AST_PIPELINE);
+
+ if (pipe == NULL)
+ {
+ cleanup(node, state);
+ return NULL;
+ }
+
+ set_left(pipe, node);
+
+ while (next.type == TOKEN_NEWLINE)
+ {
+ lexer_pop(lexer);
+ next = lexer_peek(lexer);
+ }
+
+ set_right(pipe, parse_command(lexer, state));
+
+ next = lexer_peek(lexer);
+
+ if (error_check(pipe, state, next))
+ {
+ return NULL;
+ }
+
+ node = pipe;
+ }
+
+ return node;
+}