2929from src .api .opcodestemps import OpcodesTemps
3030from src .api .errmsg import error
3131from src .api .errmsg import warning
32+ from src .api .global_ import LoopInfo
3233
3334from src .api .check import check_and_make_label
3435from src .api .check import common_type
4546from src .api .constants import CLASS
4647from src .api .constants import SCOPE
4748from src .api .constants import CONVENTION
49+ from src .api .constants import LoopType
4850
4951import src .api .symboltable
5052import src .api .config
@@ -1535,8 +1537,8 @@ def p_next1(p):
15351537 p1 = p [1 ]
15361538 p3 = p [3 ]
15371539
1538- if p3 != gl .LOOPS [- 1 ][ 1 ] :
1539- src .api .errmsg .syntax_error_wrong_for_var (p .lineno (2 ), gl .LOOPS [- 1 ][ 1 ] , p3 )
1540+ if p3 != gl .LOOPS [- 1 ]. var :
1541+ src .api .errmsg .syntax_error_wrong_for_var (p .lineno (2 ), gl .LOOPS [- 1 ]. var , p3 )
15401542 p [0 ] = make_nop ()
15411543 return
15421544
@@ -1545,7 +1547,7 @@ def p_next1(p):
15451547
15461548def p_for_sentence_start (p ):
15471549 """for_start : FOR ID EQ expr TO expr step"""
1548- gl .LOOPS .append (( " FOR" , p [2 ]))
1550+ gl .LOOPS .append (LoopInfo ( type = LoopType . FOR , lineno = p . lineno ( 1 ), var = p [2 ]))
15491551 p [0 ] = None
15501552
15511553 if p [4 ] is None or p [6 ] is None or p [7 ] is None :
@@ -1633,7 +1635,7 @@ def p_do_loop(p):
16331635 q = p [2 ]
16341636
16351637 if p [1 ] == "DO" :
1636- gl .LOOPS .append (( "DO" , ))
1638+ gl .LOOPS .append (LoopInfo ( LoopType . DO , p . lineno ( 1 ) ))
16371639
16381640 if q is None :
16391641 warning (p .lineno (1 ), "Infinite empty loop" )
@@ -1656,7 +1658,7 @@ def p_do_loop_until(p):
16561658 r = p [4 ]
16571659
16581660 if p [1 ] == "DO" :
1659- gl .LOOPS .append (( "DO" , ))
1661+ gl .LOOPS .append (LoopInfo ( LoopType . DO , p . lineno ( 1 ) ))
16601662
16611663 p [0 ] = make_sentence (p .lineno (1 ), "DO_UNTIL" , r , q )
16621664
@@ -1779,7 +1781,7 @@ def p_do_loop_while(p):
17791781 r = p [4 ]
17801782
17811783 if p [1 ] == "DO" :
1782- gl .LOOPS .append (( "DO" , ))
1784+ gl .LOOPS .append (LoopInfo ( LoopType . DO , p . lineno ( 1 ) ))
17831785
17841786 p [0 ] = make_sentence (p .lineno (1 ), "DO_WHILE" , r , q )
17851787 gl .LOOPS .pop ()
@@ -1827,20 +1829,20 @@ def p_do_until_loop(p):
18271829def p_do_while_start (p ):
18281830 """do_while_start : DO WHILE expr"""
18291831 p [0 ] = p [3 ]
1830- gl .LOOPS .append (( "DO" , ))
1832+ gl .LOOPS .append (LoopInfo ( LoopType . DO , p . lineno ( 1 ) ))
18311833
18321834
18331835def p_do_until_start (p ):
18341836 """do_until_start : DO UNTIL expr"""
18351837 p [0 ] = p [3 ]
1836- gl .LOOPS .append (( "DO" , ))
1838+ gl .LOOPS .append (LoopInfo ( LoopType . DO , p . lineno ( 1 ) ))
18371839
18381840
18391841def p_do_start (p ):
18401842 """do_start : DO CO
18411843 | DO NEWLINE
18421844 """
1843- gl .LOOPS .append (( "DO" , ))
1845+ gl .LOOPS .append (LoopInfo ( LoopType . DO , p . lineno ( 1 ) ))
18441846
18451847
18461848def p_label_end_while (p ):
@@ -1874,7 +1876,7 @@ def p_while_sentence(p):
18741876def p_while_start (p ):
18751877 """while_start : WHILE expr"""
18761878 p [0 ] = p [2 ]
1877- gl .LOOPS .append (( " WHILE" , ))
1879+ gl .LOOPS .append (LoopInfo ( LoopType . WHILE , p . lineno ( 1 ) ))
18781880 if is_number (p [2 ]) and not p [2 ].value :
18791881 src .api .errmsg .warning_condition_is_always (p .lineno (1 ))
18801882
@@ -1887,8 +1889,8 @@ def p_exit(p):
18871889 q = p [2 ]
18881890 p [0 ] = make_sentence (p .lineno (1 ), "EXIT_%s" % q )
18891891
1890- for i in gl .LOOPS :
1891- if q == i [ 0 ] :
1892+ for loop in gl .LOOPS :
1893+ if q == loop . type :
18921894 return
18931895
18941896 error (p .lineno (1 ), "Syntax Error: EXIT %s out of loop" % q )
@@ -3391,17 +3393,28 @@ def p_abs(p):
33913393# The yyerror function
33923394# ----------------------------------------
33933395def p_error (p ):
3394- gl .has_errors += 1
3395-
33963396 if p is not None :
33973397 if p .type != "NEWLINE" :
33983398 msg = "Syntax Error. Unexpected token '%s' <%s>" % (p .value , p .type )
33993399 else :
34003400 msg = "Unexpected end of line"
34013401 error (p .lineno , msg )
3402- else :
3403- msg = "Unexpected end of file"
3404- error (zxblex .lexer .lineno , msg )
3402+ return
3403+
3404+ # Try to give some hints
3405+ if gl .LOOPS : # some loop(s) are not closed
3406+ loop_info = gl .LOOPS [- 1 ]
3407+ if loop_info .type == LoopType .FOR :
3408+ src .api .errmsg .syntax_error_for_without_next (loop_info .lineno )
3409+ else :
3410+ src .api .errmsg .syntax_error_loop_not_closed (loop_info .lineno , loop_info .type )
3411+ # If there were previous errors, stop here
3412+ # since this end of file is due to previous errors
3413+ if gl .has_errors :
3414+ return
3415+
3416+ msg = "Unexpected end of file"
3417+ error (zxblex .lexer .lineno , msg )
34053418
34063419
34073420# ----------------------------------------
0 commit comments