Throw a specific error for incomplete parse errors.

`nix-repl` will use this for deciding whether to keep waiting for input or
error out right away.
This commit is contained in:
Scott Olson 2016-02-24 04:32:18 -06:00
parent 8f71bc33d5
commit 6498adb002
3 changed files with 11 additions and 1 deletions

View file

@ -195,5 +195,7 @@ or { return OR_KW; }
} }
<<EOF>> { data->atEnd = true; return 0; }
%% %%

View file

@ -11,6 +11,7 @@ namespace nix {
MakeError(EvalError, Error) MakeError(EvalError, Error)
MakeError(ParseError, Error) MakeError(ParseError, Error)
MakeError(IncompleteParseError, ParseError)
MakeError(AssertionError, EvalError) MakeError(AssertionError, EvalError)
MakeError(ThrownError, AssertionError) MakeError(ThrownError, AssertionError)
MakeError(Abort, EvalError) MakeError(Abort, EvalError)

View file

@ -31,10 +31,12 @@ namespace nix {
Path basePath; Path basePath;
Symbol path; Symbol path;
string error; string error;
bool atEnd;
Symbol sLetBody; Symbol sLetBody;
ParseData(EvalState & state) ParseData(EvalState & state)
: state(state) : state(state)
, symbols(state.symbols) , symbols(state.symbols)
, atEnd(false)
, sLetBody(symbols.create("<let-body>")) , sLetBody(symbols.create("<let-body>"))
{ }; { };
}; };
@ -539,7 +541,12 @@ Expr * EvalState::parse(const char * text,
int res = yyparse(scanner, &data); int res = yyparse(scanner, &data);
yylex_destroy(scanner); yylex_destroy(scanner);
if (res) throw ParseError(data.error); if (res) {
if (data.atEnd)
throw IncompleteParseError(data.error);
else
throw ParseError(data.error);
}
data.result->bindVars(staticEnv); data.result->bindVars(staticEnv);