Module hebi.typed_ast
Expand source code
import typing
from ast import *
from dataclasses import dataclass
from frozenlist import FrozenList
import pluthon as plt
import uplc.ast as uplc
def distinct(xs: list):
"""Returns true iff the list consists of distinct elements"""
return len(xs) == len(set(xs))
def FrozenFrozenList(l: list):
fl = FrozenList(l)
fl.freeze()
return fl
class Type:
def constr_type(self) -> "InstanceType":
"""The type of the constructor for this class"""
raise TypeInferenceError(
f"Object of type {self.__class__} does not have a constructor"
)
def constr(self) -> plt.AST:
"""The constructor for this class"""
raise NotImplementedError(f"Constructor of {self.__class__} not implemented")
def attribute_type(self, attr) -> "Type":
"""The types of the named attributes of this class"""
raise TypeInferenceError(
f"Object of type {self.__class__} does not have attribute {attr}"
)
def attribute(self, attr) -> plt.AST:
"""The attributes of this class. Needs to be a lambda that expects as first argument the object itself"""
raise NotImplementedError(f"Attribute {attr} not implemented for type {self}")
def cmp(self, op: cmpop, o: "Type") -> plt.AST:
"""The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second the comparison."""
raise NotImplementedError(
f"Comparison {type(op).__name__} for {self.__class__.__name__} and {o.__class__.__name__} is not implemented. This is likely intended because it would always evaluate to False."
)
@dataclass(frozen=True, unsafe_hash=True)
class Record:
name: str
constructor: int
fields: typing.Union[typing.List[typing.Tuple[str, Type]], FrozenList]
@dataclass(frozen=True, unsafe_hash=True)
class ClassType(Type):
def __ge__(self, other):
raise NotImplementedError("Comparison between raw classtypes impossible")
@dataclass(frozen=True, unsafe_hash=True)
class AnyType(ClassType):
"""The top element in the partial order on types"""
def __ge__(self, other):
return True
@dataclass(frozen=True, unsafe_hash=True)
class AtomicType(ClassType):
def __ge__(self, other):
# Can only substitute for its own type (also subtypes)
return isinstance(other, self.__class__)
@dataclass(frozen=True, unsafe_hash=True)
class RecordType(ClassType):
record: Record
def constr_type(self) -> "InstanceType":
return InstanceType(
FunctionType([f[1] for f in self.record.fields], InstanceType(self))
)
def constr(self) -> plt.AST:
# wrap all constructor values to PlutusData
build_constr_params = plt.EmptyDataList()
for n, t in reversed(self.record.fields):
build_constr_params = plt.MkCons(
transform_output_map(t)(plt.Var(n)), build_constr_params
)
# then build a constr type with this PlutusData
return plt.Lambda(
["_"] + [n for n, _ in self.record.fields],
plt.ConstrData(plt.Integer(self.record.constructor), build_constr_params),
)
def attribute_type(self, attr: str) -> Type:
"""The types of the named attributes of this class"""
if attr == "CONSTR_ID":
return IntegerInstanceType
for n, t in self.record.fields:
if n == attr:
return t
raise TypeInferenceError(
f"Type {self.record.name} does not have attribute {attr}"
)
def attribute(self, attr: str) -> plt.AST:
"""The attributes of this class. Need to be a lambda that expects as first argument the object itself"""
if attr == "CONSTR_ID":
# access to constructor
return plt.Lambda(
["self"],
plt.Constructor(plt.Var("self")),
)
attr_typ = self.attribute_type(attr)
pos = next(i for i, (n, _) in enumerate(self.record.fields) if n == attr)
# access to normal fields
return plt.Lambda(
["self"],
transform_ext_params_map(attr_typ)(
plt.NthField(
plt.Var("self"),
plt.Integer(pos),
),
),
)
def cmp(self, op: cmpop, o: "Type") -> plt.AST:
"""The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second the comparison."""
# this will reject comparisons that will always be false - most likely due to faults during programming
if (isinstance(o, RecordType) and o.record == self.record) or (
isinstance(o, UnionType) and self in o.typs
):
if isinstance(op, Eq):
return plt.BuiltIn(uplc.BuiltInFun.EqualsData)
if isinstance(op, NotEq):
return plt.Lambda(
["x", "y"],
plt.Not(
plt.Apply(
plt.BuiltIn(uplc.BuiltInFun.EqualsData),
plt.Var("x"),
plt.Var("y"),
)
),
)
if (
isinstance(o, ListType)
and isinstance(o.typ, InstanceType)
and o.typ.typ >= self
):
if isinstance(op, In):
return plt.Lambda(
["x", "y"],
plt.EqualsData(
plt.Var("x"),
plt.FindList(
plt.Var("y"),
plt.Apply(
plt.BuiltIn(uplc.BuiltInFun.EqualsData), plt.Var("x")
),
# this simply ensures the default is always unequal to the searched value
plt.ConstrData(
plt.AddInteger(
plt.Constructor(plt.Var("x")), plt.Integer(1)
),
plt.MkNilData(plt.Unit()),
),
),
),
)
return super().cmp(op, o)
def __ge__(self, other):
# Can only substitute for its own type, records need to be equal
# if someone wants to be funny, they can implement <= to be true if all fields match up to some point
return isinstance(other, self.__class__) and other.record == self.record
@dataclass(frozen=True, unsafe_hash=True)
class UnionType(ClassType):
typs: typing.List[RecordType]
def attribute_type(self, attr) -> "Type":
if attr == "CONSTR_ID":
return IntegerInstanceType
# iterate through all names/types of the unioned records by position
for attr_names, attr_types in map(
lambda x: zip(*x), zip(*(t.record.fields for t in self.typs))
):
# need to have a common field with the same name, in the same position!
if any(attr_name != attr for attr_name in attr_names):
continue
for at in attr_types:
# return the maximum element if there is one
if all(at >= at2 for at2 in attr_types):
return at
# return the union type of all possible instantiations if all possible values are record types
if all(
isinstance(at, InstanceType) and isinstance(at.typ, RecordType)
for at in attr_types
) and distinct([at.typ.record.constructor for at in attr_types]):
return InstanceType(
UnionType(FrozenFrozenList([at.typ for at in attr_types]))
)
# return Anytype
return InstanceType(AnyType())
raise TypeInferenceError(
f"Can not access attribute {attr} of Union type. Cast to desired type with an 'if isinstance(_, _):' branch."
)
def attribute(self, attr: str) -> plt.AST:
if attr == "CONSTR_ID":
# access to constructor
return plt.Lambda(
["self"],
plt.Constructor(plt.Var("self")),
)
# iterate through all names/types of the unioned records by position
attr_typ = self.attribute_type(attr)
pos = next(
i
for i, (ns, _) in enumerate(
map(lambda x: zip(*x), zip(*(t.record.fields for t in self.typs)))
)
if all(n == attr for n in ns)
)
# access to normal fields
return plt.Lambda(
["self"],
transform_ext_params_map(attr_typ)(
plt.NthField(
plt.Var("self"),
plt.Integer(pos),
),
),
)
def __ge__(self, other):
if isinstance(other, UnionType):
return all(any(t >= ot for ot in other.typs) for t in self.typs)
return any(t >= other for t in self.typs)
def cmp(self, op: cmpop, o: "Type") -> plt.AST:
"""The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second the comparison."""
# this will reject comparisons that will always be false - most likely due to faults during programming
# note we require that there is an overlapt between the possible types for unions
if (isinstance(o, RecordType) and o in self.typs) or (
isinstance(o, UnionType) and set(self.typs).intersection(o.typs)
):
if isinstance(op, Eq):
return plt.BuiltIn(uplc.BuiltInFun.EqualsData)
if isinstance(op, NotEq):
return plt.Lambda(
["x", "y"],
plt.Not(
plt.Apply(
plt.BuiltIn(uplc.BuiltInFun.EqualsData),
plt.Var("x"),
plt.Var("y"),
)
),
)
raise NotImplementedError(
f"Can not compare {o} and {self} with operation {op.__class__}. Note that comparisons that always return false are also rejected."
)
@dataclass(frozen=True, unsafe_hash=True)
class TupleType(ClassType):
typs: typing.List[Type]
def __ge__(self, other):
return isinstance(other, TupleType) and all(
t >= ot for t, ot in zip(self.typs, other.typs)
)
@dataclass(frozen=True, unsafe_hash=True)
class PairType(ClassType):
"""An internal type representing built-in PlutusData pairs"""
l_typ: Type
r_typ: Type
def __ge__(self, other):
return isinstance(other, PairType) and all(
t >= ot
for t, ot in zip((self.l_typ, self.r_typ), (other.l_typ, other.r_typ))
)
@dataclass(frozen=True, unsafe_hash=True)
class ListType(ClassType):
typ: Type
def __ge__(self, other):
return isinstance(other, ListType) and self.typ >= other.typ
@dataclass(frozen=True, unsafe_hash=True)
class DictType(ClassType):
key_typ: Type
value_typ: Type
def attribute_type(self, attr) -> "Type":
if attr == "get":
return InstanceType(
FunctionType([self.key_typ, self.value_typ], self.value_typ)
)
if attr == "keys":
return InstanceType(FunctionType([], InstanceType(ListType(self.key_typ))))
if attr == "values":
return InstanceType(
FunctionType([], InstanceType(ListType(self.value_typ)))
)
if attr == "items":
return InstanceType(
FunctionType(
[],
InstanceType(
ListType(InstanceType(PairType(self.key_typ, self.value_typ)))
),
)
)
raise TypeInferenceError(
f"Type of attribute '{attr}' is unknown for type Dict."
)
def attribute(self, attr) -> plt.AST:
if attr == "get":
return plt.Lambda(
["self", "_", "key", "default"],
transform_ext_params_map(self.value_typ)(
plt.SndPair(
plt.FindList(
plt.Var("self"),
plt.Lambda(
["x"],
plt.EqualsData(
transform_output_map(self.key_typ)(plt.Var("key")),
plt.FstPair(plt.Var("x")),
),
),
# this is a bit ugly... we wrap - only to later unwrap again
plt.MkPairData(
transform_output_map(self.key_typ)(plt.Var("key")),
transform_output_map(self.value_typ)(
plt.Var("default")
),
),
),
),
),
)
if attr == "keys":
return plt.Lambda(
["self", "_"],
plt.MapList(
plt.Var("self"),
plt.Lambda(
["x"],
transform_ext_params_map(self.key_typ)(
plt.FstPair(plt.Var("x"))
),
),
empty_list(self.key_typ),
),
)
if attr == "values":
return plt.Lambda(
["self", "_"],
plt.MapList(
plt.Var("self"),
plt.Lambda(
["x"],
transform_ext_params_map(self.value_typ)(
plt.SndPair(plt.Var("x"))
),
),
empty_list(self.value_typ),
),
)
if attr == "items":
return plt.Lambda(
["self", "_"],
plt.Var("self"),
)
raise NotImplementedError(f"Attribute '{attr}' of Dict is unknown.")
def __ge__(self, other):
return (
isinstance(other, DictType)
and self.key_typ >= other.key_typ
and self.value_typ >= other.value_typ
)
@dataclass(frozen=True, unsafe_hash=True)
class FunctionType(ClassType):
argtyps: typing.List[Type]
rettyp: Type
def __ge__(self, other):
return (
isinstance(other, FunctionType)
and all(a >= oa for a, oa in zip(self.argtyps, other.argtyps))
and other.rettyp >= self.rettyp
)
@dataclass(frozen=True, unsafe_hash=True)
class InstanceType(Type):
typ: ClassType
def constr_type(self) -> FunctionType:
raise TypeInferenceError(f"Can not construct an instance {self}")
def constr(self) -> plt.AST:
raise NotImplementedError(f"Can not construct an instance {self}")
def attribute_type(self, attr) -> Type:
return self.typ.attribute_type(attr)
def attribute(self, attr) -> plt.AST:
return self.typ.attribute(attr)
def cmp(self, op: cmpop, o: "Type") -> plt.AST:
"""The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second the comparison."""
if isinstance(o, InstanceType):
return self.typ.cmp(op, o.typ)
return super().cmp(op, o)
def __ge__(self, other):
return isinstance(other, InstanceType) and self.typ >= other.typ
@dataclass(frozen=True, unsafe_hash=True)
class IntegerType(AtomicType):
def constr_type(self) -> InstanceType:
return InstanceType(FunctionType([StringInstanceType], InstanceType(self)))
def constr(self) -> plt.AST:
# TODO we need to strip the string implicitely before parsing it
return plt.Lambda(
["_", "x"],
plt.Let(
[
("e", plt.EncodeUtf8(plt.Var("x"))),
("first_int", plt.IndexByteString(plt.Var("e"), plt.Integer(0))),
("len", plt.LengthOfByteString(plt.Var("e"))),
(
"fold_start",
plt.Lambda(
["start"],
plt.FoldList(
plt.Range(plt.Var("len"), plt.Var("start")),
plt.Lambda(
["s", "i"],
plt.Let(
[
(
"b",
plt.IndexByteString(
plt.Var("e"), plt.Var("i")
),
)
],
plt.Ite(
plt.EqualsInteger(
plt.Var("b"), plt.Integer(ord("_"))
),
plt.Var("s"),
plt.Ite(
plt.Or(
plt.LessThanInteger(
plt.Var("b"),
plt.Integer(ord("0")),
),
plt.LessThanInteger(
plt.Integer(ord("9")),
plt.Var("b"),
),
),
plt.TraceError(
"ValueError: invalid literal for int() with base 10"
),
plt.AddInteger(
plt.SubtractInteger(
plt.Var("b"),
plt.Integer(ord("0")),
),
plt.MultiplyInteger(
plt.Var("s"), plt.Integer(10)
),
),
),
),
),
),
plt.Integer(0),
),
),
),
],
plt.Ite(
plt.Or(
plt.EqualsInteger(plt.Var("len"), plt.Integer(0)),
plt.EqualsInteger(
plt.Var("first_int"),
plt.Integer(ord("_")),
),
),
plt.TraceError(
"ValueError: invalid literal for int() with base 10"
),
plt.Ite(
plt.EqualsInteger(
plt.Var("first_int"),
plt.Integer(ord("-")),
),
plt.Negate(
plt.Apply(plt.Var("fold_start"), plt.Integer(1)),
),
plt.Apply(plt.Var("fold_start"), plt.Integer(0)),
),
),
),
)
def cmp(self, op: cmpop, o: "Type") -> plt.AST:
"""The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second the comparison."""
if isinstance(o, BoolType):
if isinstance(op, Eq):
# 1 == True
# 0 == False
# all other comparisons are False
return plt.Lambda(
["x", "y"],
plt.Ite(
plt.Var("y"),
plt.EqualsInteger(plt.Var("x"), plt.Integer(1)),
plt.EqualsInteger(plt.Var("x"), plt.Integer(0)),
),
)
if isinstance(o, IntegerType):
if isinstance(op, Eq):
return plt.BuiltIn(uplc.BuiltInFun.EqualsInteger)
if isinstance(op, NotEq):
return plt.Lambda(
["x", "y"],
plt.Not(
plt.Apply(
plt.BuiltIn(uplc.BuiltInFun.EqualsInteger),
plt.Var("y"),
plt.Var("x"),
)
),
)
if isinstance(op, LtE):
return plt.BuiltIn(uplc.BuiltInFun.LessThanEqualsInteger)
if isinstance(op, Lt):
return plt.BuiltIn(uplc.BuiltInFun.LessThanInteger)
if isinstance(op, Gt):
return plt.Lambda(
["x", "y"],
plt.Apply(
plt.BuiltIn(uplc.BuiltInFun.LessThanInteger),
plt.Var("y"),
plt.Var("x"),
),
)
if isinstance(op, GtE):
return plt.Lambda(
["x", "y"],
plt.Apply(
plt.BuiltIn(uplc.BuiltInFun.LessThanEqualsInteger),
plt.Var("y"),
plt.Var("x"),
),
)
if (
isinstance(o, ListType)
and isinstance(o.typ, InstanceType)
and isinstance(o.typ.typ, IntegerType)
):
if isinstance(op, In):
return plt.Lambda(
["x", "y"],
plt.EqualsInteger(
plt.Var("x"),
plt.FindList(
plt.Var("y"),
plt.Apply(
plt.BuiltIn(uplc.BuiltInFun.EqualsInteger), plt.Var("x")
),
# this simply ensures the default is always unequal to the searched value
plt.AddInteger(plt.Var("x"), plt.Integer(1)),
),
),
)
return super().cmp(op, o)
@dataclass(frozen=True, unsafe_hash=True)
class StringType(AtomicType):
def constr_type(self) -> InstanceType:
return InstanceType(FunctionType([IntegerInstanceType], InstanceType(self)))
def constr(self) -> plt.AST:
# constructs a string representation of an integer
return plt.Lambda(
["_", "x"],
plt.DecodeUtf8(
plt.Let(
[
(
"strlist",
plt.RecFun(
plt.Lambda(
["f", "i"],
plt.Ite(
plt.LessThanEqualsInteger(
plt.Var("i"), plt.Integer(0)
),
plt.EmptyIntegerList(),
plt.MkCons(
plt.AddInteger(
plt.ModInteger(
plt.Var("i"), plt.Integer(10)
),
plt.Integer(ord("0")),
),
plt.Apply(
plt.Var("f"),
plt.Var("f"),
plt.DivideInteger(
plt.Var("i"), plt.Integer(10)
),
),
),
),
),
),
),
(
"mkstr",
plt.Lambda(
["i"],
plt.FoldList(
plt.Apply(plt.Var("strlist"), plt.Var("i")),
plt.Lambda(
["b", "i"],
plt.ConsByteString(plt.Var("i"), plt.Var("b")),
),
plt.ByteString(b""),
),
),
),
],
plt.Ite(
plt.EqualsInteger(plt.Var("x"), plt.Integer(0)),
plt.ByteString(b"0"),
plt.Ite(
plt.LessThanInteger(plt.Var("x"), plt.Integer(0)),
plt.ConsByteString(
plt.Integer(ord("-")),
plt.Apply(plt.Var("mkstr"), plt.Negate(plt.Var("x"))),
),
plt.Apply(plt.Var("mkstr"), plt.Var("x")),
),
),
)
),
)
def attribute_type(self, attr) -> Type:
if attr == "encode":
return InstanceType(FunctionType([], ByteStringInstanceType))
return super().attribute_type(attr)
def attribute(self, attr) -> plt.AST:
if attr == "encode":
# No codec -> only the default (utf8) is allowed
return plt.Lambda(["x", "_"], plt.EncodeUtf8(plt.Var("x")))
return super().attribute(attr)
def cmp(self, op: cmpop, o: "Type") -> plt.AST:
if isinstance(o, StringType):
if isinstance(op, Eq):
return plt.BuiltIn(uplc.BuiltInFun.EqualsString)
return super().cmp(op, o)
@dataclass(frozen=True, unsafe_hash=True)
class ByteStringType(AtomicType):
def constr_type(self) -> InstanceType:
return InstanceType(
FunctionType(
[InstanceType(ListType(IntegerInstanceType))], InstanceType(self)
)
)
def constr(self) -> plt.AST:
return plt.Lambda(
["_", "xs"],
plt.RFoldList(
plt.Var("xs"),
plt.Lambda(["a", "x"], plt.ConsByteString(plt.Var("x"), plt.Var("a"))),
plt.ByteString(b""),
),
)
def attribute_type(self, attr) -> Type:
if attr == "decode":
return InstanceType(FunctionType([], StringInstanceType))
return super().attribute_type(attr)
def attribute(self, attr) -> plt.AST:
if attr == "decode":
# No codec -> only the default (utf8) is allowed
return plt.Lambda(["x", "_"], plt.DecodeUtf8(plt.Var("x")))
return super().attribute(attr)
def cmp(self, op: cmpop, o: "Type") -> plt.AST:
if isinstance(o, ByteStringType):
if isinstance(op, Eq):
return plt.BuiltIn(uplc.BuiltInFun.EqualsByteString)
if isinstance(op, NotEq):
return plt.Lambda(
["x", "y"],
plt.Not(
plt.Apply(
plt.BuiltIn(uplc.BuiltInFun.EqualsByteString),
plt.Var("y"),
plt.Var("x"),
)
),
)
if isinstance(op, Lt):
return plt.BuiltIn(uplc.BuiltInFun.LessThanByteString)
if isinstance(op, LtE):
return plt.BuiltIn(uplc.BuiltInFun.LessThanEqualsByteString)
if isinstance(op, Gt):
return plt.Lambda(
["x", "y"],
plt.Apply(
plt.BuiltIn(uplc.BuiltInFun.LessThanByteString),
plt.Var("y"),
plt.Var("x"),
),
)
if isinstance(op, GtE):
return plt.Lambda(
["x", "y"],
plt.Apply(
plt.BuiltIn(uplc.BuiltInFun.LessThanEqualsByteString),
plt.Var("y"),
plt.Var("x"),
),
)
if (
isinstance(o, ListType)
and isinstance(o.typ, InstanceType)
and isinstance(o.typ.typ, ByteStringType)
):
if isinstance(op, In):
return plt.Lambda(
["x", "y"],
plt.EqualsByteString(
plt.Var("x"),
plt.FindList(
plt.Var("y"),
plt.Apply(
plt.BuiltIn(uplc.BuiltInFun.EqualsByteString),
plt.Var("x"),
),
# this simply ensures the default is always unequal to the searched value
plt.ConsByteString(plt.Integer(0), plt.Var("x")),
),
),
)
return super().cmp(op, o)
@dataclass(frozen=True, unsafe_hash=True)
class BoolType(AtomicType):
def constr_type(self) -> "InstanceType":
return InstanceType(FunctionType([IntegerInstanceType], BoolInstanceType))
def constr(self) -> plt.AST:
# constructs a boolean from an integer
return plt.Lambda(
["_", "x"], plt.Not(plt.EqualsInteger(plt.Var("x"), plt.Integer(0)))
)
def cmp(self, op: cmpop, o: "Type") -> plt.AST:
if isinstance(o, IntegerType):
if isinstance(op, Eq):
# 1 == True
# 0 == False
# all other comparisons are False
return plt.Lambda(
["y", "x"],
plt.Ite(
plt.Var("y"),
plt.EqualsInteger(plt.Var("x"), plt.Integer(1)),
plt.EqualsInteger(plt.Var("x"), plt.Integer(0)),
),
)
if isinstance(o, BoolType):
if isinstance(op, Eq):
return plt.Lambda(["x", "y"], plt.Iff(plt.Var("x"), plt.Var("y")))
return super().cmp(op, o)
@dataclass(frozen=True, unsafe_hash=True)
class UnitType(AtomicType):
def cmp(self, op: cmpop, o: "Type") -> plt.AST:
if isinstance(o, UnitType):
if isinstance(op, Eq):
return plt.Lambda(["x", "y"], plt.Bool(True))
if isinstance(op, NotEq):
return plt.Lambda(["x", "y"], plt.Bool(False))
return super().cmp(op, o)
IntegerInstanceType = InstanceType(IntegerType())
StringInstanceType = InstanceType(StringType())
ByteStringInstanceType = InstanceType(ByteStringType())
BoolInstanceType = InstanceType(BoolType())
UnitInstanceType = InstanceType(UnitType())
ATOMIC_TYPES = {
int.__name__: IntegerType(),
str.__name__: StringType(),
bytes.__name__: ByteStringType(),
"Unit": UnitType(),
bool.__name__: BoolType(),
}
NoneInstanceType = UnitInstanceType
class InaccessibleType(ClassType):
"""A type that blocks overwriting of a function"""
pass
class PolymorphicFunction:
def type_from_args(self, args: typing.List[Type]) -> FunctionType:
raise NotImplementedError()
def impl_from_args(self, args: typing.List[Type]) -> plt.AST:
raise NotImplementedError()
@dataclass(frozen=True, unsafe_hash=True)
class PolymorphicFunctionType(ClassType):
"""A special type of builtin that may act differently on different parameters"""
polymorphic_function: PolymorphicFunction
@dataclass(frozen=True, unsafe_hash=True)
class PolymorphicFunctionInstanceType(InstanceType):
typ: FunctionType
polymorphic_function: PolymorphicFunction
class TypedAST(AST):
typ: Type
class typedexpr(TypedAST, expr):
pass
class typedstmt(TypedAST, stmt):
# Statements always have type None
typ = NoneInstanceType
class typedarg(TypedAST, arg):
pass
class typedarguments(TypedAST, arguments):
args: typing.List[typedarg]
vararg: typing.Union[typedarg, None]
kwonlyargs: typing.List[typedarg]
kw_defaults: typing.List[typing.Union[typedexpr, None]]
kwarg: typing.Union[typedarg, None]
defaults: typing.List[typedexpr]
class TypedModule(typedstmt, Module):
body: typing.List[typedstmt]
class TypedFunctionDef(typedstmt, FunctionDef):
body: typing.List[typedstmt]
args: arguments
class TypedIf(typedstmt, If):
test: typedexpr
body: typing.List[typedstmt]
orelse: typing.List[typedstmt]
class TypedReturn(typedstmt, Return):
value: typedexpr
class TypedExpression(typedexpr, Expression):
body: typedexpr
class TypedCall(typedexpr, Call):
func: typedexpr
args: typing.List[typedexpr]
class TypedExpr(typedstmt, Expr):
value: typedexpr
class TypedAssign(typedstmt, Assign):
targets: typing.List[typedexpr]
value: typedexpr
class TypedClassDef(typedstmt, ClassDef):
class_typ: Type
class TypedAnnAssign(typedstmt, AnnAssign):
target: typedexpr
annotation: Type
value: typedexpr
class TypedWhile(typedstmt, While):
test: typedexpr
body: typing.List[typedstmt]
orelse: typing.List[typedstmt]
class TypedFor(typedstmt, For):
target: typedexpr
iter: typedexpr
body: typing.List[typedstmt]
orelse: typing.List[typedstmt]
class TypedPass(typedstmt, Pass):
pass
class TypedName(typedexpr, Name):
pass
class TypedConstant(TypedAST, Constant):
pass
class TypedTuple(typedexpr, Tuple):
pass
class TypedList(typedexpr, List):
pass
class typedcomprehension(typedexpr, comprehension):
target: typedexpr
iter: typedexpr
ifs: typing.List[typedexpr]
class TypedListComp(typedexpr, ListComp):
generators: typing.List[typedcomprehension]
elt: typedexpr
class TypedDict(typedexpr, Dict):
pass
class TypedIfExp(typedstmt, IfExp):
test: typedexpr
body: typedexpr
orelse: typedexpr
class TypedCompare(typedexpr, Compare):
left: typedexpr
ops: typing.List[cmpop]
comparators: typing.List[typedexpr]
class TypedBinOp(typedexpr, BinOp):
left: typedexpr
right: typedexpr
class TypedBoolOp(typedexpr, BoolOp):
values: typing.List[typedexpr]
class TypedUnaryOp(typedexpr, UnaryOp):
operand: typedexpr
class TypedSubscript(typedexpr, Subscript):
value: typedexpr
class TypedAttribute(typedexpr, Attribute):
value: typedexpr
pos: int
class TypedAssert(typedstmt, Assert):
test: typedexpr
msg: typedexpr
class RawPlutoExpr(typedexpr):
typ: Type
expr: plt.AST
class TypeInferenceError(AssertionError):
pass
EmptyListMap = {
IntegerInstanceType: plt.EmptyIntegerList(),
ByteStringInstanceType: plt.EmptyByteStringList(),
StringInstanceType: plt.EmptyTextList(),
UnitInstanceType: plt.EmptyUnitList(),
BoolInstanceType: plt.EmptyBoolList(),
}
def empty_list(p: Type):
if p in EmptyListMap:
return EmptyListMap[p]
assert isinstance(p, InstanceType), "Can only create lists of instances"
if isinstance(p.typ, ListType):
el = empty_list(p.typ.typ)
return plt.EmptyListList(uplc.BuiltinList([], el.sample_value))
if isinstance(p.typ, DictType):
return plt.EmptyListList(
uplc.BuiltinList(
[],
uplc.BuiltinPair(
uplc.PlutusConstr(0, FrozenList([])),
uplc.PlutusConstr(0, FrozenList([])),
),
)
)
if isinstance(p.typ, RecordType) or isinstance(p.typ, AnyType):
return plt.EmptyDataList()
raise NotImplementedError(f"Empty lists of type {p} can't be constructed yet")
TransformExtParamsMap = {
IntegerInstanceType: lambda x: plt.UnIData(x),
ByteStringInstanceType: lambda x: plt.UnBData(x),
StringInstanceType: lambda x: plt.DecodeUtf8(plt.UnBData(x)),
UnitInstanceType: lambda x: plt.Apply(plt.Lambda(["_"], plt.Unit())),
BoolInstanceType: lambda x: plt.NotEqualsInteger(plt.UnIData(x), plt.Integer(0)),
}
def transform_ext_params_map(p: Type):
assert isinstance(
p, InstanceType
), "Can only transform instances, not classes as input"
if p in TransformExtParamsMap:
return TransformExtParamsMap[p]
if isinstance(p.typ, ListType):
list_int_typ = p.typ.typ
return lambda x: plt.MapList(
plt.UnListData(x),
plt.Lambda(["x"], transform_ext_params_map(list_int_typ)(plt.Var("x"))),
empty_list(p.typ.typ),
)
if isinstance(p.typ, DictType):
# there doesn't appear to be a constructor function to make Pair a b for any types
# so pairs will always contain Data
return lambda x: plt.UnMapData(x)
return lambda x: x
TransformOutputMap = {
StringInstanceType: lambda x: plt.BData(plt.EncodeUtf8(x)),
IntegerInstanceType: lambda x: plt.IData(x),
ByteStringInstanceType: lambda x: plt.BData(x),
UnitInstanceType: lambda x: plt.Apply(
plt.Lambda(["_"], plt.ConstrData(plt.Integer(0), plt.EmptyDataList())), x
),
BoolInstanceType: lambda x: plt.IData(
plt.IfThenElse(x, plt.Integer(1), plt.Integer(0))
),
}
def transform_output_map(p: Type):
assert isinstance(
p, InstanceType
), "Can only transform instances, not classes as input"
if p in TransformOutputMap:
return TransformOutputMap[p]
if isinstance(p.typ, ListType):
list_int_typ = p.typ.typ
return lambda x: plt.ListData(
plt.MapList(
x,
plt.Lambda(["x"], transform_output_map(list_int_typ)(plt.Var("x"))),
),
)
if isinstance(p.typ, DictType):
# there doesn't appear to be a constructor function to make Pair a b for any types
# so pairs will always contain Data
return lambda x: plt.MapData(x)
return lambda x: x
class TypedNodeTransformer(NodeTransformer):
def visit(self, node):
"""Visit a node."""
node_class_name = node.__class__.__name__
if node_class_name.startswith("Typed"):
node_class_name = node_class_name[len("Typed") :]
method = "visit_" + node_class_name
visitor = getattr(self, method, self.generic_visit)
return visitor(node)
class TypedNodeVisitor(NodeVisitor):
def visit(self, node):
"""Visit a node."""
node_class_name = node.__class__.__name__
if node_class_name.startswith("Typed"):
node_class_name = node_class_name[len("Typed") :]
method = "visit_" + node_class_name
visitor = getattr(self, method, self.generic_visit)
return visitor(node)
Functions
def FrozenFrozenList(l: list)
-
Expand source code
def FrozenFrozenList(l: list): fl = FrozenList(l) fl.freeze() return fl
def distinct(xs: list)
-
Returns true iff the list consists of distinct elements
Expand source code
def distinct(xs: list): """Returns true iff the list consists of distinct elements""" return len(xs) == len(set(xs))
def empty_list(p: Type)
-
Expand source code
def empty_list(p: Type): if p in EmptyListMap: return EmptyListMap[p] assert isinstance(p, InstanceType), "Can only create lists of instances" if isinstance(p.typ, ListType): el = empty_list(p.typ.typ) return plt.EmptyListList(uplc.BuiltinList([], el.sample_value)) if isinstance(p.typ, DictType): return plt.EmptyListList( uplc.BuiltinList( [], uplc.BuiltinPair( uplc.PlutusConstr(0, FrozenList([])), uplc.PlutusConstr(0, FrozenList([])), ), ) ) if isinstance(p.typ, RecordType) or isinstance(p.typ, AnyType): return plt.EmptyDataList() raise NotImplementedError(f"Empty lists of type {p} can't be constructed yet")
def transform_ext_params_map(p: Type)
-
Expand source code
def transform_ext_params_map(p: Type): assert isinstance( p, InstanceType ), "Can only transform instances, not classes as input" if p in TransformExtParamsMap: return TransformExtParamsMap[p] if isinstance(p.typ, ListType): list_int_typ = p.typ.typ return lambda x: plt.MapList( plt.UnListData(x), plt.Lambda(["x"], transform_ext_params_map(list_int_typ)(plt.Var("x"))), empty_list(p.typ.typ), ) if isinstance(p.typ, DictType): # there doesn't appear to be a constructor function to make Pair a b for any types # so pairs will always contain Data return lambda x: plt.UnMapData(x) return lambda x: x
def transform_output_map(p: Type)
-
Expand source code
def transform_output_map(p: Type): assert isinstance( p, InstanceType ), "Can only transform instances, not classes as input" if p in TransformOutputMap: return TransformOutputMap[p] if isinstance(p.typ, ListType): list_int_typ = p.typ.typ return lambda x: plt.ListData( plt.MapList( x, plt.Lambda(["x"], transform_output_map(list_int_typ)(plt.Var("x"))), ), ) if isinstance(p.typ, DictType): # there doesn't appear to be a constructor function to make Pair a b for any types # so pairs will always contain Data return lambda x: plt.MapData(x) return lambda x: x
Classes
class AnyType
-
The top element in the partial order on types
Expand source code
class AnyType(ClassType): """The top element in the partial order on types""" def __ge__(self, other): return True
Ancestors
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
def attribute_type(self, attr) ‑> Type
-
Inherited from:
ClassType
.attribute_type
The types of the named attributes of this class
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.constr
The constructor for this class
def constr_type(self) ‑> InstanceType
-
Inherited from:
ClassType
.constr_type
The type of the constructor for this class
class AtomicType
-
AtomicType()
Expand source code
class AtomicType(ClassType): def __ge__(self, other): # Can only substitute for its own type (also subtypes) return isinstance(other, self.__class__)
Ancestors
Subclasses
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
def attribute_type(self, attr) ‑> Type
-
Inherited from:
ClassType
.attribute_type
The types of the named attributes of this class
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.constr
The constructor for this class
def constr_type(self) ‑> InstanceType
-
Inherited from:
ClassType
.constr_type
The type of the constructor for this class
class BoolType
-
BoolType()
Expand source code
class BoolType(AtomicType): def constr_type(self) -> "InstanceType": return InstanceType(FunctionType([IntegerInstanceType], BoolInstanceType)) def constr(self) -> plt.AST: # constructs a boolean from an integer return plt.Lambda( ["_", "x"], plt.Not(plt.EqualsInteger(plt.Var("x"), plt.Integer(0))) ) def cmp(self, op: cmpop, o: "Type") -> plt.AST: if isinstance(o, IntegerType): if isinstance(op, Eq): # 1 == True # 0 == False # all other comparisons are False return plt.Lambda( ["y", "x"], plt.Ite( plt.Var("y"), plt.EqualsInteger(plt.Var("x"), plt.Integer(1)), plt.EqualsInteger(plt.Var("x"), plt.Integer(0)), ), ) if isinstance(o, BoolType): if isinstance(op, Eq): return plt.Lambda(["x", "y"], plt.Iff(plt.Var("x"), plt.Var("y"))) return super().cmp(op, o)
Ancestors
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
AtomicType
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
def attribute_type(self, attr) ‑> Type
-
Inherited from:
AtomicType
.attribute_type
The types of the named attributes of this class
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
AtomicType
.cmp
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
Expand source code
def cmp(self, op: cmpop, o: "Type") -> plt.AST: if isinstance(o, IntegerType): if isinstance(op, Eq): # 1 == True # 0 == False # all other comparisons are False return plt.Lambda( ["y", "x"], plt.Ite( plt.Var("y"), plt.EqualsInteger(plt.Var("x"), plt.Integer(1)), plt.EqualsInteger(plt.Var("x"), plt.Integer(0)), ), ) if isinstance(o, BoolType): if isinstance(op, Eq): return plt.Lambda(["x", "y"], plt.Iff(plt.Var("x"), plt.Var("y"))) return super().cmp(op, o)
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
AtomicType
.constr
The constructor for this class
Expand source code
def constr(self) -> plt.AST: # constructs a boolean from an integer return plt.Lambda( ["_", "x"], plt.Not(plt.EqualsInteger(plt.Var("x"), plt.Integer(0))) )
def constr_type(self) ‑> InstanceType
-
Inherited from:
AtomicType
.constr_type
The type of the constructor for this class
Expand source code
def constr_type(self) -> "InstanceType": return InstanceType(FunctionType([IntegerInstanceType], BoolInstanceType))
class ByteStringType
-
ByteStringType()
Expand source code
class ByteStringType(AtomicType): def constr_type(self) -> InstanceType: return InstanceType( FunctionType( [InstanceType(ListType(IntegerInstanceType))], InstanceType(self) ) ) def constr(self) -> plt.AST: return plt.Lambda( ["_", "xs"], plt.RFoldList( plt.Var("xs"), plt.Lambda(["a", "x"], plt.ConsByteString(plt.Var("x"), plt.Var("a"))), plt.ByteString(b""), ), ) def attribute_type(self, attr) -> Type: if attr == "decode": return InstanceType(FunctionType([], StringInstanceType)) return super().attribute_type(attr) def attribute(self, attr) -> plt.AST: if attr == "decode": # No codec -> only the default (utf8) is allowed return plt.Lambda(["x", "_"], plt.DecodeUtf8(plt.Var("x"))) return super().attribute(attr) def cmp(self, op: cmpop, o: "Type") -> plt.AST: if isinstance(o, ByteStringType): if isinstance(op, Eq): return plt.BuiltIn(uplc.BuiltInFun.EqualsByteString) if isinstance(op, NotEq): return plt.Lambda( ["x", "y"], plt.Not( plt.Apply( plt.BuiltIn(uplc.BuiltInFun.EqualsByteString), plt.Var("y"), plt.Var("x"), ) ), ) if isinstance(op, Lt): return plt.BuiltIn(uplc.BuiltInFun.LessThanByteString) if isinstance(op, LtE): return plt.BuiltIn(uplc.BuiltInFun.LessThanEqualsByteString) if isinstance(op, Gt): return plt.Lambda( ["x", "y"], plt.Apply( plt.BuiltIn(uplc.BuiltInFun.LessThanByteString), plt.Var("y"), plt.Var("x"), ), ) if isinstance(op, GtE): return plt.Lambda( ["x", "y"], plt.Apply( plt.BuiltIn(uplc.BuiltInFun.LessThanEqualsByteString), plt.Var("y"), plt.Var("x"), ), ) if ( isinstance(o, ListType) and isinstance(o.typ, InstanceType) and isinstance(o.typ.typ, ByteStringType) ): if isinstance(op, In): return plt.Lambda( ["x", "y"], plt.EqualsByteString( plt.Var("x"), plt.FindList( plt.Var("y"), plt.Apply( plt.BuiltIn(uplc.BuiltInFun.EqualsByteString), plt.Var("x"), ), # this simply ensures the default is always unequal to the searched value plt.ConsByteString(plt.Integer(0), plt.Var("x")), ), ), ) return super().cmp(op, o)
Ancestors
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
AtomicType
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
Expand source code
def attribute(self, attr) -> plt.AST: if attr == "decode": # No codec -> only the default (utf8) is allowed return plt.Lambda(["x", "_"], plt.DecodeUtf8(plt.Var("x"))) return super().attribute(attr)
def attribute_type(self, attr) ‑> Type
-
Inherited from:
AtomicType
.attribute_type
The types of the named attributes of this class
Expand source code
def attribute_type(self, attr) -> Type: if attr == "decode": return InstanceType(FunctionType([], StringInstanceType)) return super().attribute_type(attr)
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
AtomicType
.cmp
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
Expand source code
def cmp(self, op: cmpop, o: "Type") -> plt.AST: if isinstance(o, ByteStringType): if isinstance(op, Eq): return plt.BuiltIn(uplc.BuiltInFun.EqualsByteString) if isinstance(op, NotEq): return plt.Lambda( ["x", "y"], plt.Not( plt.Apply( plt.BuiltIn(uplc.BuiltInFun.EqualsByteString), plt.Var("y"), plt.Var("x"), ) ), ) if isinstance(op, Lt): return plt.BuiltIn(uplc.BuiltInFun.LessThanByteString) if isinstance(op, LtE): return plt.BuiltIn(uplc.BuiltInFun.LessThanEqualsByteString) if isinstance(op, Gt): return plt.Lambda( ["x", "y"], plt.Apply( plt.BuiltIn(uplc.BuiltInFun.LessThanByteString), plt.Var("y"), plt.Var("x"), ), ) if isinstance(op, GtE): return plt.Lambda( ["x", "y"], plt.Apply( plt.BuiltIn(uplc.BuiltInFun.LessThanEqualsByteString), plt.Var("y"), plt.Var("x"), ), ) if ( isinstance(o, ListType) and isinstance(o.typ, InstanceType) and isinstance(o.typ.typ, ByteStringType) ): if isinstance(op, In): return plt.Lambda( ["x", "y"], plt.EqualsByteString( plt.Var("x"), plt.FindList( plt.Var("y"), plt.Apply( plt.BuiltIn(uplc.BuiltInFun.EqualsByteString), plt.Var("x"), ), # this simply ensures the default is always unequal to the searched value plt.ConsByteString(plt.Integer(0), plt.Var("x")), ), ), ) return super().cmp(op, o)
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
AtomicType
.constr
The constructor for this class
Expand source code
def constr(self) -> plt.AST: return plt.Lambda( ["_", "xs"], plt.RFoldList( plt.Var("xs"), plt.Lambda(["a", "x"], plt.ConsByteString(plt.Var("x"), plt.Var("a"))), plt.ByteString(b""), ), )
def constr_type(self) ‑> InstanceType
-
Inherited from:
AtomicType
.constr_type
The type of the constructor for this class
Expand source code
def constr_type(self) -> InstanceType: return InstanceType( FunctionType( [InstanceType(ListType(IntegerInstanceType))], InstanceType(self) ) )
class ClassType
-
ClassType()
Expand source code
class ClassType(Type): def __ge__(self, other): raise NotImplementedError("Comparison between raw classtypes impossible")
Ancestors
Subclasses
- HashType
- AnyType
- AtomicType
- DictType
- FunctionType
- InaccessibleType
- ListType
- PairType
- PolymorphicFunctionType
- RecordType
- TupleType
- UnionType
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
Type
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
def attribute_type(self, attr) ‑> Type
-
Inherited from:
Type
.attribute_type
The types of the named attributes of this class
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
def constr(self) ‑> pluthon.pluthon_ast.AST
-
The constructor for this class
def constr_type(self) ‑> InstanceType
-
Inherited from:
Type
.constr_type
The type of the constructor for this class
class DictType (key_typ: Type, value_typ: Type)
-
DictType(key_typ: hebi.typed_ast.Type, value_typ: hebi.typed_ast.Type)
Expand source code
class DictType(ClassType): key_typ: Type value_typ: Type def attribute_type(self, attr) -> "Type": if attr == "get": return InstanceType( FunctionType([self.key_typ, self.value_typ], self.value_typ) ) if attr == "keys": return InstanceType(FunctionType([], InstanceType(ListType(self.key_typ)))) if attr == "values": return InstanceType( FunctionType([], InstanceType(ListType(self.value_typ))) ) if attr == "items": return InstanceType( FunctionType( [], InstanceType( ListType(InstanceType(PairType(self.key_typ, self.value_typ))) ), ) ) raise TypeInferenceError( f"Type of attribute '{attr}' is unknown for type Dict." ) def attribute(self, attr) -> plt.AST: if attr == "get": return plt.Lambda( ["self", "_", "key", "default"], transform_ext_params_map(self.value_typ)( plt.SndPair( plt.FindList( plt.Var("self"), plt.Lambda( ["x"], plt.EqualsData( transform_output_map(self.key_typ)(plt.Var("key")), plt.FstPair(plt.Var("x")), ), ), # this is a bit ugly... we wrap - only to later unwrap again plt.MkPairData( transform_output_map(self.key_typ)(plt.Var("key")), transform_output_map(self.value_typ)( plt.Var("default") ), ), ), ), ), ) if attr == "keys": return plt.Lambda( ["self", "_"], plt.MapList( plt.Var("self"), plt.Lambda( ["x"], transform_ext_params_map(self.key_typ)( plt.FstPair(plt.Var("x")) ), ), empty_list(self.key_typ), ), ) if attr == "values": return plt.Lambda( ["self", "_"], plt.MapList( plt.Var("self"), plt.Lambda( ["x"], transform_ext_params_map(self.value_typ)( plt.SndPair(plt.Var("x")) ), ), empty_list(self.value_typ), ), ) if attr == "items": return plt.Lambda( ["self", "_"], plt.Var("self"), ) raise NotImplementedError(f"Attribute '{attr}' of Dict is unknown.") def __ge__(self, other): return ( isinstance(other, DictType) and self.key_typ >= other.key_typ and self.value_typ >= other.value_typ )
Ancestors
Class variables
var key_typ : Type
var value_typ : Type
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
Expand source code
def attribute(self, attr) -> plt.AST: if attr == "get": return plt.Lambda( ["self", "_", "key", "default"], transform_ext_params_map(self.value_typ)( plt.SndPair( plt.FindList( plt.Var("self"), plt.Lambda( ["x"], plt.EqualsData( transform_output_map(self.key_typ)(plt.Var("key")), plt.FstPair(plt.Var("x")), ), ), # this is a bit ugly... we wrap - only to later unwrap again plt.MkPairData( transform_output_map(self.key_typ)(plt.Var("key")), transform_output_map(self.value_typ)( plt.Var("default") ), ), ), ), ), ) if attr == "keys": return plt.Lambda( ["self", "_"], plt.MapList( plt.Var("self"), plt.Lambda( ["x"], transform_ext_params_map(self.key_typ)( plt.FstPair(plt.Var("x")) ), ), empty_list(self.key_typ), ), ) if attr == "values": return plt.Lambda( ["self", "_"], plt.MapList( plt.Var("self"), plt.Lambda( ["x"], transform_ext_params_map(self.value_typ)( plt.SndPair(plt.Var("x")) ), ), empty_list(self.value_typ), ), ) if attr == "items": return plt.Lambda( ["self", "_"], plt.Var("self"), ) raise NotImplementedError(f"Attribute '{attr}' of Dict is unknown.")
def attribute_type(self, attr) ‑> Type
-
Inherited from:
ClassType
.attribute_type
The types of the named attributes of this class
Expand source code
def attribute_type(self, attr) -> "Type": if attr == "get": return InstanceType( FunctionType([self.key_typ, self.value_typ], self.value_typ) ) if attr == "keys": return InstanceType(FunctionType([], InstanceType(ListType(self.key_typ)))) if attr == "values": return InstanceType( FunctionType([], InstanceType(ListType(self.value_typ))) ) if attr == "items": return InstanceType( FunctionType( [], InstanceType( ListType(InstanceType(PairType(self.key_typ, self.value_typ))) ), ) ) raise TypeInferenceError( f"Type of attribute '{attr}' is unknown for type Dict." )
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.constr
The constructor for this class
def constr_type(self) ‑> InstanceType
-
Inherited from:
ClassType
.constr_type
The type of the constructor for this class
class FunctionType (argtyps: List[Type], rettyp: Type)
-
FunctionType(argtyps: List[hebi.typed_ast.Type], rettyp: hebi.typed_ast.Type)
Expand source code
class FunctionType(ClassType): argtyps: typing.List[Type] rettyp: Type def __ge__(self, other): return ( isinstance(other, FunctionType) and all(a >= oa for a, oa in zip(self.argtyps, other.argtyps)) and other.rettyp >= self.rettyp )
Ancestors
Class variables
var argtyps : List[Type]
var rettyp : Type
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
def attribute_type(self, attr) ‑> Type
-
Inherited from:
ClassType
.attribute_type
The types of the named attributes of this class
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.constr
The constructor for this class
def constr_type(self) ‑> InstanceType
-
Inherited from:
ClassType
.constr_type
The type of the constructor for this class
class InaccessibleType
-
A type that blocks overwriting of a function
Expand source code
class InaccessibleType(ClassType): """A type that blocks overwriting of a function""" pass
Ancestors
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
def attribute_type(self, attr) ‑> Type
-
Inherited from:
ClassType
.attribute_type
The types of the named attributes of this class
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.constr
The constructor for this class
def constr_type(self) ‑> InstanceType
-
Inherited from:
ClassType
.constr_type
The type of the constructor for this class
class InstanceType (typ: ClassType)
-
InstanceType(typ: hebi.typed_ast.ClassType)
Expand source code
class InstanceType(Type): typ: ClassType def constr_type(self) -> FunctionType: raise TypeInferenceError(f"Can not construct an instance {self}") def constr(self) -> plt.AST: raise NotImplementedError(f"Can not construct an instance {self}") def attribute_type(self, attr) -> Type: return self.typ.attribute_type(attr) def attribute(self, attr) -> plt.AST: return self.typ.attribute(attr) def cmp(self, op: cmpop, o: "Type") -> plt.AST: """The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second the comparison.""" if isinstance(o, InstanceType): return self.typ.cmp(op, o.typ) return super().cmp(op, o) def __ge__(self, other): return isinstance(other, InstanceType) and self.typ >= other.typ
Ancestors
Subclasses
Class variables
var typ : ClassType
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
Type
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
Expand source code
def attribute(self, attr) -> plt.AST: return self.typ.attribute(attr)
def attribute_type(self, attr) ‑> Type
-
Inherited from:
Type
.attribute_type
The types of the named attributes of this class
Expand source code
def attribute_type(self, attr) -> Type: return self.typ.attribute_type(attr)
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
Expand source code
def cmp(self, op: cmpop, o: "Type") -> plt.AST: """The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second the comparison.""" if isinstance(o, InstanceType): return self.typ.cmp(op, o.typ) return super().cmp(op, o)
def constr(self) ‑> pluthon.pluthon_ast.AST
-
The constructor for this class
Expand source code
def constr(self) -> plt.AST: raise NotImplementedError(f"Can not construct an instance {self}")
def constr_type(self) ‑> FunctionType
-
Inherited from:
Type
.constr_type
The type of the constructor for this class
Expand source code
def constr_type(self) -> FunctionType: raise TypeInferenceError(f"Can not construct an instance {self}")
class IntegerType
-
IntegerType()
Expand source code
class IntegerType(AtomicType): def constr_type(self) -> InstanceType: return InstanceType(FunctionType([StringInstanceType], InstanceType(self))) def constr(self) -> plt.AST: # TODO we need to strip the string implicitely before parsing it return plt.Lambda( ["_", "x"], plt.Let( [ ("e", plt.EncodeUtf8(plt.Var("x"))), ("first_int", plt.IndexByteString(plt.Var("e"), plt.Integer(0))), ("len", plt.LengthOfByteString(plt.Var("e"))), ( "fold_start", plt.Lambda( ["start"], plt.FoldList( plt.Range(plt.Var("len"), plt.Var("start")), plt.Lambda( ["s", "i"], plt.Let( [ ( "b", plt.IndexByteString( plt.Var("e"), plt.Var("i") ), ) ], plt.Ite( plt.EqualsInteger( plt.Var("b"), plt.Integer(ord("_")) ), plt.Var("s"), plt.Ite( plt.Or( plt.LessThanInteger( plt.Var("b"), plt.Integer(ord("0")), ), plt.LessThanInteger( plt.Integer(ord("9")), plt.Var("b"), ), ), plt.TraceError( "ValueError: invalid literal for int() with base 10" ), plt.AddInteger( plt.SubtractInteger( plt.Var("b"), plt.Integer(ord("0")), ), plt.MultiplyInteger( plt.Var("s"), plt.Integer(10) ), ), ), ), ), ), plt.Integer(0), ), ), ), ], plt.Ite( plt.Or( plt.EqualsInteger(plt.Var("len"), plt.Integer(0)), plt.EqualsInteger( plt.Var("first_int"), plt.Integer(ord("_")), ), ), plt.TraceError( "ValueError: invalid literal for int() with base 10" ), plt.Ite( plt.EqualsInteger( plt.Var("first_int"), plt.Integer(ord("-")), ), plt.Negate( plt.Apply(plt.Var("fold_start"), plt.Integer(1)), ), plt.Apply(plt.Var("fold_start"), plt.Integer(0)), ), ), ), ) def cmp(self, op: cmpop, o: "Type") -> plt.AST: """The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second the comparison.""" if isinstance(o, BoolType): if isinstance(op, Eq): # 1 == True # 0 == False # all other comparisons are False return plt.Lambda( ["x", "y"], plt.Ite( plt.Var("y"), plt.EqualsInteger(plt.Var("x"), plt.Integer(1)), plt.EqualsInteger(plt.Var("x"), plt.Integer(0)), ), ) if isinstance(o, IntegerType): if isinstance(op, Eq): return plt.BuiltIn(uplc.BuiltInFun.EqualsInteger) if isinstance(op, NotEq): return plt.Lambda( ["x", "y"], plt.Not( plt.Apply( plt.BuiltIn(uplc.BuiltInFun.EqualsInteger), plt.Var("y"), plt.Var("x"), ) ), ) if isinstance(op, LtE): return plt.BuiltIn(uplc.BuiltInFun.LessThanEqualsInteger) if isinstance(op, Lt): return plt.BuiltIn(uplc.BuiltInFun.LessThanInteger) if isinstance(op, Gt): return plt.Lambda( ["x", "y"], plt.Apply( plt.BuiltIn(uplc.BuiltInFun.LessThanInteger), plt.Var("y"), plt.Var("x"), ), ) if isinstance(op, GtE): return plt.Lambda( ["x", "y"], plt.Apply( plt.BuiltIn(uplc.BuiltInFun.LessThanEqualsInteger), plt.Var("y"), plt.Var("x"), ), ) if ( isinstance(o, ListType) and isinstance(o.typ, InstanceType) and isinstance(o.typ.typ, IntegerType) ): if isinstance(op, In): return plt.Lambda( ["x", "y"], plt.EqualsInteger( plt.Var("x"), plt.FindList( plt.Var("y"), plt.Apply( plt.BuiltIn(uplc.BuiltInFun.EqualsInteger), plt.Var("x") ), # this simply ensures the default is always unequal to the searched value plt.AddInteger(plt.Var("x"), plt.Integer(1)), ), ), ) return super().cmp(op, o)
Ancestors
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
AtomicType
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
def attribute_type(self, attr) ‑> Type
-
Inherited from:
AtomicType
.attribute_type
The types of the named attributes of this class
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
AtomicType
.cmp
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
Expand source code
def cmp(self, op: cmpop, o: "Type") -> plt.AST: """The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second the comparison.""" if isinstance(o, BoolType): if isinstance(op, Eq): # 1 == True # 0 == False # all other comparisons are False return plt.Lambda( ["x", "y"], plt.Ite( plt.Var("y"), plt.EqualsInteger(plt.Var("x"), plt.Integer(1)), plt.EqualsInteger(plt.Var("x"), plt.Integer(0)), ), ) if isinstance(o, IntegerType): if isinstance(op, Eq): return plt.BuiltIn(uplc.BuiltInFun.EqualsInteger) if isinstance(op, NotEq): return plt.Lambda( ["x", "y"], plt.Not( plt.Apply( plt.BuiltIn(uplc.BuiltInFun.EqualsInteger), plt.Var("y"), plt.Var("x"), ) ), ) if isinstance(op, LtE): return plt.BuiltIn(uplc.BuiltInFun.LessThanEqualsInteger) if isinstance(op, Lt): return plt.BuiltIn(uplc.BuiltInFun.LessThanInteger) if isinstance(op, Gt): return plt.Lambda( ["x", "y"], plt.Apply( plt.BuiltIn(uplc.BuiltInFun.LessThanInteger), plt.Var("y"), plt.Var("x"), ), ) if isinstance(op, GtE): return plt.Lambda( ["x", "y"], plt.Apply( plt.BuiltIn(uplc.BuiltInFun.LessThanEqualsInteger), plt.Var("y"), plt.Var("x"), ), ) if ( isinstance(o, ListType) and isinstance(o.typ, InstanceType) and isinstance(o.typ.typ, IntegerType) ): if isinstance(op, In): return plt.Lambda( ["x", "y"], plt.EqualsInteger( plt.Var("x"), plt.FindList( plt.Var("y"), plt.Apply( plt.BuiltIn(uplc.BuiltInFun.EqualsInteger), plt.Var("x") ), # this simply ensures the default is always unequal to the searched value plt.AddInteger(plt.Var("x"), plt.Integer(1)), ), ), ) return super().cmp(op, o)
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
AtomicType
.constr
The constructor for this class
Expand source code
def constr(self) -> plt.AST: # TODO we need to strip the string implicitely before parsing it return plt.Lambda( ["_", "x"], plt.Let( [ ("e", plt.EncodeUtf8(plt.Var("x"))), ("first_int", plt.IndexByteString(plt.Var("e"), plt.Integer(0))), ("len", plt.LengthOfByteString(plt.Var("e"))), ( "fold_start", plt.Lambda( ["start"], plt.FoldList( plt.Range(plt.Var("len"), plt.Var("start")), plt.Lambda( ["s", "i"], plt.Let( [ ( "b", plt.IndexByteString( plt.Var("e"), plt.Var("i") ), ) ], plt.Ite( plt.EqualsInteger( plt.Var("b"), plt.Integer(ord("_")) ), plt.Var("s"), plt.Ite( plt.Or( plt.LessThanInteger( plt.Var("b"), plt.Integer(ord("0")), ), plt.LessThanInteger( plt.Integer(ord("9")), plt.Var("b"), ), ), plt.TraceError( "ValueError: invalid literal for int() with base 10" ), plt.AddInteger( plt.SubtractInteger( plt.Var("b"), plt.Integer(ord("0")), ), plt.MultiplyInteger( plt.Var("s"), plt.Integer(10) ), ), ), ), ), ), plt.Integer(0), ), ), ), ], plt.Ite( plt.Or( plt.EqualsInteger(plt.Var("len"), plt.Integer(0)), plt.EqualsInteger( plt.Var("first_int"), plt.Integer(ord("_")), ), ), plt.TraceError( "ValueError: invalid literal for int() with base 10" ), plt.Ite( plt.EqualsInteger( plt.Var("first_int"), plt.Integer(ord("-")), ), plt.Negate( plt.Apply(plt.Var("fold_start"), plt.Integer(1)), ), plt.Apply(plt.Var("fold_start"), plt.Integer(0)), ), ), ), )
def constr_type(self) ‑> InstanceType
-
Inherited from:
AtomicType
.constr_type
The type of the constructor for this class
Expand source code
def constr_type(self) -> InstanceType: return InstanceType(FunctionType([StringInstanceType], InstanceType(self)))
class ListType (typ: Type)
-
ListType(typ: hebi.typed_ast.Type)
Expand source code
class ListType(ClassType): typ: Type def __ge__(self, other): return isinstance(other, ListType) and self.typ >= other.typ
Ancestors
Class variables
var typ : Type
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
def attribute_type(self, attr) ‑> Type
-
Inherited from:
ClassType
.attribute_type
The types of the named attributes of this class
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.constr
The constructor for this class
def constr_type(self) ‑> InstanceType
-
Inherited from:
ClassType
.constr_type
The type of the constructor for this class
class PairType (l_typ: Type, r_typ: Type)
-
An internal type representing built-in PlutusData pairs
Expand source code
class PairType(ClassType): """An internal type representing built-in PlutusData pairs""" l_typ: Type r_typ: Type def __ge__(self, other): return isinstance(other, PairType) and all( t >= ot for t, ot in zip((self.l_typ, self.r_typ), (other.l_typ, other.r_typ)) )
Ancestors
Class variables
var l_typ : Type
var r_typ : Type
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
def attribute_type(self, attr) ‑> Type
-
Inherited from:
ClassType
.attribute_type
The types of the named attributes of this class
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.constr
The constructor for this class
def constr_type(self) ‑> InstanceType
-
Inherited from:
ClassType
.constr_type
The type of the constructor for this class
class PolymorphicFunction
-
Expand source code
class PolymorphicFunction: def type_from_args(self, args: typing.List[Type]) -> FunctionType: raise NotImplementedError() def impl_from_args(self, args: typing.List[Type]) -> plt.AST: raise NotImplementedError()
Subclasses
Methods
def impl_from_args(self, args: List[Type]) ‑> pluthon.pluthon_ast.AST
-
Expand source code
def impl_from_args(self, args: typing.List[Type]) -> plt.AST: raise NotImplementedError()
def type_from_args(self, args: List[Type]) ‑> FunctionType
-
Expand source code
def type_from_args(self, args: typing.List[Type]) -> FunctionType: raise NotImplementedError()
class PolymorphicFunctionInstanceType (typ: FunctionType, polymorphic_function: PolymorphicFunction)
-
PolymorphicFunctionInstanceType(typ: hebi.typed_ast.FunctionType, polymorphic_function: hebi.typed_ast.PolymorphicFunction)
Expand source code
class PolymorphicFunctionInstanceType(InstanceType): typ: FunctionType polymorphic_function: PolymorphicFunction
Ancestors
Class variables
var polymorphic_function : PolymorphicFunction
var typ : FunctionType
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
InstanceType
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
def attribute_type(self, attr) ‑> Type
-
Inherited from:
InstanceType
.attribute_type
The types of the named attributes of this class
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
InstanceType
.cmp
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
InstanceType
.constr
The constructor for this class
def constr_type(self) ‑> FunctionType
-
Inherited from:
InstanceType
.constr_type
The type of the constructor for this class
class PolymorphicFunctionType (polymorphic_function: PolymorphicFunction)
-
A special type of builtin that may act differently on different parameters
Expand source code
class PolymorphicFunctionType(ClassType): """A special type of builtin that may act differently on different parameters""" polymorphic_function: PolymorphicFunction
Ancestors
Class variables
var polymorphic_function : PolymorphicFunction
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
def attribute_type(self, attr) ‑> Type
-
Inherited from:
ClassType
.attribute_type
The types of the named attributes of this class
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.constr
The constructor for this class
def constr_type(self) ‑> InstanceType
-
Inherited from:
ClassType
.constr_type
The type of the constructor for this class
class RawPlutoExpr (*args, **kwargs)
-
Expand source code
class RawPlutoExpr(typedexpr): typ: Type expr: plt.AST
Ancestors
Class variables
var expr : pluthon.pluthon_ast.AST
var typ : Type
class Record (name: str, constructor: int, fields: Union[List[Tuple[str, Type]], frozenlist._frozenlist.FrozenList])
-
Record(name: str, constructor: int, fields: Union[List[Tuple[str, hebi.typed_ast.Type]], frozenlist._frozenlist.FrozenList])
Expand source code
class Record: name: str constructor: int fields: typing.Union[typing.List[typing.Tuple[str, Type]], FrozenList]
Class variables
var constructor : int
var fields : Union[List[Tuple[str, Type]], frozenlist._frozenlist.FrozenList]
var name : str
class RecordType (record: Record)
-
RecordType(record: hebi.typed_ast.Record)
Expand source code
class RecordType(ClassType): record: Record def constr_type(self) -> "InstanceType": return InstanceType( FunctionType([f[1] for f in self.record.fields], InstanceType(self)) ) def constr(self) -> plt.AST: # wrap all constructor values to PlutusData build_constr_params = plt.EmptyDataList() for n, t in reversed(self.record.fields): build_constr_params = plt.MkCons( transform_output_map(t)(plt.Var(n)), build_constr_params ) # then build a constr type with this PlutusData return plt.Lambda( ["_"] + [n for n, _ in self.record.fields], plt.ConstrData(plt.Integer(self.record.constructor), build_constr_params), ) def attribute_type(self, attr: str) -> Type: """The types of the named attributes of this class""" if attr == "CONSTR_ID": return IntegerInstanceType for n, t in self.record.fields: if n == attr: return t raise TypeInferenceError( f"Type {self.record.name} does not have attribute {attr}" ) def attribute(self, attr: str) -> plt.AST: """The attributes of this class. Need to be a lambda that expects as first argument the object itself""" if attr == "CONSTR_ID": # access to constructor return plt.Lambda( ["self"], plt.Constructor(plt.Var("self")), ) attr_typ = self.attribute_type(attr) pos = next(i for i, (n, _) in enumerate(self.record.fields) if n == attr) # access to normal fields return plt.Lambda( ["self"], transform_ext_params_map(attr_typ)( plt.NthField( plt.Var("self"), plt.Integer(pos), ), ), ) def cmp(self, op: cmpop, o: "Type") -> plt.AST: """The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second the comparison.""" # this will reject comparisons that will always be false - most likely due to faults during programming if (isinstance(o, RecordType) and o.record == self.record) or ( isinstance(o, UnionType) and self in o.typs ): if isinstance(op, Eq): return plt.BuiltIn(uplc.BuiltInFun.EqualsData) if isinstance(op, NotEq): return plt.Lambda( ["x", "y"], plt.Not( plt.Apply( plt.BuiltIn(uplc.BuiltInFun.EqualsData), plt.Var("x"), plt.Var("y"), ) ), ) if ( isinstance(o, ListType) and isinstance(o.typ, InstanceType) and o.typ.typ >= self ): if isinstance(op, In): return plt.Lambda( ["x", "y"], plt.EqualsData( plt.Var("x"), plt.FindList( plt.Var("y"), plt.Apply( plt.BuiltIn(uplc.BuiltInFun.EqualsData), plt.Var("x") ), # this simply ensures the default is always unequal to the searched value plt.ConstrData( plt.AddInteger( plt.Constructor(plt.Var("x")), plt.Integer(1) ), plt.MkNilData(plt.Unit()), ), ), ), ) return super().cmp(op, o) def __ge__(self, other): # Can only substitute for its own type, records need to be equal # if someone wants to be funny, they can implement <= to be true if all fields match up to some point return isinstance(other, self.__class__) and other.record == self.record
Ancestors
Class variables
var record : Record
Methods
def attribute(self, attr: str) ‑> pluthon.pluthon_ast.AST
-
The attributes of this class. Need to be a lambda that expects as first argument the object itself
Expand source code
def attribute(self, attr: str) -> plt.AST: """The attributes of this class. Need to be a lambda that expects as first argument the object itself""" if attr == "CONSTR_ID": # access to constructor return plt.Lambda( ["self"], plt.Constructor(plt.Var("self")), ) attr_typ = self.attribute_type(attr) pos = next(i for i, (n, _) in enumerate(self.record.fields) if n == attr) # access to normal fields return plt.Lambda( ["self"], transform_ext_params_map(attr_typ)( plt.NthField( plt.Var("self"), plt.Integer(pos), ), ), )
def attribute_type(self, attr: str) ‑> Type
-
Inherited from:
ClassType
.attribute_type
The types of the named attributes of this class
Expand source code
def attribute_type(self, attr: str) -> Type: """The types of the named attributes of this class""" if attr == "CONSTR_ID": return IntegerInstanceType for n, t in self.record.fields: if n == attr: return t raise TypeInferenceError( f"Type {self.record.name} does not have attribute {attr}" )
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
Expand source code
def cmp(self, op: cmpop, o: "Type") -> plt.AST: """The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second the comparison.""" # this will reject comparisons that will always be false - most likely due to faults during programming if (isinstance(o, RecordType) and o.record == self.record) or ( isinstance(o, UnionType) and self in o.typs ): if isinstance(op, Eq): return plt.BuiltIn(uplc.BuiltInFun.EqualsData) if isinstance(op, NotEq): return plt.Lambda( ["x", "y"], plt.Not( plt.Apply( plt.BuiltIn(uplc.BuiltInFun.EqualsData), plt.Var("x"), plt.Var("y"), ) ), ) if ( isinstance(o, ListType) and isinstance(o.typ, InstanceType) and o.typ.typ >= self ): if isinstance(op, In): return plt.Lambda( ["x", "y"], plt.EqualsData( plt.Var("x"), plt.FindList( plt.Var("y"), plt.Apply( plt.BuiltIn(uplc.BuiltInFun.EqualsData), plt.Var("x") ), # this simply ensures the default is always unequal to the searched value plt.ConstrData( plt.AddInteger( plt.Constructor(plt.Var("x")), plt.Integer(1) ), plt.MkNilData(plt.Unit()), ), ), ), ) return super().cmp(op, o)
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.constr
The constructor for this class
Expand source code
def constr(self) -> plt.AST: # wrap all constructor values to PlutusData build_constr_params = plt.EmptyDataList() for n, t in reversed(self.record.fields): build_constr_params = plt.MkCons( transform_output_map(t)(plt.Var(n)), build_constr_params ) # then build a constr type with this PlutusData return plt.Lambda( ["_"] + [n for n, _ in self.record.fields], plt.ConstrData(plt.Integer(self.record.constructor), build_constr_params), )
def constr_type(self) ‑> InstanceType
-
Inherited from:
ClassType
.constr_type
The type of the constructor for this class
Expand source code
def constr_type(self) -> "InstanceType": return InstanceType( FunctionType([f[1] for f in self.record.fields], InstanceType(self)) )
class StringType
-
StringType()
Expand source code
class StringType(AtomicType): def constr_type(self) -> InstanceType: return InstanceType(FunctionType([IntegerInstanceType], InstanceType(self))) def constr(self) -> plt.AST: # constructs a string representation of an integer return plt.Lambda( ["_", "x"], plt.DecodeUtf8( plt.Let( [ ( "strlist", plt.RecFun( plt.Lambda( ["f", "i"], plt.Ite( plt.LessThanEqualsInteger( plt.Var("i"), plt.Integer(0) ), plt.EmptyIntegerList(), plt.MkCons( plt.AddInteger( plt.ModInteger( plt.Var("i"), plt.Integer(10) ), plt.Integer(ord("0")), ), plt.Apply( plt.Var("f"), plt.Var("f"), plt.DivideInteger( plt.Var("i"), plt.Integer(10) ), ), ), ), ), ), ), ( "mkstr", plt.Lambda( ["i"], plt.FoldList( plt.Apply(plt.Var("strlist"), plt.Var("i")), plt.Lambda( ["b", "i"], plt.ConsByteString(plt.Var("i"), plt.Var("b")), ), plt.ByteString(b""), ), ), ), ], plt.Ite( plt.EqualsInteger(plt.Var("x"), plt.Integer(0)), plt.ByteString(b"0"), plt.Ite( plt.LessThanInteger(plt.Var("x"), plt.Integer(0)), plt.ConsByteString( plt.Integer(ord("-")), plt.Apply(plt.Var("mkstr"), plt.Negate(plt.Var("x"))), ), plt.Apply(plt.Var("mkstr"), plt.Var("x")), ), ), ) ), ) def attribute_type(self, attr) -> Type: if attr == "encode": return InstanceType(FunctionType([], ByteStringInstanceType)) return super().attribute_type(attr) def attribute(self, attr) -> plt.AST: if attr == "encode": # No codec -> only the default (utf8) is allowed return plt.Lambda(["x", "_"], plt.EncodeUtf8(plt.Var("x"))) return super().attribute(attr) def cmp(self, op: cmpop, o: "Type") -> plt.AST: if isinstance(o, StringType): if isinstance(op, Eq): return plt.BuiltIn(uplc.BuiltInFun.EqualsString) return super().cmp(op, o)
Ancestors
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
AtomicType
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
Expand source code
def attribute(self, attr) -> plt.AST: if attr == "encode": # No codec -> only the default (utf8) is allowed return plt.Lambda(["x", "_"], plt.EncodeUtf8(plt.Var("x"))) return super().attribute(attr)
def attribute_type(self, attr) ‑> Type
-
Inherited from:
AtomicType
.attribute_type
The types of the named attributes of this class
Expand source code
def attribute_type(self, attr) -> Type: if attr == "encode": return InstanceType(FunctionType([], ByteStringInstanceType)) return super().attribute_type(attr)
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
AtomicType
.cmp
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
Expand source code
def cmp(self, op: cmpop, o: "Type") -> plt.AST: if isinstance(o, StringType): if isinstance(op, Eq): return plt.BuiltIn(uplc.BuiltInFun.EqualsString) return super().cmp(op, o)
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
AtomicType
.constr
The constructor for this class
Expand source code
def constr(self) -> plt.AST: # constructs a string representation of an integer return plt.Lambda( ["_", "x"], plt.DecodeUtf8( plt.Let( [ ( "strlist", plt.RecFun( plt.Lambda( ["f", "i"], plt.Ite( plt.LessThanEqualsInteger( plt.Var("i"), plt.Integer(0) ), plt.EmptyIntegerList(), plt.MkCons( plt.AddInteger( plt.ModInteger( plt.Var("i"), plt.Integer(10) ), plt.Integer(ord("0")), ), plt.Apply( plt.Var("f"), plt.Var("f"), plt.DivideInteger( plt.Var("i"), plt.Integer(10) ), ), ), ), ), ), ), ( "mkstr", plt.Lambda( ["i"], plt.FoldList( plt.Apply(plt.Var("strlist"), plt.Var("i")), plt.Lambda( ["b", "i"], plt.ConsByteString(plt.Var("i"), plt.Var("b")), ), plt.ByteString(b""), ), ), ), ], plt.Ite( plt.EqualsInteger(plt.Var("x"), plt.Integer(0)), plt.ByteString(b"0"), plt.Ite( plt.LessThanInteger(plt.Var("x"), plt.Integer(0)), plt.ConsByteString( plt.Integer(ord("-")), plt.Apply(plt.Var("mkstr"), plt.Negate(plt.Var("x"))), ), plt.Apply(plt.Var("mkstr"), plt.Var("x")), ), ), ) ), )
def constr_type(self) ‑> InstanceType
-
Inherited from:
AtomicType
.constr_type
The type of the constructor for this class
Expand source code
def constr_type(self) -> InstanceType: return InstanceType(FunctionType([IntegerInstanceType], InstanceType(self)))
class TupleType (typs: List[Type])
-
TupleType(typs: List[hebi.typed_ast.Type])
Expand source code
class TupleType(ClassType): typs: typing.List[Type] def __ge__(self, other): return isinstance(other, TupleType) and all( t >= ot for t, ot in zip(self.typs, other.typs) )
Ancestors
Class variables
var typs : List[Type]
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
def attribute_type(self, attr) ‑> Type
-
Inherited from:
ClassType
.attribute_type
The types of the named attributes of this class
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.constr
The constructor for this class
def constr_type(self) ‑> InstanceType
-
Inherited from:
ClassType
.constr_type
The type of the constructor for this class
class Type
-
Expand source code
class Type: def constr_type(self) -> "InstanceType": """The type of the constructor for this class""" raise TypeInferenceError( f"Object of type {self.__class__} does not have a constructor" ) def constr(self) -> plt.AST: """The constructor for this class""" raise NotImplementedError(f"Constructor of {self.__class__} not implemented") def attribute_type(self, attr) -> "Type": """The types of the named attributes of this class""" raise TypeInferenceError( f"Object of type {self.__class__} does not have attribute {attr}" ) def attribute(self, attr) -> plt.AST: """The attributes of this class. Needs to be a lambda that expects as first argument the object itself""" raise NotImplementedError(f"Attribute {attr} not implemented for type {self}") def cmp(self, op: cmpop, o: "Type") -> plt.AST: """The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second the comparison.""" raise NotImplementedError( f"Comparison {type(op).__name__} for {self.__class__.__name__} and {o.__class__.__name__} is not implemented. This is likely intended because it would always evaluate to False." )
Subclasses
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
Expand source code
def attribute(self, attr) -> plt.AST: """The attributes of this class. Needs to be a lambda that expects as first argument the object itself""" raise NotImplementedError(f"Attribute {attr} not implemented for type {self}")
def attribute_type(self, attr) ‑> Type
-
The types of the named attributes of this class
Expand source code
def attribute_type(self, attr) -> "Type": """The types of the named attributes of this class""" raise TypeInferenceError( f"Object of type {self.__class__} does not have attribute {attr}" )
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second the comparison.
Expand source code
def cmp(self, op: cmpop, o: "Type") -> plt.AST: """The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second the comparison.""" raise NotImplementedError( f"Comparison {type(op).__name__} for {self.__class__.__name__} and {o.__class__.__name__} is not implemented. This is likely intended because it would always evaluate to False." )
def constr(self) ‑> pluthon.pluthon_ast.AST
-
The constructor for this class
Expand source code
def constr(self) -> plt.AST: """The constructor for this class""" raise NotImplementedError(f"Constructor of {self.__class__} not implemented")
def constr_type(self) ‑> InstanceType
-
The type of the constructor for this class
Expand source code
def constr_type(self) -> "InstanceType": """The type of the constructor for this class""" raise TypeInferenceError( f"Object of type {self.__class__} does not have a constructor" )
class TypeInferenceError (*args, **kwargs)
-
Assertion failed.
Expand source code
class TypeInferenceError(AssertionError): pass
Ancestors
- builtins.AssertionError
- builtins.Exception
- builtins.BaseException
class TypedAST (*args, **kwargs)
-
Expand source code
class TypedAST(AST): typ: Type
Ancestors
- _ast.AST
Subclasses
Class variables
var typ : Type
class TypedAnnAssign (*args, **kwargs)
-
Expand source code
class TypedAnnAssign(typedstmt, AnnAssign): target: typedexpr annotation: Type value: typedexpr
Ancestors
Class variables
var annotation : Type
var target : typedexpr
var value : typedexpr
class TypedAssert (*args, **kwargs)
-
Expand source code
class TypedAssert(typedstmt, Assert): test: typedexpr msg: typedexpr
Ancestors
Class variables
var msg : typedexpr
var test : typedexpr
class TypedAssign (*args, **kwargs)
-
Expand source code
class TypedAssign(typedstmt, Assign): targets: typing.List[typedexpr] value: typedexpr
Ancestors
Class variables
var targets : List[typedexpr]
var value : typedexpr
class TypedAttribute (*args, **kwargs)
-
Expand source code
class TypedAttribute(typedexpr, Attribute): value: typedexpr pos: int
Ancestors
Class variables
var pos : int
var value : typedexpr
class TypedBinOp (*args, **kwargs)
-
Expand source code
class TypedBinOp(typedexpr, BinOp): left: typedexpr right: typedexpr
Ancestors
Class variables
var left : typedexpr
var right : typedexpr
class TypedBoolOp (*args, **kwargs)
-
Expand source code
class TypedBoolOp(typedexpr, BoolOp): values: typing.List[typedexpr]
Ancestors
Class variables
var values : List[typedexpr]
class TypedCall (*args, **kwargs)
-
Expand source code
class TypedCall(typedexpr, Call): func: typedexpr args: typing.List[typedexpr]
Ancestors
Class variables
var args : List[typedexpr]
var func : typedexpr
class TypedClassDef (*args, **kwargs)
-
Expand source code
class TypedClassDef(typedstmt, ClassDef): class_typ: Type
Ancestors
Class variables
var class_typ : Type
class TypedCompare (*args, **kwargs)
-
Expand source code
class TypedCompare(typedexpr, Compare): left: typedexpr ops: typing.List[cmpop] comparators: typing.List[typedexpr]
Ancestors
Class variables
var comparators : List[typedexpr]
var left : typedexpr
var ops : List[_ast.cmpop]
class TypedConstant (*args, **kwargs)
-
Expand source code
class TypedConstant(TypedAST, Constant): pass
Ancestors
- TypedAST
- _ast.Constant
- _ast.expr
- _ast.AST
Class variables
var typ : Type
class TypedDict (*args, **kwargs)
-
Expand source code
class TypedDict(typedexpr, Dict): pass
Ancestors
Class variables
var typ : Type
class TypedExpr (*args, **kwargs)
-
Expand source code
class TypedExpr(typedstmt, Expr): value: typedexpr
Ancestors
Class variables
var value : typedexpr
class TypedExpression (*args, **kwargs)
-
Expand source code
class TypedExpression(typedexpr, Expression): body: typedexpr
Ancestors
Class variables
var body : typedexpr
class TypedFor (*args, **kwargs)
-
Expand source code
class TypedFor(typedstmt, For): target: typedexpr iter: typedexpr body: typing.List[typedstmt] orelse: typing.List[typedstmt]
Ancestors
Class variables
var body : List[typedstmt]
var iter : typedexpr
var orelse : List[typedstmt]
var target : typedexpr
class TypedFunctionDef (*args, **kwargs)
-
Expand source code
class TypedFunctionDef(typedstmt, FunctionDef): body: typing.List[typedstmt] args: arguments
Ancestors
Class variables
var args : _ast.arguments
var body : List[typedstmt]
class TypedIf (*args, **kwargs)
-
Expand source code
class TypedIf(typedstmt, If): test: typedexpr body: typing.List[typedstmt] orelse: typing.List[typedstmt]
Ancestors
Class variables
var body : List[typedstmt]
var orelse : List[typedstmt]
var test : typedexpr
class TypedIfExp (*args, **kwargs)
-
Expand source code
class TypedIfExp(typedstmt, IfExp): test: typedexpr body: typedexpr orelse: typedexpr
Ancestors
Class variables
var body : typedexpr
var orelse : typedexpr
var test : typedexpr
class TypedList (*args, **kwargs)
-
Expand source code
class TypedList(typedexpr, List): pass
Ancestors
Class variables
var typ : Type
class TypedListComp (*args, **kwargs)
-
Expand source code
class TypedListComp(typedexpr, ListComp): generators: typing.List[typedcomprehension] elt: typedexpr
Ancestors
Class variables
var elt : typedexpr
var generators : List[typedcomprehension]
class TypedModule (*args, **kwargs)
-
Expand source code
class TypedModule(typedstmt, Module): body: typing.List[typedstmt]
Ancestors
Class variables
var body : List[typedstmt]
class TypedName (*args, **kwargs)
-
Expand source code
class TypedName(typedexpr, Name): pass
Ancestors
Class variables
var typ : Type
class TypedNodeTransformer
-
A :class:
NodeVisitor
subclass that walks the abstract syntax tree and allows modification of nodes.The
NodeTransformer
will walk the AST and use the return value of the visitor methods to replace or remove the old node. If the return value of the visitor method isNone
, the node will be removed from its location, otherwise it is replaced with the return value. The return value may be the original node in which case no replacement takes place.Here is an example transformer that rewrites all occurrences of name lookups (
foo
) todata['foo']
::class RewriteName(NodeTransformer):
def visit_Name(self, node): return Subscript( value=Name(id='data', ctx=Load()), slice=Index(value=Str(s=node.id)), ctx=node.ctx )
Keep in mind that if the node you're operating on has child nodes you must either transform the child nodes yourself or call the :meth:
generic_visit
method for the node first.For nodes that were part of a collection of statements (that applies to all statement nodes), the visitor may also return a list of nodes rather than just a single node.
Usually you use the transformer like this::
node = YourTransformer().visit(node)
Expand source code
class TypedNodeTransformer(NodeTransformer): def visit(self, node): """Visit a node.""" node_class_name = node.__class__.__name__ if node_class_name.startswith("Typed"): node_class_name = node_class_name[len("Typed") :] method = "visit_" + node_class_name visitor = getattr(self, method, self.generic_visit) return visitor(node)
Ancestors
- ast.NodeTransformer
- ast.NodeVisitor
Subclasses
Methods
def visit(self, node)
-
Visit a node.
Expand source code
def visit(self, node): """Visit a node.""" node_class_name = node.__class__.__name__ if node_class_name.startswith("Typed"): node_class_name = node_class_name[len("Typed") :] method = "visit_" + node_class_name visitor = getattr(self, method, self.generic_visit) return visitor(node)
class TypedNodeVisitor
-
A node visitor base class that walks the abstract syntax tree and calls a visitor function for every node found. This function may return a value which is forwarded by the
visit
method.This class is meant to be subclassed, with the subclass adding visitor methods.
Per default the visitor functions for the nodes are
'visit_'
+ class name of the node. So aTryFinally
node visit function would bevisit_TryFinally
. This behavior can be changed by overriding thevisit
method. If no visitor function exists for a node (return valueNone
) thegeneric_visit
visitor is used instead.Don't use the
NodeVisitor
if you want to apply changes to nodes during traversing. For this a special visitor exists (NodeTransformer
) that allows modifications.Expand source code
class TypedNodeVisitor(NodeVisitor): def visit(self, node): """Visit a node.""" node_class_name = node.__class__.__name__ if node_class_name.startswith("Typed"): node_class_name = node_class_name[len("Typed") :] method = "visit_" + node_class_name visitor = getattr(self, method, self.generic_visit) return visitor(node)
Ancestors
- ast.NodeVisitor
Subclasses
Methods
def visit(self, node)
-
Visit a node.
Expand source code
def visit(self, node): """Visit a node.""" node_class_name = node.__class__.__name__ if node_class_name.startswith("Typed"): node_class_name = node_class_name[len("Typed") :] method = "visit_" + node_class_name visitor = getattr(self, method, self.generic_visit) return visitor(node)
class TypedPass (*args, **kwargs)
-
Expand source code
class TypedPass(typedstmt, Pass): pass
Ancestors
Class variables
var typ : Type
class TypedReturn (*args, **kwargs)
-
Expand source code
class TypedReturn(typedstmt, Return): value: typedexpr
Ancestors
Class variables
var value : typedexpr
class TypedSubscript (*args, **kwargs)
-
Expand source code
class TypedSubscript(typedexpr, Subscript): value: typedexpr
Ancestors
Class variables
var value : typedexpr
class TypedTuple (*args, **kwargs)
-
Expand source code
class TypedTuple(typedexpr, Tuple): pass
Ancestors
Class variables
var typ : Type
class TypedUnaryOp (*args, **kwargs)
-
Expand source code
class TypedUnaryOp(typedexpr, UnaryOp): operand: typedexpr
Ancestors
Class variables
var operand : typedexpr
class TypedWhile (*args, **kwargs)
-
Expand source code
class TypedWhile(typedstmt, While): test: typedexpr body: typing.List[typedstmt] orelse: typing.List[typedstmt]
Ancestors
Class variables
var body : List[typedstmt]
var orelse : List[typedstmt]
var test : typedexpr
class UnionType (typs: List[RecordType])
-
UnionType(typs: List[hebi.typed_ast.RecordType])
Expand source code
class UnionType(ClassType): typs: typing.List[RecordType] def attribute_type(self, attr) -> "Type": if attr == "CONSTR_ID": return IntegerInstanceType # iterate through all names/types of the unioned records by position for attr_names, attr_types in map( lambda x: zip(*x), zip(*(t.record.fields for t in self.typs)) ): # need to have a common field with the same name, in the same position! if any(attr_name != attr for attr_name in attr_names): continue for at in attr_types: # return the maximum element if there is one if all(at >= at2 for at2 in attr_types): return at # return the union type of all possible instantiations if all possible values are record types if all( isinstance(at, InstanceType) and isinstance(at.typ, RecordType) for at in attr_types ) and distinct([at.typ.record.constructor for at in attr_types]): return InstanceType( UnionType(FrozenFrozenList([at.typ for at in attr_types])) ) # return Anytype return InstanceType(AnyType()) raise TypeInferenceError( f"Can not access attribute {attr} of Union type. Cast to desired type with an 'if isinstance(_, _):' branch." ) def attribute(self, attr: str) -> plt.AST: if attr == "CONSTR_ID": # access to constructor return plt.Lambda( ["self"], plt.Constructor(plt.Var("self")), ) # iterate through all names/types of the unioned records by position attr_typ = self.attribute_type(attr) pos = next( i for i, (ns, _) in enumerate( map(lambda x: zip(*x), zip(*(t.record.fields for t in self.typs))) ) if all(n == attr for n in ns) ) # access to normal fields return plt.Lambda( ["self"], transform_ext_params_map(attr_typ)( plt.NthField( plt.Var("self"), plt.Integer(pos), ), ), ) def __ge__(self, other): if isinstance(other, UnionType): return all(any(t >= ot for ot in other.typs) for t in self.typs) return any(t >= other for t in self.typs) def cmp(self, op: cmpop, o: "Type") -> plt.AST: """The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second the comparison.""" # this will reject comparisons that will always be false - most likely due to faults during programming # note we require that there is an overlapt between the possible types for unions if (isinstance(o, RecordType) and o in self.typs) or ( isinstance(o, UnionType) and set(self.typs).intersection(o.typs) ): if isinstance(op, Eq): return plt.BuiltIn(uplc.BuiltInFun.EqualsData) if isinstance(op, NotEq): return plt.Lambda( ["x", "y"], plt.Not( plt.Apply( plt.BuiltIn(uplc.BuiltInFun.EqualsData), plt.Var("x"), plt.Var("y"), ) ), ) raise NotImplementedError( f"Can not compare {o} and {self} with operation {op.__class__}. Note that comparisons that always return false are also rejected." )
Ancestors
Class variables
var typs : List[RecordType]
Methods
def attribute(self, attr: str) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
Expand source code
def attribute(self, attr: str) -> plt.AST: if attr == "CONSTR_ID": # access to constructor return plt.Lambda( ["self"], plt.Constructor(plt.Var("self")), ) # iterate through all names/types of the unioned records by position attr_typ = self.attribute_type(attr) pos = next( i for i, (ns, _) in enumerate( map(lambda x: zip(*x), zip(*(t.record.fields for t in self.typs))) ) if all(n == attr for n in ns) ) # access to normal fields return plt.Lambda( ["self"], transform_ext_params_map(attr_typ)( plt.NthField( plt.Var("self"), plt.Integer(pos), ), ), )
def attribute_type(self, attr) ‑> Type
-
Inherited from:
ClassType
.attribute_type
The types of the named attributes of this class
Expand source code
def attribute_type(self, attr) -> "Type": if attr == "CONSTR_ID": return IntegerInstanceType # iterate through all names/types of the unioned records by position for attr_names, attr_types in map( lambda x: zip(*x), zip(*(t.record.fields for t in self.typs)) ): # need to have a common field with the same name, in the same position! if any(attr_name != attr for attr_name in attr_names): continue for at in attr_types: # return the maximum element if there is one if all(at >= at2 for at2 in attr_types): return at # return the union type of all possible instantiations if all possible values are record types if all( isinstance(at, InstanceType) and isinstance(at.typ, RecordType) for at in attr_types ) and distinct([at.typ.record.constructor for at in attr_types]): return InstanceType( UnionType(FrozenFrozenList([at.typ for at in attr_types])) ) # return Anytype return InstanceType(AnyType()) raise TypeInferenceError( f"Can not access attribute {attr} of Union type. Cast to desired type with an 'if isinstance(_, _):' branch." )
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
Expand source code
def cmp(self, op: cmpop, o: "Type") -> plt.AST: """The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second the comparison.""" # this will reject comparisons that will always be false - most likely due to faults during programming # note we require that there is an overlapt between the possible types for unions if (isinstance(o, RecordType) and o in self.typs) or ( isinstance(o, UnionType) and set(self.typs).intersection(o.typs) ): if isinstance(op, Eq): return plt.BuiltIn(uplc.BuiltInFun.EqualsData) if isinstance(op, NotEq): return plt.Lambda( ["x", "y"], plt.Not( plt.Apply( plt.BuiltIn(uplc.BuiltInFun.EqualsData), plt.Var("x"), plt.Var("y"), ) ), ) raise NotImplementedError( f"Can not compare {o} and {self} with operation {op.__class__}. Note that comparisons that always return false are also rejected." )
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
ClassType
.constr
The constructor for this class
def constr_type(self) ‑> InstanceType
-
Inherited from:
ClassType
.constr_type
The type of the constructor for this class
class UnitType
-
UnitType()
Expand source code
class UnitType(AtomicType): def cmp(self, op: cmpop, o: "Type") -> plt.AST: if isinstance(o, UnitType): if isinstance(op, Eq): return plt.Lambda(["x", "y"], plt.Bool(True)) if isinstance(op, NotEq): return plt.Lambda(["x", "y"], plt.Bool(False)) return super().cmp(op, o)
Ancestors
Methods
def attribute(self, attr) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
AtomicType
.attribute
The attributes of this class. Needs to be a lambda that expects as first argument the object itself
def attribute_type(self, attr) ‑> Type
-
Inherited from:
AtomicType
.attribute_type
The types of the named attributes of this class
def cmp(self, op: _ast.cmpop, o: Type) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
AtomicType
.cmp
The implementation of comparing this type to type o via operator op. Returns a lambda that expects as first argument the object itself and as second …
Expand source code
def cmp(self, op: cmpop, o: "Type") -> plt.AST: if isinstance(o, UnitType): if isinstance(op, Eq): return plt.Lambda(["x", "y"], plt.Bool(True)) if isinstance(op, NotEq): return plt.Lambda(["x", "y"], plt.Bool(False)) return super().cmp(op, o)
def constr(self) ‑> pluthon.pluthon_ast.AST
-
Inherited from:
AtomicType
.constr
The constructor for this class
def constr_type(self) ‑> InstanceType
-
Inherited from:
AtomicType
.constr_type
The type of the constructor for this class
class typedarg (*args, **kwargs)
-
Expand source code
class typedarg(TypedAST, arg): pass
Ancestors
- TypedAST
- _ast.arg
- _ast.AST
Class variables
var typ : Type
class typedarguments (*args, **kwargs)
-
Expand source code
class typedarguments(TypedAST, arguments): args: typing.List[typedarg] vararg: typing.Union[typedarg, None] kwonlyargs: typing.List[typedarg] kw_defaults: typing.List[typing.Union[typedexpr, None]] kwarg: typing.Union[typedarg, None] defaults: typing.List[typedexpr]
Ancestors
- TypedAST
- _ast.arguments
- _ast.AST
Class variables
var args : List[typedarg]
var defaults : List[typedexpr]
var kw_defaults : List[Optional[typedexpr]]
var kwarg : Optional[typedarg]
var kwonlyargs : List[typedarg]
var vararg : Optional[typedarg]
class typedcomprehension (*args, **kwargs)
-
Expand source code
class typedcomprehension(typedexpr, comprehension): target: typedexpr iter: typedexpr ifs: typing.List[typedexpr]
Ancestors
Class variables
var ifs : List[typedexpr]
var iter : typedexpr
var target : typedexpr
class typedexpr (*args, **kwargs)
-
Expand source code
class typedexpr(TypedAST, expr): pass
Ancestors
- TypedAST
- _ast.expr
- _ast.AST
Subclasses
- RawPlutoExpr
- TypedAttribute
- TypedBinOp
- TypedBoolOp
- TypedCall
- TypedCompare
- TypedDict
- TypedExpression
- TypedList
- TypedListComp
- TypedName
- TypedSubscript
- TypedTuple
- TypedUnaryOp
- typedcomprehension
Class variables
var typ : Type
class typedstmt (*args, **kwargs)
-
Expand source code
class typedstmt(TypedAST, stmt): # Statements always have type None typ = NoneInstanceType
Ancestors
- TypedAST
- _ast.stmt
- _ast.AST
Subclasses
- TypedAnnAssign
- TypedAssert
- TypedAssign
- TypedClassDef
- TypedExpr
- TypedFor
- TypedFunctionDef
- TypedIf
- TypedIfExp
- TypedModule
- TypedPass
- TypedReturn
- TypedWhile
Class variables
var typ : Type