unification

package
v0.0.0-...-173ccf6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 5, 2018 License: GPL-3.0 Imports: 5 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// Name is the prefix for our solver log messages.
	Name = "solver: simple"
)

Variables

This section is empty.

Functions

func SimpleInvariantSolverLogger

func SimpleInvariantSolverLogger(logf func(format string, v ...interface{})) func([]interfaces.Invariant) (*InvariantSolution, error)

SimpleInvariantSolverLogger is a wrapper which returns a SimpleInvariantSolver with the log parameter of your choice specified. The result satisfies the correct signature for the solver parameter of the Unification function.

func Unify

func Unify(ast interfaces.Stmt, solver func([]interfaces.Invariant) (*InvariantSolution, error)) error

Unify takes an AST expression tree and attempts to assign types to every node using the specified solver. The expression tree returns a list of invariants (or constraints) which must be met in order to find a unique value for the type of each expression. This list of invariants is passed into the solver, which hopefully finds a solution. If it cannot find a unique solution, then it will return an error. The invariants are available in different flavours which describe different constraint scenarios. The simplest expresses that a a particular node id (it's pointer) must be a certain type. More complicated invariants might express that two different node id's must have the same type. This function and logic was invented after the author could not find any proper literature or examples describing a well-known implementation of this process. Improvements and polite recommendations are welcome.

Types

type AnyInvariant

type AnyInvariant struct {
	Expr interfaces.Expr
}

AnyInvariant is an invariant that symbolizes that the expression can be any type. It is sometimes used to ensure that an expr actually gets a solution type so that it is not left unreferenced, and as a result, unsolved. TODO: is there a better name than AnyInvariant

func (*AnyInvariant) String

func (obj *AnyInvariant) String() string

String returns a representation of this invariant.

type ConjunctionInvariant

type ConjunctionInvariant struct {
	Invariants []interfaces.Invariant
}

ConjunctionInvariant represents a list of invariants which must all be true together. In other words, it's a grouping construct for a set of invariants.

func (*ConjunctionInvariant) String

func (obj *ConjunctionInvariant) String() string

String returns a representation of this invariant.

type EqualityInvariant

type EqualityInvariant struct {
	Expr1 interfaces.Expr
	Expr2 interfaces.Expr
}

EqualityInvariant is an invariant that symbolizes that the two expressions must have equivalent types. TODO: is there a better name than EqualityInvariant

func (*EqualityInvariant) String

func (obj *EqualityInvariant) String() string

String returns a representation of this invariant.

type EqualityInvariantList

type EqualityInvariantList struct {
	Exprs []interfaces.Expr
}

EqualityInvariantList is an invariant that symbolizes that all the expressions listed must have equivalent types.

func (*EqualityInvariantList) String

func (obj *EqualityInvariantList) String() string

String returns a representation of this invariant.

type EqualityWrapFuncInvariant

type EqualityWrapFuncInvariant struct {
	Expr1    interfaces.Expr
	Expr2Map map[string]interfaces.Expr
	Expr2Ord []string
	Expr2Out interfaces.Expr
}

EqualityWrapFuncInvariant expresses that a func in Expr1 must have args that match the type of the expressions listed in Expr2Map and a return value that matches the type of the expression in Expr2Out. TODO: should this be named EqualityWrapCallInvariant or not?

func (*EqualityWrapFuncInvariant) String

func (obj *EqualityWrapFuncInvariant) String() string

String returns a representation of this invariant.

type EqualityWrapListInvariant

type EqualityWrapListInvariant struct {
	Expr1    interfaces.Expr
	Expr2Val interfaces.Expr
}

EqualityWrapListInvariant expresses that a list in Expr1 must have elements that have the same type as the expression in Expr2Val.

func (*EqualityWrapListInvariant) String

func (obj *EqualityWrapListInvariant) String() string

String returns a representation of this invariant.

type EqualityWrapMapInvariant

type EqualityWrapMapInvariant struct {
	Expr1    interfaces.Expr
	Expr2Key interfaces.Expr
	Expr2Val interfaces.Expr
}

EqualityWrapMapInvariant expresses that a map in Expr1 must have keys that match the type of the expression in Expr2Key and values that match the type of the expression in Expr2Val.

func (*EqualityWrapMapInvariant) String

func (obj *EqualityWrapMapInvariant) String() string

String returns a representation of this invariant.

type EqualityWrapStructInvariant

type EqualityWrapStructInvariant struct {
	Expr1    interfaces.Expr
	Expr2Map map[string]interfaces.Expr
	Expr2Ord []string
}

EqualityWrapStructInvariant expresses that a struct in Expr1 must have fields that match the type of the expressions listed in Expr2Map.

func (*EqualityWrapStructInvariant) String

func (obj *EqualityWrapStructInvariant) String() string

String returns a representation of this invariant.

type EqualsInvariant

type EqualsInvariant struct {
	Expr interfaces.Expr
	Type *types.Type
}

EqualsInvariant is an invariant that symbolizes that the expression has a known type. TODO: is there a better name than EqualsInvariant

func (*EqualsInvariant) String

func (obj *EqualsInvariant) String() string

String returns a representation of this invariant.

type ExclusiveInvariant

type ExclusiveInvariant struct {
	Invariants []interfaces.Invariant
}

ExclusiveInvariant represents a list of invariants where one and *only* one should hold true. To combine multiple invariants in one of the list elements, you can group multiple invariants together using a ConjunctionInvariant. Do note that the solver might not verify that only one of the invariants in the list holds true, as it might choose to be lazy and pick the first solution found.

func (*ExclusiveInvariant) String

func (obj *ExclusiveInvariant) String() string

String returns a representation of this invariant.

type InvariantSolution

type InvariantSolution struct {
	Solutions []*EqualsInvariant // list of trivial solutions for each node
}

InvariantSolution lists a trivial set of EqualsInvariant mappings so that you can populate your AST with SetType calls in a simple loop.

func SimpleInvariantSolver

func SimpleInvariantSolver(invariants []interfaces.Invariant, logf func(format string, v ...interface{})) (*InvariantSolution, error)

SimpleInvariantSolver is an iterative invariant solver for AST expressions. It is intended to be very simple, even if it's computationally inefficient.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL