curry.typecheck.builder module

The typed builder of curry.expr (item Y7 of the typed boundary, epic #48).

curry.expr describes its arguments as a tree of specs, types the tree with the engine (engine), defaults the class constraints, resolves the dictionaries, and then builds the nodes through make_node of the backend. The conversion of the arguments, the typing and the materialization each walk the tree with an explicit stack, so the depth of a description is not bounded by the recursion limit. Python values convert by the expected type: an int under Float is a Float, a str under [Char] is one string, a list converts in a loop under its element type, and the items of an iterator convert when the list is demanded. A Curry node that fills a parameter is typed by a walk of its content, capped at VALUE_WALK_CAP nodes; a bare node alone passes through untouched. The walk types a node without successors, such as [], at every position it holds, because the runtime shares one such node between positions of different types (TypedProblem._walk()).

The result type of a node the builder returns is kept in a weak record (TypeRecord) keyed by the identity of the node, so curry.typeof answers for it and curry.eval hands the static type of a goal to the converter. Description holds a tree of specs for the DSL and types it only when a consumer asks for nodes.

class curry.typecheck.builder.Description(interp, args, anchors=None, exprtype=None)[source]

Bases: object

The description of an expression: the spec tree of the arguments of curry.expr, with the anchors of its keyword arguments and its exprtype. It is typed when a consumer asks: curry.expr(description) or curry.eval(description) build its node, typeof() gives its type, and each typing starts afresh. A description may be an argument of a larger one; its anchors travel with it, and a reference outside the description cannot name them. str prints it in Curry syntax.

build(exprtype=None, target=None)[source]

The node of the expression; exprtype overrides the description’s.

typeof(defaulted=False)[source]

The type of the expression in Curry syntax; see typeof().

class curry.typecheck.builder.Group[source]

Bases: Spec

The anchors of the keyword arguments followed by the expression. The type and the node of the group are those of the last item; the anchors are built first, so a reference to one of them finds its node.

items
class curry.typecheck.builder.Raw(payload, walk=False, typeexpr=None)[source]

Bases: Spec

A part the typed builder makes untyped. With walk set, the payload is a Curry node typed by a walk of its content. Otherwise the payload is built by the untyped builder: the fail marker, a list headed by an InfoTable, the application of a class dictionary (an _inst# symbol), or a boxed literal over an unboxed value; its type is typeexpr when given, else a fresh variable.

typeexpr
walk
class curry.typecheck.builder.Ref(var)[source]

Bases: Spec

A reference to an anchor; payload is the variable of the anchor.

class curry.typecheck.builder.TypeRecord[source]

Bases: object

The result types of the nodes curry.expr returned: the undefaulted scheme and the defaulted type. An entry is keyed by the identity of the node and held by a weak reference, so it goes when the node goes and is never lent to a node that took the same id later.

get(node)[source]

The pair of the scheme and the type of a recorded node, or None.

put(node, scheme, typeexpr)[source]
class curry.typecheck.builder.TypedBuilder(interp, target=None)[source]

Bases: object

Builds one expression: converts the arguments of curry.expr to specs (specs()), types them (TypedProblem) and makes the nodes (materialize()).

count_freevar()[source]

Counts a free variable made outside an evaluation; see RuntimeState.set_goal.

dict_node(d)[source]

The node of a dictionary term: the instance function applied to the dictionaries of its context, a partial application with one missing argument. One node per distinct term within one expression.

finish(problem, spec, args, target)[source]

The node of a spec whose children are the nodes args.

static is_dictionary(arg)[source]

Whether an argument is a class dictionary: the symbol of an instance function, a node of one, or a list that starts with one.

materialize(problem)[source]

The node of a solved problem: a post-order walk with an explicit stack.

property raw
raw_build(form, target=None)[source]
run(root, exprtype=None)[source]

Types a spec tree, builds its node and records the result type.

spec_of(arg)[source]

The spec of one argument and the children to convert, as triples of a value, a container and an index.

specs(args, anchors=())[source]

The spec tree of the arguments of curry.expr. anchors are the keyword arguments, pairs of a name and a value; they come first in a Group.

string_node(text, target=None)[source]

The node of a Python string at the type [Char]: on the Python backend one _biString node over the code points, which the step unfolds one character at a time; on the C++ backend the list the step of _biString would build, made natively in one call (Node.create_string). The empty string is [].

class curry.typecheck.builder.TypedProblem(builder, root, exprtype=None)[source]

Bases: Problem

The engine’s problem with the specs of the builder: a value typed by a walk of its content, the wrappers, the references and the groups.

anchor_type(key)[source]

The type variable of an anchor in this problem, shared with its references.

class curry.typecheck.builder.Unboxed(payload, primitive=None)[source]

Bases: Spec

An unboxed marker the problem refuses; payload is the Python value. The payload of a primitive, [Int, unboxed(3)], is a Raw part instead (TypedBuilder._application()), so this spec stands alone, in a list or a tuple, or as an argument, where a node is expected (issue #107); or, with primitive set to 'Int', 'Char' or 'Float', it is a payload that does not fit that primitive, such as [Int, unboxed(2.5)]. A description prints the payload.

primitive
class curry.typecheck.builder.Wrap(kind, extra=None)[source]

Bases: Spec

A node around one typed child. The kinds: anchor (extra is the variable of the anchor, shared with its references), fwd, setgrd (extra is the set id), strict, nonstrict and binding (extra is the pair, built untyped).

extra
items
kind
curry.typecheck.builder.build(interp, args, anchors, exprtype=None, target=None)[source]

curry.expr on the typed path. A bare node alone passes through untouched when no type is asked of it.

curry.typecheck.builder.build_description(description, exprtype=None, target=None)[source]
curry.typecheck.builder.record_of(interp)[source]
curry.typecheck.builder.recorded(interp, node)[source]

The recorded scheme and type of a node, or None.

curry.typecheck.builder.result_type(interp, node)[source]

The defaulted result type of a node curry.expr built, or None.

curry.typecheck.builder.symbol_map(interp)[source]

A dict from the id of an info table to its symbol, over the loaded modules of an interpreter. The map is built again when a module was loaded or released since the last call.

curry.typecheck.builder.typeof(interp, e, defaulted=False)[source]

The type of an expression in Curry syntax: the undefaulted scheme, what :type prints, or the defaulted type. e is a node curry.expr returned (its recorded type) or any other Curry node (typed by its content), a symbol, a Description, or any argument of curry.expr.