aboutsummaryrefslogtreecommitdiff
path: root/build
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-07-13 08:46:45 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-07-13 08:46:45 +0200
commit4208f2d755f2bd2215051390f6500ccf54f1858f (patch)
tree643336ed7ca628fd06127be73caec2a1b4d9ae4e /build
parentd7ed84309eeda86e793c42864cebd7f8f3b7c66c (diff)
Add support for pair-enabled variables
Diffstat (limited to 'build')
-rw-r--r--build/lexer3
-rw-r--r--build/name2
-rw-r--r--build/name.cxx7
-rw-r--r--build/parser.cxx36
-rw-r--r--build/variable5
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