Skip to content

Commit b693c3e

Browse files
authored
Merge pull request #440 from boriel/bugfix/crash_upon_let_error_typing
Bugfix/crash upon let error typing
2 parents d1d73ac + fe45a12 commit b693c3e

9 files changed

Lines changed: 46 additions & 14 deletions

File tree

src/api/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@
1212
from src.api import debug # noqa
1313
from src.api import errors # noqa
1414
from src.api import errmsg # noqa
15+
from src.api import symboltable # noqa

src/api/global_.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,22 @@
99
# the GNU General License
1010
# ----------------------------------------------------------------------
1111

12+
from typing import Dict
13+
from typing import Optional
14+
from typing import Set
15+
16+
import src.api
17+
18+
from .opcodestemps import OpcodesTemps
19+
from .constants import TYPE
20+
1221
# ----------------------------------------------------------------------
1322
# Simple global container for internal constants.
1423
# Internal constants might be architecture dependant. They're set
1524
# on module init (at __init__.py) on api.arch.<arch>/init.py
1625
#
1726
# Don't touch unless you know what are you doing
1827
# ----------------------------------------------------------------------
19-
from typing import Dict
20-
21-
from .opcodestemps import OpcodesTemps
22-
from .constants import TYPE
2328

2429
# ----------------------------------------------------------------------
2530
# Initializes a singleton container
@@ -73,7 +78,7 @@
7378
# ----------------------------------------------------------------------
7479
# Global Symbol Table
7580
# ----------------------------------------------------------------------
76-
SYMBOL_TABLE = None # Must be initialized with SymbolTable()
81+
SYMBOL_TABLE: Optional['src.api.symboltable.SymbolTable'] = None # Must be initialized with SymbolTable()
7782

7883
# ----------------------------------------------------------------------
7984
# Function calls pending to check
@@ -90,7 +95,7 @@
9095
# ----------------------------------------------------------------------
9196
# Initialization routines to be called automatically at program start
9297
# ----------------------------------------------------------------------
93-
INITS = set([])
98+
INITS: Set[str] = set([])
9499

95100
# ----------------------------------------------------------------------
96101
# FUNCTIONS pending to translate after parsing stage
@@ -156,7 +161,7 @@
156161
# ----------------------------------------------------------------------
157162
# Cache of Message errors to avoid repetition
158163
# ----------------------------------------------------------------------
159-
error_msg_cache = set()
164+
error_msg_cache: Set[str] = set()
160165

161166

162167
# ----------------------------------------------------------------------

src/libzxbc/zxbparser.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
# PI Constant
1414
# PI = 3.1415927 is ZX Spectrum PI representation
1515
# But a better one is 3.141592654, so take it from math
16+
1617
import math
1718
from math import pi as PI
1819
import collections
1920

2021
# typings
2122
from typing import NamedTuple
23+
from typing import Optional
2224

2325
# Compiler API
2426
from src.api.debug import __DEBUG__ # analysis:ignore
@@ -181,15 +183,18 @@ def make_nop():
181183
return symbols.NOP()
182184

183185

184-
def make_number(value, lineno, type_=None):
186+
def make_number(value, lineno: int, type_=None):
185187
""" Wrapper: creates a constant number node.
186188
"""
187189
return symbols.NUMBER(value, type_=type_, lineno=lineno)
188190

189191

190-
def make_typecast(type_, node, lineno):
192+
def make_typecast(type_: symbols.TYPE, node: Optional[symbols.SYMBOL], lineno: int):
191193
""" Wrapper: returns a Typecast node
192194
"""
195+
if node is None or node.type_ is None:
196+
return # syntax / semantic error
197+
193198
assert isinstance(type_, symbols.TYPE)
194199
return symbols.TYPECAST.make_node(type_, node, lineno)
195200

@@ -2906,6 +2911,13 @@ def p_function_header(p):
29062911
p[0] = p[1]
29072912

29082913

2914+
def p_function_header_error(p):
2915+
""" function_header : function_def error CO
2916+
| function_def error NEWLINE
2917+
"""
2918+
p[0] = None
2919+
2920+
29092921
def p_function_header_pre(p):
29102922
""" function_header_pre : function_def param_decl typedef
29112923
"""

src/parsetab/tabs.dbm.bak

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
'zxbpp', (0, 72571)
22
'asmparse', (72704, 254311)
33
'zxnext_asmparse', (327168, 285299)
4-
'zxbparser', (612864, 712099)
4+
'zxbparser', (612864, 715296)

src/parsetab/tabs.dbm.dat

3.12 KB
Binary file not shown.

src/parsetab/tabs.dbm.dir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
'zxbpp', (0, 72571)
22
'asmparse', (72704, 254311)
33
'zxnext_asmparse', (327168, 285299)
4-
'zxbparser', (612864, 712099)
4+
'zxbparser', (612864, 715296)

src/symbols/number.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
import numbers
1313

14+
from typing import Optional
15+
1416
from src.api.constants import CLASS
1517
from .symbol_ import Symbol
1618
from .type_ import SymbolTYPE
@@ -35,16 +37,15 @@ class SymbolNUMBER(Symbol):
3537
""" Defines an NUMBER symbol.
3638
"""
3739

38-
def __init__(self, value, lineno, type_=None):
40+
def __init__(self, value, lineno: int, type_: Optional[SymbolTYPE] = None):
3941
assert lineno is not None
4042
assert type_ is None or isinstance(type_, SymbolTYPE)
4143

4244
if isinstance(value, SymbolNUMBER):
4345
value = value.value
4446

4547
assert isinstance(value, numbers.Number)
46-
47-
super(SymbolNUMBER, self).__init__()
48+
super().__init__()
4849
self.class_ = CLASS.const
4950

5051
if int(value) == value:
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
DIM a as Ubyte
2+
3+
FUNCTION editStringFN(ByREF s AS Byte) as s
4+
s = s + 1
5+
RETURN s
6+
END FUNCTION
7+
8+
a = editStringFN(a, 1, "i")
9+

tests/functional/test_errmsg.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ prepro76.bi:2: error: this is an intended error
176176
line_asm.bi:26: warning: this should be line 26
177177
>>> process_file('line_err.bas')
178178
line_err.bas:5: error: Variable 'q' already declared at line_err.bas:1
179+
>>> process_file('let_expr_type_crash.bas')
180+
let_expr_type_crash.bas:3: error: Syntax Error. Unexpected token 's' <ID>
181+
let_expr_type_crash.bas:8: error: Function 'editStringFN' takes 0 parameters, not 3
179182

180183
# Test warning silencing
181184
>>> process_file('mcleod3.bas', ['-S', '-q', '-O --expect-warnings=2'])
@@ -184,3 +187,4 @@ mcleod3.bas:3: error: 'GenerateSpaces' is neither an array nor a function.
184187
>>> process_file('doloop2.bas', ['-S', '-q', '-O -W110'])
185188
doloop2.bas:4: warning: [W100] Using default implicit type 'ubyte' for 'a'
186189
doloop2.bas:4: warning: [W150] Variable 'a' is never used
190+

0 commit comments

Comments
 (0)