This also removes the InternalPassAsPointer experiment. This also fixes that u8 values were stores as 32 bits in structs and tuples (but not dynamic arrays since that is special cased as bytes). Also, fixes allocation issue wi th dynamic arrays, it would allocate quadratic amount of memory.
617 lines
18 KiB
Python
617 lines
18 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,
|
|
})
|
|
|
|
Foldable = Type3Class('Foldable', (t, ), methods={
|
|
'sum': [t(a), a],
|
|
}, operators={}, additional_context={
|
|
'sum': [Constraint_TypeClassInstanceExists(NatNum, (a, ))],
|
|
})
|
|
|
|
instance_type_class(Foldable, static_array, methods={
|
|
'sum': stdtypes.static_array_sum,
|
|
})
|
|
|
|
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,
|
|
**Foldable.methods,
|
|
}
|