Skip to content

Commit 8c16a5d

Browse files
committed
fix: crash un undeclared substring assign
1 parent 748928c commit 8c16a5d

7 files changed

Lines changed: 468 additions & 10 deletions

File tree

‎src/api/errmsg.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"register_warning",
2020
"warning",
2121
"warning_not_used",
22+
"warning_uninitalized_string_var",
2223
)
2324

2425

@@ -127,6 +128,12 @@ def warning_implicit_type(lineno: int, id_: str, type_: str = None):
127128
warning(lineno, "Using default implicit type '%s' for '%s'" % (type_, id_))
128129

129130

131+
@register_warning("101")
132+
def warning_uninitalized_string_var(lineno: int, id_: str):
133+
"""Warning: Accessing uninitialized string variable"""
134+
warning(lineno, f"Accessing uninitialized string variable '{id_}'")
135+
136+
130137
@register_warning("110")
131138
def warning_condition_is_always(lineno: int, cond: bool = False):
132139
"""Warning: Condition is always false/true"""

‎src/api/symboltable/symboltable.py‎

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def declare(self, id_: str, lineno: int, entry: symbols.ID | symbols.TYPE) -> No
132132

133133
return entry
134134

135-
def declare_safe(self, id_: str, lineno: int, entry: symbols.ID):
135+
def declare_safe(self, id_: str, lineno: int, entry: symbols.ID) -> symbols.ID | symbols.TYPE:
136136
"""Like declare, but never returns None"""
137137
result = self.declare(id_, lineno, entry)
138138
assert result is not None
@@ -204,7 +204,7 @@ def check_is_undeclared(
204204
)
205205
return False
206206

207-
def check_class(self, id_: str, class_: CLASS, lineno: int, scope: Scope = None, show_error=True) -> bool:
207+
def check_class(self, id_: str, class_: CLASS, lineno: int, scope: Scope | None = None, show_error=True) -> bool:
208208
"""Check the id is either undefined or defined with
209209
the given class.
210210
@@ -342,7 +342,7 @@ def access_id(
342342
default_class: CLASS = CLASS.unknown,
343343
*,
344344
ignore_explicit_flag=False,
345-
):
345+
) -> symbols.ID | None:
346346
"""Access a symbol by its identifier and checks if it exists.
347347
If not, it's supposed to be an implicitly declared variable.
348348
@@ -442,10 +442,9 @@ def access_func(self, id_: str, lineno: int, scope=None, default_type=None):
442442

443443
return result
444444

445-
def access_call(self, id_: str, lineno: int, scope=None, type_=None):
445+
def access_call(self, id_: str, lineno: int, scope=None, type_=None) -> symbols.ID | None:
446446
"""Creates a func/array/string call. Checks if id is callable or not.
447-
An identifier is "callable" if it can be followed by a list of para-
448-
meters.
447+
An identifier is "callable" if it can be followed by a list of parameters.
449448
This does not mean the id_ is a function, but that it allows the same
450449
syntax a function does:
451450

‎src/zxbc/zxbparser.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,8 @@ def p_substr_assignment_no_let(p):
12651265
return
12661266

12671267
if entry.class_ == CLASS.unknown:
1268-
entry.class_ = CLASS.var
1268+
errmsg.warning_uninitalized_string_var(p.lineno(1), entry.name)
1269+
entry.to_var()
12691270

12701271
if p[6].type_ != Type.string:
12711272
errmsg.syntax_error_expected_string(p.lineno(5), p[6].type_)

0 commit comments

Comments
 (0)