aboutsummaryrefslogtreecommitdiff
path: root/build
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-09-08 12:37:39 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-09-08 12:37:39 +0200
commitefd76ff778c0b7b1f8cb9e0485bb9b4b62b149a7 (patch)
tree81551df937191dde3503cdaa81fc472e120fa3c5 /build
parentb66d30af9fb5c50966183820f8ed7af6b8791a2e (diff)
Implement single quote support
Diffstat (limited to 'build')
-rw-r--r--build/bootstrap.build1
-rw-r--r--build/lexer5
-rw-r--r--build/lexer.cxx39
-rw-r--r--build/root.build7
4 files changed, 47 insertions, 5 deletions
diff --git a/build/bootstrap.build b/build/bootstrap.build
index 381b45e..05aac3e 100644
--- a/build/bootstrap.build
+++ b/build/bootstrap.build
@@ -4,3 +4,4 @@
project = build2
subprojects = # No subprojects.
using config
+using test
diff --git a/build/lexer b/build/lexer
index e5676cc..9a0582d 100644
--- a/build/lexer
+++ b/build/lexer
@@ -61,7 +61,10 @@ namespace build
private:
token
- name (xchar, bool separated);
+ name (bool separated);
+
+ void
+ single_quote (std::string& lexeme);
// Return true we have seen any spaces. Skipped empty lines don't
// count. In other words, we are only interested in spaces that
diff --git a/build/lexer.cxx b/build/lexer.cxx
index 88628d3..4151087 100644
--- a/build/lexer.cxx
+++ b/build/lexer.cxx
@@ -94,17 +94,20 @@ namespace build
// Otherwise it is a name.
//
- return name (c, sep);
+ unget (c);
+ return name (sep);
}
token lexer::
- name (xchar c, bool sep)
+ name (bool sep)
{
+ xchar c (peek ());
+ assert (!eos (c));
+
uint64_t ln (c.line), cn (c.column);
string lexeme;
- lexeme += (c != '\\' ? c : escape ());
- for (c = peek (); !eos (c); c = peek ())
+ for (; !eos (c); c = peek ())
{
bool done (false);
@@ -173,6 +176,11 @@ namespace build
lexeme += escape ();
break;
}
+ case '\'':
+ {
+ single_quote (lexeme);
+ break;
+ }
default:
{
get ();
@@ -185,12 +193,35 @@ namespace build
break;
}
+ // The first character shall not be a separator (we shouldn't have
+ // been called if that's the case).
+ //
+ assert (c.line != ln || c.column != cn);
+
if (mode_ == lexer_mode::variable)
next_mode_ = prev_mode_;
return token (lexeme, sep, ln, cn);
}
+ // Assuming the next character is the opening single quote, scan
+ // the stream until the closing quote (or eos), accumulating
+ // characters in between in lexeme. Fail if eos is reached before
+ // the closing quote.
+ //
+ void lexer::
+ single_quote (string& lexeme)
+ {
+ xchar c (get ()); // Opening quote mark.
+ assert (c == '\'');
+
+ for (c = get (); !eos (c) && c != '\''; c = get ())
+ lexeme += c;
+
+ if (eos (c))
+ fail (c) << "unterminated single-quoted sequence";
+ }
+
bool lexer::
skip_spaces ()
{
diff --git a/build/root.build b/build/root.build
index 5af4637..1afbe80 100644
--- a/build/root.build
+++ b/build/root.build
@@ -11,3 +11,10 @@ cxx.ext = cxx
cxx.std = 14
cxx.poptions += -I$src_root
+
+# All exe{} in tests/ are, well, tests.
+#
+tests/:
+{
+ test.exe = true
+}