696 lines
20 KiB
Python
696 lines
20 KiB
Python
"""
|
|
The prelude are all the builtin types, type classes and methods
|
|
"""
|
|
from typing import Any, Callable
|
|
from warnings import warn
|
|
|
|
from phasm.stdlib import types as stdtypes
|
|
from phasm.wasmgenerator import Generator
|
|
|
|
from ..type3.functions import (
|
|
Constraint_TypeClassInstanceExists,
|
|
TypeConstructorVariable,
|
|
TypeVariable,
|
|
TypeVariableApplication_Nullary,
|
|
)
|
|
from ..type3.routers import TypeClassArgsRouter, TypeVariableLookup
|
|
from ..type3.typeclasses import Type3Class, Type3ClassMethod
|
|
from ..type3.types import (
|
|
Type3,
|
|
TypeApplication_Nullary,
|
|
TypeConstructor_Base,
|
|
TypeConstructor_DynamicArray,
|
|
TypeConstructor_Function,
|
|
TypeConstructor_StaticArray,
|
|
TypeConstructor_Struct,
|
|
TypeConstructor_Tuple,
|
|
)
|
|
|
|
PRELUDE_TYPE_CLASS_INSTANCES_EXISTING: set[tuple[Type3Class, tuple[Type3 | TypeConstructor_Base[Any], ...]]] = set()
|
|
|
|
PRELUDE_TYPE_CLASS_INSTANCE_METHODS: dict[Type3ClassMethod, TypeClassArgsRouter[Generator, None]] = {}
|
|
|
|
class MissingImplementationException(Exception):
|
|
pass
|
|
|
|
class MissingImplementationWarning(Warning):
|
|
pass
|
|
|
|
def instance_type_class(
|
|
cls: Type3Class,
|
|
*typ: Type3 | TypeConstructor_Base[Any],
|
|
methods: dict[str, Callable[[Generator, TypeVariableLookup], None]] = {},
|
|
operators: dict[str, Callable[[Generator, TypeVariableLookup], None]] = {},
|
|
) -> None:
|
|
global PRELUDE_TYPE_CLASS_INSTANCES_EXISTING
|
|
global PRELUDE_TYPE_CLASS_INSTANCE_METHODS
|
|
|
|
assert len(cls.args) == len(typ)
|
|
|
|
tv_map: dict[TypeVariable, Type3] = {}
|
|
tc_map: dict[TypeConstructorVariable, TypeConstructor_Base[Any]] = {}
|
|
for arg_tv, arg_tp in zip(cls.args, typ, strict=True):
|
|
if isinstance(arg_tv, TypeVariable):
|
|
assert isinstance(arg_tp, Type3)
|
|
tv_map[arg_tv] = arg_tp
|
|
elif isinstance(arg_tv, TypeConstructorVariable):
|
|
assert isinstance(arg_tp, TypeConstructor_Base)
|
|
tc_map[arg_tv] = arg_tp
|
|
else:
|
|
raise NotImplementedError(arg_tv, arg_tp)
|
|
|
|
# TODO: Check for required existing instantiations
|
|
|
|
PRELUDE_TYPE_CLASS_INSTANCES_EXISTING.add((cls, tuple(typ), ))
|
|
|
|
for method_name, method in cls.methods.items():
|
|
router = PRELUDE_TYPE_CLASS_INSTANCE_METHODS.get(method)
|
|
if router is None:
|
|
router = TypeClassArgsRouter[Generator, None](cls.args)
|
|
PRELUDE_TYPE_CLASS_INSTANCE_METHODS[method] = router
|
|
|
|
try:
|
|
generator = methods[method_name]
|
|
except KeyError:
|
|
warn(MissingImplementationWarning(str(method), cls.name + ' ' + ' '.join(x.name for x in typ)))
|
|
continue
|
|
|
|
router.add(tv_map, tc_map, generator)
|
|
|
|
for operator_name, operator in cls.operators.items():
|
|
router = PRELUDE_TYPE_CLASS_INSTANCE_METHODS.get(operator)
|
|
if router is None:
|
|
router = TypeClassArgsRouter[Generator, None](cls.args)
|
|
PRELUDE_TYPE_CLASS_INSTANCE_METHODS[operator] = router
|
|
|
|
try:
|
|
generator = operators[operator_name]
|
|
except KeyError:
|
|
warn(MissingImplementationWarning(str(operator), cls.name + ' ' + ' '.join(x.name for x in typ)))
|
|
continue
|
|
|
|
router.add(tv_map, tc_map, generator)
|
|
|
|
none = Type3('none', TypeApplication_Nullary(None, None))
|
|
"""
|
|
The none type, for when functions simply don't return anything. e.g., IO().
|
|
"""
|
|
|
|
bool_ = Type3('bool', TypeApplication_Nullary(None, None))
|
|
"""
|
|
The bool type, either True or False
|
|
|
|
Suffixes with an underscores, as it's a Python builtin
|
|
"""
|
|
|
|
u8 = Type3('u8', TypeApplication_Nullary(None, None))
|
|
"""
|
|
The unsigned 8-bit integer type.
|
|
|
|
Operations on variables employ modular arithmetic, with modulus 2^8.
|
|
"""
|
|
|
|
u32 = Type3('u32', TypeApplication_Nullary(None, None))
|
|
"""
|
|
The unsigned 32-bit integer type.
|
|
|
|
Operations on variables employ modular arithmetic, with modulus 2^32.
|
|
"""
|
|
|
|
u64 = Type3('u64', TypeApplication_Nullary(None, None))
|
|
"""
|
|
The unsigned 64-bit integer type.
|
|
|
|
Operations on variables employ modular arithmetic, with modulus 2^64.
|
|
"""
|
|
|
|
i8 = Type3('i8', TypeApplication_Nullary(None, None))
|
|
"""
|
|
The signed 8-bit integer type.
|
|
|
|
Operations on variables employ modular arithmetic, with modulus 2^8, but
|
|
with the middel point being 0.
|
|
"""
|
|
|
|
i32 = Type3('i32', TypeApplication_Nullary(None, None))
|
|
"""
|
|
The unsigned 32-bit integer type.
|
|
|
|
Operations on variables employ modular arithmetic, with modulus 2^32, but
|
|
with the middel point being 0.
|
|
"""
|
|
|
|
i64 = Type3('i64', TypeApplication_Nullary(None, None))
|
|
"""
|
|
The unsigned 64-bit integer type.
|
|
|
|
Operations on variables employ modular arithmetic, with modulus 2^64, but
|
|
with the middel point being 0.
|
|
"""
|
|
|
|
f32 = Type3('f32', TypeApplication_Nullary(None, None))
|
|
"""
|
|
A 32-bits IEEE 754 float, of 32 bits width.
|
|
"""
|
|
|
|
f64 = Type3('f64', TypeApplication_Nullary(None, None))
|
|
"""
|
|
A 32-bits IEEE 754 float, of 64 bits width.
|
|
"""
|
|
|
|
dynamic_array = TypeConstructor_DynamicArray('dynamic_array')
|
|
"""
|
|
This is a dynamic length piece of memory.
|
|
|
|
It should be applied with two arguments. It has a runtime
|
|
determined length, and each argument is the same.
|
|
"""
|
|
|
|
static_array = TypeConstructor_StaticArray('static_array')
|
|
"""
|
|
This is a fixed length piece of memory.
|
|
|
|
It should be applied with two arguments. It has a compile time
|
|
determined length, and each argument is the same.
|
|
"""
|
|
|
|
tuple_ = TypeConstructor_Tuple('tuple')
|
|
"""
|
|
This is a fixed length piece of memory.
|
|
|
|
It should be applied with zero or more arguments. It has a compile time
|
|
determined length, and each argument can be different.
|
|
"""
|
|
|
|
function = TypeConstructor_Function('function')
|
|
"""
|
|
This is a function.
|
|
|
|
It should be applied with one or more arguments. The last argument is the 'return' type.
|
|
"""
|
|
|
|
struct = TypeConstructor_Struct('struct')
|
|
"""
|
|
This is like a tuple, but each argument is named, so that developers
|
|
can get and set fields by name.
|
|
"""
|
|
|
|
a = TypeVariable('a', TypeVariableApplication_Nullary(None, None))
|
|
b = TypeVariable('b', TypeVariableApplication_Nullary(None, None))
|
|
|
|
t = TypeConstructorVariable('t')
|
|
|
|
Eq = Type3Class('Eq', (a, ), methods={}, operators={
|
|
'==': [a, a, bool_],
|
|
'!=': [a, a, bool_],
|
|
# FIXME: Do we want to expose 'eqz'? Or is that a compiler optimization?
|
|
})
|
|
|
|
instance_type_class(Eq, u8, operators={
|
|
'==': stdtypes.u8_eq_equals,
|
|
'!=': stdtypes.u8_eq_not_equals,
|
|
})
|
|
instance_type_class(Eq, u32, operators={
|
|
'==': stdtypes.u32_eq_equals,
|
|
'!=': stdtypes.u32_eq_not_equals,
|
|
})
|
|
instance_type_class(Eq, u64, operators={
|
|
'==': stdtypes.u64_eq_equals,
|
|
'!=': stdtypes.u64_eq_not_equals,
|
|
})
|
|
instance_type_class(Eq, i8, operators={
|
|
'==': stdtypes.i8_eq_equals,
|
|
'!=': stdtypes.i8_eq_not_equals,
|
|
})
|
|
instance_type_class(Eq, i32, operators={
|
|
'==': stdtypes.i32_eq_equals,
|
|
'!=': stdtypes.i32_eq_not_equals,
|
|
})
|
|
instance_type_class(Eq, i64, operators={
|
|
'==': stdtypes.i64_eq_equals,
|
|
'!=': stdtypes.i64_eq_not_equals,
|
|
})
|
|
instance_type_class(Eq, f32, operators={
|
|
'==': stdtypes.f32_eq_equals,
|
|
'!=': stdtypes.f32_eq_not_equals,
|
|
})
|
|
instance_type_class(Eq, f64, operators={
|
|
'==': stdtypes.f64_eq_equals,
|
|
'!=': stdtypes.f64_eq_not_equals,
|
|
})
|
|
|
|
Ord = Type3Class('Ord', (a, ), methods={
|
|
'min': [a, a, a],
|
|
'max': [a, a, a],
|
|
}, operators={
|
|
'<': [a, a, bool_],
|
|
'<=': [a, a, bool_],
|
|
'>': [a, a, bool_],
|
|
'>=': [a, a, bool_],
|
|
}, inherited_classes=[Eq])
|
|
|
|
instance_type_class(Ord, u8, methods={
|
|
'min': stdtypes.u8_ord_min,
|
|
'max': stdtypes.u8_ord_max,
|
|
}, operators={
|
|
'<': stdtypes.u8_ord_less_than,
|
|
'<=': stdtypes.u8_ord_less_than_or_equal,
|
|
'>': stdtypes.u8_ord_greater_than,
|
|
'>=': stdtypes.u8_ord_greater_than_or_equal,
|
|
})
|
|
instance_type_class(Ord, u32, methods={
|
|
'min': stdtypes.u32_ord_min,
|
|
'max': stdtypes.u32_ord_max,
|
|
}, operators={
|
|
'<': stdtypes.u32_ord_less_than,
|
|
'<=': stdtypes.u32_ord_less_than_or_equal,
|
|
'>': stdtypes.u32_ord_greater_than,
|
|
'>=': stdtypes.u32_ord_greater_than_or_equal,
|
|
})
|
|
instance_type_class(Ord, u64, methods={
|
|
'min': stdtypes.u64_ord_min,
|
|
'max': stdtypes.u64_ord_max,
|
|
}, operators={
|
|
'<': stdtypes.u64_ord_less_than,
|
|
'<=': stdtypes.u64_ord_less_than_or_equal,
|
|
'>': stdtypes.u64_ord_greater_than,
|
|
'>=': stdtypes.u64_ord_greater_than_or_equal,
|
|
})
|
|
instance_type_class(Ord, i8, methods={
|
|
'min': stdtypes.i8_ord_min,
|
|
'max': stdtypes.i8_ord_max,
|
|
}, operators={
|
|
'<': stdtypes.i8_ord_less_than,
|
|
'<=': stdtypes.i8_ord_less_than_or_equal,
|
|
'>': stdtypes.i8_ord_greater_than,
|
|
'>=': stdtypes.i8_ord_greater_than_or_equal,
|
|
})
|
|
instance_type_class(Ord, i32, methods={
|
|
'min': stdtypes.i32_ord_min,
|
|
'max': stdtypes.i32_ord_max,
|
|
}, operators={
|
|
'<': stdtypes.i32_ord_less_than,
|
|
'<=': stdtypes.i32_ord_less_than_or_equal,
|
|
'>': stdtypes.i32_ord_greater_than,
|
|
'>=': stdtypes.i32_ord_greater_than_or_equal,
|
|
})
|
|
instance_type_class(Ord, i64, methods={
|
|
'min': stdtypes.i64_ord_min,
|
|
'max': stdtypes.i64_ord_max,
|
|
}, operators={
|
|
'<': stdtypes.i64_ord_less_than,
|
|
'<=': stdtypes.i64_ord_less_than_or_equal,
|
|
'>': stdtypes.i64_ord_greater_than,
|
|
'>=': stdtypes.i64_ord_greater_than_or_equal,
|
|
})
|
|
instance_type_class(Ord, f32, methods={
|
|
'min': stdtypes.f32_ord_min,
|
|
'max': stdtypes.f32_ord_max,
|
|
}, operators={
|
|
'<': stdtypes.f32_ord_less_than,
|
|
'<=': stdtypes.f32_ord_less_than_or_equal,
|
|
'>': stdtypes.f32_ord_greater_than,
|
|
'>=': stdtypes.f32_ord_greater_than_or_equal,
|
|
})
|
|
instance_type_class(Ord, f64, methods={
|
|
'min': stdtypes.f64_ord_min,
|
|
'max': stdtypes.f64_ord_max,
|
|
}, operators={
|
|
'<': stdtypes.f64_ord_less_than,
|
|
'<=': stdtypes.f64_ord_less_than_or_equal,
|
|
'>': stdtypes.f64_ord_greater_than,
|
|
'>=': stdtypes.f64_ord_greater_than_or_equal,
|
|
})
|
|
|
|
Bits = Type3Class('Bits', (a, ), methods={
|
|
'shl': [a, u32, a], # Logical shift left
|
|
'shr': [a, u32, a], # Logical shift right
|
|
'rotl': [a, u32, a], # Rotate bits left
|
|
'rotr': [a, u32, a], # Rotate bits right
|
|
# FIXME: Do we want to expose clz, ctz, popcnt?
|
|
}, operators={
|
|
'&': [a, a, a], # Bit-wise and
|
|
'|': [a, a, a], # Bit-wise or
|
|
'^': [a, a, a], # Bit-wise xor
|
|
})
|
|
|
|
instance_type_class(Bits, u8, methods={
|
|
'shl': stdtypes.u8_bits_logical_shift_left,
|
|
'shr': stdtypes.u8_bits_logical_shift_right,
|
|
'rotl': stdtypes.u8_bits_rotate_left,
|
|
'rotr': stdtypes.u8_bits_rotate_right,
|
|
}, operators={
|
|
'&': stdtypes.u8_bits_bitwise_and,
|
|
'|': stdtypes.u8_bits_bitwise_or,
|
|
'^': stdtypes.u8_bits_bitwise_xor,
|
|
})
|
|
instance_type_class(Bits, u32, methods={
|
|
'shl': stdtypes.u32_bits_logical_shift_left,
|
|
'shr': stdtypes.u32_bits_logical_shift_right,
|
|
'rotl': stdtypes.u32_bits_rotate_left,
|
|
'rotr': stdtypes.u32_bits_rotate_right,
|
|
}, operators={
|
|
'&': stdtypes.u32_bits_bitwise_and,
|
|
'|': stdtypes.u32_bits_bitwise_or,
|
|
'^': stdtypes.u32_bits_bitwise_xor,
|
|
})
|
|
instance_type_class(Bits, u64, methods={
|
|
'shl': stdtypes.u64_bits_logical_shift_left,
|
|
'shr': stdtypes.u64_bits_logical_shift_right,
|
|
'rotl': stdtypes.u64_bits_rotate_left,
|
|
'rotr': stdtypes.u64_bits_rotate_right,
|
|
}, operators={
|
|
'&': stdtypes.u64_bits_bitwise_and,
|
|
'|': stdtypes.u64_bits_bitwise_or,
|
|
'^': stdtypes.u64_bits_bitwise_xor,
|
|
})
|
|
|
|
NatNum = Type3Class('NatNum', (a, ), methods={}, operators={
|
|
'+': [a, a, a],
|
|
'-': [a, a, a],
|
|
'*': [a, a, a],
|
|
'<<': [a, u32, a], # Arithmic shift left
|
|
'>>': [a, u32, a], # Arithmic shift right
|
|
})
|
|
|
|
instance_type_class(NatNum, u32, operators={
|
|
'+': stdtypes.u32_natnum_add,
|
|
'-': stdtypes.u32_natnum_sub,
|
|
'*': stdtypes.u32_natnum_mul,
|
|
'<<': stdtypes.u32_natnum_arithmic_shift_left,
|
|
'>>': stdtypes.u32_natnum_arithmic_shift_right,
|
|
})
|
|
instance_type_class(NatNum, u64, operators={
|
|
'+': stdtypes.u64_natnum_add,
|
|
'-': stdtypes.u64_natnum_sub,
|
|
'*': stdtypes.u64_natnum_mul,
|
|
'<<': stdtypes.u64_natnum_arithmic_shift_left,
|
|
'>>': stdtypes.u64_natnum_arithmic_shift_right,
|
|
})
|
|
instance_type_class(NatNum, i32, operators={
|
|
'+': stdtypes.i32_natnum_add,
|
|
'-': stdtypes.i32_natnum_sub,
|
|
'*': stdtypes.i32_natnum_mul,
|
|
'<<': stdtypes.i32_natnum_arithmic_shift_left,
|
|
'>>': stdtypes.i32_natnum_arithmic_shift_right,
|
|
})
|
|
instance_type_class(NatNum, i64, operators={
|
|
'+': stdtypes.i64_natnum_add,
|
|
'-': stdtypes.i64_natnum_sub,
|
|
'*': stdtypes.i64_natnum_mul,
|
|
'<<': stdtypes.i64_natnum_arithmic_shift_left,
|
|
'>>': stdtypes.i64_natnum_arithmic_shift_right,
|
|
})
|
|
instance_type_class(NatNum, f32, operators={
|
|
'+': stdtypes.f32_natnum_add,
|
|
'-': stdtypes.f32_natnum_sub,
|
|
'*': stdtypes.f32_natnum_mul,
|
|
'<<': stdtypes.f32_natnum_arithmic_shift_left,
|
|
'>>': stdtypes.f32_natnum_arithmic_shift_right,
|
|
})
|
|
instance_type_class(NatNum, f64, operators={
|
|
'+': stdtypes.f64_natnum_add,
|
|
'-': stdtypes.f64_natnum_sub,
|
|
'*': stdtypes.f64_natnum_mul,
|
|
'<<': stdtypes.f64_natnum_arithmic_shift_left,
|
|
'>>': stdtypes.f64_natnum_arithmic_shift_right,
|
|
})
|
|
|
|
IntNum = Type3Class('IntNum', (a, ), methods={
|
|
'abs': [a, a],
|
|
'neg': [a, a],
|
|
}, operators={}, inherited_classes=[NatNum])
|
|
|
|
instance_type_class(IntNum, i32, methods={
|
|
'abs': stdtypes.i32_intnum_abs,
|
|
'neg': stdtypes.i32_intnum_neg,
|
|
})
|
|
instance_type_class(IntNum, i64, methods={
|
|
'abs': stdtypes.i64_intnum_abs,
|
|
'neg': stdtypes.i64_intnum_neg,
|
|
})
|
|
instance_type_class(IntNum, f32, methods={
|
|
'abs': stdtypes.f32_intnum_abs,
|
|
'neg': stdtypes.f32_intnum_neg,
|
|
})
|
|
instance_type_class(IntNum, f64, methods={
|
|
'abs': stdtypes.f64_intnum_abs,
|
|
'neg': stdtypes.f64_intnum_neg,
|
|
})
|
|
|
|
Integral = Type3Class('Integral', (a, ), methods={
|
|
}, operators={
|
|
'//': [a, a, a],
|
|
'%': [a, a, a],
|
|
}, inherited_classes=[NatNum])
|
|
|
|
instance_type_class(Integral, u32, operators={
|
|
'//': stdtypes.u32_integral_div,
|
|
'%': stdtypes.u32_integral_rem,
|
|
})
|
|
instance_type_class(Integral, u64, operators={
|
|
'//': stdtypes.u64_integral_div,
|
|
'%': stdtypes.u64_integral_rem,
|
|
})
|
|
instance_type_class(Integral, i32, operators={
|
|
'//': stdtypes.i32_integral_div,
|
|
'%': stdtypes.i32_integral_rem,
|
|
})
|
|
instance_type_class(Integral, i64, operators={
|
|
'//': stdtypes.i64_integral_div,
|
|
'%': stdtypes.i64_integral_rem,
|
|
})
|
|
|
|
Fractional = Type3Class('Fractional', (a, ), methods={
|
|
'ceil': [a, a],
|
|
'floor': [a, a],
|
|
'trunc': [a, a],
|
|
'nearest': [a, a],
|
|
}, operators={
|
|
'/': [a, a, a],
|
|
}, inherited_classes=[NatNum])
|
|
|
|
instance_type_class(Fractional, f32, methods={
|
|
'ceil': stdtypes.f32_fractional_ceil,
|
|
'floor': stdtypes.f32_fractional_floor,
|
|
'trunc': stdtypes.f32_fractional_trunc,
|
|
'nearest': stdtypes.f32_fractional_nearest,
|
|
}, operators={
|
|
'/': stdtypes.f32_fractional_div,
|
|
})
|
|
instance_type_class(Fractional, f64, methods={
|
|
'ceil': stdtypes.f64_fractional_ceil,
|
|
'floor': stdtypes.f64_fractional_floor,
|
|
'trunc': stdtypes.f64_fractional_trunc,
|
|
'nearest': stdtypes.f64_fractional_nearest,
|
|
}, operators={
|
|
'/': stdtypes.f64_fractional_div,
|
|
})
|
|
|
|
Floating = Type3Class('Floating', (a, ), methods={
|
|
'sqrt': [a, a],
|
|
}, operators={}, inherited_classes=[Fractional])
|
|
|
|
# FIXME: Do we want to expose copysign?
|
|
|
|
instance_type_class(Floating, f32, methods={
|
|
'sqrt': stdtypes.f32_floating_sqrt,
|
|
})
|
|
instance_type_class(Floating, f64, methods={
|
|
'sqrt': stdtypes.f64_floating_sqrt,
|
|
})
|
|
|
|
Sized_ = Type3Class('Sized', (t, ), methods={
|
|
'len': [t(a), u32],
|
|
}, operators={}) # FIXME: Once we get type class families, add [] here
|
|
|
|
instance_type_class(Sized_, dynamic_array, methods={
|
|
'len': stdtypes.dynamic_array_sized_len,
|
|
})
|
|
instance_type_class(Sized_, static_array, methods={
|
|
'len': stdtypes.static_array_sized_len,
|
|
})
|
|
|
|
Extendable = Type3Class('Extendable', (a, b, ), methods={
|
|
'extend': [a, b],
|
|
'wrap': [b, a],
|
|
}, operators={})
|
|
|
|
instance_type_class(Extendable, u8, u32, methods={
|
|
'extend': stdtypes.u8_u32_extend,
|
|
'wrap': stdtypes.u8_u32_wrap,
|
|
})
|
|
instance_type_class(Extendable, u8, u64, methods={
|
|
'extend': stdtypes.u8_u64_extend,
|
|
'wrap': stdtypes.u8_u64_wrap,
|
|
})
|
|
instance_type_class(Extendable, u32, u64, methods={
|
|
'extend': stdtypes.u32_u64_extend,
|
|
'wrap': stdtypes.u32_u64_wrap,
|
|
})
|
|
instance_type_class(Extendable, i8, i32, methods={
|
|
'extend': stdtypes.i8_i32_extend,
|
|
'wrap': stdtypes.i8_i32_wrap,
|
|
})
|
|
instance_type_class(Extendable, i8, i64, methods={
|
|
'extend': stdtypes.i8_i64_extend,
|
|
'wrap': stdtypes.i8_i64_wrap,
|
|
})
|
|
instance_type_class(Extendable, i32, i64, methods={
|
|
'extend': stdtypes.i32_i64_extend,
|
|
'wrap': stdtypes.i32_i64_wrap,
|
|
})
|
|
|
|
Promotable = Type3Class('Promotable', (a, b, ), methods={
|
|
'promote': [a, b],
|
|
'demote': [b, a],
|
|
}, operators={})
|
|
|
|
instance_type_class(Promotable, f32, f64, methods={
|
|
'promote': stdtypes.f32_f64_promote,
|
|
'demote': stdtypes.f32_f64_demote,
|
|
})
|
|
|
|
Reinterpretable = Type3Class('Reinterpretable', (a, b, ), methods={
|
|
'reinterpret': [a, b]
|
|
}, operators={})
|
|
|
|
instance_type_class(Reinterpretable, u32, f32, methods={
|
|
'reinterpret': stdtypes.u32_f32_reinterpret,
|
|
})
|
|
instance_type_class(Reinterpretable, u64, f64, methods={
|
|
'reinterpret': stdtypes.u64_f64_reinterpret,
|
|
})
|
|
instance_type_class(Reinterpretable, i32, f32, methods={
|
|
'reinterpret': stdtypes.i32_f32_reinterpret,
|
|
})
|
|
instance_type_class(Reinterpretable, i64, f64, methods={
|
|
'reinterpret': stdtypes.i64_f64_reinterpret,
|
|
})
|
|
instance_type_class(Reinterpretable, f32, u32, methods={
|
|
'reinterpret': stdtypes.f32_u32_reinterpret,
|
|
})
|
|
instance_type_class(Reinterpretable, f64, u64, methods={
|
|
'reinterpret': stdtypes.f64_u64_reinterpret,
|
|
})
|
|
instance_type_class(Reinterpretable, f32, i32, methods={
|
|
'reinterpret': stdtypes.f32_i32_reinterpret,
|
|
})
|
|
instance_type_class(Reinterpretable, f64, i64, methods={
|
|
'reinterpret': stdtypes.f64_i64_reinterpret,
|
|
})
|
|
|
|
Convertable = Type3Class('Convertable', (a, b, ), methods={
|
|
'convert': [a, b],
|
|
'truncate': [b, a], # To prevent name clas with Fractional
|
|
}, operators={})
|
|
|
|
instance_type_class(Convertable, u32, f32, methods={
|
|
'convert': stdtypes.u32_f32_convert,
|
|
'truncate': stdtypes.u32_f32_truncate,
|
|
})
|
|
instance_type_class(Convertable, u32, f64, methods={
|
|
'convert': stdtypes.u32_f64_convert,
|
|
'truncate': stdtypes.u32_f64_truncate,
|
|
})
|
|
instance_type_class(Convertable, u64, f32, methods={
|
|
'convert': stdtypes.u64_f32_convert,
|
|
'truncate': stdtypes.u64_f32_truncate,
|
|
})
|
|
instance_type_class(Convertable, u64, f64, methods={
|
|
'convert': stdtypes.u64_f64_convert,
|
|
'truncate': stdtypes.u64_f64_truncate,
|
|
})
|
|
instance_type_class(Convertable, i32, f32, methods={
|
|
'convert': stdtypes.i32_f32_convert,
|
|
'truncate': stdtypes.i32_f32_truncate,
|
|
})
|
|
instance_type_class(Convertable, i32, f64, methods={
|
|
'convert': stdtypes.i32_f64_convert,
|
|
'truncate': stdtypes.i32_f64_truncate,
|
|
})
|
|
instance_type_class(Convertable, i64, f32, methods={
|
|
'convert': stdtypes.i64_f32_convert,
|
|
'truncate': stdtypes.i64_f32_truncate,
|
|
})
|
|
instance_type_class(Convertable, i64, f64, methods={
|
|
'convert': stdtypes.i64_f64_convert,
|
|
'truncate': stdtypes.i64_f64_truncate,
|
|
})
|
|
|
|
|
|
Foldable = Type3Class('Foldable', (t, ), methods={
|
|
'sum': [t(a), a],
|
|
'foldl': [[b, a, b], b, t(a), b],
|
|
'foldr': [[a, b, b], b, t(a), b],
|
|
}, operators={}, additional_context={
|
|
'sum': [Constraint_TypeClassInstanceExists(NatNum, (a, ))],
|
|
})
|
|
|
|
instance_type_class(Foldable, dynamic_array, methods={
|
|
'sum': stdtypes.dynamic_array_sum,
|
|
'foldl': stdtypes.dynamic_array_foldl,
|
|
'foldr': stdtypes.dynamic_array_foldr,
|
|
})
|
|
instance_type_class(Foldable, static_array, methods={
|
|
'sum': stdtypes.static_array_sum,
|
|
'foldl': stdtypes.static_array_foldl,
|
|
'foldr': stdtypes.static_array_foldr,
|
|
})
|
|
|
|
bytes_ = dynamic_array(u8)
|
|
|
|
PRELUDE_TYPES: dict[str, Type3] = {
|
|
'none': none,
|
|
'bool': bool_,
|
|
'u8': u8,
|
|
'u32': u32,
|
|
'u64': u64,
|
|
'i8': i8,
|
|
'i32': i32,
|
|
'i64': i64,
|
|
'f32': f32,
|
|
'f64': f64,
|
|
'bytes': bytes_,
|
|
}
|
|
|
|
PRELUDE_TYPE_CLASSES = {
|
|
'Eq': Eq,
|
|
'Ord': Ord,
|
|
'Bits': Bits,
|
|
'NatNum': NatNum,
|
|
'IntNum': IntNum,
|
|
'Integral': Integral,
|
|
'Fractional': Fractional,
|
|
'Floating': Floating,
|
|
'Extendable': Extendable,
|
|
'Promotable': Promotable,
|
|
}
|
|
|
|
PRELUDE_OPERATORS = {
|
|
**Bits.operators,
|
|
**Eq.operators,
|
|
**Ord.operators,
|
|
**Fractional.operators,
|
|
**Integral.operators,
|
|
**IntNum.operators,
|
|
**NatNum.operators,
|
|
}
|
|
|
|
PRELUDE_METHODS = {
|
|
**Bits.methods,
|
|
**Eq.methods,
|
|
**Ord.methods,
|
|
**Floating.methods,
|
|
**Fractional.methods,
|
|
**Integral.methods,
|
|
**IntNum.methods,
|
|
**NatNum.methods,
|
|
**Sized_.methods,
|
|
**Extendable.methods,
|
|
**Promotable.methods,
|
|
**Reinterpretable.methods,
|
|
**Convertable.methods,
|
|
**Foldable.methods,
|
|
}
|