aboutsummaryrefslogtreecommitdiff
path: root/build/lexer
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-09-09 14:10:24 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-09-09 14:10:24 +0200
commit7a2f5753a12a68e87f8556f6e833710f147533b2 (patch)
tree850bfc8e3b0a40671db5656e695d640488bdda0a /build/lexer
parente3b6dc455ab5c98606e38983bd19426ae346f469 (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/lexer50
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_;
};
}