Type System Base Class: Module type_system

These classes provide the type system mechanism.

Inheritance diagram of pyrser.type_system.Scope, pyrser.type_system.TypeName, pyrser.type_system.Symbol, pyrser.type_system.Signature, pyrser.type_system.EvalCtx, pyrser.type_system.Scope, pyrser.type_system.Tuple, pyrser.type_system.Type, pyrser.type_system.Var, pyrser.type_system.Val, pyrser.type_system.Fun, pyrser.type_system.Translator, pyrser.type_system.MapSourceTranslate, pyrser.type_system.MapTargetTranslate, pyrser.type_system.Inference, pyrser.type_system.InferNode

class pyrser.type_system.TypeName(value)[source]

Bases: str

__eq__(self, oth) → bool[source]
__hash__(self) → int[source]
__init__(self, value)[source]
__lt__(self, oth) → bool[source]
__str__(self) → str[source]
get_subcomponents(self) → list[source]
is_polymorphic

Check if one of composed type name is poly

class pyrser.type_system.Symbol(name, parent=None)[source]

Bases: object

Symbol are semantic name used in a language. Could be map to binary symbol but conceptually are more related to language symbol table.

__getstate__(self)[source]

For pickle don’t handle weakrefs...

__init__(self, name, parent= None)[source]
__repr__(self) → str[source]
__str__(self) → str[source]
get_parent(self) → object[source]

Auto deref parent and return the instance.

get_scope_list(self) → list[source]

Return the list of all contained scope from global to local

get_scope_names(self) → list[source]

Return the list of all contained scope from global to local

internal_name(self) → str[source]

Returns the namespace’s internal_name.

set_parent(self, parent) → object[source]
show_name(self) → str[source]

Return a convenient name for type checking

class pyrser.type_system.Signature(name: str)[source]

Bases: pyrser.type_system.symbol.Symbol

Describe a function or variable signature for the language

__init__(self, name: str)[source]
__str__(self) → str[source]
class pyrser.type_system.EvalCtx(sig: pyrser.type_system.signature.Signature)[source]

Bases: object

Store environment for mono/poly call.

__init__(self, sig: Signature)[source]
__len__(self) → int[source]
__str__(self) → str[source]
compute_tret
from_sig(sig: Signature) → object[source]
get_compute_sig(self) → Signature[source]

Compute a signature Using resolution!!!

TODO: discuss of relevance of a final generation for a signature

get_parent(self)[source]
get_resolved_names(self, type_name: TypeName) → list[source]

Use self.resolution to subsitute type_name. Allow to instanciate polymorphic type ?1, ?toto

internal_name(self)[source]
is_polymorphic
name
resolve(self)[source]

Process the signature and find definition for type.

set_parent(self, parent) → object[source]

When we add a parent (from Symbol), don’t forget to resolve.

set_resolved_name(self, ref: dict, type_name2solve: TypeName, type_name_ref: TypeName)[source]

Warning!!! Need to rethink it when global poly type

show_name(self)[source]
tparams
tret
use_translator(self, translator)[source]

Attach a translator to an EvalCtx to convert output of the function into another type

use_variadic_types(self, list_type)[source]

Attach a list of types for extra variadic argument of a call

values(self) → list[source]

Make EvalCtx iterable (to update a scope with it)

variadic
class pyrser.type_system.Scope(name: str=None, sig: [<class 'pyrser.type_system.signature.Signature'>]=None, state=0, is_namespace=True)[source]

Bases: pyrser.type_system.symbol.Symbol

Scope of Signature for a Scope/namespace/type etc... Basic abstraction of type checking. Scope is not a ‘pure’ python set but something between a set and a dict...

_Scope__update_count(self)

Update internal counters

__and__(self, sig: Scope) → Scope[source]

& operator

__contains__(self, s: Signature) → bool[source]

check if a Signature or a Type is declared in a Scope

__getstate__(self)[source]

For pickle, we don’t handle weakrefs...

__iand__(self, sig: Scope) → Scope[source]

&= operator

__init__(self, name: str= None, sig= None, state= 0, is_namespace= True)[source]

Unnamed scope for global scope

A Scope have basically 3 possibles states:

FREE: it’s a standalone Scope, generally the global Scope LINKED: the Scope is related to another Scope for type resolution,

like compound statement
EMBEDDED: the Scope was added into another Scope,
it forwards all ‘in’ calls...like namespacing

A Scope could or couldn’t act like a namespace. All Signature added into a ‘namespaced’ Scope was prefixed by the Scope name.

__ior__(self, sig: list) → Scope[source]

|= operator

__isub__(self, sig: Scope) → Scope[source]

-= operator

__ixor__(self, sig: Scope) → Scope[source]

^= operator

__len__(self) → int[source]

Len of the Set

__or__(self, sig: Scope) → Scope[source]
operator
__repr__(self) → str[source]

Internal representation

__str__(self) → str[source]
__sub__(self, sig: Scope) → Scope[source]
  • operator
__xor__(self, sig: Scope) → Scope[source]

^ operator

add(self, it: Signature) → bool[source]

Add it to the Set

addTranslator(self, val: Translator, as_global= False)[source]
addTranslatorInjector(self, ast_method)[source]

Could be redefine in a subscope

callInjector(self, old: Node, trans: Translator) → Node[source]

If don’t have injector call from parent

clear(self) → bool[source]

Clear all signatures in the Set

count_funs(self) → int[source]

Count function define by this scope

count_types(self) → int[source]

Count subtypes

count_vars(self) → int[source]

Count var define by this scope

difference(self, sig: Scope) → Scope[source]

Create a new Set produce by a Set subtracted by another Set

difference_update(self, oset: Scope) → Scope[source]

Remove values common with another Set

discard(self, it: Signature) → bool[source]

Remove it only if present

findTranslationTo(self, t2: str)[source]

Find an arrow (->) aka a function able to translate something to t2

first(self) → Signature[source]

Retrieve the first Signature ordered by mangling descendant

get(self, key: str, default= None) → Signature[source]

Get a signature instance by its internal_name

get_all_polymorphic_return(self) → bool[source]

For now, polymorphic return type are handle by symbol artefact.

–> possible multi-polymorphic but with different constraint attached!

get_by_params(self, params)[source]

Retrieve a Set of all signature that match the parameter list. Return a pair:

pair[0] the overloads for the functions pair[1] the overloads for the parameters

(a list of candidate list of parameters)
get_by_return_type(self, tname: str) → Scope[source]

Retrieve a Set of all signature by (return) type

get_by_symbol_name(self, name: str) → Scope[source]

Retrieve a Set of all signature by symbol name

getsig_by_symbol_name(self, name: str) → Signature[source]

Retrieve the unique Signature of a symbol. Fail if the Signature is not unique

intersection(self, sig: Scope) → Scope[source]

Create a new Set produce by the intersection of 2 Set

intersection_update(self, oset: Scope) → Scope[source]

Update Set with common values of another Set

keys(self)[source]

Retrieve all keys

last(self) → Signature[source]

Retrieve the last Signature ordered by mangling descendant

pop(self) → Signature[source]

Pop a random Signature

remove(self, it: Signature) → bool[source]

Remove it but raise KeyError if not found

set_name(self, name: str)[source]

You could set the name after construction

set_parent(self, parent: Scope) → object[source]
symmetric_difference(self, sig: Scope) → Scope[source]

Create a new Set with values present in only one Set

symmetric_difference_update(self, oset: Scope) → Scope[source]

Remove common values and Update specific values from another Set

union(self, sig: Scope) → Scope[source]

Create a new Set produce by the union of 2 Set

update(self, sig: list) → Scope[source]

Update the Set with values of another Set

values(self)[source]

Retrieve all values

pyrser.type_system.StateScope

alias of Enum

class pyrser.type_system.Tuple(sig: [<class 'pyrser.type_system.signature.Signature'>]=None)[source]

Bases: list

A tuple is just a list of signature.

__init__(self, sig= None)[source]
__repr__(self) → str[source]

Internal representation

__str__(self) → str[source]

Usefull representation

add(self, sig: Signature)[source]
to_fmt(self) → indentable[source]

Return an Fmt representation for pretty-printing

class pyrser.type_system.Type(name: str, sig: [<class 'pyrser.type_system.signature.Signature'>]=None)[source]

Bases: pyrser.type_system.scope.Scope

A Type is a named scope similar to ADT (Abstract Data Type). So we have member variables (ordered) that represent internal state. Member functions (work on an instance of type, depend of the language ref/or not). Non member variables/functions/values as in a scope.

__init__(self, name: str, sig= None)[source]
__str__(self) → str[source]
type_name
class pyrser.type_system.Var(name: str, tret: str)[source]

Bases: pyrser.type_system.signature.Signature

Describe a variable signature for the language

__init__(self, name: str, tret: str)[source]
__str__(self) → str[source]
internal_name(self)[source]

Return the unique internal name

is_polymorphic
class pyrser.type_system.Val(value, tret: str)[source]

Bases: pyrser.type_system.signature.Signature

Describe a value signature for the language

__init__(self, value, tret: str)[source]
__str__(self) → str[source]
internal_name(self)[source]

Return the unique internal name

nvalues = 0
valuniq = {}
class pyrser.type_system.Fun(name: str, tret: str, tparams: list=None, variadic=None)[source]

Bases: pyrser.type_system.signature.Signature

Describe a function signature for the language

__init__(self, name: str, tret: str, tparams: list= None, variadic= None)[source]
__str__(self) → str[source]
arity
internal_name(self)[source]

Return the unique internal name

is_polymorphic
return_type
this_type
class pyrser.type_system.Translator(fun: pyrser.type_system.fun.Fun, notify: pyrser.error.Notification=None)[source]

Bases: object

Handle conversion from type_source to type_target thru a function. Do error.Notification if applyiable.

__hash__(self) → str[source]
__init__(self, fun: Fun, notify: Notification= None)[source]
__str__(self) → str[source]
fun
notify
source
target
class pyrser.type_system.MapSourceTranslate[source]

Bases: dict

Handle all conversions functions provide as Translator.

_MapSourceTranslate__reversed(self) → reversed
__contains__(self, key: str) → bool[source]
__delitem__(self, key: str)[source]
__getitem__(self, key: str) → MapTargetTranslate[source]
__init__(self)[source]
__iter__(self) → iter[source]
__len__(self) → int[source]
__setitem__(self, key: str, val: MapTargetTranslate)[source]
__str__(self) → str[source]
addTranslator(self, val: Translator, as_global= False)[source]
set_parent(self, parent: MapSourceTranslate)[source]
class pyrser.type_system.MapTargetTranslate[source]

Bases: dict

Handle all translation to one type

_MapTargetTranslate__reversed(self) → reversed
__contains__(self, key: str) → bool[source]
__delitem__(self, key: str)[source]
__getitem__(self, key: str) → Translator[source]
__init__(self)[source]
__iter__(self) → iter[source]
__len__(self) → int[source]
__setitem__(self, key: str, val: Translator)[source]
__str__(self) → str[source]
key
class pyrser.type_system.Inference[source]

Bases: object

feedback(self, diagnostic= None)[source]

Do feedback. Write infos into diagnostic object, if this parameter is not provide and self is a AST (has is own diagnostic object), use the diagnostic of self.

feedback_block(self, diagnostic= None)[source]
feedback_fun(self, diagnostic= None)[source]
feedback_id(self, diagnostic= None)[source]
feedback_leaf(self, diagnostic= None)[source]
feedback_subexpr(self, diagnostic= None)[source]
infer_block(self, body, diagnostic= None)[source]

Infer type on block is to type each of is sub-element

infer_fun(self, args, diagnostic= None)[source]
infer_id(self, ident, diagnostic= None)[source]

Infer type from an ID! - check if ID is declarated in the scope - if no ID is polymorphic type

infer_literal(self, args, diagnostic= None)[source]

Infer type from an LITERAL! Type of literal depend of language. We adopt a basic convention

infer_subexpr(self, expr, diagnostic= None)[source]

Infer type on the subexpr

infer_type(self, init_scope: Scope= None, diagnostic= None)[source]

Do inference. Write infos into diagnostic object, if this parameter is not provide and self is a AST (has is own diagnostic object), use the diagnostic of self.

type_algos(self)[source]
Sub class must return a Tuple of 3 elements:
  • the method to use to infer type.
  • the list of params to used when infer a type.
  • the method to use when feedback a type.

This is useful to connect AST members to generic algo or to overload some specific semantic for your language.

class pyrser.type_system.InferNode(init_scope: pyrser.type_system.scope.Scope=None, parent: pyrser.type_system.scope.Scope=None)[source]

Bases: object

An instance of this class is automatically attach on each AST Nodes by the inference algorithm during the inference process into the ‘.infer_node’ attribute. The aim is to keep track of the correct Scope and the final EvalCtx for each AST Nodes.

__init__(self, init_scope: Scope= None, parent: Scope= None)[source]