summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/wast-lexer.cc32
-rw-r--r--src/wast-parser.cc5
2 files changed, 22 insertions, 15 deletions
diff --git a/src/wast-lexer.cc b/src/wast-lexer.cc
index c37f5af3..59bc0d71 100644
--- a/src/wast-lexer.cc
+++ b/src/wast-lexer.cc
@@ -175,7 +175,9 @@ Token WastLexer::GetToken(WastParser* parser) {
}
Location WastLexer::GetLocation() {
- auto column = [=](const char* p) { return p - line_start_ + 1; };
+ auto column = [=](const char* p) {
+ return std::max(1, static_cast<int>(p - line_start_ + 1));
+ };
return Location(filename_, line_, column(token_start_), column(cursor_));
}
@@ -288,9 +290,10 @@ void WastLexer::ReadWhitespace() {
}
Token WastLexer::GetStringToken(WastParser* parser) {
- auto saved_loc = GetLocation();
- ReadChar();
+ const char* saved_token_start = token_start_;
+ bool has_error = false;
bool in_string = true;
+ ReadChar();
while (in_string) {
switch (ReadChar()) {
case kEof:
@@ -299,6 +302,7 @@ Token WastLexer::GetStringToken(WastParser* parser) {
case '\n':
token_start_ = cursor_ - 1;
ERROR("newline in string");
+ has_error = true;
Newline();
continue;
@@ -339,8 +343,10 @@ Token WastLexer::GetStringToken(WastParser* parser) {
case 'D':
case 'E':
case 'F': // Hex byte escape.
- if (!IsHexDigit(ReadChar())) {
- token_start_ = cursor_ - 3;
+ if (IsHexDigit(PeekChar())) {
+ ReadChar();
+ } else {
+ token_start_ = cursor_ - 2;
goto error;
}
break;
@@ -352,19 +358,19 @@ Token WastLexer::GetStringToken(WastParser* parser) {
error:
ERROR("bad escape \"%.*s\"",
static_cast<int>(cursor_ - token_start_), token_start_);
+ has_error = true;
break;
}
break;
}
}
}
- auto token = TextToken(TokenType::Text);
- // Use line and first_column from the saved location instead. Otherwise, the
- // beginning of the string may not start with a quote if the string contains
- // a newline.
- token.loc.line = saved_loc.line;
- token.loc.first_column = saved_loc.first_column;
- return token;
+ token_start_ = saved_token_start;
+ if (has_error) {
+ return Token(GetLocation(), TokenType::Invalid);
+ }
+
+ return TextToken(TokenType::Text);
}
// static
@@ -466,7 +472,7 @@ Token WastLexer::GetHexNumberToken(TokenType token_type) {
if (MatchChar('p') || MatchChar('P')) {
token_type = TokenType::Float;
ReadSign();
- if (!ReadHexNum()) {
+ if (!ReadNum()) {
return GetReservedToken();
}
}
diff --git a/src/wast-parser.cc b/src/wast-parser.cc
index bdbba00c..6be18464 100644
--- a/src/wast-parser.cc
+++ b/src/wast-parser.cc
@@ -396,10 +396,11 @@ TokenType WastParser::Peek(size_t n) {
if (cur.token_type() != TokenType::LparAnn) {
tokens_.push_back(cur);
} else {
- // Custom annotation. For now, discard until matching Rpar
+ // Custom annotation. For now, discard until matching Rpar.
if (!options_->features.annotations_enabled()) {
Error(cur.loc, "annotations not enabled: %s", cur.to_string().c_str());
- return TokenType::Invalid;
+ tokens_.push_back(Token(cur.loc, TokenType::Invalid));
+ continue;
}
int indent = 1;
while (indent > 0) {