forked from Mirror/wren
Better handling for lexing errors.
This commit is contained in:
2
runtests
2
runtests
@ -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')
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
3
test/comments/unterminated_block.wren
Normal file
3
test/comments/unterminated_block.wren
Normal file
@ -0,0 +1,3 @@
|
||||
// expect error line 3
|
||||
IO.write("nope") /*
|
||||
oops
|
||||
4
test/comments/unterminated_nested_block.wren
Normal file
4
test/comments/unterminated_nested_block.wren
Normal file
@ -0,0 +1,4 @@
|
||||
// expect error line 4
|
||||
IO.write("nope") /* /* /*
|
||||
*/
|
||||
oops
|
||||
3
test/unexpected_character.wren
Normal file
3
test/unexpected_character.wren
Normal file
@ -0,0 +1,3 @@
|
||||
IO.write("no")
|
||||
// Something that's not a valid character:
|
||||
^ // expect error
|
||||
Reference in New Issue
Block a user