@@ -4395,8 +4395,23 @@ def _execute_block(self, statements: List[Statement], env: Environment) -> None:
43954395
43964396 def _execute_statement (self , statement : Statement , env : Environment ) -> None :
43974397 self ._log_step (rule = statement .__class__ .__name__ , location = statement .location )
4398+
4399+ def _name_exists_or_declared (name : str ) -> bool :
4400+ cur : Optional [Environment ] = env
4401+ while cur is not None :
4402+ if name in cur .values or name in cur .declared :
4403+ return True
4404+ cur = cur .parent
4405+ return False
4406+
43984407 statement_type = type (statement )
43994408 if statement_type is Declaration :
4409+ if "." in statement .name and not _name_exists_or_declared (statement .name ):
4410+ raise ASMRuntimeError (
4411+ f"Cannot create module-qualified name '{ statement .name } '" ,
4412+ location = statement .location ,
4413+ rewrite_rule = "ASSIGN" ,
4414+ )
44004415 # Record a type declaration without creating a value. Do not
44014416 # introduce a binding; reads will still raise until the name is
44024417 # assigned. If a value already exists in the same environment,
@@ -4419,6 +4434,16 @@ def _execute_statement(self, statement: Statement, env: Environment) -> None:
44194434 env .declared [statement .name ] = statement .declared_type
44204435 return
44214436 if statement_type is Assignment :
4437+ if (
4438+ statement .declared_type is not None
4439+ and "." in statement .target
4440+ and not _name_exists_or_declared (statement .target )
4441+ ):
4442+ raise ASMRuntimeError (
4443+ f"Cannot create module-qualified name '{ statement .target } '" ,
4444+ location = statement .location ,
4445+ rewrite_rule = "ASSIGN" ,
4446+ )
44224447 if statement .target in self .functions :
44234448 raise ASMRuntimeError (
44244449 f"Identifier '{ statement .target } ' already bound as function" , location = statement .location , rewrite_rule = "ASSIGN"
0 commit comments