1
0
forked from Mirror/wren

Better handling for lexing errors.

This commit is contained in:
Bob Nystrom
2013-12-23 14:51:06 -08:00
parent 1503e74233
commit c8cb0be816
5 changed files with 36 additions and 6 deletions

View File

@ -35,7 +35,7 @@ else:
EXPECT_PATTERN = re.compile(r'// expect: (.*)')
EXPECT_ERROR_PATTERN = re.compile(r'// expect error')
EXPECT_ERROR_LINE_PATTERN = re.compile(r'// expect error line (\d+)')
ERROR_PATTERN = re.compile(r'\[Line (\d+)\] Error ')
ERROR_PATTERN = re.compile(r'\[Line (\d+)\] Error')
SKIP_PATTERN = re.compile(r'// skip: (.*)')
NONTEST_PATTERN = re.compile(r'// nontest')

View File

@ -279,6 +279,24 @@ static int initCompiler(Compiler* compiler, Parser* parser, Compiler* parent,
return addConstant(parent, OBJ_VAL(compiler->fn));
}
// Outputs a compile or syntax error. This also marks the compilation as having
// an error, which ensures that the resulting code will be discarded and never
// run. This means that after calling lexError(), it's fine to generate whatever
// invalid bytecode you want since it won't be used.
static void lexError(Parser* parser, const char* format, ...)
{
parser->hasError = true;
fprintf(stderr, "[Line %d] Error: ", parser->currentLine);
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
fprintf(stderr, "\n");
}
// Outputs a compile or syntax error. This also marks the compilation as having
// an error, which ensures that the resulting code will be discarded and never
// run. This means that after calling error(), it's fine to generate whatever
@ -344,6 +362,7 @@ static char nextChar(Parser* parser)
{
char c = peekChar(parser);
parser->currentChar++;
if (c == '\n') parser->currentLine++;
return c;
}
@ -388,8 +407,11 @@ static void skipBlockComment(Parser* parser)
int nesting = 1;
while (nesting > 0)
{
// TODO: Unterminated comment. Should return error.
if (peekChar(parser) == '\0') return;
if (peekChar(parser) == '\0')
{
lexError(parser, "Unterminated block comment.");
return;
}
if (peekChar(parser) == '/' && peekNextChar(parser) == '*')
{
@ -581,7 +603,6 @@ static void readRawToken(Parser* parser)
return;
case '\n':
parser->currentLine++;
makeToken(parser, TOKEN_LINE);
return;
@ -604,8 +625,7 @@ static void readRawToken(Parser* parser)
}
else
{
// TODO: Handle error.
makeToken(parser, TOKEN_ERROR);
lexError(parser, "Invalid character '%c'.", c);
}
return;
}

View File

@ -0,0 +1,3 @@
// expect error line 3
IO.write("nope") /*
oops

View File

@ -0,0 +1,4 @@
// expect error line 4
IO.write("nope") /* /* /*
*/
oops

View File

@ -0,0 +1,3 @@
IO.write("no")
// Something that's not a valid character:
^ // expect error