@@ -62,23 +62,28 @@ typedef enum {
6262#define EMIT_INLINE_ASM (fun ) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm))
6363#define EMIT_INLINE_ASM_ARG (fun , ...) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm, __VA_ARGS__))
6464
65+ // elements in this struct are ordered to make it compact
6566typedef struct _compiler_t {
6667 qstr source_file ;
68+
6769 uint8_t is_repl ;
6870 uint8_t pass ; // holds enum type pass_kind_t
69- uint8_t had_error ; // try to keep compiler clean from nlr
7071 uint8_t func_arg_is_super ; // used to compile special case of super() function call
72+ uint8_t have_star ;
73+
74+ // try to keep compiler clean from nlr
75+ // this is set to an exception object if we have a compile error
76+ mp_obj_t compile_error ;
7177
7278 uint next_label ;
7379
80+ uint16_t num_dict_params ;
81+ uint16_t num_default_params ;
82+
7483 uint16_t break_label ; // highest bit set indicates we are breaking out of a for loop
7584 uint16_t continue_label ;
76- int break_continue_except_level ;
7785 uint16_t cur_except_level ; // increased for SETUP_EXCEPT, SETUP_FINALLY; decreased for POP_BLOCK, POP_EXCEPT
78-
79- uint8_t have_star ;
80- uint16_t num_dict_params ;
81- uint16_t num_default_params ;
86+ int break_continue_except_level ;
8287
8388 scope_t * scope_head ;
8489 scope_t * scope_cur ;
@@ -91,14 +96,15 @@ typedef struct _compiler_t {
9196} compiler_t ;
9297
9398STATIC void compile_syntax_error (compiler_t * comp , mp_parse_node_t pn , const char * msg ) {
94- // TODO store the error message to a variable in compiler_t instead of printing it
99+ mp_obj_t exc = mp_obj_new_exception_msg (& mp_type_SyntaxError , msg );
100+ // we don't have a 'block' name, so just pass the NULL qstr to indicate this
95101 if (MP_PARSE_NODE_IS_STRUCT (pn )) {
96- printf ( " File \"%s\", line " UINT_FMT "\n" , qstr_str ( comp -> source_file ) , (mp_uint_t )((mp_parse_node_struct_t * )pn )-> source_line );
102+ mp_obj_exception_add_traceback ( exc , comp -> source_file , (mp_uint_t )((mp_parse_node_struct_t * )pn )-> source_line , MP_QSTR_NULL );
97103 } else {
98- printf (" File \"%s\"\n" , qstr_str (comp -> source_file ));
104+ // we don't have a line number, so just pass 0
105+ mp_obj_exception_add_traceback (exc , comp -> source_file , 0 , MP_QSTR_NULL );
99106 }
100- printf ("SyntaxError: %s\n" , msg );
101- comp -> had_error = true;
107+ comp -> compile_error = exc ;
102108}
103109
104110STATIC const mp_map_elem_t mp_constants_table [] = {
@@ -1107,7 +1113,7 @@ qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint
11071113 comp -> num_default_params = 0 ;
11081114 apply_to_single_or_list (comp , pns -> nodes [1 ], PN_typedargslist , compile_funcdef_param );
11091115
1110- if (comp -> had_error ) {
1116+ if (comp -> compile_error != MP_OBJ_NULL ) {
11111117 return MP_QSTR_NULL ;
11121118 }
11131119
@@ -3415,7 +3421,8 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
34153421 if (comp -> pass > MP_PASS_SCOPE ) {
34163422 bool success = EMIT_INLINE_ASM (end_pass );
34173423 if (!success ) {
3418- comp -> had_error = true;
3424+ // TODO get proper exception from inline assembler
3425+ compile_syntax_error (comp , MP_PARSE_NODE_NULL , "inline assembler error" );
34193426 }
34203427 }
34213428}
@@ -3550,6 +3557,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
35503557 compiler_t * comp = m_new0 (compiler_t , 1 );
35513558 comp -> source_file = source_file ;
35523559 comp -> is_repl = is_repl ;
3560+ comp -> compile_error = MP_OBJ_NULL ;
35533561
35543562 // optimise constants
35553563 mp_map_t consts ;
@@ -3566,7 +3574,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
35663574 comp -> emit_inline_asm = NULL ;
35673575 comp -> emit_inline_asm_method_table = NULL ;
35683576 uint max_num_labels = 0 ;
3569- for (scope_t * s = comp -> scope_head ; s != NULL && ! comp -> had_error ; s = s -> next ) {
3577+ for (scope_t * s = comp -> scope_head ; s != NULL && comp -> compile_error == MP_OBJ_NULL ; s = s -> next ) {
35703578 if (false) {
35713579#if MICROPY_EMIT_INLINE_THUMB
35723580 } else if (s -> emit_options == MP_EMIT_OPT_ASM_THUMB ) {
@@ -3583,7 +3591,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
35833591 }
35843592
35853593 // compute some things related to scope and identifiers
3586- for (scope_t * s = comp -> scope_head ; s != NULL && ! comp -> had_error ; s = s -> next ) {
3594+ for (scope_t * s = comp -> scope_head ; s != NULL && comp -> compile_error == MP_OBJ_NULL ; s = s -> next ) {
35873595 compile_scope_compute_things (comp , s );
35883596 }
35893597
@@ -3600,7 +3608,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
36003608 emit_inline_asm_t * emit_inline_thumb = NULL ;
36013609#endif
36023610#endif // !MICROPY_EMIT_CPYTHON
3603- for (scope_t * s = comp -> scope_head ; s != NULL && ! comp -> had_error ; s = s -> next ) {
3611+ for (scope_t * s = comp -> scope_head ; s != NULL && comp -> compile_error == MP_OBJ_NULL ; s = s -> next ) {
36043612 if (false) {
36053613 // dummy
36063614
@@ -3615,7 +3623,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
36153623 comp -> emit_inline_asm = emit_inline_thumb ;
36163624 comp -> emit_inline_asm_method_table = & emit_inline_thumb_method_table ;
36173625 compile_scope_inline_asm (comp , s , MP_PASS_CODE_SIZE );
3618- if (! comp -> had_error ) {
3626+ if (comp -> compile_error == MP_OBJ_NULL ) {
36193627 compile_scope_inline_asm (comp , s , MP_PASS_EMIT );
36203628 }
36213629#endif
@@ -3674,12 +3682,12 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
36743682#endif // !MICROPY_EMIT_CPYTHON
36753683
36763684 // second last pass: compute code size
3677- if (! comp -> had_error ) {
3685+ if (comp -> compile_error == MP_OBJ_NULL ) {
36783686 compile_scope (comp , s , MP_PASS_CODE_SIZE );
36793687 }
36803688
36813689 // final pass: emit code
3682- if (! comp -> had_error ) {
3690+ if (comp -> compile_error == MP_OBJ_NULL ) {
36833691 compile_scope (comp , s , MP_PASS_EMIT );
36843692 }
36853693 }
@@ -3722,12 +3730,11 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
37223730 }
37233731
37243732 // free the compiler
3725- bool had_error = comp -> had_error ;
3733+ mp_obj_t compile_error = comp -> compile_error ;
37263734 m_del_obj (compiler_t , comp );
37273735
3728- if (had_error ) {
3729- // TODO return a proper error message
3730- return mp_const_none ;
3736+ if (compile_error != MP_OBJ_NULL ) {
3737+ return compile_error ;
37313738 } else {
37323739#if MICROPY_EMIT_CPYTHON
37333740 // can't create code, so just return true
0 commit comments