py: Add traceback info to syntax errors.

Should fix issue #463.
This commit is contained in:
Damien George 2014-04-13 11:56:02 +01:00
parent 3d484d9ad4
commit 4b01de44ba
4 changed files with 27 additions and 11 deletions

View File

@ -25,13 +25,16 @@ STATIC mp_obj_t parse_compile_execute(mp_obj_t o_in, mp_parse_input_kind_t parse
// parse the string // parse the string
mp_parse_error_kind_t parse_error_kind; mp_parse_error_kind_t parse_error_kind;
mp_parse_node_t pn = mp_parse(lex, parse_input_kind, &parse_error_kind); mp_parse_node_t pn = mp_parse(lex, parse_input_kind, &parse_error_kind);
mp_lexer_free(lex);
if (pn == MP_PARSE_NODE_NULL) { if (pn == MP_PARSE_NODE_NULL) {
// parse error; raise exception // parse error; raise exception
nlr_raise(mp_parse_make_exception(parse_error_kind)); mp_obj_t exc = mp_parse_make_exception(lex, parse_error_kind);
mp_lexer_free(lex);
nlr_raise(exc);
} }
mp_lexer_free(lex);
// compile the string // compile the string
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, false); mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, false);
mp_parse_node_free(pn); mp_parse_node_free(pn);

View File

@ -100,15 +100,18 @@ void do_load(mp_obj_t module_obj, vstr_t *file) {
// parse the imported script // parse the imported script
mp_parse_error_kind_t parse_error_kind; mp_parse_error_kind_t parse_error_kind;
mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_error_kind); mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_error_kind);
mp_lexer_free(lex);
if (pn == MP_PARSE_NODE_NULL) { if (pn == MP_PARSE_NODE_NULL) {
// parse error; clean up and raise exception // parse error; clean up and raise exception
mp_obj_t exc = mp_parse_make_exception(lex, parse_error_kind);
mp_lexer_free(lex);
mp_locals_set(old_locals); mp_locals_set(old_locals);
mp_globals_set(old_globals); mp_globals_set(old_globals);
nlr_raise(mp_parse_make_exception(parse_error_kind)); nlr_raise(exc);
} }
mp_lexer_free(lex);
// compile the imported script // compile the imported script
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, false); mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, false);
mp_parse_node_free(pn); mp_parse_node_free(pn);

View File

@ -38,20 +38,30 @@ void mp_parse_show_exception(mp_lexer_t *lex, mp_parse_error_kind_t parse_error_
} }
} }
mp_obj_t mp_parse_make_exception(mp_parse_error_kind_t parse_error_kind) { mp_obj_t mp_parse_make_exception(mp_lexer_t *lex, mp_parse_error_kind_t parse_error_kind) {
// TODO add source file and line number to exception? // make exception object
mp_obj_t exc;
switch (parse_error_kind) { switch (parse_error_kind) {
case MP_PARSE_ERROR_MEMORY: case MP_PARSE_ERROR_MEMORY:
return mp_obj_new_exception_msg(&mp_type_MemoryError, STR_MEMORY); exc = mp_obj_new_exception_msg(&mp_type_MemoryError, STR_MEMORY);
break;
case MP_PARSE_ERROR_UNEXPECTED_INDENT: case MP_PARSE_ERROR_UNEXPECTED_INDENT:
return mp_obj_new_exception_msg(&mp_type_IndentationError, STR_UNEXPECTED_INDENT); exc = mp_obj_new_exception_msg(&mp_type_IndentationError, STR_UNEXPECTED_INDENT);
break;
case MP_PARSE_ERROR_UNMATCHED_UNINDENT: case MP_PARSE_ERROR_UNMATCHED_UNINDENT:
return mp_obj_new_exception_msg(&mp_type_IndentationError, STR_UNMATCHED_UNINDENT); exc = mp_obj_new_exception_msg(&mp_type_IndentationError, STR_UNMATCHED_UNINDENT);
break;
case MP_PARSE_ERROR_INVALID_SYNTAX: case MP_PARSE_ERROR_INVALID_SYNTAX:
default: default:
return mp_obj_new_exception_msg(&mp_type_SyntaxError, STR_INVALID_SYNTAX); exc = mp_obj_new_exception_msg(&mp_type_SyntaxError, STR_INVALID_SYNTAX);
break;
} }
// add traceback to give info about file name and location
mp_obj_exception_add_traceback(exc, mp_lexer_source_name(lex), mp_lexer_cur(lex)->src_line, mp_lexer_cur(lex)->src_column);
return exc;
} }

View File

@ -1,2 +1,2 @@
void mp_parse_show_exception(mp_lexer_t *lex, mp_parse_error_kind_t parse_error_kind); void mp_parse_show_exception(mp_lexer_t *lex, mp_parse_error_kind_t parse_error_kind);
mp_obj_t mp_parse_make_exception(mp_parse_error_kind_t parse_error_kind); mp_obj_t mp_parse_make_exception(mp_lexer_t *lex, mp_parse_error_kind_t parse_error_kind);