diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2015-09-09 14:10:24 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2015-09-09 14:10:24 +0200 |
commit | 7a2f5753a12a68e87f8556f6e833710f147533b2 (patch) | |
tree | 850bfc8e3b0a40671db5656e695d640488bdda0a /build/lexer | |
parent | e3b6dc455ab5c98606e38983bd19426ae346f469 (diff) |
Add support for evaluation context
For now it acts as just the value mode that can be enabled anywhere
variable expansion is supported, for example:
(foo=bar):
And the primary use currently is to enable/test quoted and indirect
variable expansion:
"foo bar" = FOO BAR
print $"foo bar" # Invalid.
print $("foo bar") # Yeah, baby.
foo = FOO
FOO = foo
print $($foo)
Not that you should do something like this...
Diffstat (limited to 'build/lexer')
-rw-r--r-- | build/lexer | 50 |
1 files changed, 21 insertions, 29 deletions
diff --git a/build/lexer b/build/lexer index 37c7807..13f28cb 100644 --- a/build/lexer +++ b/build/lexer @@ -5,6 +5,7 @@ #ifndef BUILD_LEXER #define BUILD_LEXER +#include <stack> #include <string> #include <iosfwd> #include <cstddef> // size_t @@ -21,16 +22,20 @@ namespace build { // Context-dependent lexing mode. In the value mode we don't treat // certain characters (e.g., +, =) as special so that we can use - // them in the variable values, e.g., 'foo = g++'. In contrast, - // in the variable mode, we restrict certain character (e.g., /) - // from appearing in the name. The pairs mode is just like value - // except that we split names separated by the pair character. - // The alternnative modes must be set manually. The value and - // pairs modes are automatically reset after the end of the line. - // The variable mode is automatically reset after the name token. - // Quoted is an internal mode and should not be explicitly set. + // them in the variable values, e.g., 'foo = g++'. In contrast, in + // the variable mode, we restrict certain character (e.g., /) from + // appearing in the name. The pairs mode is just like value except + // that we split names separated by the pair character. The eval + // mode is used in the evaluation context. // - enum class lexer_mode {normal, quoted, variable, value, pairs}; + // The alternnative modes must be set manually. The value and pairs + // modes are automatically reset after the end of the line. The + // variable mode is reset after the name token. And the eval mode + // is reset after the closing ')'. + // + // Quoted is an internal mode and should not be set explicitly. + // + enum class lexer_mode {normal, variable, value, pairs, eval, quoted}; class lexer: protected butl::char_scanner { @@ -69,14 +74,17 @@ namespace build private: token + next_eval (); + + token next_quoted (); token name (bool separated); - // Return true we have seen any spaces. Skipped empty lines don't - // count. In other words, we are only interested in spaces that - // are on the same line as the following non-space character. + // Return true if we have seen any spaces. Skipped empty lines + // don't count. In other words, we are only interested in spaces + // that are on the same line as the following non-space character. // bool skip_spaces (); @@ -101,23 +109,7 @@ namespace build private: fail_mark fail; - // Currently, the maximum mode nesting is 4: {normal, value, quoted, - // variable}. - // - struct mode_stack - { - static const size_t max_size = 4; - - void push (lexer_mode m) {assert (n_ != max_size); d_[n_++] = m;} - void pop () {assert (n_ != 0); n_--;} - lexer_mode top () const {return d_[n_ - 1];} - - private: - size_t n_ = 0; - lexer_mode d_[max_size]; - }; - - mode_stack mode_; + std::stack<lexer_mode> mode_; char pair_separator_; }; } |