Removes some hardcoded references to prelude
This commit is contained in:
parent
faaf7912b1
commit
292c9548fb
@ -7,8 +7,8 @@ from typing import Dict, Iterable, List, Optional, Union
|
|||||||
from typing_extensions import Final
|
from typing_extensions import Final
|
||||||
|
|
||||||
from . import prelude
|
from . import prelude
|
||||||
from .type3 import typeclasses as type3typeclasses
|
|
||||||
from .type3.placeholders import PlaceholderForType, Type3OrPlaceholder
|
from .type3.placeholders import PlaceholderForType, Type3OrPlaceholder
|
||||||
|
from .type3.typeclasses import Type3ClassMethod
|
||||||
from .type3.types import Type3
|
from .type3.types import Type3
|
||||||
|
|
||||||
WEBASSEMBLY_BUILTIN_BYTES_OPS: Final = ('len', )
|
WEBASSEMBLY_BUILTIN_BYTES_OPS: Final = ('len', )
|
||||||
@ -150,11 +150,11 @@ class BinaryOp(Expression):
|
|||||||
"""
|
"""
|
||||||
__slots__ = ('operator', 'left', 'right', )
|
__slots__ = ('operator', 'left', 'right', )
|
||||||
|
|
||||||
operator: type3typeclasses.Type3ClassMethod
|
operator: Type3ClassMethod
|
||||||
left: Expression
|
left: Expression
|
||||||
right: Expression
|
right: Expression
|
||||||
|
|
||||||
def __init__(self, operator: type3typeclasses.Type3ClassMethod, left: Expression, right: Expression) -> None:
|
def __init__(self, operator: Type3ClassMethod, left: Expression, right: Expression) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.operator = operator
|
self.operator = operator
|
||||||
@ -170,10 +170,10 @@ class FunctionCall(Expression):
|
|||||||
"""
|
"""
|
||||||
__slots__ = ('function', 'arguments', )
|
__slots__ = ('function', 'arguments', )
|
||||||
|
|
||||||
function: Union['Function', type3typeclasses.Type3ClassMethod]
|
function: Union['Function', Type3ClassMethod]
|
||||||
arguments: List[Expression]
|
arguments: List[Expression]
|
||||||
|
|
||||||
def __init__(self, function: Union['Function', type3typeclasses.Type3ClassMethod]) -> None:
|
def __init__(self, function: Union['Function', Type3ClassMethod]) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.function = function
|
self.function = function
|
||||||
@ -411,15 +411,19 @@ class Module:
|
|||||||
"""
|
"""
|
||||||
A module is a file and consists of functions
|
A module is a file and consists of functions
|
||||||
"""
|
"""
|
||||||
__slots__ = ('data', 'types', 'struct_definitions', 'constant_defs', 'functions',)
|
__slots__ = ('data', 'types', 'struct_definitions', 'constant_defs', 'functions', 'operators', )
|
||||||
|
|
||||||
data: ModuleData
|
data: ModuleData
|
||||||
|
types: dict[str, Type3]
|
||||||
struct_definitions: Dict[str, StructDefinition]
|
struct_definitions: Dict[str, StructDefinition]
|
||||||
constant_defs: Dict[str, ModuleConstantDef]
|
constant_defs: Dict[str, ModuleConstantDef]
|
||||||
functions: Dict[str, Function]
|
functions: Dict[str, Function]
|
||||||
|
operators: Dict[str, Type3ClassMethod]
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.data = ModuleData()
|
self.data = ModuleData()
|
||||||
|
self.types = {}
|
||||||
self.struct_definitions = {}
|
self.struct_definitions = {}
|
||||||
self.constant_defs = {}
|
self.constant_defs = {}
|
||||||
self.functions = {}
|
self.functions = {}
|
||||||
|
self.operators = {}
|
||||||
|
|||||||
@ -97,6 +97,9 @@ class OurVisitor:
|
|||||||
def visit_Module(self, node: ast.Module) -> Module:
|
def visit_Module(self, node: ast.Module) -> Module:
|
||||||
module = Module()
|
module = Module()
|
||||||
|
|
||||||
|
module.operators.update(PRELUDE_OPERATORS)
|
||||||
|
module.types.update(PRELUDE_TYPES)
|
||||||
|
|
||||||
_not_implemented(not node.type_ignores, 'Module.type_ignores')
|
_not_implemented(not node.type_ignores, 'Module.type_ignores')
|
||||||
|
|
||||||
# Second pass for the types
|
# Second pass for the types
|
||||||
@ -113,14 +116,15 @@ class OurVisitor:
|
|||||||
module.constant_defs[res.name] = res
|
module.constant_defs[res.name] = res
|
||||||
|
|
||||||
if isinstance(res, StructDefinition):
|
if isinstance(res, StructDefinition):
|
||||||
if res.struct_type3.name in module.struct_definitions:
|
if res.struct_type3.name in module.types:
|
||||||
raise StaticError(
|
raise StaticError(
|
||||||
f'{res.struct_type3.name} already defined on line {module.struct_definitions[res.struct_type3.name].lineno}'
|
f'{res.struct_type3.name} already defined as type'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
module.types[res.struct_type3.name] = res.struct_type3
|
||||||
|
module.functions[res.struct_type3.name] = StructConstructor(res.struct_type3)
|
||||||
|
# Store that the definition was done in this module for the formatter
|
||||||
module.struct_definitions[res.struct_type3.name] = res
|
module.struct_definitions[res.struct_type3.name] = res
|
||||||
constructor = StructConstructor(res.struct_type3)
|
|
||||||
module.functions[constructor.name] = constructor
|
|
||||||
|
|
||||||
if isinstance(res, Function):
|
if isinstance(res, Function):
|
||||||
if res.name in module.functions:
|
if res.name in module.functions:
|
||||||
@ -367,11 +371,11 @@ class OurVisitor:
|
|||||||
else:
|
else:
|
||||||
raise NotImplementedError(f'Operator {node.op}')
|
raise NotImplementedError(f'Operator {node.op}')
|
||||||
|
|
||||||
if operator not in PRELUDE_OPERATORS:
|
if operator not in module.operators:
|
||||||
raise NotImplementedError(f'Operator {operator}')
|
raise NotImplementedError(f'Operator {operator}')
|
||||||
|
|
||||||
return BinaryOp(
|
return BinaryOp(
|
||||||
PRELUDE_OPERATORS[operator],
|
module.operators[operator],
|
||||||
self.visit_Module_FunctionDef_expr(module, function, our_locals, node.left),
|
self.visit_Module_FunctionDef_expr(module, function, our_locals, node.left),
|
||||||
self.visit_Module_FunctionDef_expr(module, function, our_locals, node.right),
|
self.visit_Module_FunctionDef_expr(module, function, our_locals, node.right),
|
||||||
)
|
)
|
||||||
@ -408,11 +412,11 @@ class OurVisitor:
|
|||||||
else:
|
else:
|
||||||
raise NotImplementedError(f'Operator {node.ops}')
|
raise NotImplementedError(f'Operator {node.ops}')
|
||||||
|
|
||||||
if operator not in PRELUDE_OPERATORS:
|
if operator not in module.operators:
|
||||||
raise NotImplementedError(f'Operator {operator}')
|
raise NotImplementedError(f'Operator {operator}')
|
||||||
|
|
||||||
return BinaryOp(
|
return BinaryOp(
|
||||||
PRELUDE_OPERATORS[operator],
|
module.operators[operator],
|
||||||
self.visit_Module_FunctionDef_expr(module, function, our_locals, node.left),
|
self.visit_Module_FunctionDef_expr(module, function, our_locals, node.left),
|
||||||
self.visit_Module_FunctionDef_expr(module, function, our_locals, node.comparators[0]),
|
self.visit_Module_FunctionDef_expr(module, function, our_locals, node.comparators[0]),
|
||||||
)
|
)
|
||||||
@ -476,13 +480,6 @@ class OurVisitor:
|
|||||||
|
|
||||||
if node.func.id in PRELUDE_METHODS:
|
if node.func.id in PRELUDE_METHODS:
|
||||||
func = PRELUDE_METHODS[node.func.id]
|
func = PRELUDE_METHODS[node.func.id]
|
||||||
elif node.func.id in module.struct_definitions:
|
|
||||||
struct_definition = module.struct_definitions[node.func.id]
|
|
||||||
struct_constructor = StructConstructor(struct_definition.struct_type3)
|
|
||||||
|
|
||||||
# FIXME: Defer struct de-allocation
|
|
||||||
|
|
||||||
func = module.functions[struct_constructor.name]
|
|
||||||
elif node.func.id == 'u32':
|
elif node.func.id == 'u32':
|
||||||
if 1 != len(node.args):
|
if 1 != len(node.args):
|
||||||
_raise_static_error(node, f'Function {node.func.id} requires 1 arguments but {len(node.args)} are given')
|
_raise_static_error(node, f'Function {node.func.id} requires 1 arguments but {len(node.args)} are given')
|
||||||
@ -654,11 +651,8 @@ class OurVisitor:
|
|||||||
if not isinstance(node.ctx, ast.Load):
|
if not isinstance(node.ctx, ast.Load):
|
||||||
_raise_static_error(node, 'Must be load context')
|
_raise_static_error(node, 'Must be load context')
|
||||||
|
|
||||||
if node.id in PRELUDE_TYPES:
|
if node.id in module.types:
|
||||||
return PRELUDE_TYPES[node.id]
|
return module.types[node.id]
|
||||||
|
|
||||||
if node.id in module.struct_definitions:
|
|
||||||
return module.struct_definitions[node.id].struct_type3
|
|
||||||
|
|
||||||
_raise_static_error(node, f'Unrecognized type {node.id}')
|
_raise_static_error(node, f'Unrecognized type {node.id}')
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from phasm.exceptions import StaticError
|
||||||
from phasm.type3.entry import Type3Exception
|
from phasm.type3.entry import Type3Exception
|
||||||
|
|
||||||
from ..helpers import Suite
|
from ..helpers import Suite
|
||||||
@ -76,3 +77,26 @@ def testEntry(arg: Struct) -> (i32, i32, ):
|
|||||||
|
|
||||||
with pytest.raises(Type3Exception, match=type_ + r' must be \(i32, i32, \) instead'):
|
with pytest.raises(Type3Exception, match=type_ + r' must be \(i32, i32, \) instead'):
|
||||||
Suite(code_py).run_code()
|
Suite(code_py).run_code()
|
||||||
|
|
||||||
|
@pytest.mark.integration_test
|
||||||
|
def test_name_already_use_struct():
|
||||||
|
code_py = """
|
||||||
|
class Struct:
|
||||||
|
param: i32
|
||||||
|
|
||||||
|
class Struct:
|
||||||
|
param: i64
|
||||||
|
"""
|
||||||
|
|
||||||
|
with pytest.raises(StaticError, match='Struct already defined as type'):
|
||||||
|
Suite(code_py).run_code()
|
||||||
|
|
||||||
|
@pytest.mark.integration_test
|
||||||
|
def test_name_already_use_type():
|
||||||
|
code_py = """
|
||||||
|
class f32:
|
||||||
|
param: i32
|
||||||
|
"""
|
||||||
|
|
||||||
|
with pytest.raises(StaticError, match='f32 already defined as type'):
|
||||||
|
Suite(code_py).run_code()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user