diff --git a/src/ast.h b/src/ast.h index b15bd5a..4cf92f0 100644 --- a/src/ast.h +++ b/src/ast.h @@ -102,14 +102,23 @@ typedef struct { extern const tokens_list_t TOKENS_LIST[]; +// Main funcs ast_t *parse_expression(ast_ctx_t *ctx); -void print_ast(ast_ctx_t *ctx, ast_t *ast, size_t depth); token_t get_next_token(ast_ctx_t *ctx); int visitor(char *buffer, env_t *env, history_t *history); + +// Utils funcs ast_t *create_node(ast_ctx_t *ctx); bool ensure_node_cap(ast_t *node); bool ensure_list_cap(ast_t *node); bool parser_eat(ast_ctx_t *ctx, token_type_t expected); ast_t *parse_loop(ast_ctx_t *ctx); void free_ast(ast_ctx_t *ctx); +void print_ast(ast_t *ast, ast_ctx_t *ctx, size_t depth); + +// Outside needed parser +ast_t *parse_cmd(ast_ctx_t *ctx); +ast_t *parse_condition(ast_ctx_t *ctx); +ast_t *parse_and(ast_ctx_t *ctx, ast_t *l_node); +ast_t *parse_or(ast_ctx_t *ctx, ast_t *l_node); #endif /* AST_H */ diff --git a/src/ast/ast.c b/src/ast/ast.c index d293313..0417dad 100644 --- a/src/ast/ast.c +++ b/src/ast/ast.c @@ -49,12 +49,16 @@ ast_t *fill_cmd_node(ast_ctx_t *ctx) return parse_arg(ctx, node); } -static +/* + * Removed this check to do && || if, nothing has changed, + * to be seen in case of trouble, + * putting it back this may solve the problem but will break the && || if + * if (ctx->act_tok.type == T_EOF) + * return ctx->ast; + */ ast_t *parse_cmd(ast_ctx_t *ctx) { - if (ctx->act_tok.type == T_EOF) - return ctx->ast; - if (ctx->act_tok.type != T_ARG){ + if (ctx->act_tok.type != T_ARG) { if (ctx->act_tok.type & (T_WHILE | T_FOREACH)) return NULL; if (!parser_eat(ctx, T_ARG)) @@ -75,7 +79,6 @@ bool parse_pipe_childs(ast_ctx_t *ctx, ast_t *node) return true; } -static ast_t *parse_pipe(ast_ctx_t *ctx, ast_t *l_node) { ast_t *node = create_node(ctx); @@ -98,17 +101,43 @@ ast_t *parse_pipe(ast_ctx_t *ctx, ast_t *l_node) return node; } -static -ast_t *parse_semi(ast_ctx_t *ctx) +ast_t *parse_condition(ast_ctx_t *ctx) { ast_t *l_node = parse_cmd(ctx); + if (l_node == NULL) + return NULL; if (ctx->act_tok.type & (T_WHILE | T_FOREACH)) ctx->ast = parse_loop(ctx); - else if (ctx->act_tok.type == T_PIPE) - ctx->ast = parse_pipe(ctx, l_node); - else - return l_node; + else { + switch (ctx->act_tok.type) { + case T_PIPE: + ctx->ast = parse_pipe(ctx, l_node); + break; + default: + return l_node; + } + } + return ctx->ast; +} + +static +ast_t *parse_semi(ast_ctx_t *ctx) +{ + ast_t *l_node = parse_condition(ctx); + + if (l_node == NULL) + return NULL; + switch (ctx->act_tok.type) { + case T_AND: + ctx->ast = parse_and(ctx, l_node); + break; + case T_OR: + ctx->ast = parse_or(ctx, l_node); + break; + default: + return l_node; + } return ctx->ast; } diff --git a/src/ast/conditions.c b/src/ast/conditions.c new file mode 100644 index 0000000..512a28c --- /dev/null +++ b/src/ast/conditions.c @@ -0,0 +1,38 @@ +/* +** EPITECH PROJECT, 2025 +** __ +** File description: +** _ +*/ + +#include "ast.h" + +ast_t *parse_and(ast_ctx_t *ctx, ast_t *l_node) +{ + ast_t *node = create_node(ctx); + + if (node == NULL || l_node == NULL) + return NULL; + node->tok = ctx->act_tok; + node->type = N_BIN; + node->binary.left = l_node; + node->binary.right = parse_condition(ctx); + if (node->binary.right == NULL) + return NULL; + return node; +} + +ast_t *parse_or(ast_ctx_t *ctx, ast_t *l_node) +{ + ast_t *node = create_node(ctx); + + if (node == NULL || l_node == NULL) + return NULL; + node->tok = ctx->act_tok; + node->type = N_BIN; + node->binary.left = l_node; + node->binary.right = parse_condition(ctx); + if (node->binary.right == NULL) + return NULL; + return node; +}