From 4208f2d755f2bd2215051390f6500ccf54f1858f Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 13 Jul 2015 08:46:45 +0200 Subject: Add support for pair-enabled variables --- build/lexer | 3 +++ build/name | 2 +- build/name.cxx | 7 ++++++- build/parser.cxx | 36 ++++++++++++++++-------------------- build/variable | 5 +++-- 5 files changed, 29 insertions(+), 24 deletions(-) diff --git a/build/lexer b/build/lexer index 5205ae9..1e5bfd0 100644 --- a/build/lexer +++ b/build/lexer @@ -49,6 +49,9 @@ namespace build lexer_mode mode () const {return mode_;} + char + pair_separator () const {return pair_separator_;} + // Scanner. // token diff --git a/build/name b/build/name index 924c123..4a86950 100644 --- a/build/name +++ b/build/name @@ -52,7 +52,7 @@ namespace build std::string type; dir_path dir; std::string value; - bool pair {false}; // Store pair symbol for printing? + char pair = '\0'; // Pair symbol, if any. }; inline bool diff --git a/build/name.cxx b/build/name.cxx index 4ead47a..89236ee 100644 --- a/build/name.cxx +++ b/build/name.cxx @@ -47,7 +47,12 @@ namespace build { const name& n (*i); ++i; - os << n << (n.pair ? "=" : (i != e ? " " : "")); + os << n; + + if (n.pair != '\0') + os << n.pair; + else if (i != e) + os << ' '; } return os; diff --git a/build/parser.cxx b/build/parser.cxx index e051124..0238adc 100644 --- a/build/parser.cxx +++ b/build/parser.cxx @@ -67,10 +67,8 @@ namespace build target_ = nullptr; scope_ = &s; - token t (type::eos, false, 0, 0); type tt; - next (t, tt); - + token t (type::eos, false, 0, 0); variable (t, tt, name, kind); return t; } @@ -316,9 +314,7 @@ namespace build else target_ = &enter_target (move (n)); - type kind (tt); - next (t, tt); - variable (t, tt, move (var), kind); + variable (t, tt, move (var), tt); scope_ = os; target_ = ot; @@ -389,11 +385,7 @@ namespace build // if (tt == type::equal || tt == type::plus_equal) { - string var (variable_name (move (ns), nloc)); - - type kind (tt); - next (t, tt); - variable (t, tt, move (var), kind); + variable (t, tt, variable_name (move (ns), nloc), tt); if (tt == type::newline) next (t, tt); @@ -766,12 +758,16 @@ namespace build variable (token& t, token_type& tt, string name, token_type kind) { bool assign (kind == type::equal); + const auto& var (variable_pool.find (move (name))); + + if (var.pairs != '\0') + lexer_->mode (lexer_mode::pairs, var.pairs); + + next (t, tt); names_type vns (tt != type::newline && tt != type::eos ? names (t, tt) : names_type ()); - const auto& var (variable_pool.find (move (name))); - if (assign) { auto v (target_ != nullptr @@ -910,7 +906,7 @@ namespace build ns, (pair != 0 ? pair - : (ns.empty () || !ns.back ().pair ? 0 : ns.size ())), + : (ns.empty () || ns.back ().pair == '\0' ? 0 : ns.size ())), dp1, tp1); count = ns.size () - count; @@ -1085,7 +1081,7 @@ namespace build { // Check that there are no nested pairs. // - if (n.pair) + if (n.pair != '\0') fail (t) << "nested pair in variable expansion"; // And add another first half unless this is the first instance. @@ -1115,7 +1111,7 @@ namespace build ns, (pair != 0 ? pair - : (ns.empty () || !ns.back ().pair ? 0 : ns.size ())), + : (ns.empty () || ns.back ().pair == '\0' ? 0 : ns.size ())), dp, tp); count = ns.size () - count; @@ -1146,7 +1142,7 @@ namespace build count = 1; } - ns.back ().pair = true; + ns.back ().pair = lexer_->pair_separator (); tt = peek (); continue; } @@ -1175,7 +1171,7 @@ namespace build // Handle the empty RHS in a pair, (e.g., {y=}). // - if (!ns.empty () && ns.back ().pair) + if (!ns.empty () && ns.back ().pair != '\0') { ns.emplace_back ((tp != nullptr ? *tp : string ()), (dp != nullptr ? *dp : dir_path ()), @@ -1213,7 +1209,7 @@ namespace build { // First it has to be a non-empty simple name. // - if (n.pair || !n.type.empty () || !n.dir.empty () || n.value.empty ()) + if (n.pair != '\0' || !n.simple () || n.empty ()) return false; // C identifier. @@ -1278,7 +1274,7 @@ namespace build // Do we have the src_base? // dir_path src_base; - if (i->pair) + if (i->pair != '\0') { if (!i->type.empty ()) fail (l) << "expected target src_base instead of " << *i; diff --git a/build/variable b/build/variable index 9c6d3bc..10e6247 100644 --- a/build/variable +++ b/build/variable @@ -35,10 +35,11 @@ namespace build struct variable { explicit - variable (std::string n): name (std::move (n)), type (nullptr) {} + variable (std::string n): name (std::move (n)) {} std::string name; - const value_type* type; // If NULL, then this variable has no fixed type. + char pairs = '\0'; + //const value_type* type = nullptr; // If NULL, then no fixed type. }; inline bool -- cgit v1.1