From cc12225142fbb0085dc4af935aa84a747384d717 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 2 Mar 2014 13:46:30 -0800 Subject: [PATCH] Clean up various block types and state as part of new parser --- builtin.cpp | 75 +-------------------------------------------- parse_execution.cpp | 20 +++++------- parser.cpp | 41 ++++++------------------- parser.h | 44 +++----------------------- 4 files changed, 22 insertions(+), 158 deletions(-) diff --git a/builtin.cpp b/builtin.cpp index 930d10be2..85d60a29a 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -3309,78 +3309,6 @@ static int builtin_bg(parser_t &parser, wchar_t **argv) } -/** - Builtin for looping over a list -*/ -static int builtin_for(parser_t &parser, wchar_t **argv) -{ - int argc = builtin_count_args(argv); - int res=STATUS_BUILTIN_ERROR; - - /* Hackish - if we have no arguments other than the command, we are a "naked invocation" and we just print help */ - if (argc == 1) - { - builtin_print_help(parser, argv[0], stdout_buffer); - return STATUS_BUILTIN_ERROR; - } - - if (argc < 3) - { - append_format(stderr_buffer, - BUILTIN_FOR_ERR_COUNT, - argv[0] , - argc); - builtin_print_help(parser, argv[0], stderr_buffer); - } - else if (wcsvarname(argv[1])) - { - append_format(stderr_buffer, - BUILTIN_FOR_ERR_NAME, - argv[0], - argv[1]); - builtin_print_help(parser, argv[0], stderr_buffer); - } - else if (wcscmp(argv[2], L"in") != 0) - { - append_format(stderr_buffer, - BUILTIN_FOR_ERR_IN, - argv[0]); - builtin_print_help(parser, argv[0], stderr_buffer); - } - else - { - res=0; - } - - - if (res) - { - parser.push_block(new fake_block_t()); - } - else - { - const wchar_t *for_variable = argv[1]; - for_block_t *fb = new for_block_t(for_variable); - parser.push_block(fb); - fb->tok_pos = parser.get_pos(); - - /* Note that we store the sequence of values in opposite order */ - wcstring_list_t &for_vars = fb->sequence; - for (int i=argc-1; i>3; i--) - for_vars.push_back(argv[i]); - - if (argc > 3) - { - env_set(for_variable, argv[3], ENV_LOCAL); - } - else - { - parser.current_block()->skip=1; - } - } - return res; -} - /** This function handles both the 'continue' and the 'break' builtins that are used for loop control. @@ -3509,7 +3437,6 @@ static int builtin_return(parser_t &parser, wchar_t **argv) for (size_t i=0; i < function_block_idx; i++) { block_t *b = parser.block_at_index(i); - b->mark_as_fake(); b->skip = true; } parser.block_at_index(function_block_idx)->skip = true; @@ -3734,7 +3661,7 @@ static const builtin_data_t builtin_datas[]= { L"exec", &builtin_generic, N_(L"Run command in current process") }, { L"exit", &builtin_exit, N_(L"Exit the shell") }, { L"fg", &builtin_fg, N_(L"Send job to foreground") }, - { L"for", &builtin_for, N_(L"Perform a set of commands multiple times") }, + { L"for", &builtin_generic, N_(L"Perform a set of commands multiple times") }, { L"function", &builtin_generic, N_(L"Define a new function") }, { L"functions", &builtin_functions, N_(L"List or remove functions") }, { L"history", &builtin_history, N_(L"History of commands executed by user") }, diff --git a/parse_execution.cpp b/parse_execution.cpp index 15c7de5f2..47a1d8579 100644 --- a/parse_execution.cpp +++ b/parse_execution.cpp @@ -447,7 +447,7 @@ parse_execution_result_t parse_execution_context_t::run_for_statement(const pars /* Get the contents to iterate over. */ const parse_node_t *unmatched_wildcard = NULL; - wcstring_list_t argument_list = this->determine_arguments(header, &unmatched_wildcard); + wcstring_list_t argument_sequence = this->determine_arguments(header, &unmatched_wildcard); if (unmatched_wildcard != NULL) { return report_unmatched_wildcard_error(*unmatched_wildcard); @@ -455,15 +455,12 @@ parse_execution_result_t parse_execution_context_t::run_for_statement(const pars parse_execution_result_t ret = parse_execution_success; - for_block_t *fb = new for_block_t(for_var_name); + for_block_t *fb = new for_block_t(); parser->push_block(fb); - /* Note that we store the sequence of values in opposite order */ - std::reverse(argument_list.begin(), argument_list.end()); - fb->sequence = argument_list; - /* Now drive the for loop. */ - while (! fb->sequence.empty()) + const size_t arg_count = argument_sequence.size(); + for (size_t i=0; i < arg_count; i++) { if (should_cancel_execution(fb)) { @@ -471,10 +468,8 @@ parse_execution_result_t parse_execution_context_t::run_for_statement(const pars break; } - const wcstring &for_variable = fb->variable; - const wcstring &val = fb->sequence.back(); - env_set(for_variable, val.c_str(), ENV_LOCAL); - fb->sequence.pop_back(); + const wcstring &val = argument_sequence.at(i); + env_set(for_var_name, val.c_str(), ENV_LOCAL); fb->loop_status = LOOP_NORMAL; fb->skip = 0; @@ -551,7 +546,7 @@ parse_execution_result_t parse_execution_context_t::run_switch_statement(const p } const wcstring &switch_value_expanded = switch_values_expanded.at(0).completion; - switch_block_t *sb = new switch_block_t(switch_value_expanded); + switch_block_t *sb = new switch_block_t(); parser->push_block(sb); if (result == parse_execution_success) @@ -620,7 +615,6 @@ parse_execution_result_t parse_execution_context_t::run_while_statement(const pa /* Push a while block */ while_block_t *wb = new while_block_t(); - wb->status = WHILE_TEST_FIRST; wb->node_offset = this->get_offset(header); parser->push_block(wb); diff --git a/parser.cpp b/parser.cpp index f23ddda92..33a8b7e04 100644 --- a/parser.cpp +++ b/parser.cpp @@ -249,7 +249,9 @@ void parser_t::push_block(block_t *new_current) const block_t *old_current = this->current_block(); if (old_current && old_current->skip) - new_current->mark_as_fake(); + { + new_current->skip = true; + } /* New blocks should be skipped if the outer block is skipped, @@ -1407,7 +1409,6 @@ void parser_t::get_backtrace(const wcstring &src, const parse_error_list_t &erro block_t::block_t(block_type_t t) : block_type(t), - made_fake(false), skip(), had_command(), tok_pos(), @@ -1427,12 +1428,7 @@ block_t::~block_t() /* Various block constructors */ -if_block_t::if_block_t() : - block_t(IF), - if_expr_evaluated(false), - is_elseif_entry(false), - any_branch_taken(false), - else_evaluated(false) +if_block_t::if_block_t() : block_t(IF) { } @@ -1455,45 +1451,28 @@ source_block_t::source_block_t(const wchar_t *src) : { } -for_block_t::for_block_t(const wcstring &var) : - block_t(FOR), - variable(var), - sequence() +for_block_t::for_block_t() : block_t(FOR) { } -while_block_t::while_block_t() : - block_t(WHILE), - status(0) +while_block_t::while_block_t() : block_t(WHILE) { } -switch_block_t::switch_block_t(const wcstring &sv) : - block_t(SWITCH), - switch_taken(false), - switch_value(sv) +switch_block_t::switch_block_t() : block_t(SWITCH) { } -fake_block_t::fake_block_t() : - block_t(FAKE) +fake_block_t::fake_block_t() : block_t(FAKE) { } -function_def_block_t::function_def_block_t() : - block_t(FUNCTION_DEF), - function_data() -{ -} - -scope_block_t::scope_block_t(block_type_t type) : - block_t(type) +scope_block_t::scope_block_t(block_type_t type) : block_t(type) { assert(type == BEGIN || type == TOP || type == SUBST); } -breakpoint_block_t::breakpoint_block_t() : - block_t(BREAKPOINT) +breakpoint_block_t::breakpoint_block_t() : block_t(BREAKPOINT) { } diff --git a/parser.h b/parser.h index 931d5b165..0c3066829 100644 --- a/parser.h +++ b/parser.h @@ -64,8 +64,7 @@ enum block_type_t SOURCE, /**< Block created by the . (source) builtin */ EVENT, /**< Block created on event notifier invocation */ BREAKPOINT, /**< Breakpoint block */ -} -; +}; /** block_t represents a block of commands. @@ -78,18 +77,11 @@ protected: private: const block_type_t block_type; /**< Type of block. */ - bool made_fake; public: block_type_t type() const { - return this->made_fake ? FAKE : this->block_type; - } - - /** Mark a block as fake; this is used by the return statement. */ - void mark_as_fake() - { - this->made_fake = true; + return this->block_type; } bool skip; /**< Whether execution of the commands in this block should be skipped */ @@ -122,11 +114,6 @@ public: struct if_block_t : public block_t { - bool if_expr_evaluated; // whether we've evaluated the if expression - bool is_elseif_entry; // whether we're at the beginning of an ELSEIF branch - bool any_branch_taken; // whether the clause of the if statement or any elseif has been found to be true - bool else_evaluated; // whether we've encountered a terminal else block - if_block_t(); }; @@ -151,22 +138,17 @@ struct source_block_t : public block_t struct for_block_t : public block_t { - wcstring variable; // the variable that will be assigned each value in the sequence - wcstring_list_t sequence; // the sequence of values - for_block_t(const wcstring &var); + for_block_t(); }; struct while_block_t : public block_t { - int status; while_block_t(); }; struct switch_block_t : public block_t { - bool switch_taken; - const wcstring switch_value; - switch_block_t(const wcstring &sv); + switch_block_t(); }; struct fake_block_t : public block_t @@ -174,12 +156,6 @@ struct fake_block_t : public block_t fake_block_t(); }; -struct function_def_block_t : public block_t -{ - function_data_t function_data; - function_def_block_t(); -}; - struct scope_block_t : public block_t { scope_block_t(block_type_t type); //must be BEGIN, TOP or SUBST @@ -201,18 +177,6 @@ enum loop_status }; -/** - Possible states for a while block -*/ -enum while_status -{ - WHILE_TEST_FIRST, /**< This is the first command of the first lap of a while loop */ - WHILE_TEST_AGAIN, /**< This is not the first lap of the while loop, but it is the first command of the loop */ - WHILE_TESTED, /**< This is not the first command in the loop */ -} -; - - /** Errors that can be generated by the parser */