From 4b01de44ba110394cac66f83a44a037fc58ae4e8 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 13 Apr 2014 11:56:02 +0100 Subject: [PATCH] py: Add traceback info to syntax errors. Should fix issue #463. --- py/builtinevex.c | 7 +++++-- py/builtinimport.c | 7 +++++-- py/parsehelper.c | 22 ++++++++++++++++------ py/parsehelper.h | 2 +- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/py/builtinevex.c b/py/builtinevex.c index fc3a60182e..ae82537374 100644 --- a/py/builtinevex.c +++ b/py/builtinevex.c @@ -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 mp_parse_error_kind_t 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) { // 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 mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, false); mp_parse_node_free(pn); diff --git a/py/builtinimport.c b/py/builtinimport.c index 697244878f..3fb658c272 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -100,15 +100,18 @@ void do_load(mp_obj_t module_obj, vstr_t *file) { // parse the imported script mp_parse_error_kind_t 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) { // 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_globals_set(old_globals); - nlr_raise(mp_parse_make_exception(parse_error_kind)); + nlr_raise(exc); } + mp_lexer_free(lex); + // compile the imported script mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, false); mp_parse_node_free(pn); diff --git a/py/parsehelper.c b/py/parsehelper.c index e069657b1d..d467399a17 100644 --- a/py/parsehelper.c +++ b/py/parsehelper.c @@ -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) { - // TODO add source file and line number to exception? +mp_obj_t mp_parse_make_exception(mp_lexer_t *lex, mp_parse_error_kind_t parse_error_kind) { + // make exception object + mp_obj_t exc; switch (parse_error_kind) { 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: - 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: - 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: 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; } diff --git a/py/parsehelper.h b/py/parsehelper.h index 1de70d19d6..b8f8c106dd 100644 --- a/py/parsehelper.h +++ b/py/parsehelper.h @@ -1,2 +1,2 @@ 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);