diff --git a/phasm/compiler.py b/phasm/compiler.py index 66409b2..2d768f6 100644 --- a/phasm/compiler.py +++ b/phasm/compiler.py @@ -183,18 +183,6 @@ INSTANCES = { 'a=i32': stdlib_types.i32_integral_rem, 'a=i64': stdlib_types.i64_integral_rem, }, - prelude.IntNum.methods['abs']: { - 'a=i32': stdlib_types.i32_intnum_abs, - 'a=i64': stdlib_types.i64_intnum_abs, - 'a=f32': stdlib_types.f32_intnum_abs, - 'a=f64': stdlib_types.f64_intnum_abs, - }, - prelude.IntNum.methods['neg']: { - 'a=i32': stdlib_types.i32_intnum_neg, - 'a=i64': stdlib_types.i64_intnum_neg, - 'a=f32': stdlib_types.f32_intnum_neg, - 'a=f64': stdlib_types.f64_intnum_neg, - }, prelude.NatNum.operators['+']: { 'a=u32': stdlib_types.u32_natnum_add, 'a=u64': stdlib_types.u64_natnum_add, @@ -487,6 +475,18 @@ def expression(wgn: WasmGenerator, inp: ourlang.Expression) -> None: assert arg_expr.type3 is not None, TYPE3_ASSERTION_ERROR type_var_map[type_var] = arg_expr.type3 + method_instance_key = ( + inp.function, + tuple( + + ) + ) + + instance = PRELUDE_TYPE_CLASS_INSTANCE_METHODS.get(method_instance_key) + if isinstance is not None: + instance(wgn) + return + instance_key = ','.join( f'{k.letter}={v.name}' for k, v in sorted(type_var_map.items(), key=lambda x: x[0].letter) diff --git a/phasm/prelude/__init__.py b/phasm/prelude/__init__.py index 86e42b1..04ddf84 100644 --- a/phasm/prelude/__init__.py +++ b/phasm/prelude/__init__.py @@ -1,9 +1,13 @@ """ The prelude are all the builtin types, type classes and methods """ +from typing import Callable + +from phasm.stdlib import types as stdtypes +from phasm.wasmgenerator import Generator from ..type3.functions import TypeVariable -from ..type3.typeclasses import Type3Class +from ..type3.typeclasses import Type3Class, Type3ClassMethod from ..type3.types import ( Type3, TypeConstructor_StaticArray, @@ -13,14 +17,19 @@ from ..type3.types import ( PRELUDE_TYPE_CLASS_INSTANCES_EXISTING: set[tuple[Type3Class, tuple[Type3, ...]]] = set() +PRELUDE_TYPE_CLASS_INSTANCE_METHODS: dict[tuple[Type3ClassMethod, tuple[Type3, ...]], Callable[[Generator, Type3], None]] = {} -def instance_type_class(cls: Type3Class, *typ: Type3) -> None: +def instance_type_class(cls: Type3Class, *typ: Type3, methods: dict[str, Callable[[Generator, Type3], None]] = {}) -> None: global PRELUDE_TYPE_CLASS_INSTANCES_EXISTING + global PRELUDE_TYPE_CLASS_INSTANCE_METHODS # TODO: Check for required existing instantiations PRELUDE_TYPE_CLASS_INSTANCES_EXISTING.add((cls, tuple(typ), )) + for method, generator in methods.items(): + PRELUDE_TYPE_CLASS_INSTANCE_METHODS[(cls.methods[method], tuple(typ))] = generator + none = Type3('none') """ The none type, for when functions simply don't return anything. e.g., IO(). @@ -224,7 +233,9 @@ IntNum = Type3Class('IntNum', [a], methods={ 'neg': [a, a], }, operators={}, inherited_classes=[NatNum]) -instance_type_class(IntNum, i32) +instance_type_class(IntNum, i32, methods={ + 'abs': stdtypes.i32_intnum_abs, +}) instance_type_class(IntNum, i64) instance_type_class(IntNum, f32) instance_type_class(IntNum, f64) diff --git a/phasm/stdlib/types.py b/phasm/stdlib/types.py index 5c7e46a..d81f971 100644 --- a/phasm/stdlib/types.py +++ b/phasm/stdlib/types.py @@ -2,6 +2,7 @@ stdlib: Standard types that are not wasm primitives """ from phasm.stdlib import alloc +from phasm.type3.types import Type3 from phasm.wasmgenerator import Generator, func_wrapper from phasm.wasmgenerator import VarType_i32 as i32 from phasm.wasmgenerator import VarType_i64 as i64 @@ -832,7 +833,7 @@ def f64_natnum_arithmic_shift_right(g: Generator) -> None: ## ### ## class IntNum -def i32_intnum_abs(g: Generator) -> None: +def i32_intnum_abs(g: Generator, t: Type3 | None = None) -> None: g.add_statement('call $stdlib.types.__i32_intnum_abs__') def i64_intnum_abs(g: Generator) -> None: