diff --git a/ast/Filelist.ast.mk b/ast/Filelist.ast.mk index 2db27b11..50a5712c 100644 --- a/ast/Filelist.ast.mk +++ b/ast/Filelist.ast.mk @@ -1,14 +1,20 @@ SRC_FILES = \ -_not_done_function \ -_not_done_print \ ast_alloc/ast_alloc \ ast_alloc/ast_alloc_scripting \ ast_free/ast_free \ ast_free/ast_free_scripting \ from_node/arithmetic_node2 \ from_node/artihmetic_node \ +from_node/boucle_node \ +from_node/condition_node \ +from_node/expansion_node \ from_node/from_node \ from_node/node_utils \ +from_node/node_utils2 \ +from_node/redirect_node \ +from_node/scripting_node \ +_not_done_function \ +_not_done_print \ print_ast/ast_print_command \ print_ast/ast_print_global \ print_ast/ast_print_node \ diff --git a/ast/include/ast/_from_node.h b/ast/include/ast/_from_node.h index e82b7314..90082708 100644 --- a/ast/include/ast/_from_node.h +++ b/ast/include/ast/_from_node.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/02 16:54:31 by maiboyer #+# #+# */ -/* Updated: 2024/08/02 17:00:38 by maiboyer ### ########.fr */ +/* Updated: 2024/08/06 19:02:40 by rparodi ### ########.fr */ /* */ /* ************************************************************************** */ @@ -124,5 +124,6 @@ t_error build_sym_while_statement(t_parse_node self, t_const_str input, t_ast_node *out); t_error build_sym_word(t_parse_node self, t_const_str input, t_ast_node *out); +t_vec_ast *_append_scripting(t_ast_node node); #endif /* _FROM_NODE_H */ diff --git a/ast/src/from_node/boucle_node.c b/ast/src/from_node/boucle_node.c new file mode 100644 index 00000000..783f5376 --- /dev/null +++ b/ast/src/from_node/boucle_node.c @@ -0,0 +1,127 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* boucle_node.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rparodi +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/08/06 18:43:35 by rparodi #+# #+# */ +/* Updated: 2024/08/06 18:44:55 by rparodi ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ast/_from_node.h" +#include "ast/ast.h" +#include "gmr/field_identifiers.h" +#include "gmr/field_identifiers.h" +#include "gmr/symbols.h" +#include "gmr/symbols.h" +#include "me/str/str.h" +#include "me/types.h" +#include "me/vec/vec_ast.h" +#include "parser/api.h" +#include + +t_vec_ast *_append_scripting(\ + t_ast_node node) +{ + if (node->kind == AST_WHILE) + return (&node->data.while_.suffixes_redirections); + if (node->kind == AST_FOR) + return (&node->data.for_.suffixes_redirections); + if (node->kind == AST_IF) + return (&node->data.if_.suffixes_redirections); + if (node->kind == AST_UNTIL) + return (&node->data.until.suffixes_redirections); + return (NULL); +} + +t_error build_sym_for_statement(\ + t_parse_node self, t_const_str input, t_ast_node *out) +{ + t_ast_node ret; + t_ast_node tmp; + t_usize i; + + (void)(out); + (void)(input); + (void)(self); + if (out == NULL) + return (ERROR); + if (ts_node_symbol(self) != sym_for_statement) + return (ERROR); + ret = ast_alloc(AST_FOR); + i = 0; + while (i < ts_node_child_count(self)) + { + if (!ts_node_is_named(ts_node_child(self, i)) && (i++, true)) + continue ; + if (ts_node_field_id_for_child(self, i) == field_var) + { + ret->data.for_.var_name = \ + _extract_str(ts_node_child(self, i), input); + } + if (ts_node_field_id_for_child(self, i) == field_value) + { + if (ast_from_node(ts_node_child(self, i), input, &tmp)) + return (ast_free(ret), ERROR); + vec_ast_push(&ret->data.for_.words, tmp); + } + if (ts_node_field_id_for_child(self, i) == field_body) + { + if (ast_from_node(ts_node_child(self, i), input, &tmp)) + return (ast_free(ret), ERROR); + vec_ast_push(&ret->data.for_.do_, tmp); + } + i++; + } + return (*out = ret, NO_ERROR); +} + +t_error build_sym_while_statement(\ + t_parse_node self, t_const_str input, t_ast_node *out) +{ + t_ast_node ret; + t_ast_node tmp; + t_usize i; + t_parse_node child; + t_ast_terminator_kind term; + + (void)(out); + (void)(input); + (void)(self); + if (out == NULL) + return (ERROR); + if (ts_node_symbol(self) != sym_while_statement) + return (ERROR); + i = 0; + if (ts_node_symbol(ts_node_child(self, 0)) == anon_sym_until) + ret = ast_alloc(AST_UNTIL); + else if (ts_node_symbol(ts_node_child(self, 0)) == anon_sym_while) + ret = ast_alloc(AST_WHILE); + else + return (ERROR); + while (i < ts_node_child_count(self)) + { + child = ts_node_child(self, i); + if (!ts_node_is_named(child) && (i++, true)) + continue ; + if (ts_node_field_id_for_child(self, i) == field_term) + { + term = _select_term(ts_node_child(self, i)); + ast_set_term(\ + &ret->data.while_.condition.buffer[\ + ret->data.while_.condition.len - 1], term); + i++; + continue ; + } + if (ast_from_node(child, input, &tmp)) + return (ast_free(ret), ERROR); + if (ts_node_field_id_for_child(self, i) == field_stmt) + vec_ast_push(&ret->data.while_.condition, tmp); + if (ts_node_field_id_for_child(self, i) == field_body) + vec_ast_push(&ret->data.while_.do_, tmp); + i++; + } + return (*out = ret, NO_ERROR); +} diff --git a/ast/src/from_node/condition_node.c b/ast/src/from_node/condition_node.c new file mode 100644 index 00000000..f7121a48 --- /dev/null +++ b/ast/src/from_node/condition_node.c @@ -0,0 +1,171 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* condition_node.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rparodi +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/08/06 18:36:09 by rparodi #+# #+# */ +/* Updated: 2024/08/06 18:58:01 by rparodi ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ast/_from_node.h" +#include "ast/ast.h" +#include "gmr/field_identifiers.h" +#include "gmr/field_identifiers.h" +#include "gmr/symbols.h" +#include "gmr/symbols.h" +#include "me/str/str.h" +#include "me/types.h" +#include "me/vec/vec_ast.h" +#include "parser/api.h" +#include + +void ast_set_term(t_ast_node *node, t_ast_terminator_kind term) +{ + t_ast_terminator_kind void_storage; + t_ast_terminator_kind *ptr; + t_ast_node val; + + if (node == NULL) + return ((void)printf("node == NULL\n")); + val = *node; + ptr = &void_storage; + if (val->kind == AST_CASE) + ptr = &val->data.case_.term; + if (val->kind == AST_CASE_ITEM) + ptr = &val->data.case_item.term; + if (val->kind == AST_COMMAND) + ptr = &val->data.command.term; + if (val->kind == AST_COMPOUND_STATEMENT) + ptr = &val->data.compound_statement.term; + if (val->kind == AST_IF) + ptr = &val->data.if_.term; + if (val->kind == AST_SUBSHELL) + ptr = &val->data.subshell.term; + *ptr = term; + if (ptr == &void_storage) + printf("node wasn't a term capable node\n"); + (void)(void_storage); +} + +t_error build_sym_if_statement(\ + t_parse_node self, t_const_str input, t_ast_node *out) +{ + t_parse_node child; + t_ast_node ret; + t_ast_node tmp; + t_usize i; + + (void)(out); + (void)(input); + (void)(self); + if (out == NULL) + return (ERROR); + if (ts_node_symbol(self) != sym_if_statement) + return (ERROR); + ret = ast_alloc(AST_IF); + i = 0; + while (i < ts_node_child_count(self)) + { + child = ts_node_child(self, i); + if (!ts_node_is_named(child) && (i++, true)) + continue ; + if (ts_node_field_id_for_child(self, i) == field_cond) + { + if (ast_from_node(child, input, &tmp)) + return (ast_free(ret), ERROR); + vec_ast_push(&ret->data.if_.condition, tmp); + } + if (ts_node_field_id_for_child(self, i) == field_body) + { + if (ast_from_node(child, input, &tmp)) + return (ast_free(ret), ERROR); + vec_ast_push(&ret->data.if_.then, tmp); + } + if (ts_node_field_id_for_child(self, i) == field_elif) + { + if (ast_from_node(child, input, &tmp)) + return (ast_free(ret), ERROR); + vec_ast_push(&ret->data.if_.elif_, tmp); + } + if (ts_node_field_id_for_child(self, i) == field_else) + { + if (ast_from_node(child, input, &tmp)) + return (ast_free(ret), ERROR); + ret->data.if_.else_ = tmp; + } + } + return (*out = ret, NO_ERROR); +} + +t_error build_sym_elif_clause(\ + t_parse_node self, t_const_str input, t_ast_node *out) +{ + t_ast_node ret; + t_ast_node tmp; + t_usize i; + t_parse_node child; + + (void)(out); + (void)(input); + (void)(self); + if (out == NULL) + return (ERROR); + if (ts_node_symbol(self) != sym_elif_clause) + return (ERROR); + ret = ast_alloc(AST_ELIF); + i = 0; + while (i < ts_node_child_count(self)) + { + child = ts_node_child(self, i); + if (!ts_node_is_named(child) && (i++, true)) + continue ; + if (ts_node_field_id_for_child(self, i) == field_cond) + { + if (ast_from_node(child, input, &tmp)) + return (ast_free(ret), ERROR); + vec_ast_push(&ret->data.elif.condition, tmp); + } + if (ts_node_field_id_for_child(self, i) == field_body) + { + if (ast_from_node(child, input, &tmp)) + return (ast_free(ret), ERROR); + vec_ast_push(&ret->data.elif.then, tmp); + } + } + return (*out = ret, NO_ERROR); +} + +t_error build_sym_else_clause(\ + t_parse_node self, t_const_str input, t_ast_node *out) +{ + t_ast_node ret; + t_ast_node tmp; + t_usize i; + t_parse_node child; + + (void)(out); + (void)(input); + (void)(self); + if (out == NULL) + return (ERROR); + if (ts_node_symbol(self) != sym_else_clause) + return (ERROR); + ret = ast_alloc(AST_ELSE); + i = 0; + while (i < ts_node_child_count(self)) + { + child = ts_node_child(self, i); + if (!ts_node_is_named(child) && (i++, true)) + continue ; + if (ts_node_field_id_for_child(self, i) == field_body) + { + if (ast_from_node(child, input, &tmp)) + return (ast_free(ret), ERROR); + vec_ast_push(&ret->data.else_.then, tmp); + } + } + return (*out = ret, NO_ERROR); +} diff --git a/ast/src/from_node/expansion_node.c b/ast/src/from_node/expansion_node.c new file mode 100644 index 00000000..6205ad29 --- /dev/null +++ b/ast/src/from_node/expansion_node.c @@ -0,0 +1,123 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expansion_node.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rparodi +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/08/06 18:26:15 by rparodi #+# #+# */ +/* Updated: 2024/08/06 18:31:32 by rparodi ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ast/_from_node.h" +#include "ast/ast.h" +#include "gmr/field_identifiers.h" +#include "gmr/field_identifiers.h" +#include "gmr/symbols.h" +#include "gmr/symbols.h" +#include "me/str/str.h" +#include "me/types.h" +#include "me/vec/vec_ast.h" +#include "parser/api.h" +#include + +t_error build_sym_regex(\ + t_parse_node self, t_const_str input, t_ast_node *out) +{ + t_ast_node ret; + + (void)(out); + (void)(input); + (void)(self); + if (out == NULL) + return (ERROR); + if (ts_node_symbol(self) != sym_regex) + return (ERROR); + ret = ast_alloc(AST_REGEX); + ret->data.regex.pattern = _extract_str(self, input); + return (*out = ret, NO_ERROR); +} + +t_error build_sym_extglob_pattern(\ + t_parse_node self, t_const_str input, t_ast_node *out) +{ + t_ast_node ret; + + (void)(out); + (void)(input); + (void)(self); + if (out == NULL) + return (ERROR); + if (ts_node_symbol(self) != sym_extglob_pattern) + return (ERROR); + ret = ast_alloc(AST_EXTGLOB); + ret->data.extglob.pattern = _extract_str(self, input); + return (*out = ret, NO_ERROR); +} + +t_error build_sym_expansion(\ + t_parse_node self, t_const_str input, t_ast_node *out) +{ + t_ast_node ret; + t_ast_node tmp; + t_usize i; + + (void)(out); + (void)(input); + (void)(self); + if (out == NULL) + return (ERROR); + if (ts_node_symbol(self) != sym_expansion) + return (ERROR); + ret = ast_alloc(AST_EXPANSION); + ret->data.expansion.kind = E_OP_NONE; + i = 0; + while (i < ts_node_child_count(self)) + { + if (!ts_node_is_named(ts_node_child(self, i)) && (i++, true)) + continue ; + if (ts_node_field_id_for_child(self, i) == field_len) + ret->data.expansion.len_operator = true; + if (ts_node_field_id_for_child(self, i) == field_name) + ret->data.expansion.var_name = \ + _extract_str(ts_node_child(self, i), input); + if (ts_node_field_id_for_child(self, i) == field_op) + ret->data.expansion.kind = _extract_exp_op(ts_node_child(self, i)); + if (ts_node_field_id_for_child(self, i) == field_args) + { + if (ast_from_node(ts_node_child(self, i), input, &tmp)) + return (ast_free(ret), ERROR); + vec_ast_push(&ret->data.expansion.args, tmp); + } + i++; + } + return (*out = ret, NO_ERROR); +} + +t_error build_sym_simple_expansion(\ + t_parse_node self, t_const_str input, t_ast_node *out) +{ + t_ast_node ret; + t_usize i; + + (void)(out); + (void)(input); + (void)(self); + if (out == NULL) + return (ERROR); + if (ts_node_symbol(self) != sym_simple_expansion) + return (ERROR); + ret = ast_alloc(AST_EXPANSION); + ret->data.expansion.kind = E_OP_NONE; + i = 0; + while (i < ts_node_child_count(self)) + { + if (!ts_node_is_named(ts_node_child(self, i)) && (i++, true)) + continue ; + ret->data.expansion.var_name = \ + _extract_str(ts_node_child(self, i), input); + i++; + } + return (*out = ret, NO_ERROR); +} diff --git a/ast/src/from_node/from_node.c b/ast/src/from_node/from_node.c index 2623f5d0..d782f2a9 100644 --- a/ast/src/from_node/from_node.c +++ b/ast/src/from_node/from_node.c @@ -6,7 +6,7 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/26 10:55:52 by rparodi #+# #+# */ -/* Updated: 2024/08/05 16:37:43 by maiboyer ### ########.fr */ +/* Updated: 2024/08/06 19:00:51 by rparodi ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,7 +21,6 @@ #include "me/vec/vec_ast.h" #include "parser/api.h" #include - /* sym_arithmetic_binary_expression sym_arithmetic_expansion @@ -63,7 +62,7 @@ sym_program sym_raw_string sym_redirected_statement sym_regex -sym_simple_expansion +sym_simplex _expansion sym_simple_heredoc_body sym_string sym_string_content @@ -75,100 +74,6 @@ sym_while_statement sym_word */ -void ast_set_term(t_ast_node *node, t_ast_terminator_kind term) -{ - t_ast_terminator_kind void_storage; - t_ast_terminator_kind *ptr; - t_ast_node val; - - if (node == NULL) - return ((void)printf("node == NULL\n")); - val = *node; - ptr = &void_storage; - if (val->kind == AST_CASE) - ptr = &val->data.case_.term; - if (val->kind == AST_CASE_ITEM) - ptr = &val->data.case_item.term; - if (val->kind == AST_COMMAND) - ptr = &val->data.command.term; - if (val->kind == AST_COMPOUND_STATEMENT) - ptr = &val->data.compound_statement.term; - if (val->kind == AST_IF) - ptr = &val->data.if_.term; - if (val->kind == AST_SUBSHELL) - ptr = &val->data.subshell.term; - *ptr = term; - if (ptr == &void_storage) - printf("node wasn't a term capable node\n"); - (void)(void_storage); -} - -t_vec_ast *_append_scripting(\ - t_ast_node node) -{ - if (node->kind == AST_WHILE) - return (&node->data.while_.suffixes_redirections); - if (node->kind == AST_FOR) - return (&node->data.for_.suffixes_redirections); - if (node->kind == AST_IF) - return (&node->data.if_.suffixes_redirections); - if (node->kind == AST_UNTIL) - return (&node->data.until.suffixes_redirections); - return (NULL); -} - -void _append_redirection(t_ast_node node, t_ast_node redirection) -{ - t_vec_ast *vec; - - vec = NULL; - if (!(redirection->kind == AST_FILE_REDIRECTION || \ - redirection->kind == AST_HEREDOC_REDIRECTION)) - return (ast_free(redirection)); - if (node->kind == AST_CASE) - vec = &node->data.case_.suffixes_redirections; - else if (node->kind == AST_COMMAND) - vec = &node->data.command.suffixes_redirections; - else if (node->kind == AST_COMPOUND_STATEMENT) - vec = &node->data.compound_statement.suffixes_redirections; - else if (node->kind == AST_LIST) - vec = &node->data.list.suffixes_redirections; - else if (node->kind == AST_PIPELINE) - vec = &node->data.pipeline.suffixes_redirections; - else if (node->kind == AST_SUBSHELL) - vec = &node->data.subshell.suffixes_redirections; - else - vec = _append_scripting(node); - if (vec != NULL) - vec_ast_push(vec, redirection); - else - (ast_free(redirection)); -} - -t_ast_terminator_kind _select_term(t_parse_node node) -{ - t_symbol symbol; - - symbol = ts_node_grammar_symbol(ts_node_child(node, 0)); - if (symbol == anon_sym_SEMI) - return (AST_TERM_SEMI); - if (symbol == anon_sym_SEMI_SEMI) - return (AST_TERM_DOUBLE_SEMI); - printf("unknown term symbol %d\n", symbol); - return (AST_TERM_NONE); -} - -t_str _extract_str(t_parse_node self, t_const_str input) -{ - t_usize start; - t_usize end; - t_str result; - - start = ts_node_start_byte(self); - end = ts_node_end_byte(self); - result = str_substring(input, start, end - start); - return (result); -} /* E_OP_NONE = 0, // ${var} E_OP_DEFAULT, // ${var-word} @@ -245,72 +150,6 @@ t_error build_sym_command_substitution(\ return (*out = ret, NO_ERROR); } -t_error build_sym_expansion(\ - t_parse_node self, t_const_str input, t_ast_node *out) -{ - t_ast_node ret; - t_ast_node tmp; - t_usize i; - - (void)(out); - (void)(input); - (void)(self); - if (out == NULL) - return (ERROR); - if (ts_node_symbol(self) != sym_expansion) - return (ERROR); - ret = ast_alloc(AST_EXPANSION); - ret->data.expansion.kind = E_OP_NONE; - i = 0; - while (i < ts_node_child_count(self)) - { - if (!ts_node_is_named(ts_node_child(self, i)) && (i++, true)) - continue ; - if (ts_node_field_id_for_child(self, i) == field_len) - ret->data.expansion.len_operator = true; - if (ts_node_field_id_for_child(self, i) == field_name) - ret->data.expansion.var_name = \ - _extract_str(ts_node_child(self, i), input); - if (ts_node_field_id_for_child(self, i) == field_op) - ret->data.expansion.kind = _extract_exp_op(ts_node_child(self, i)); - if (ts_node_field_id_for_child(self, i) == field_args) - { - if (ast_from_node(ts_node_child(self, i), input, &tmp)) - return (ast_free(ret), ERROR); - vec_ast_push(&ret->data.expansion.args, tmp); - } - i++; - } - return (*out = ret, NO_ERROR); -} - -t_error build_sym_simple_expansion(\ - t_parse_node self, t_const_str input, t_ast_node *out) -{ - t_ast_node ret; - t_usize i; - - (void)(out); - (void)(input); - (void)(self); - if (out == NULL) - return (ERROR); - if (ts_node_symbol(self) != sym_simple_expansion) - return (ERROR); - ret = ast_alloc(AST_EXPANSION); - ret->data.expansion.kind = E_OP_NONE; - i = 0; - while (i < ts_node_child_count(self)) - { - if (!ts_node_is_named(ts_node_child(self, i)) && (i++, true)) - continue ; - ret->data.expansion.var_name = \ - _extract_str(ts_node_child(self, i), input); - i++; - } - return (*out = ret, NO_ERROR); -} - t_error build_sym_file_descriptor(\ t_parse_node self, t_const_str input, t_ast_node *out) { @@ -390,345 +229,6 @@ t_error build_sym_file_redirect(\ return (*out = ret, NO_ERROR); } -t_error build_sym_regex(\ - t_parse_node self, t_const_str input, t_ast_node *out) -{ - t_ast_node ret; - - (void)(out); - (void)(input); - (void)(self); - if (out == NULL) - return (ERROR); - if (ts_node_symbol(self) != sym_regex) - return (ERROR); - ret = ast_alloc(AST_REGEX); - ret->data.regex.pattern = _extract_str(self, input); - return (*out = ret, NO_ERROR); -} - -t_error build_sym_extglob_pattern(\ - t_parse_node self, t_const_str input, t_ast_node *out) -{ - t_ast_node ret; - - (void)(out); - (void)(input); - (void)(self); - if (out == NULL) - return (ERROR); - if (ts_node_symbol(self) != sym_extglob_pattern) - return (ERROR); - ret = ast_alloc(AST_EXTGLOB); - ret->data.extglob.pattern = _extract_str(self, input); - return (*out = ret, NO_ERROR); -} - -t_error build_sym_function_definition(\ - t_parse_node self, t_const_str input, t_ast_node *out) -{ - t_ast_node ret; - t_ast_node tmp; - t_usize i; - - (void)(out); - (void)(input); - (void)(self); - if (out == NULL) - return (ERROR); - if (ts_node_symbol(self) != sym_function_definition) - return (ERROR); - ret = ast_alloc(AST_FUNCTION_DEFINITION); - i = 0; - while (i < ts_node_child_count(self)) - { - if (!ts_node_is_named(ts_node_child(self, i)) && (i++, true)) - continue ; - if (ts_node_field_id_for_child(self, i) == field_name) - ret->data.function_definition.name = \ - _extract_str(ts_node_child(self, i), input); - if (ts_node_field_id_for_child(self, i) == field_body) - { - if (ast_from_node(ts_node_child(self, i), input, &tmp)) - return (ast_free(ret), ERROR); - vec_ast_push(&ret->data.function_definition.body, tmp); - } - i++; - } - return (*out = ret, NO_ERROR); -} - -t_error build_sym_case_statement(\ - t_parse_node self, t_const_str input, t_ast_node *out) -{ - t_ast_node ret; - t_ast_node tmp; - t_usize i; - - (void)(out); - (void)(input); - (void)(self); - if (out == NULL) - return (ERROR); - if (ts_node_symbol(self) != sym_case_statement) - return (ERROR); - ret = ast_alloc(AST_CASE); - i = 0; - while (i < ts_node_child_count(self)) - { - if (!ts_node_is_named(ts_node_child(self, i)) && (i++, true)) - continue ; - if (ts_node_field_id_for_child(self, i) == field_value) - if (ast_from_node(ts_node_child(self, i), \ - input, &ret->data.case_.word)) - return (ast_free(ret), ERROR); - if (ts_node_field_id_for_child(self, i) == field_cases) - { - if (ast_from_node(ts_node_child(self, i), input, &tmp)) - return (ast_free(ret), ERROR); - vec_ast_push(&ret->data.case_.cases, tmp); - } - i++; - } - return (*out = ret, NO_ERROR); -} - -t_error build_sym__case_item_last(\ - t_parse_node self, t_const_str input, t_ast_node *out) -{ - t_ast_node ret; - t_ast_node tmp; - t_usize i; - - (void)(out); - (void)(input); - (void)(self); - if (out == NULL) - return (ERROR); - if (ts_node_symbol(self) != sym__case_item_last) - return (ERROR); - ret = ast_alloc(AST_CASE_ITEM); - i = 0; - while (i < ts_node_child_count(self)) - { - if (!ts_node_is_named(ts_node_child(self, i)) && (i++, true)) - continue ; - if (ts_node_field_id_for_child(self, i) == field_value) - { - if (ast_from_node(ts_node_child(self, i), input, &tmp)) - return (ast_free(ret), ERROR); - vec_ast_push(&ret->data.case_item.pattern, tmp); - } - if (ts_node_field_id_for_child(self, i) == field_body) - { - if (ast_from_node(ts_node_child(self, i), input, &tmp)) - return (ast_free(ret), ERROR); - vec_ast_push(&ret->data.case_item.body, tmp); - } - i++; - } - return (*out = ret, NO_ERROR); -} - -t_error build_sym_case_item(\ - t_parse_node self, t_const_str input, t_ast_node *out) -{ - t_ast_node ret; - t_ast_node tmp; - t_usize i; - - (void)(out); - (void)(input); - (void)(self); - if (out == NULL) - return (ERROR); - if (ts_node_symbol(self) != sym_case_item) - return (ERROR); - ret = ast_alloc(AST_CASE_ITEM); - i = 0; - while (i < ts_node_child_count(self)) - { - if (!ts_node_is_named(ts_node_child(self, i)) && (i++, true)) - continue ; - if (ts_node_field_id_for_child(self, i) == field_value) - { - if (ast_from_node(ts_node_child(self, i), input, &tmp)) - return (ast_free(ret), ERROR); - vec_ast_push(&ret->data.case_item.pattern, tmp); - } - if (ts_node_field_id_for_child(self, i) == field_body) - { - if (ast_from_node(ts_node_child(self, i), input, &tmp)) - return (ast_free(ret), ERROR); - vec_ast_push(&ret->data.case_item.body, tmp); - } - i++; - } - return (*out = ret, NO_ERROR); -} - -t_error build_sym_if_statement(\ - t_parse_node self, t_const_str input, t_ast_node *out) -{ - t_parse_node child; - t_ast_node ret; - t_ast_node tmp; - t_usize i; - - (void)(out); - (void)(input); - (void)(self); - if (out == NULL) - return (ERROR); - if (ts_node_symbol(self) != sym_if_statement) - return (ERROR); - ret = ast_alloc(AST_IF); - i = 0; - while (i < ts_node_child_count(self)) - { - child = ts_node_child(self, i); - if (!ts_node_is_named(child) && (i++, true)) - continue ; - if (ts_node_field_id_for_child(self, i) == field_cond) - { - if (ast_from_node(child, input, &tmp)) - return (ast_free(ret), ERROR); - vec_ast_push(&ret->data.if_.condition, tmp); - } - if (ts_node_field_id_for_child(self, i) == field_body) - { - if (ast_from_node(child, input, &tmp)) - return (ast_free(ret), ERROR); - vec_ast_push(&ret->data.if_.then, tmp); - } - if (ts_node_field_id_for_child(self, i) == field_elif) - { - if (ast_from_node(child, input, &tmp)) - return (ast_free(ret), ERROR); - vec_ast_push(&ret->data.if_.elif_, tmp); - } - if (ts_node_field_id_for_child(self, i) == field_else) - { - if (ast_from_node(child, input, &tmp)) - return (ast_free(ret), ERROR); - ret->data.if_.else_ = tmp; - } - } - return (*out = ret, NO_ERROR); -} - -t_error build_sym_elif_clause(\ - t_parse_node self, t_const_str input, t_ast_node *out) -{ - t_ast_node ret; - t_ast_node tmp; - t_usize i; - t_parse_node child; - - (void)(out); - (void)(input); - (void)(self); - if (out == NULL) - return (ERROR); - if (ts_node_symbol(self) != sym_elif_clause) - return (ERROR); - ret = ast_alloc(AST_ELIF); - i = 0; - while (i < ts_node_child_count(self)) - { - child = ts_node_child(self, i); - if (!ts_node_is_named(child) && (i++, true)) - continue ; - if (ts_node_field_id_for_child(self, i) == field_cond) - { - if (ast_from_node(child, input, &tmp)) - return (ast_free(ret), ERROR); - vec_ast_push(&ret->data.elif.condition, tmp); - } - if (ts_node_field_id_for_child(self, i) == field_body) - { - if (ast_from_node(child, input, &tmp)) - return (ast_free(ret), ERROR); - vec_ast_push(&ret->data.elif.then, tmp); - } - } - return (*out = ret, NO_ERROR); -} - -t_error build_sym_else_clause(\ - t_parse_node self, t_const_str input, t_ast_node *out) -{ - t_ast_node ret; - t_ast_node tmp; - t_usize i; - t_parse_node child; - - (void)(out); - (void)(input); - (void)(self); - if (out == NULL) - return (ERROR); - if (ts_node_symbol(self) != sym_else_clause) - return (ERROR); - ret = ast_alloc(AST_ELSE); - i = 0; - while (i < ts_node_child_count(self)) - { - child = ts_node_child(self, i); - if (!ts_node_is_named(child) && (i++, true)) - continue ; - if (ts_node_field_id_for_child(self, i) == field_body) - { - if (ast_from_node(child, input, &tmp)) - return (ast_free(ret), ERROR); - vec_ast_push(&ret->data.else_.then, tmp); - } - } - return (*out = ret, NO_ERROR); -} - -t_error build_sym_for_statement(\ - t_parse_node self, t_const_str input, t_ast_node *out) -{ - t_ast_node ret; - t_ast_node tmp; - t_usize i; - - (void)(out); - (void)(input); - (void)(self); - if (out == NULL) - return (ERROR); - if (ts_node_symbol(self) != sym_for_statement) - return (ERROR); - ret = ast_alloc(AST_FOR); - i = 0; - while (i < ts_node_child_count(self)) - { - if (!ts_node_is_named(ts_node_child(self, i)) && (i++, true)) - continue ; - if (ts_node_field_id_for_child(self, i) == field_var) - { - ret->data.for_.var_name = \ - _extract_str(ts_node_child(self, i), input); - } - if (ts_node_field_id_for_child(self, i) == field_value) - { - if (ast_from_node(ts_node_child(self, i), input, &tmp)) - return (ast_free(ret), ERROR); - vec_ast_push(&ret->data.for_.words, tmp); - } - if (ts_node_field_id_for_child(self, i) == field_body) - { - if (ast_from_node(ts_node_child(self, i), input, &tmp)) - return (ast_free(ret), ERROR); - vec_ast_push(&ret->data.for_.do_, tmp); - } - i++; - } - return (*out = ret, NO_ERROR); -} - t_error build_sym_pipeline(\ t_parse_node self, t_const_str input, t_ast_node *out) { @@ -841,94 +341,8 @@ t_error build_sym_subshell(\ return (*out = ret, NO_ERROR); } -t_error build_sym_while_statement(\ - t_parse_node self, t_const_str input, t_ast_node *out) -{ - t_ast_node ret; - t_ast_node tmp; - t_usize i; - t_parse_node child; - t_ast_terminator_kind term; - - (void)(out); - (void)(input); - (void)(self); - if (out == NULL) - return (ERROR); - if (ts_node_symbol(self) != sym_while_statement) - return (ERROR); - i = 0; - if (ts_node_symbol(ts_node_child(self, 0)) == anon_sym_until) - ret = ast_alloc(AST_UNTIL); - else if (ts_node_symbol(ts_node_child(self, 0)) == anon_sym_while) - ret = ast_alloc(AST_WHILE); - else - return (ERROR); - while (i < ts_node_child_count(self)) - { - child = ts_node_child(self, i); - if (!ts_node_is_named(child) && (i++, true)) - continue ; - if (ts_node_field_id_for_child(self, i) == field_term) - { - term = _select_term(ts_node_child(self, i)); - ast_set_term(\ - &ret->data.while_.condition.buffer[\ - ret->data.while_.condition.len - 1], term); - i++; - continue ; - } - if (ast_from_node(child, input, &tmp)) - return (ast_free(ret), ERROR); - if (ts_node_field_id_for_child(self, i) == field_stmt) - vec_ast_push(&ret->data.while_.condition, tmp); - if (ts_node_field_id_for_child(self, i) == field_body) - vec_ast_push(&ret->data.while_.do_, tmp); - i++; - } - return (*out = ret, NO_ERROR); -} - // t_error buildw -t_error build_sym_redirected_statement(\ - t_parse_node self, t_const_str input, t_ast_node *out) -{ - t_ast_node ret_tmp; - t_ast_node ret; - t_ast_node tmp; - t_usize i; - - (void)(out); - (void)(input); - (void)(self); - if (out == NULL) - return (ERROR); - if (ts_node_symbol(self) != sym_redirected_statement) - return (ERROR); - i = 0; - ret = ast_alloc(AST_COMMAND); - ret_tmp = ret; - while (i < ts_node_child_count(self)) - { - if (!ts_node_is_named(ts_node_child(self, i)) && (i++, true)) - continue ; - if (!(ts_node_symbol(ts_node_child(self, i)) == sym_file_redirect || \ - ts_node_symbol(ts_node_child(self, i)) == sym_heredoc_redirect)) - { - if (ast_from_node(ts_node_child(self, i++), input, &ret)) - return (ast_free(ret_tmp), ERROR); - continue ; - } - if (ast_from_node(ts_node_child(self, i++), input, &tmp)) - return ((void)((ret != ret_tmp) \ - && (ast_free(ret_tmp), true)), ast_free(ret), ERROR); - _append_redirection(ret, tmp); - } - return ((void)((ret != ret_tmp) \ - && (ast_free(ret_tmp), true)), *out = ret, NO_ERROR); -} - t_error build_sym_negated_command(\ t_parse_node self, t_const_str input, t_ast_node *out) { diff --git a/ast/src/from_node/node_utils2.c b/ast/src/from_node/node_utils2.c new file mode 100644 index 00000000..12576edb --- /dev/null +++ b/ast/src/from_node/node_utils2.c @@ -0,0 +1,93 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* node_utils2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rparodi +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/08/06 18:27:48 by rparodi #+# #+# */ +/* Updated: 2024/08/06 18:30:53 by rparodi ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ast/_from_node.h" +#include "ast/ast.h" +#include "gmr/field_identifiers.h" +#include "gmr/field_identifiers.h" +#include "gmr/symbols.h" +#include "gmr/symbols.h" +#include "me/str/str.h" +#include "me/types.h" +#include "me/vec/vec_ast.h" +#include "parser/api.h" +#include + +void _append_redirection(t_ast_node node, t_ast_node redirection) +{ + t_vec_ast *vec; + + vec = NULL; + if (!(redirection->kind == AST_FILE_REDIRECTION || \ + redirection->kind == AST_HEREDOC_REDIRECTION)) + return (ast_free(redirection)); + if (node->kind == AST_CASE) + vec = &node->data.case_.suffixes_redirections; + else if (node->kind == AST_COMMAND) + vec = &node->data.command.suffixes_redirections; + else if (node->kind == AST_COMPOUND_STATEMENT) + vec = &node->data.compound_statement.suffixes_redirections; + else if (node->kind == AST_LIST) + vec = &node->data.list.suffixes_redirections; + else if (node->kind == AST_PIPELINE) + vec = &node->data.pipeline.suffixes_redirections; + else if (node->kind == AST_SUBSHELL) + vec = &node->data.subshell.suffixes_redirections; + else + vec = _append_scripting(node); + if (vec != NULL) + vec_ast_push(vec, redirection); + else + (ast_free(redirection)); +} + +t_ast_terminator_kind _select_term(t_parse_node node) +{ + t_symbol symbol; + + symbol = ts_node_grammar_symbol(ts_node_child(node, 0)); + if (symbol == anon_sym_SEMI) + return (AST_TERM_SEMI); + if (symbol == anon_sym_SEMI_SEMI) + return (AST_TERM_DOUBLE_SEMI); + printf("unknown term symbol %d\n", symbol); + return (AST_TERM_NONE); +} + +t_str _extract_str(t_parse_node self, t_const_str input) +{ + t_usize start; + t_usize end; + t_str result; + + start = ts_node_start_byte(self); + end = ts_node_end_byte(self); + result = str_substring(input, start, end - start); + return (result); +} + +/* + E_OP_NONE = 0, // ${var} + E_OP_DEFAULT, // ${var-word} + E_OP_ASSIGN_DEFAULT, // ${var=word} + E_OP_ERROR, // ${var?word} + E_OP_ALTERNATE, // ${var+word} + E_OP_DEFAULT_COLON, // ${var:-word} + E_OP_ASSIGN_DEFAULT_COLON, // ${var:=word} + E_OP_ERROR_COLON, // ${var:?word} + E_OP_ALTERNATE_COLON, // ${var:+word} + E_OP_LENGTH, // ${#var} + E_OP_SMALLEST_PREFIX, // ${var#pattern} + E_OP_LARGEST_PREFIX, // ${var##pattern} + E_OP_SMALLEST_SUFFIX, // ${var%pattern} + E_OP_LARGEST_SUFFIX, // ${var%%pattern} +*/ diff --git a/ast/src/from_node/redirect_node.c b/ast/src/from_node/redirect_node.c new file mode 100644 index 00000000..da563582 --- /dev/null +++ b/ast/src/from_node/redirect_node.c @@ -0,0 +1,63 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirect_node.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rparodi +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/08/06 18:45:21 by rparodi #+# #+# */ +/* Updated: 2024/08/06 18:59:40 by rparodi ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ast/_from_node.h" +#include "ast/ast.h" +#include "gmr/field_identifiers.h" +#include "gmr/field_identifiers.h" +#include "gmr/symbols.h" +#include "gmr/symbols.h" +#include "me/str/str.h" +#include "me/types.h" +#include "me/vec/vec_ast.h" +#include "parser/api.h" +#include + +t_error build_sym_redirected_statement(\ + t_parse_node self, t_const_str input, t_ast_node *out) +{ + t_ast_node ret_tmp; + t_ast_node ret; + t_ast_node tmp; + t_usize i; + + (void)(out); + (void)(input); + (void)(self); + if (out == NULL) + return (ERROR); + if (ts_node_symbol(self) != sym_redirected_statement) + return (ERROR); + i = 0; + ret = ast_alloc(AST_COMMAND); + ret_tmp = ret; + while (i < ts_node_child_count(self)) + { + if (!ts_node_is_named(ts_node_child(self, i)) && (i++, true)) + continue ; + if (!(ts_node_symbol(ts_node_child(self, i)) == sym_file_redirect || \ + ts_node_symbol(ts_node_child(self, i)) == sym_heredoc_redirect)) + { + if (ast_from_node(ts_node_child(self, i++), input, &ret)) + return (ast_free(ret_tmp), ERROR); + continue ; + } + if (ast_from_node(ts_node_child(self, i++), input, &tmp)) + return ((void)((ret != ret_tmp) \ + && (ast_free(ret_tmp), true)), ast_free(ret), ERROR); + _append_redirection(ret, tmp); + } + return ((void)((ret != ret_tmp) \ + && (ast_free(ret_tmp), true)), *out = ret, NO_ERROR); +} + + diff --git a/ast/src/from_node/scripting_node.c b/ast/src/from_node/scripting_node.c new file mode 100644 index 00000000..bc3db596 --- /dev/null +++ b/ast/src/from_node/scripting_node.c @@ -0,0 +1,167 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* scripting_node.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rparodi +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/08/06 18:34:12 by rparodi #+# #+# */ +/* Updated: 2024/08/06 18:35:57 by rparodi ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ast/_from_node.h" +#include "ast/ast.h" +#include "gmr/field_identifiers.h" +#include "gmr/field_identifiers.h" +#include "gmr/symbols.h" +#include "gmr/symbols.h" +#include "me/str/str.h" +#include "me/types.h" +#include "me/vec/vec_ast.h" +#include "parser/api.h" +#include + +t_error build_sym_function_definition(\ + t_parse_node self, t_const_str input, t_ast_node *out) +{ + t_ast_node ret; + t_ast_node tmp; + t_usize i; + + (void)(out); + (void)(input); + (void)(self); + if (out == NULL) + return (ERROR); + if (ts_node_symbol(self) != sym_function_definition) + return (ERROR); + ret = ast_alloc(AST_FUNCTION_DEFINITION); + i = 0; + while (i < ts_node_child_count(self)) + { + if (!ts_node_is_named(ts_node_child(self, i)) && (i++, true)) + continue ; + if (ts_node_field_id_for_child(self, i) == field_name) + ret->data.function_definition.name = \ + _extract_str(ts_node_child(self, i), input); + if (ts_node_field_id_for_child(self, i) == field_body) + { + if (ast_from_node(ts_node_child(self, i), input, &tmp)) + return (ast_free(ret), ERROR); + vec_ast_push(&ret->data.function_definition.body, tmp); + } + i++; + } + return (*out = ret, NO_ERROR); +} + +t_error build_sym_case_statement(\ + t_parse_node self, t_const_str input, t_ast_node *out) +{ + t_ast_node ret; + t_ast_node tmp; + t_usize i; + + (void)(out); + (void)(input); + (void)(self); + if (out == NULL) + return (ERROR); + if (ts_node_symbol(self) != sym_case_statement) + return (ERROR); + ret = ast_alloc(AST_CASE); + i = 0; + while (i < ts_node_child_count(self)) + { + if (!ts_node_is_named(ts_node_child(self, i)) && (i++, true)) + continue ; + if (ts_node_field_id_for_child(self, i) == field_value) + if (ast_from_node(ts_node_child(self, i), \ + input, &ret->data.case_.word)) + return (ast_free(ret), ERROR); + if (ts_node_field_id_for_child(self, i) == field_cases) + { + if (ast_from_node(ts_node_child(self, i), input, &tmp)) + return (ast_free(ret), ERROR); + vec_ast_push(&ret->data.case_.cases, tmp); + } + i++; + } + return (*out = ret, NO_ERROR); +} + +t_error build_sym__case_item_last(\ + t_parse_node self, t_const_str input, t_ast_node *out) +{ + t_ast_node ret; + t_ast_node tmp; + t_usize i; + + (void)(out); + (void)(input); + (void)(self); + if (out == NULL) + return (ERROR); + if (ts_node_symbol(self) != sym__case_item_last) + return (ERROR); + ret = ast_alloc(AST_CASE_ITEM); + i = 0; + while (i < ts_node_child_count(self)) + { + if (!ts_node_is_named(ts_node_child(self, i)) && (i++, true)) + continue ; + if (ts_node_field_id_for_child(self, i) == field_value) + { + if (ast_from_node(ts_node_child(self, i), input, &tmp)) + return (ast_free(ret), ERROR); + vec_ast_push(&ret->data.case_item.pattern, tmp); + } + if (ts_node_field_id_for_child(self, i) == field_body) + { + if (ast_from_node(ts_node_child(self, i), input, &tmp)) + return (ast_free(ret), ERROR); + vec_ast_push(&ret->data.case_item.body, tmp); + } + i++; + } + return (*out = ret, NO_ERROR); +} + +t_error build_sym_case_item(\ + t_parse_node self, t_const_str input, t_ast_node *out) +{ + t_ast_node ret; + t_ast_node tmp; + t_usize i; + + (void)(out); + (void)(input); + (void)(self); + if (out == NULL) + return (ERROR); + if (ts_node_symbol(self) != sym_case_item) + return (ERROR); + ret = ast_alloc(AST_CASE_ITEM); + i = 0; + while (i < ts_node_child_count(self)) + { + if (!ts_node_is_named(ts_node_child(self, i)) && (i++, true)) + continue ; + if (ts_node_field_id_for_child(self, i) == field_value) + { + if (ast_from_node(ts_node_child(self, i), input, &tmp)) + return (ast_free(ret), ERROR); + vec_ast_push(&ret->data.case_item.pattern, tmp); + } + if (ts_node_field_id_for_child(self, i) == field_body) + { + if (ast_from_node(ts_node_child(self, i), input, &tmp)) + return (ast_free(ret), ERROR); + vec_ast_push(&ret->data.case_item.body, tmp); + } + i++; + } + return (*out = ret, NO_ERROR); +} + diff --git a/sources/builtin/env.c b/sources/builtin/env.c new file mode 100644 index 00000000..21cb66bb --- /dev/null +++ b/sources/builtin/env.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* env.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rparodi +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/08/07 14:22:50 by rparodi #+# #+# */ +/* Updated: 2024/08/07 14:23:14 by rparodi ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/env.h" +#include "me/string/string.h" +#include "me/hash/hasher.h" +#include "me/hashmap/hashmap_env.h" +#include "me/mem/mem.h" +#include "me/str/str.h" +#include "me/str/str.h" +#include "me/str/str.h" +#include "me/types.h" +#include "me/vec/vec_str.h" +#include +#include + +void env(t_str *envp) +{ + size_t i; + + i = 0; + while (envp[i] != NULL) + { + printf("%s\n", envp[i]); + i++; + } +} diff --git a/sources/builtin/export.c b/sources/builtin/export.c new file mode 100644 index 00000000..4862a524 --- /dev/null +++ b/sources/builtin/export.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* export.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rparodi +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/08/07 14:13:41 by rparodi #+# #+# */ +/* Updated: 2024/08/07 14:22:23 by rparodi ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/env.h" +#include "me/string/string.h" +#include "me/hash/hasher.h" +#include "me/hashmap/hashmap_env.h" +#include "me/mem/mem.h" +#include "me/str/str.h" +#include "me/str/str.h" +#include "me/str/str.h" +#include "me/types.h" +#include "me/vec/vec_str.h" +#include +#include + +void export(t_str *envp) +{ + size_t i; + + i = 0; + while (envp[i] != NULL) + { + printf("%s\n", envp[i]); + i++; + } +} diff --git a/sources/builtin/pwd.c b/sources/builtin/pwd.c new file mode 100644 index 00000000..8303ff95 --- /dev/null +++ b/sources/builtin/pwd.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pwd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rparodi +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/08/07 13:58:37 by rparodi #+# #+# */ +/* Updated: 2024/08/07 14:07:39 by rparodi ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/env.h" +#include "me/string/string.h" +#include "me/hash/hasher.h" +#include "me/hashmap/hashmap_env.h" +#include "me/mem/mem.h" +#include "me/str/str.h" +#include "me/str/str.h" +#include "me/str/str.h" +#include "me/types.h" +#include "me/vec/vec_str.h" +#include + +void pwd(void) +{ + t_str str; + t_usize size; + + size = 1024; + str = (t_str)mem_alloc((size + 1) * sizeof(t_i8)); + if (str == NULL) + me_abort("Error allocating for pwd builtin"); + while (getcwd(str, size) == NULL) + { + if (str) + free(str); + size *= 2; + str = (t_str)mem_alloc(sizeof(t_i8) * size); + if (str == NULL) + me_abort("Error allocating for pwd builtin"); + } + printf("%s\n", str); + free(str); +}