From 0bda853dc73c937d0731180df747d3721da48b79 Mon Sep 17 00:00:00 2001 From: Mahmoud Al-Qudsi Date: Thu, 28 Mar 2019 19:55:23 -0500 Subject: [PATCH] Add detection of `eval` to the parser While `eval` is still a function, this paves the way for changing that in the future, and lets the proc/exec functions detect when an eval is used to allow/disallow certain behaviors and optimizations. --- src/complete.cpp | 8 ++++++++ src/exec.cpp | 1 + src/parse_constants.h | 9 ++++++--- src/parse_grammar.h | 2 ++ src/parse_productions.cpp | 4 ++++ src/proc.h | 2 ++ 6 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/complete.cpp b/src/complete.cpp index d4091855d..c892f4482 100644 --- a/src/complete.cpp +++ b/src/complete.cpp @@ -1465,6 +1465,14 @@ void completer_t::perform() { use_abbr = false; break; } + case parse_statement_decoration_eval: { + use_command = true; + use_function = true; + use_builtin = true; + use_implicit_cd = false; + use_abbr = false; + break; + } } if (cmd_node.location_in_or_at_end_of_source_range(pos)) { diff --git a/src/exec.cpp b/src/exec.cpp index be1eec6b6..a6441798e 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -944,6 +944,7 @@ static bool exec_process_in_job(parser_t &parser, process_t *p, std::shared_ptr< // Execute the process. p->check_generations_before_launch(); switch (p->type) { + case process_type_t::eval: /* so long as `eval` is a function */ case process_type_t::function: case process_type_t::block_node: { // Allow buffering unless this is a deferred run. If deferred, then processes after us diff --git a/src/parse_constants.h b/src/parse_constants.h index 53eda65c4..2f86f05fd 100644 --- a/src/parse_constants.h +++ b/src/parse_constants.h @@ -97,7 +97,6 @@ const enum_map token_enum_map[] = { // // IMPORTANT: These enums must start at zero. enum parse_keyword_t { - parse_keyword_none = 0, parse_keyword_and, parse_keyword_begin, parse_keyword_builtin, @@ -105,13 +104,15 @@ enum parse_keyword_t { parse_keyword_command, parse_keyword_else, parse_keyword_end, + parse_keyword_eval, + parse_keyword_exclam, parse_keyword_exec, parse_keyword_for, parse_keyword_function, parse_keyword_if, parse_keyword_in, + parse_keyword_none, parse_keyword_not, - parse_keyword_exclam, parse_keyword_or, parse_keyword_switch, parse_keyword_while, @@ -125,6 +126,7 @@ const enum_map keyword_enum_map[] = {{parse_keyword_exclam, L"! {parse_keyword_command, L"command"}, {parse_keyword_else, L"else"}, {parse_keyword_end, L"end"}, + {parse_keyword_eval, L"eval"}, {parse_keyword_exec, L"exec"}, {parse_keyword_for, L"for"}, {parse_keyword_function, L"function"}, @@ -144,7 +146,8 @@ enum parse_statement_decoration_t { parse_statement_decoration_none, parse_statement_decoration_command, parse_statement_decoration_builtin, - parse_statement_decoration_exec + parse_statement_decoration_exec, + parse_statement_decoration_eval, }; // Boolean statement types, stored in node tag. diff --git a/src/parse_grammar.h b/src/parse_grammar.h index b6b1cb2ee..03e163ae1 100644 --- a/src/parse_grammar.h +++ b/src/parse_grammar.h @@ -334,6 +334,8 @@ DEF_ALT(decorated_statement) { using cmds = seq, plain_statement>; using builtins = seq, plain_statement>; using execs = seq, plain_statement>; + // using evals = seq, plain_statement>; + using evals = single; /* so long as `eval` is a function */ ALT_BODY(decorated_statement, plains, cmds, builtins, execs); }; diff --git a/src/parse_productions.cpp b/src/parse_productions.cpp index 4718d826a..2e60f3b46 100644 --- a/src/parse_productions.cpp +++ b/src/parse_productions.cpp @@ -314,6 +314,10 @@ RESOLVE(decorated_statement) { *out_tag = parse_statement_decoration_exec; return production_for(); } + case parse_keyword_eval: { + *out_tag = parse_statement_decoration_eval; + return production_for(); + } default: { *out_tag = parse_statement_decoration_none; return production_for(); diff --git a/src/proc.h b/src/proc.h index c39e1a123..abca58465 100644 --- a/src/proc.h +++ b/src/proc.h @@ -36,6 +36,8 @@ enum class process_type_t { block_node, /// The exec builtin. exec, + /// A literal evaluation + eval, }; enum class job_control_t {