diff --git a/phasm/compiler.py b/phasm/compiler.py index 5040902..8a09bfc 100644 --- a/phasm/compiler.py +++ b/phasm/compiler.py @@ -39,6 +39,10 @@ INSTANCES = { 'a=f32': stdlib_types.f32_eq_equals, 'a=f64': stdlib_types.f64_eq_equals, }, + type3classes.Floating.methods['sqrt']: { + 'a=f32': stdlib_types.f32_floating_sqrt, + 'a=f64': stdlib_types.f64_floating_sqrt, + }, type3classes.Fractional.operators['/']: { 'a=f32': stdlib_types.f32_fractional_div, 'a=f64': stdlib_types.f64_fractional_div, diff --git a/phasm/ourlang.py b/phasm/ourlang.py index ae242dd..07ee7ef 100644 --- a/phasm/ourlang.py +++ b/phasm/ourlang.py @@ -10,7 +10,7 @@ from .type3 import typeclasses as type3typeclasses from .type3 import types as type3types from .type3.types import PlaceholderForType, StructType3, Type3, Type3OrPlaceholder -WEBASSEMBLY_BUILTIN_FLOAT_OPS: Final = ('abs', 'sqrt', 'ceil', 'floor', 'trunc', 'nearest', ) +WEBASSEMBLY_BUILTIN_FLOAT_OPS: Final = ('abs', 'ceil', 'floor', 'trunc', 'nearest', ) WEBASSEMBLY_BUILTIN_BYTES_OPS: Final = ('len', ) class Expression: diff --git a/phasm/parser.py b/phasm/parser.py index 10e281f..537a7e0 100644 --- a/phasm/parser.py +++ b/phasm/parser.py @@ -44,6 +44,7 @@ PRELUDE_OPERATORS = { PRELUDE_METHODS = { **type3typeclasses.Eq.methods, + **type3typeclasses.Floating.methods, **type3typeclasses.Fractional.methods, **type3typeclasses.Integral.methods, **type3typeclasses.Num.methods, diff --git a/phasm/stdlib/types.py b/phasm/stdlib/types.py index 2aa906c..080f545 100644 --- a/phasm/stdlib/types.py +++ b/phasm/stdlib/types.py @@ -96,6 +96,12 @@ def f32_fractional_div(g: Generator) -> None: def f64_fractional_div(g: Generator) -> None: g.add_statement('f64.div') +def f32_floating_sqrt(g: Generator) -> None: + g.add_statement('f32.sqrt') + +def f64_floating_sqrt(g: Generator) -> None: + g.add_statement('f64.sqrt') + def u32_integral_div(g: Generator) -> None: g.add_statement('i32.div_u') diff --git a/phasm/type3/constraintsgenerator.py b/phasm/type3/constraintsgenerator.py index 8927747..76c3997 100644 --- a/phasm/type3/constraintsgenerator.py +++ b/phasm/type3/constraintsgenerator.py @@ -52,12 +52,6 @@ def expression(ctx: Context, inp: ourlang.Expression) -> ConstraintGenerator: yield SameTypeConstraint(type3types.u32, inp.type3, comment='len :: Sized a => a -> u32') return - if 'sqrt' == inp.operator: - yield from expression(ctx, inp.right) - yield MustImplementTypeClassConstraint('FloatingPoint', inp.right.type3) - yield SameTypeConstraint(inp.right.type3, inp.type3, comment='sqrt :: FloatingPoint a => a -> a') - return - if 'cast' == inp.operator: yield from expression(ctx, inp.right) yield CastableConstraint(inp.right.type3, inp.type3) diff --git a/phasm/type3/typeclasses.py b/phasm/type3/typeclasses.py index 6670c34..126ec64 100644 --- a/phasm/type3/typeclasses.py +++ b/phasm/type3/typeclasses.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, Iterable, List, Mapping, Union +from typing import Any, Dict, Iterable, Optional, List, Mapping, Union class TypeVariable: @@ -69,7 +69,16 @@ class Type3Class: methods: Dict[str, Type3ClassMethod] operators: Dict[str, Type3ClassMethod] - def __init__(self, name: str, args: Iterable[str], methods: Mapping[str, str], operators: Mapping[str, str]) -> None: + def __init__( + self, + name: str, + args: Iterable[str], + methods: Mapping[str, str], + operators: Mapping[str, str], + inherited_classes: Optional[List['Type3Class']] = None, + ) -> None: + del inherited_classes # Not implemented yet + self.name = name self.args = [TypeVariable(x) for x in args] self.methods = { @@ -88,16 +97,20 @@ Eq = Type3Class('Eq', ['a'], methods={}, operators={ '==': 'a -> a -> bool', }) -Fractional = Type3Class('Fractional', ['a'], methods={}, operators={ - '/': 'a -> a -> a', -}) - -Integral = Type3Class('Eq', ['a'], methods={ - 'div': 'a -> a -> a', -}, operators={}) - Num = Type3Class('Num', ['a'], methods={}, operators={ '+': 'a -> a -> a', '-': 'a -> a -> a', '*': 'a -> a -> a', }) + +Fractional = Type3Class('Fractional', ['a'], methods={}, operators={ + '/': 'a -> a -> a', +}, inherited_classes=[Num]) + +Floating = Type3Class('Floating', ['a'], methods={ + 'sqrt': 'a -> a', +}, operators={}, inherited_classes=[Fractional]) + +Integral = Type3Class('Eq', ['a'], methods={ + 'div': 'a -> a -> a', +}, operators={}) diff --git a/phasm/type3/types.py b/phasm/type3/types.py index 2b2ad9e..d141f30 100644 --- a/phasm/type3/types.py +++ b/phasm/type3/types.py @@ -6,7 +6,7 @@ constraint generator works with. """ from typing import Any, Dict, Iterable, List, Optional, Protocol, Union -from .typeclasses import Eq, Fractional, Integral, Num, Type3Class +from .typeclasses import Eq, Floating, Fractional, Integral, Num, Type3Class TYPE3_ASSERTION_ERROR = 'You must call phasm_type3 after calling phasm_parse before you can call any other method' @@ -287,12 +287,12 @@ Operations on variables employ modular arithmetic, with modulus 2^64, but with the middel point being 0. """ -f32 = PrimitiveType3('f32', [Eq, Fractional, Num]) +f32 = PrimitiveType3('f32', [Eq, Floating, Fractional, Num]) """ A 32-bits IEEE 754 float, of 32 bits width. """ -f64 = PrimitiveType3('f64', [Eq, Fractional, Num]) +f64 = PrimitiveType3('f64', [Eq, Floating, Fractional, Num]) """ A 32-bits IEEE 754 float, of 64 bits width. """