fix(checker): avoid raising on unknown variable

when an unknown variable is referenced, avoid raising an error and only report it with a diagnostic, returning `UnknownType` instead
This commit is contained in:
2026-07-09 17:37:49 +02:00
parent 0c851cbc9b
commit 44984af8a3

View File

@@ -110,7 +110,7 @@ class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[Type], m.Type.Visitor[Type
return self._local_variables[name]
return self.types.get_type(name)
def get_variable(self, name: str) -> Type:
def get_variable(self, location: Location, name: str) -> Type:
"""Get the type of a variable
This function will first look into the current predicate's parameters if
@@ -118,11 +118,9 @@ class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[Type], m.Type.Visitor[Type
The the variable is looked up in the preamble (i.e. global environment)
Args:
location (Location): the location of the variable reference
name (str): the name of the variable
Raises:
NameError: if the variable cannot be found
Returns:
Type: the type of the variable
"""
@@ -136,7 +134,8 @@ class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[Type], m.Type.Visitor[Type
if global_ is not None:
return global_
raise NameError(f"Unknown variable '{name}'")
self.reporter.error(location, f"Unknown variable '{name}'")
return UnknownType()
def resolve(self, stmts: list[m.Stmt]):
"""Process a sequence of statements
@@ -350,7 +349,7 @@ class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[Type], m.Type.Visitor[Type
return member
def visit_variable_expr(self, expr: m.VariableExpr) -> Type:
return self.get_variable(expr.name.lexeme)
return self.get_variable(expr.location, expr.name.lexeme)
def visit_grouping_expr(self, expr: m.GroupingExpr) -> Type:
return expr.expr.accept(self)
@@ -370,7 +369,7 @@ class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[Type], m.Type.Visitor[Type
return UnknownType()
def visit_wildcard_expr(self, expr: m.WildcardExpr) -> Type:
return self.get_variable("_")
return self.get_variable(expr.location, "_")
def visit_named_type(self, type: m.NamedType) -> Type:
name: str = type.name.lexeme