aboutsummaryrefslogtreecommitdiff
path: root/build2/parser.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-01-21 15:03:26 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-01-21 15:03:26 +0200
commit67382c15f7e9176dea44c3da7f7013759c88ce33 (patch)
tree5ff4fe1436792a01d4a8576f1e0efa3ce2ff9c20 /build2/parser.cxx
parent41f091f46b47c20dc1571db5d56a1eaade25cb1e (diff)
Add support for ==, != in eval context
Diffstat (limited to 'build2/parser.cxx')
-rw-r--r--build2/parser.cxx45
1 files changed, 42 insertions, 3 deletions
diff --git a/build2/parser.cxx b/build2/parser.cxx
index b1a4414..187c47e 100644
--- a/build2/parser.cxx
+++ b/build2/parser.cxx
@@ -1134,12 +1134,51 @@ namespace build2
mode (lexer_mode::eval);
next (t, tt);
- names_type ns (tt != type::rparen ? names (t, tt) : names_type ());
+ names_type ns;
+ eval_trailer (t, tt, ns);
+ return ns;
+ }
+ void parser::
+ eval_trailer (token& t, type& tt, names_type& ns)
+ {
+ // Note that names() will handle the ( == foo) case since if it gets
+ // called, it expects to see a name.
+ //
if (tt != type::rparen)
- fail (t) << "expected ')' instead of " << t;
+ names (t, tt, ns);
- return ns;
+ switch (tt)
+ {
+ case type::equal:
+ case type::not_equal:
+ {
+ type op (tt);
+
+ // ==, != are left-associative, so get the rhs name and evaluate.
+ //
+ next (t, tt);
+ names_type rhs (names (t, tt));
+
+ bool r;
+ switch (op)
+ {
+ case type::equal: r = ns == rhs; break;
+ case type::not_equal: r = ns != rhs; break;
+ default: r = false; assert (false);
+ }
+
+ ns.resize (1);
+ ns[0] = name (r ? "true" : "false");
+
+ eval_trailer (t, tt, ns);
+ break;
+ }
+ case type::rparen:
+ break;
+ default:
+ fail (t) << "expected ')' instead of " << t;
+ }
}
// Parse names inside {} and handle the following "crosses" (i.e.,