Adds Floating type class with sqrt as method

This commit is contained in:
Johan B.W. de Vries 2025-04-06 14:02:45 +02:00
parent 111cb0f702
commit 74ab3b47fd
7 changed files with 38 additions and 20 deletions

View File

@ -39,6 +39,10 @@ INSTANCES = {
'a=f32': stdlib_types.f32_eq_equals, 'a=f32': stdlib_types.f32_eq_equals,
'a=f64': stdlib_types.f64_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['/']: { type3classes.Fractional.operators['/']: {
'a=f32': stdlib_types.f32_fractional_div, 'a=f32': stdlib_types.f32_fractional_div,
'a=f64': stdlib_types.f64_fractional_div, 'a=f64': stdlib_types.f64_fractional_div,

View File

@ -10,7 +10,7 @@ from .type3 import typeclasses as type3typeclasses
from .type3 import types as type3types from .type3 import types as type3types
from .type3.types import PlaceholderForType, StructType3, Type3, Type3OrPlaceholder 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', ) WEBASSEMBLY_BUILTIN_BYTES_OPS: Final = ('len', )
class Expression: class Expression:

View File

@ -44,6 +44,7 @@ PRELUDE_OPERATORS = {
PRELUDE_METHODS = { PRELUDE_METHODS = {
**type3typeclasses.Eq.methods, **type3typeclasses.Eq.methods,
**type3typeclasses.Floating.methods,
**type3typeclasses.Fractional.methods, **type3typeclasses.Fractional.methods,
**type3typeclasses.Integral.methods, **type3typeclasses.Integral.methods,
**type3typeclasses.Num.methods, **type3typeclasses.Num.methods,

View File

@ -96,6 +96,12 @@ def f32_fractional_div(g: Generator) -> None:
def f64_fractional_div(g: Generator) -> None: def f64_fractional_div(g: Generator) -> None:
g.add_statement('f64.div') 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: def u32_integral_div(g: Generator) -> None:
g.add_statement('i32.div_u') g.add_statement('i32.div_u')

View File

@ -52,12 +52,6 @@ def expression(ctx: Context, inp: ourlang.Expression) -> ConstraintGenerator:
yield SameTypeConstraint(type3types.u32, inp.type3, comment='len :: Sized a => a -> u32') yield SameTypeConstraint(type3types.u32, inp.type3, comment='len :: Sized a => a -> u32')
return 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: if 'cast' == inp.operator:
yield from expression(ctx, inp.right) yield from expression(ctx, inp.right)
yield CastableConstraint(inp.right.type3, inp.type3) yield CastableConstraint(inp.right.type3, inp.type3)

View File

@ -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: class TypeVariable:
@ -69,7 +69,16 @@ class Type3Class:
methods: Dict[str, Type3ClassMethod] methods: Dict[str, Type3ClassMethod]
operators: 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.name = name
self.args = [TypeVariable(x) for x in args] self.args = [TypeVariable(x) for x in args]
self.methods = { self.methods = {
@ -88,16 +97,20 @@ Eq = Type3Class('Eq', ['a'], methods={}, operators={
'==': 'a -> a -> bool', '==': '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={ Num = Type3Class('Num', ['a'], methods={}, operators={
'+': 'a -> a -> a', '+': 'a -> a -> a',
'-': 'a -> a -> a', '-': '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={})

View File

@ -6,7 +6,7 @@ constraint generator works with.
""" """
from typing import Any, Dict, Iterable, List, Optional, Protocol, Union 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' 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. 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. 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. A 32-bits IEEE 754 float, of 64 bits width.
""" """