lang

package
v0.0.0-...-c555478 Latest Latest
Warning

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

Go to latest
Published: Aug 9, 2021 License: GPL-3.0 Imports: 38 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// ModuleMagicPrefix is the prefix which, if found as a prefix to the
	// last token in an import path, will be removed silently if there are
	// remaining characters following the name. If this is the empty string
	// then it will be ignored.
	ModuleMagicPrefix = "mgmt-"

	// CoreDir is the directory prefix where core bindata mcl code is added.
	CoreDir = "core/"
)
View Source
const (
	ErrLexerUnrecognized      = interfaces.Error("unrecognized")
	ErrLexerUnrecognizedCR    = interfaces.Error("unrecognized carriage return")
	ErrLexerStringBadEscaping = interfaces.Error("string: bad escaping")
	ErrLexerIntegerOverflow   = interfaces.Error("integer: overflow")
	ErrLexerFloatOverflow     = interfaces.Error("float: overflow")
	ErrParseError             = interfaces.Error("parser")
	ErrParseSetType           = interfaces.Error("can't set return type in parser")
	ErrParseResFieldInvalid   = interfaces.Error("can't use unknown resource field")
	ErrParseAdditionalEquals  = interfaces.Error(errstrParseAdditionalEquals)
	ErrParseExpectingComma    = interfaces.Error(errstrParseExpectingComma)
)

These constants represent the different possible lexer/parser errors.

View Source
const (
	// EdgeNotify declares an edge a -> b, such that a notification occurs.
	// This is most similar to "notify" in Puppet.
	EdgeNotify = "notify"

	// EdgeBefore declares an edge a -> b, such that no notification occurs.
	// This is most similar to "before" in Puppet.
	EdgeBefore = "before"

	// EdgeListen declares an edge a <- b, such that a notification occurs.
	// This is most similar to "subscribe" in Puppet.
	EdgeListen = "listen"

	// EdgeDepend declares an edge a <- b, such that no notification occurs.
	// This is most similar to "require" in Puppet.
	EdgeDepend = "depend"

	// MetaField is the prefix used to specify a meta parameter for the res.
	MetaField = "meta"

	// AllowUserDefinedPolyFunc specifies if we allow user-defined
	// polymorphic functions or not. At the moment this is not implemented.
	// XXX: not implemented
	AllowUserDefinedPolyFunc = false

	// RequireStrictModulePath can be set to true if you wish to ignore any
	// of the metadata parent path searching. By default that is allowed,
	// unless it is disabled per module with ParentPathBlock. This option is
	// here in case we decide that the parent module searching is confusing.
	RequireStrictModulePath = false

	// RequireTopologicalOrdering specifies if the code *must* be written in
	// a topologically correct order. This prevents "out-of-order" code that
	// is valid, but possibly confusing to the read. The main author
	// (purpleidea) believes that this is better of as false. This is
	// because occasionally code might be more logical when out-of-order,
	// and hiding the fundamental structure of the language isn't elegant.
	RequireTopologicalOrdering = false

	// TopologicalOrderingWarning specifies whether a warning is emitted if
	// the code is not in a topologically correct order. If this warning is
	// seen too often, then we should consider disabling this by default.
	TopologicalOrderingWarning = true

	// ErrNoStoredScope is an error that tells us we can't get a scope here.
	ErrNoStoredScope = interfaces.Error("scope is not stored in this node")
)
View Source
const (
	// Name is the name of this frontend.
	Name = "lang"
)
View Source
const (
	// UseHilInterpolation specifies that we use the legacy Hil interpolate.
	// This can't properly escape a $ in the standard way. It's here in case
	// someone wants to play with it and examine how the AST stuff worked...
	UseHilInterpolation = false
)

Variables

This section is empty.

Functions

func CollectFiles

func CollectFiles(ast interfaces.Stmt) ([]string, error)

CollectFiles collects all the files used in the AST. You will see more files based on how many compiling steps have run. In general, this is useful for collecting all the files needed to store in our file system for a deploy.

func DirectoryReader

func DirectoryReader(fs engine.Fs, dir string) (io.Reader, map[uint64]string, error)

DirectoryReader takes a filesystem and an absolute directory path, and it returns a combined reader into that directory, and an offset map of the file contents. This is used to build a reader from a directory containing language source files, and as a result, this will skip over files that don't have the correct extension. The offsets are in units of file size (bytes) and not length (lines). TODO: Due to an implementation difficulty, offsets are currently in length! NOTE: This was used for an older deprecated form of lex/parse file combining.

func FuncPrefixToFunctionsScope

func FuncPrefixToFunctionsScope(prefix string) map[string]interfaces.Expr

FuncPrefixToFunctionsScope is a helper function to return the functions portion of the scope from a function prefix lookup. Basically this wraps the implementation in the Func interface in the *ExprFunc struct.

func InterpolateHil

func InterpolateHil(str string, pos *Pos, data *interfaces.Data) (interfaces.Expr, error)

InterpolateHil interpolates a string and returns the representative AST. This particular implementation uses the hashicorp hil library and syntax to do so.

func InterpolateRagel

func InterpolateRagel(str string, pos *Pos, data *interfaces.Data) (interfaces.Expr, error)

InterpolateRagel interpolates a string and returns the representative AST. It uses the ragel parser to perform the string interpolation.

func InterpolateStr

func InterpolateStr(str string, pos *Pos, data *interfaces.Data) (interfaces.Expr, error)

InterpolateStr interpolates a string and returns the representative AST.

func LexParse

func LexParse(input io.Reader) (interfaces.Stmt, error)

LexParse runs the lexer/parser machinery and returns the AST.

func LexParseWithOffsets

func LexParseWithOffsets(input io.Reader, offsets map[uint64]string) (interfaces.Stmt, error)

LexParseWithOffsets takes an io.Reader input and a list of corresponding offsets and runs LexParse on them. The input to this function is most commonly the output from DirectoryReader which returns a single io.Reader and the offsets map. It usually produces the combined io.Reader from an io.MultiReader grouper. If the offsets map is nil or empty, then it simply redirects directly to LexParse. This differs because when it errors it will also report the corresponding file the error occurred in based on some offset math. The offsets are in units of file size (bytes) and not length (lines). TODO: Due to an implementation difficulty, offsets are currently in length! NOTE: This was used for an older deprecated form of lex/parse file combining.

func MergeExprMaps

func MergeExprMaps(m, extra map[string]interfaces.Expr, prefix ...string) (map[string]interfaces.Expr, error)

MergeExprMaps merges the two maps of Expr's, and errors if any overwriting would occur. If any prefix string is specified, that is added to the keys of the second "extra" map before doing the merge. This doesn't change the input maps.

func ParseImportName

func ParseImportName(name string) (*interfaces.ImportData, error)

ParseImportName parses an import name and returns the default namespace name that should be used with it. For example, if the import name was: "git://example.com/purpleidea/Module-Name", this might return an alias of "module_name". It also returns a bunch of other data about the parsed import. TODO: check for invalid or unwanted special characters

func ValueToExpr

func ValueToExpr(val types.Value) (interfaces.Expr, error)

ValueToExpr converts a Value into the equivalent Expr. FIXME: Add some tests for this function.

func VarPrefixToVariablesScope

func VarPrefixToVariablesScope(prefix string) map[string]interfaces.Expr

VarPrefixToVariablesScope is a helper function to return the variables portion of the scope from a variable prefix lookup. Basically this is useful to pull out a portion of the variables we've defined by API.

Types

type Downloader

type Downloader struct {

	// Depth is the max recursion depth that we should descent to. A
	// negative value means infinite. This is usually the default.
	Depth int

	// Retry is the max number of retries we should run if we encounter a
	// network error. A negative value means infinite. The default is
	// usually zero.
	Retry int
	// contains filtered or unexported fields
}

Downloader implements the Downloader interface. It provides a mechanism to pull down new code from the internet. This is usually done with git.

func (*Downloader) Get

func (obj *Downloader) Get(info *interfaces.ImportData, modulesPath string) error

Get runs a single download of an import and stores it on disk. XXX: this should only touch the filesystem via obj.info.Fs, but that is not implemented at the moment, so we cheat and use the local fs directly. This is not disastrous, since we only run Get on a local fs, since we don't download to etcdfs directly with the downloader during a deploy. This is because we'd need to implement the afero.Fs -> billy.Filesystem mapping layer.

func (*Downloader) Init

func (obj *Downloader) Init(info *interfaces.DownloadInfo) error

Init initializes the downloader with some core structures we'll need.

type ExprBool

type ExprBool struct {
	V bool
	// contains filtered or unexported fields
}

ExprBool is a representation of a boolean.

func (*ExprBool) Apply

func (obj *ExprBool) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*ExprBool) Copy

func (obj *ExprBool) Copy() (interfaces.Expr, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*ExprBool) Func

func (obj *ExprBool) Func() (interfaces.Func, error)

Func returns the reactive stream of values that this expression produces.

func (*ExprBool) Graph

func (obj *ExprBool) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This returns a graph with a single vertex (itself) in it.

func (*ExprBool) Init

func (obj *ExprBool) Init(*interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*ExprBool) Interpolate

func (obj *ExprBool) Interpolate() (interfaces.Expr, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents. Here it simply returns itself, as no interpolation is possible.

func (*ExprBool) Ordering

func (obj *ExprBool) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in.

func (*ExprBool) SetScope

func (obj *ExprBool) SetScope(scope *interfaces.Scope) error

SetScope does nothing for this struct, because it has no child nodes, and it does not need to know about the parent scope. It does however store it for later possible use.

func (*ExprBool) SetType

func (obj *ExprBool) SetType(typ *types.Type) error

SetType will make no changes if called here. It will error if anything other than a Bool is passed in, and doesn't need to be called for this expr to work.

func (*ExprBool) SetValue

func (obj *ExprBool) SetValue(value types.Value) error

SetValue for a bool expression is always populated statically, and does not ever receive any incoming values (no incoming edges) so this should never be called. It has been implemented for uniformity.

func (*ExprBool) String

func (obj *ExprBool) String() string

String returns a short representation of this expression.

func (*ExprBool) Type

func (obj *ExprBool) Type() (*types.Type, error)

Type returns the type of this expression. This method always returns Bool here.

func (*ExprBool) Unify

func (obj *ExprBool) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

func (*ExprBool) Value

func (obj *ExprBool) Value() (types.Value, error)

Value returns the value of this expression in our type system. This will usually only be valid once the engine has run and values have been produced. This might get called speculatively (early) during unification to learn more. This particular value is always known since it is a constant.

type ExprCall

type ExprCall struct {
	V types.Value // stored result (set with SetValue)

	// Name of the function to be called. We look for it in the scope.
	Name string
	// Args are the list of inputs to this function.
	Args []interfaces.Expr // list of args in parsed order
	// Var specifies whether the function being called is a lambda in a var.
	Var bool
	// contains filtered or unexported fields
}

ExprCall is a representation of a function call. This does not represent the declaration or implementation of a new function value. This struct has an analogous symmetry with ExprVar.

func (*ExprCall) Apply

func (obj *ExprCall) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*ExprCall) Copy

func (obj *ExprCall) Copy() (interfaces.Expr, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*ExprCall) Func

func (obj *ExprCall) Func() (interfaces.Func, error)

Func returns the reactive stream of values that this expression produces. Reminder that this looks very similar to ExprVar...

func (*ExprCall) Graph

func (obj *ExprCall) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This returns a graph with a single vertex (itself) in it, and the edges from all of the child graphs to this.

func (*ExprCall) Init

func (obj *ExprCall) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*ExprCall) Interpolate

func (obj *ExprCall) Interpolate() (interfaces.Expr, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents.

func (*ExprCall) Ordering

func (obj *ExprCall) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in.

func (*ExprCall) SetScope

func (obj *ExprCall) SetScope(scope *interfaces.Scope) error

SetScope stores the scope for later use in this resource and its children, which it propagates this downwards to. This particular function has been heavily optimized to work correctly with calling functions with the correct args. Edit cautiously and with extensive testing.

func (*ExprCall) SetType

func (obj *ExprCall) SetType(typ *types.Type) error

SetType is used to set the type of this expression once it is known. This usually happens during type unification, but it can also happen during parsing if a type is specified explicitly. Since types are static and don't change on expressions, if you attempt to set a different type than what has previously been set (when not initially known) this will error. Remember that for this function expression, the type is the *return type* of the function, not the full type of the function signature.

func (*ExprCall) SetValue

func (obj *ExprCall) SetValue(value types.Value) error

SetValue here is used to store the result of the last computation of this expression node after it has received all the required input values. This value is cached and can be retrieved by calling Value.

func (*ExprCall) String

func (obj *ExprCall) String() string

String returns a short representation of this expression.

func (*ExprCall) Type

func (obj *ExprCall) Type() (*types.Type, error)

Type returns the type of this expression, which is the return type of the function call.

func (*ExprCall) Unify

func (obj *ExprCall) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

func (*ExprCall) Value

func (obj *ExprCall) Value() (types.Value, error)

Value returns the value of this expression in our type system. This will usually only be valid once the engine has run and values have been produced. This might get called speculatively (early) during unification to learn more. It is often unlikely that this kind of speculative execution finds something. This particular implementation of the function returns the previously stored and cached value as received by SetValue.

type ExprFloat

type ExprFloat struct {
	V float64
	// contains filtered or unexported fields
}

ExprFloat is a representation of a float.

func (*ExprFloat) Apply

func (obj *ExprFloat) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*ExprFloat) Copy

func (obj *ExprFloat) Copy() (interfaces.Expr, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*ExprFloat) Func

func (obj *ExprFloat) Func() (interfaces.Func, error)

Func returns the reactive stream of values that this expression produces.

func (*ExprFloat) Graph

func (obj *ExprFloat) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This returns a graph with a single vertex (itself) in it.

func (*ExprFloat) Init

func (obj *ExprFloat) Init(*interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*ExprFloat) Interpolate

func (obj *ExprFloat) Interpolate() (interfaces.Expr, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents. Here it simply returns itself, as no interpolation is possible.

func (*ExprFloat) Ordering

func (obj *ExprFloat) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in.

func (*ExprFloat) SetScope

func (obj *ExprFloat) SetScope(scope *interfaces.Scope) error

SetScope does nothing for this struct, because it has no child nodes, and it does not need to know about the parent scope. It does however store it for later possible use.

func (*ExprFloat) SetType

func (obj *ExprFloat) SetType(typ *types.Type) error

SetType will make no changes if called here. It will error if anything other than a Float is passed in, and doesn't need to be called for this expr to work.

func (*ExprFloat) SetValue

func (obj *ExprFloat) SetValue(value types.Value) error

SetValue for a float expression is always populated statically, and does not ever receive any incoming values (no incoming edges) so this should never be called. It has been implemented for uniformity.

func (*ExprFloat) String

func (obj *ExprFloat) String() string

String returns a short representation of this expression.

func (*ExprFloat) Type

func (obj *ExprFloat) Type() (*types.Type, error)

Type returns the type of this expression. This method always returns Float here.

func (*ExprFloat) Unify

func (obj *ExprFloat) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

func (*ExprFloat) Value

func (obj *ExprFloat) Value() (types.Value, error)

Value returns the value of this expression in our type system. This will usually only be valid once the engine has run and values have been produced. This might get called speculatively (early) during unification to learn more. This particular value is always known since it is a constant.

type ExprFunc

type ExprFunc struct {

	// Title is a friendly-name to use for identifying the function. It can
	// be used in debugging and error-handling. It is not required. It is
	// *not* called Name, because that could get confused with the Name
	// field in ExprCall and similar nodes.
	Title string

	// Args are the list of args that were used when defining the function.
	// This can include a string name and a type, however the type might be
	// absent here.
	Args []*interfaces.Arg
	// Return is the return type of the function if it was defined.
	Return *types.Type // return type if specified
	// Body is the contents of the function. It can be any expression.
	Body interfaces.Expr

	// Function is the built implementation of the function interface as
	// represented by the top-level function API.
	Function func() interfaces.Func // store like this to build on demand!

	// Values represents a list of simple functions. This means this can be
	// polymorphic if more than one was specified!
	Values []*types.FuncValue

	// XXX: is this necessary?
	V func([]types.Value) (types.Value, error)
	// contains filtered or unexported fields
}

ExprFunc is a representation of a function value. This is not a function call, that is represented by ExprCall. This can represent either the contents of a StmtFunc, a lambda function, or a core system function. You may only use one of the internal representations of a function to build this, if you use more than one then the behaviour is not defined, and could conceivably panic. The first possibility is to specify the function via the Args, Return, and Body fields. This is used for native mcl code. The second possibility is to specify the function via the Function field only. This is used for built-in functions that implement the Func API. The third possibility is to specify a list of function values via the Values field. This is used for built-in functions that implement the simple function API or the simplepoly function API and that aren't wrapped in the Func API. (This was the historical case.)

func (*ExprFunc) Apply

func (obj *ExprFunc) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*ExprFunc) Copy

func (obj *ExprFunc) Copy() (interfaces.Expr, error)

Copy returns a light copy of this struct. Anything static will not be copied. All the constants aren't copied, because we don't want to duplicate them unnecessarily in the function graph. For example, an static integer will not ever change, where as a function value (expr) might get used with two different signatures depending on the caller.

func (*ExprFunc) Func

func (obj *ExprFunc) Func() (interfaces.Func, error)

Func returns the reactive stream of values that this expression produces. We need this indirection, because our returned function that actually runs also accepts the "body" of the function (an expr) as an input.

func (*ExprFunc) Graph

func (obj *ExprFunc) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This returns a graph with a single vertex (itself) in it.

func (*ExprFunc) Init

func (obj *ExprFunc) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*ExprFunc) Interpolate

func (obj *ExprFunc) Interpolate() (interfaces.Expr, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents. Here it simply returns itself, as no interpolation is possible.

func (*ExprFunc) Ordering

func (obj *ExprFunc) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in. XXX: do we need to add ordering around named args, eg: obj.Args Name strings?

func (*ExprFunc) SetScope

func (obj *ExprFunc) SetScope(scope *interfaces.Scope) error

SetScope stores the scope for later use in this resource and its children, which it propagates this downwards to.

func (*ExprFunc) SetType

func (obj *ExprFunc) SetType(typ *types.Type) error

SetType is used to set the type of this expression once it is known. This usually happens during type unification, but it can also happen during parsing if a type is specified explicitly. Since types are static and don't change on expressions, if you attempt to set a different type than what has previously been set (when not initially known) this will error.

func (*ExprFunc) SetValue

func (obj *ExprFunc) SetValue(value types.Value) error

SetValue for a func expression is always populated statically, and does not ever receive any incoming values (no incoming edges) so this should never be called. It has been implemented for uniformity.

func (*ExprFunc) String

func (obj *ExprFunc) String() string

String returns a short representation of this expression.

func (*ExprFunc) Type

func (obj *ExprFunc) Type() (*types.Type, error)

Type returns the type of this expression. It will attempt to speculate on the type if it can be determined statically before type unification.

func (*ExprFunc) Unify

func (obj *ExprFunc) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

func (*ExprFunc) Value

func (obj *ExprFunc) Value() (types.Value, error)

Value returns the value of this expression in our type system. This will usually only be valid once the engine has run and values have been produced. This might get called speculatively (early) during unification to learn more. This particular value is always known since it is a constant.

type ExprIf

type ExprIf struct {
	Condition  interfaces.Expr
	ThenBranch interfaces.Expr // could be an ExprBranch
	ElseBranch interfaces.Expr // could be an ExprBranch
	// contains filtered or unexported fields
}

ExprIf represents an if expression which *must* have both branches, and which returns a value. As a result, it has a type. This is different from a StmtIf, which does not need to have both branches, and which does not return a value.

func (*ExprIf) Apply

func (obj *ExprIf) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*ExprIf) Copy

func (obj *ExprIf) Copy() (interfaces.Expr, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*ExprIf) Func

func (obj *ExprIf) Func() (interfaces.Func, error)

Func returns a function which returns the correct branch based on the ever changing conditional boolean input.

func (*ExprIf) Graph

func (obj *ExprIf) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This particular if expression doesn't do anything clever here other than adding in both branches of the graph. Since we're functional, this shouldn't have any ill effects. XXX: is this completely true if we're running technically impure, but safe built-in functions on both branches? Can we turn off half of this?

func (*ExprIf) Init

func (obj *ExprIf) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*ExprIf) Interpolate

func (obj *ExprIf) Interpolate() (interfaces.Expr, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents.

func (*ExprIf) Ordering

func (obj *ExprIf) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in.

func (*ExprIf) SetScope

func (obj *ExprIf) SetScope(scope *interfaces.Scope) error

SetScope stores the scope for later use in this resource and its children, which it propagates this downwards to.

func (*ExprIf) SetType

func (obj *ExprIf) SetType(typ *types.Type) error

SetType is used to set the type of this expression once it is known. This usually happens during type unification, but it can also happen during parsing if a type is specified explicitly. Since types are static and don't change on expressions, if you attempt to set a different type than what has previously been set (when not initially known) this will error.

func (*ExprIf) SetValue

func (obj *ExprIf) SetValue(value types.Value) error

SetValue here is a no-op, because algorithmically when this is called from the func engine, the child fields (the branches expr's) will have had this done to them first, and as such when we try and retrieve the set value from this expression by calling `Value`, it will build it from scratch!

func (*ExprIf) String

func (obj *ExprIf) String() string

String returns a short representation of this expression.

func (*ExprIf) Type

func (obj *ExprIf) Type() (*types.Type, error)

Type returns the type of this expression.

func (*ExprIf) Unify

func (obj *ExprIf) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

func (*ExprIf) Value

func (obj *ExprIf) Value() (types.Value, error)

Value returns the value of this expression in our type system. This will usually only be valid once the engine has run and values have been produced. This might get called speculatively (early) during unification to learn more. This particular expression evaluates the condition and returns the correct branch's value accordingly.

type ExprInt

type ExprInt struct {
	V int64
	// contains filtered or unexported fields
}

ExprInt is a representation of an int.

func (*ExprInt) Apply

func (obj *ExprInt) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*ExprInt) Copy

func (obj *ExprInt) Copy() (interfaces.Expr, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*ExprInt) Func

func (obj *ExprInt) Func() (interfaces.Func, error)

Func returns the reactive stream of values that this expression produces.

func (*ExprInt) Graph

func (obj *ExprInt) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This returns a graph with a single vertex (itself) in it.

func (*ExprInt) Init

func (obj *ExprInt) Init(*interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*ExprInt) Interpolate

func (obj *ExprInt) Interpolate() (interfaces.Expr, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents. Here it simply returns itself, as no interpolation is possible.

func (*ExprInt) Ordering

func (obj *ExprInt) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in.

func (*ExprInt) SetScope

func (obj *ExprInt) SetScope(scope *interfaces.Scope) error

SetScope does nothing for this struct, because it has no child nodes, and it does not need to know about the parent scope. It does however store it for later possible use.

func (*ExprInt) SetType

func (obj *ExprInt) SetType(typ *types.Type) error

SetType will make no changes if called here. It will error if anything other than an Int is passed in, and doesn't need to be called for this expr to work.

func (*ExprInt) SetValue

func (obj *ExprInt) SetValue(value types.Value) error

SetValue for an int expression is always populated statically, and does not ever receive any incoming values (no incoming edges) so this should never be called. It has been implemented for uniformity.

func (*ExprInt) String

func (obj *ExprInt) String() string

String returns a short representation of this expression.

func (*ExprInt) Type

func (obj *ExprInt) Type() (*types.Type, error)

Type returns the type of this expression. This method always returns Int here.

func (*ExprInt) Unify

func (obj *ExprInt) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

func (*ExprInt) Value

func (obj *ExprInt) Value() (types.Value, error)

Value returns the value of this expression in our type system. This will usually only be valid once the engine has run and values have been produced. This might get called speculatively (early) during unification to learn more. This particular value is always known since it is a constant.

type ExprList

type ExprList struct {

	//Elements []*ExprListElement
	Elements []interfaces.Expr
	// contains filtered or unexported fields
}

ExprList is a representation of a list.

func (*ExprList) Apply

func (obj *ExprList) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*ExprList) Copy

func (obj *ExprList) Copy() (interfaces.Expr, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*ExprList) Func

func (obj *ExprList) Func() (interfaces.Func, error)

Func returns the reactive stream of values that this expression produces.

func (*ExprList) Graph

func (obj *ExprList) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This returns a graph with a single vertex (itself) in it, and the edges from all of the child graphs to this.

func (*ExprList) Init

func (obj *ExprList) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*ExprList) Interpolate

func (obj *ExprList) Interpolate() (interfaces.Expr, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents.

func (*ExprList) Ordering

func (obj *ExprList) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in.

func (*ExprList) SetScope

func (obj *ExprList) SetScope(scope *interfaces.Scope) error

SetScope stores the scope for later use in this resource and its children, which it propagates this downwards to.

func (*ExprList) SetType

func (obj *ExprList) SetType(typ *types.Type) error

SetType is used to set the type of this expression once it is known. This usually happens during type unification, but it can also happen during parsing if a type is specified explicitly. Since types are static and don't change on expressions, if you attempt to set a different type than what has previously been set (when not initially known) this will error.

func (*ExprList) SetValue

func (obj *ExprList) SetValue(value types.Value) error

SetValue here is a no-op, because algorithmically when this is called from the func engine, the child elements (the list elements) will have had this done to them first, and as such when we try and retrieve the set value from this expression by calling `Value`, it will build it from scratch!

func (*ExprList) String

func (obj *ExprList) String() string

String returns a short representation of this expression.

func (*ExprList) Type

func (obj *ExprList) Type() (*types.Type, error)

Type returns the type of this expression.

func (*ExprList) Unify

func (obj *ExprList) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

func (*ExprList) Value

func (obj *ExprList) Value() (types.Value, error)

Value returns the value of this expression in our type system. This will usually only be valid once the engine has run and values have been produced. This might get called speculatively (early) during unification to learn more.

type ExprMap

type ExprMap struct {
	KVs []*ExprMapKV
	// contains filtered or unexported fields
}

ExprMap is a representation of a (dictionary) map.

func (*ExprMap) Apply

func (obj *ExprMap) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*ExprMap) Copy

func (obj *ExprMap) Copy() (interfaces.Expr, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*ExprMap) Func

func (obj *ExprMap) Func() (interfaces.Func, error)

Func returns the reactive stream of values that this expression produces.

func (*ExprMap) Graph

func (obj *ExprMap) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This returns a graph with a single vertex (itself) in it, and the edges from all of the child graphs to this.

func (*ExprMap) Init

func (obj *ExprMap) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*ExprMap) Interpolate

func (obj *ExprMap) Interpolate() (interfaces.Expr, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents.

func (*ExprMap) Ordering

func (obj *ExprMap) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in.

func (*ExprMap) SetScope

func (obj *ExprMap) SetScope(scope *interfaces.Scope) error

SetScope stores the scope for later use in this resource and its children, which it propagates this downwards to.

func (*ExprMap) SetType

func (obj *ExprMap) SetType(typ *types.Type) error

SetType is used to set the type of this expression once it is known. This usually happens during type unification, but it can also happen during parsing if a type is specified explicitly. Since types are static and don't change on expressions, if you attempt to set a different type than what has previously been set (when not initially known) this will error.

func (*ExprMap) SetValue

func (obj *ExprMap) SetValue(value types.Value) error

SetValue here is a no-op, because algorithmically when this is called from the func engine, the child key/value's (the map elements) will have had this done to them first, and as such when we try and retrieve the set value from this expression by calling `Value`, it will build it from scratch!

func (*ExprMap) String

func (obj *ExprMap) String() string

String returns a short representation of this expression.

func (*ExprMap) Type

func (obj *ExprMap) Type() (*types.Type, error)

Type returns the type of this expression.

func (*ExprMap) Unify

func (obj *ExprMap) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

func (*ExprMap) Value

func (obj *ExprMap) Value() (types.Value, error)

Value returns the value of this expression in our type system. This will usually only be valid once the engine has run and values have been produced. This might get called speculatively (early) during unification to learn more.

type ExprMapKV

type ExprMapKV struct {
	Key interfaces.Expr // keys can be strings, int's, etc...
	Val interfaces.Expr
}

ExprMapKV represents a key and value pair in a (dictionary) map. This does not satisfy the Expr interface.

type ExprStr

type ExprStr struct {
	V string // value of this string
	// contains filtered or unexported fields
}

ExprStr is a representation of a string.

func (*ExprStr) Apply

func (obj *ExprStr) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*ExprStr) Copy

func (obj *ExprStr) Copy() (interfaces.Expr, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*ExprStr) Func

func (obj *ExprStr) Func() (interfaces.Func, error)

Func returns the reactive stream of values that this expression produces.

func (*ExprStr) Graph

func (obj *ExprStr) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This returns a graph with a single vertex (itself) in it.

func (*ExprStr) Init

func (obj *ExprStr) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*ExprStr) Interpolate

func (obj *ExprStr) Interpolate() (interfaces.Expr, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents. Here it attempts to expand the string if there are any internal variables which need interpolation. If any are found, it returns a larger AST which has a function which returns a string as its root. Otherwise it returns itself.

func (*ExprStr) Ordering

func (obj *ExprStr) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in. This Ordering method runs *after* the Interpolate method, so if this originally would have expanded into a bigger AST, but the time Ordering runs, this is only used on a raw string expression. As a result, it doesn't need to build a map of consumed nodes, because none are consumed. The returned graph is empty!

func (*ExprStr) SetScope

func (obj *ExprStr) SetScope(scope *interfaces.Scope) error

SetScope does nothing for this struct, because it has no child nodes, and it does not need to know about the parent scope. It does however store it for later possible use.

func (*ExprStr) SetType

func (obj *ExprStr) SetType(typ *types.Type) error

SetType will make no changes if called here. It will error if anything other than an Str is passed in, and doesn't need to be called for this expr to work.

func (*ExprStr) SetValue

func (obj *ExprStr) SetValue(value types.Value) error

SetValue for an str expression is always populated statically, and does not ever receive any incoming values (no incoming edges) so this should never be called. It has been implemented for uniformity.

func (*ExprStr) String

func (obj *ExprStr) String() string

String returns a short representation of this expression.

func (*ExprStr) Type

func (obj *ExprStr) Type() (*types.Type, error)

Type returns the type of this expression. This method always returns Str here.

func (*ExprStr) Unify

func (obj *ExprStr) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

func (*ExprStr) Value

func (obj *ExprStr) Value() (types.Value, error)

Value returns the value of this expression in our type system. This will usually only be valid once the engine has run and values have been produced. This might get called speculatively (early) during unification to learn more. This particular value is always known since it is a constant.

type ExprStruct

type ExprStruct struct {
	Fields []*ExprStructField // the list (fields) are intentionally ordered!
	// contains filtered or unexported fields
}

ExprStruct is a representation of a struct.

func (*ExprStruct) Apply

func (obj *ExprStruct) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*ExprStruct) Copy

func (obj *ExprStruct) Copy() (interfaces.Expr, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*ExprStruct) Func

func (obj *ExprStruct) Func() (interfaces.Func, error)

Func returns the reactive stream of values that this expression produces.

func (*ExprStruct) Graph

func (obj *ExprStruct) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This returns a graph with a single vertex (itself) in it, and the edges from all of the child graphs to this.

func (*ExprStruct) Init

func (obj *ExprStruct) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*ExprStruct) Interpolate

func (obj *ExprStruct) Interpolate() (interfaces.Expr, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents.

func (*ExprStruct) Ordering

func (obj *ExprStruct) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in.

func (*ExprStruct) SetScope

func (obj *ExprStruct) SetScope(scope *interfaces.Scope) error

SetScope stores the scope for later use in this resource and its children, which it propagates this downwards to.

func (*ExprStruct) SetType

func (obj *ExprStruct) SetType(typ *types.Type) error

SetType is used to set the type of this expression once it is known. This usually happens during type unification, but it can also happen during parsing if a type is specified explicitly. Since types are static and don't change on expressions, if you attempt to set a different type than what has previously been set (when not initially known) this will error.

func (*ExprStruct) SetValue

func (obj *ExprStruct) SetValue(value types.Value) error

SetValue here is a no-op, because algorithmically when this is called from the func engine, the child fields (the struct elements) will have had this done to them first, and as such when we try and retrieve the set value from this expression by calling `Value`, it will build it from scratch!

func (*ExprStruct) String

func (obj *ExprStruct) String() string

String returns a short representation of this expression.

func (*ExprStruct) Type

func (obj *ExprStruct) Type() (*types.Type, error)

Type returns the type of this expression.

func (*ExprStruct) Unify

func (obj *ExprStruct) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

func (*ExprStruct) Value

func (obj *ExprStruct) Value() (types.Value, error)

Value returns the value of this expression in our type system. This will usually only be valid once the engine has run and values have been produced. This might get called speculatively (early) during unification to learn more.

type ExprStructField

type ExprStructField struct {
	Name  string
	Value interfaces.Expr
}

ExprStructField represents a name value pair in a struct field. This does not satisfy the Expr interface.

type ExprVar

type ExprVar struct {
	Name string // name of the variable
	// contains filtered or unexported fields
}

ExprVar is a representation of a variable lookup. It returns the expression that that variable refers to.

func (*ExprVar) Apply

func (obj *ExprVar) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*ExprVar) Copy

func (obj *ExprVar) Copy() (interfaces.Expr, error)

Copy returns a light copy of this struct. Anything static will not be copied. This intentionally returns a copy, because if a function (usually a lambda) that is used more than once, contains this variable, we will want each instantiation of it to be unique, otherwise they will be the same pointer, and they won't be able to have different values.

func (*ExprVar) Func

func (obj *ExprVar) Func() (interfaces.Func, error)

Func returns a "pass-through" function which receives the bound value, and passes it to the consumer. This is essential for satisfying the type checker of the function graph engine. Reminder that this looks very similar to ExprCall...

func (*ExprVar) Graph

func (obj *ExprVar) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This returns a graph with a single vertex (itself) in it, and the edges from all of the child graphs to this. The child graph in this case is the graph which is obtained from the bound expression. The edge points from that expression to this vertex. The function used for this vertex is a simple placeholder which sucks incoming values in and passes them on. This is important for filling the logical requirements of the graph type checker, and to avoid duplicating production of the incoming input value from the bound expression.

func (*ExprVar) Init

func (obj *ExprVar) Init(*interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*ExprVar) Interpolate

func (obj *ExprVar) Interpolate() (interfaces.Expr, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents. Here it returns itself, since variable names cannot be interpolated. We don't support variable, variables or anything crazy like that.

func (*ExprVar) Ordering

func (obj *ExprVar) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in.

func (*ExprVar) SetScope

func (obj *ExprVar) SetScope(scope *interfaces.Scope) error

SetScope stores the scope for use in this resource.

func (*ExprVar) SetType

func (obj *ExprVar) SetType(typ *types.Type) error

SetType is used to set the type of this expression once it is known. This usually happens during type unification, but it can also happen during parsing if a type is specified explicitly. Since types are static and don't change on expressions, if you attempt to set a different type than what has previously been set (when not initially known) this will error.

func (*ExprVar) SetValue

func (obj *ExprVar) SetValue(value types.Value) error

SetValue here is a no-op, because algorithmically when this is called from the func engine, the child fields (the dest lookup expr) will have had this done to them first, and as such when we try and retrieve the set value from this expression by calling `Value`, it will build it from scratch!

func (*ExprVar) String

func (obj *ExprVar) String() string

String returns a short representation of this expression.

func (*ExprVar) Type

func (obj *ExprVar) Type() (*types.Type, error)

Type returns the type of this expression.

func (*ExprVar) Unify

func (obj *ExprVar) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

func (*ExprVar) Value

func (obj *ExprVar) Value() (types.Value, error)

Value returns the value of this expression in our type system. This will usually only be valid once the engine has run and values have been produced. This might get called speculatively (early) during unification to learn more. This returns the value this variable points to. It is able to do so because it can lookup in the previous set scope which expression this points to, and then it can call Value on that expression.

type GAPI

type GAPI struct {
	InputURI string // input URI of code file system to run
	// contains filtered or unexported fields
}

GAPI implements the main lang GAPI interface.

func (*GAPI) Cli

func (obj *GAPI) Cli(cliInfo *gapi.CliInfo) (*gapi.Deploy, error)

Cli takes a cli.Context, and returns our GAPI if activated. All arguments should take the prefix of the registered name. On activation, if there are any validation problems, you should return an error. If this was not activated, then you should return a nil GAPI and a nil error. This is passed in a functional file system interface. For standalone usage, this will be a temporary memory-backed filesystem so that the same deploy API is used, and for normal clustered usage, this will be the normal implementation which is usually an etcd backed fs. At this point we should be copying the necessary local file system data into our fs for future use when the GAPI is running. IOW, running this Cli function, when activated, produces a deploy object which is run by our main loop. The difference between running from `deploy` or from `run` (both of which can activate this GAPI) is that `deploy` copies to an etcdFs, and `run` copies to a memFs. All GAPI's run off of the fs that is passed in.

func (*GAPI) CliFlags

func (obj *GAPI) CliFlags(command string) []cli.Flag

CliFlags returns a list of flags used by the specified subcommand.

func (*GAPI) Close

func (obj *GAPI) Close() error

Close shuts down the lang GAPI.

func (*GAPI) Get

func (obj *GAPI) Get(getInfo *gapi.GetInfo) error

Get runs the necessary downloads. This basically runs the lexer, parser and sets the scope so that all the imports are followed. It passes a downloader in, which can be used to pull down or update any missing imports. This will also work when called with the download flag during a normal execution run.

func (*GAPI) Graph

func (obj *GAPI) Graph() (*pgraph.Graph, error)

Graph returns a current Graph.

func (*GAPI) Init

func (obj *GAPI) Init(data *gapi.Data) error

Init initializes the lang GAPI struct.

func (*GAPI) LangClose

func (obj *GAPI) LangClose() error

LangClose is a wrapper around the lang Close method.

func (*GAPI) LangInit

func (obj *GAPI) LangInit() error

LangInit is a wrapper around the lang Init method.

func (*GAPI) Next

func (obj *GAPI) Next() chan gapi.Next

Next returns nil errors every time there could be a new graph.

type Lang

type Lang struct {
	Fs    engine.Fs // connected fs where input dir or metadata exists
	FsURI string

	// Input is a string which specifies what the lang should run. It can
	// accept values in several different forms. If is passed a single dash
	// (-), then it will use `os.Stdin`. If it is passed a single .mcl file,
	// then it will attempt to run that. If it is passed a directory path,
	// then it will attempt to run from there. Instead, if it is passed the
	// path to a metadata file, then it will attempt to parse that and run
	// from that specification. If none of those match, it will attempt to
	// run the raw string as mcl code.
	Input string

	Hostname string
	World    engine.World
	Prefix   string
	Debug    bool
	Logf     func(format string, v ...interface{})
	// contains filtered or unexported fields
}

Lang is the main language lexer/parser object.

func (*Lang) Close

func (obj *Lang) Close() error

Close shuts down the lang struct and causes all the funcs to shutdown. It must be called when finished after any successful Init ran.

func (*Lang) Init

func (obj *Lang) Init() error

Init initializes the lang struct, and starts up the initial data sources. NOTE: The trick is that we need to get the list of funcs to watch AND start watching them, *before* we pull their values, that way we'll know if they changed from the values we wanted.

func (*Lang) Interpret

func (obj *Lang) Interpret() (*pgraph.Graph, error)

Interpret runs the interpreter and returns a graph and corresponding error.

func (*Lang) Stream

func (obj *Lang) Stream() chan error

Stream returns a channel of graph change requests or errors. These are usually sent when a func output changes.

type LexParseErr

type LexParseErr struct {
	Err interfaces.Error
	Str string
	Row int // this is zero-indexed (the first line is 0)
	Col int // this is zero-indexed (the first char is 0)

	// Filename is the file that this error occurred in. If this is unknown,
	// then it will be empty. This is not set when run by the basic LexParse
	// function.
	Filename string
}

LexParseErr is a permanent failure error to notify about borkage.

func (*LexParseErr) Error

func (e *LexParseErr) Error() string

Error displays this error with all the relevant state information.

type ParsedInput

type ParsedInput struct {
	//activated bool // if struct is not nil we're activated
	Base     string   // base path (abs path with trailing slash)
	Main     []byte   // contents of main entry mcl code
	Files    []string // files and dirs to copy to fs (abs paths)
	Metadata *interfaces.Metadata
	Workers  []func(engine.Fs) error // copy files here that aren't listed!
}

ParsedInput is the output struct which contains all the information we need.

type Pos

type Pos struct {
	Line     int    // line number starting at 1
	Column   int    // column number starting at 1
	Filename string // optional source filename, if known
}

Pos represents a position in the code. TODO: consider expanding with range characteristics.

type StmtBind

type StmtBind struct {
	Ident string
	Value interfaces.Expr
}

StmtBind is a representation of an assignment, which binds a variable to an expression.

func (*StmtBind) Apply

func (obj *StmtBind) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*StmtBind) Copy

func (obj *StmtBind) Copy() (interfaces.Stmt, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*StmtBind) Graph

func (obj *StmtBind) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This particular bind statement adds its linked expression to the graph. It is not logically done in the ExprVar since that could exist multiple times for the single binding operation done here.

func (*StmtBind) Init

func (obj *StmtBind) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*StmtBind) Interpolate

func (obj *StmtBind) Interpolate() (interfaces.Stmt, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents.

func (*StmtBind) Ordering

func (obj *StmtBind) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in. We only really care about the consumers here, because the "produces" aspect of this resource is handled by the StmtProg Ordering function. This is because the "prog" allows out-of-order statements, therefore it solves this by running an early (second) loop through the program and peering into this Stmt and extracting the produced name.

func (*StmtBind) Output

func (obj *StmtBind) Output() (*interfaces.Output, error)

Output for the bind statement produces no output. Any values of interest come from the use of the var which this binds the expression to.

func (*StmtBind) SetScope

func (obj *StmtBind) SetScope(scope *interfaces.Scope) error

SetScope sets the scope of the child expression bound to it. It seems this is necessary in order to reach this, in particular in situations when a bound expression points to a previously bound expression.

func (*StmtBind) String

func (obj *StmtBind) String() string

String returns a short representation of this statement.

func (*StmtBind) Unify

func (obj *StmtBind) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

type StmtClass

type StmtClass struct {
	Name string
	Args []*interfaces.Arg
	Body interfaces.Stmt // probably a *StmtProg
	// contains filtered or unexported fields
}

StmtClass represents a user defined class. It's effectively a program body that can optionally take some parameterized inputs. TODO: We don't currently support defining polymorphic classes (eg: different signatures for the same class name) but it might be something to consider.

func (*StmtClass) Apply

func (obj *StmtClass) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*StmtClass) Copy

func (obj *StmtClass) Copy() (interfaces.Stmt, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*StmtClass) Graph

func (obj *StmtClass) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This particular func statement adds its linked expression to the graph.

func (*StmtClass) Init

func (obj *StmtClass) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*StmtClass) Interpolate

func (obj *StmtClass) Interpolate() (interfaces.Stmt, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents.

func (*StmtClass) Ordering

func (obj *StmtClass) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in. We only really care about the consumers here, because the "produces" aspect of this resource is handled by the StmtProg Ordering function. This is because the "prog" allows out-of-order statements, therefore it solves this by running an early (second) loop through the program and peering into this Stmt and extracting the produced name. TODO: Is Ordering in StmtInclude done properly and in sync with this? XXX: do we need to add ordering around named args, eg: obj.Args Name strings?

func (*StmtClass) Output

func (obj *StmtClass) Output() (*interfaces.Output, error)

Output for the class statement produces no output. Any values of interest come from the use of the include which this binds the statements to. This is usually called from the parent in StmtProg, but it skips running it so that it can be called from the StmtInclude Output method.

func (*StmtClass) SetScope

func (obj *StmtClass) SetScope(scope *interfaces.Scope) error

SetScope sets the scope of the child expression bound to it. It seems this is necessary in order to reach this, in particular in situations when a bound expression points to a previously bound expression.

func (*StmtClass) String

func (obj *StmtClass) String() string

String returns a short representation of this statement.

func (*StmtClass) Unify

func (obj *StmtClass) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

type StmtComment

type StmtComment struct {
	Value string
}

StmtComment is a representation of a comment. It is currently unused. It probably makes sense to make a third kind of Node (not a Stmt or an Expr) so that comments can still be part of the AST (for eventual automatic code formatting) but so that they can exist anywhere in the code. Currently these are dropped by the lexer.

func (*StmtComment) Apply

func (obj *StmtComment) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*StmtComment) Copy

func (obj *StmtComment) Copy() (interfaces.Stmt, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*StmtComment) Graph

func (obj *StmtComment) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This particular graph does nothing clever.

func (*StmtComment) Init

func (obj *StmtComment) Init(*interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*StmtComment) Interpolate

func (obj *StmtComment) Interpolate() (interfaces.Stmt, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents. Here it simply returns itself, as no interpolation is possible.

func (*StmtComment) Ordering

func (obj *StmtComment) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in.

func (*StmtComment) Output

func (obj *StmtComment) Output() (*interfaces.Output, error)

Output for the comment statement produces no output.

func (*StmtComment) SetScope

func (obj *StmtComment) SetScope(*interfaces.Scope) error

SetScope does nothing for this struct, because it has no child nodes, and it does not need to know about the parent scope.

func (*StmtComment) String

func (obj *StmtComment) String() string

String returns a short representation of this statement.

func (*StmtComment) Unify

func (obj *StmtComment) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

type StmtEdge

type StmtEdge struct {
	EdgeHalfList []*StmtEdgeHalf // represents a chain of edges

	// TODO: should notify be an Expr?
	Notify bool // specifies that this edge sends a notification as well
}

StmtEdge is a representation of a dependency. It also supports send/recv. Edges represents that the first resource (Kind/Name) listed in the EdgeHalfList should happen in the resource graph *before* the next resource in the list. If there are multiple StmtEdgeHalf structs listed, then they should represent a chain, eg: a->b->c, should compile into a->b & b->c. If specified, values are sent and received along these edges if the Send/Recv names are compatible and listed. In this case of Send/Recv, only lists of length two are legal.

func (*StmtEdge) Apply

func (obj *StmtEdge) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*StmtEdge) Copy

func (obj *StmtEdge) Copy() (interfaces.Stmt, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*StmtEdge) Graph

func (obj *StmtEdge) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. It is interesting to note that nothing directly adds an edge to the edges created, but rather, once all the values (expressions) with no outgoing function graph edges have produced at least a single value, then the edges know they're able to be built.

func (*StmtEdge) Init

func (obj *StmtEdge) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*StmtEdge) Interpolate

func (obj *StmtEdge) Interpolate() (interfaces.Stmt, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents. TODO: could we expand the Name's from the EdgeHalf (if they're lists) to have them return a list of Edges's ? XXX: type check the kind1:send -> kind2:recv fields are compatible! XXX: we won't know the names yet, but it's okay.

func (*StmtEdge) Ordering

func (obj *StmtEdge) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in.

func (*StmtEdge) Output

func (obj *StmtEdge) Output() (*interfaces.Output, error)

Output returns the output that this "program" produces. This output is what is used to build the output graph. This only exists for statements. The analogous function for expressions is Value. Those Value functions might get called by this Output function if they are needed to produce the output. In the case of this edge statement, this is definitely the case. This edge stmt returns output consisting of edges.

func (*StmtEdge) SetScope

func (obj *StmtEdge) SetScope(scope *interfaces.Scope) error

SetScope stores the scope for later use in this resource and its children, which it propagates this downwards to.

func (*StmtEdge) String

func (obj *StmtEdge) String() string

String returns a short representation of this statement.

func (*StmtEdge) Unify

func (obj *StmtEdge) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

type StmtEdgeHalf

type StmtEdgeHalf struct {
	Kind     string          // kind of resource, eg: pkg, file, svc, etc...
	Name     interfaces.Expr // unique name for the res of this kind
	SendRecv string          // name of field to send/recv from/to, empty to ignore
}

StmtEdgeHalf represents half of an edge in the parsed edge representation. This does not satisfy the Stmt interface.

func (*StmtEdgeHalf) Apply

func (obj *StmtEdgeHalf) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*StmtEdgeHalf) Copy

func (obj *StmtEdgeHalf) Copy() (*StmtEdgeHalf, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*StmtEdgeHalf) Graph

func (obj *StmtEdgeHalf) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. It is interesting to note that nothing directly adds an edge to the resources created, but rather, once all the values (expressions) with no outgoing edges have produced at least a single value, then the resources know they're able to be built.

func (*StmtEdgeHalf) Init

func (obj *StmtEdgeHalf) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*StmtEdgeHalf) Interpolate

func (obj *StmtEdgeHalf) Interpolate() (*StmtEdgeHalf, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents. This interpolate is different It is different from the interpolate found in the Expr and Stmt interfaces because it returns a different type as output.

func (*StmtEdgeHalf) SetScope

func (obj *StmtEdgeHalf) SetScope(scope *interfaces.Scope) error

SetScope stores the scope for later use in this resource and its children, which it propagates this downwards to.

func (*StmtEdgeHalf) String

func (obj *StmtEdgeHalf) String() string

String returns a short representation of this statement.

func (*StmtEdgeHalf) Unify

func (obj *StmtEdgeHalf) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

type StmtFunc

type StmtFunc struct {
	Name string
	//Func *ExprFunc // TODO: should it be this instead?
	Func interfaces.Expr // TODO: is this correct?
}

StmtFunc represents a user defined function. It binds the specified name to the supplied function in the current scope and irrespective of the order of definition.

func (*StmtFunc) Apply

func (obj *StmtFunc) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*StmtFunc) Copy

func (obj *StmtFunc) Copy() (interfaces.Stmt, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*StmtFunc) Graph

func (obj *StmtFunc) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This particular func statement adds its linked expression to the graph.

func (*StmtFunc) Init

func (obj *StmtFunc) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*StmtFunc) Interpolate

func (obj *StmtFunc) Interpolate() (interfaces.Stmt, error)

Interpolate returns a new node (or itself) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents.

func (*StmtFunc) Ordering

func (obj *StmtFunc) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in. We only really care about the consumers here, because the "produces" aspect of this resource is handled by the StmtProg Ordering function. This is because the "prog" allows out-of-order statements, therefore it solves this by running an early (second) loop through the program and peering into this Stmt and extracting the produced name.

func (*StmtFunc) Output

func (obj *StmtFunc) Output() (*interfaces.Output, error)

Output for the func statement produces no output. Any values of interest come from the use of the func which this binds the function to.

func (*StmtFunc) SetScope

func (obj *StmtFunc) SetScope(scope *interfaces.Scope) error

SetScope sets the scope of the child expression bound to it. It seems this is necessary in order to reach this, in particular in situations when a bound expression points to a previously bound expression.

func (*StmtFunc) String

func (obj *StmtFunc) String() string

String returns a short representation of this statement.

func (*StmtFunc) Unify

func (obj *StmtFunc) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

type StmtIf

type StmtIf struct {
	Condition  interfaces.Expr
	ThenBranch interfaces.Stmt // optional, but usually present
	ElseBranch interfaces.Stmt // optional
}

StmtIf represents an if condition that contains between one and two branches of statements to be executed based on the evaluation of the boolean condition over time. In particular, this is different from an ExprIf which returns a value, where as this produces some Output. Normally if one of the branches is optional, it is the else branch, although this struct allows either to be optional, even if it is not commonly used.

func (*StmtIf) Apply

func (obj *StmtIf) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*StmtIf) Copy

func (obj *StmtIf) Copy() (interfaces.Stmt, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*StmtIf) Graph

func (obj *StmtIf) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This particular if statement doesn't do anything clever here other than adding in both branches of the graph. Since we're functional, this shouldn't have any ill effects. XXX: is this completely true if we're running technically impure, but safe built-in functions on both branches? Can we turn off half of this?

func (*StmtIf) Init

func (obj *StmtIf) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*StmtIf) Interpolate

func (obj *StmtIf) Interpolate() (interfaces.Stmt, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents.

func (*StmtIf) Ordering

func (obj *StmtIf) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in.

func (*StmtIf) Output

func (obj *StmtIf) Output() (*interfaces.Output, error)

Output returns the output that this "program" produces. This output is what is used to build the output graph. This only exists for statements. The analogous function for expressions is Value. Those Value functions might get called by this Output function if they are needed to produce the output.

func (*StmtIf) SetScope

func (obj *StmtIf) SetScope(scope *interfaces.Scope) error

SetScope stores the scope for later use in this resource and its children, which it propagates this downwards to.

func (*StmtIf) String

func (obj *StmtIf) String() string

String returns a short representation of this statement.

func (*StmtIf) Unify

func (obj *StmtIf) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

type StmtImport

type StmtImport struct {
	Name  string
	Alias string
}

StmtImport adds the exported scope definitions of a module into the current scope. It can be used anywhere a statement is allowed, and can even be nested inside a class definition. By convention, it is commonly used at the top of a file. As with any statement, it produces output, but that output is empty. To benefit from its inclusion, reference the scope definitions you want.

func (*StmtImport) Apply

func (obj *StmtImport) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*StmtImport) Copy

func (obj *StmtImport) Copy() (interfaces.Stmt, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*StmtImport) Graph

func (obj *StmtImport) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This particular statement just returns an empty graph.

func (*StmtImport) Init

func (obj *StmtImport) Init(*interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*StmtImport) Interpolate

func (obj *StmtImport) Interpolate() (interfaces.Stmt, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents.

func (*StmtImport) Ordering

func (obj *StmtImport) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in. Nothing special happens in this method, the import magic happens in StmtProg.

func (*StmtImport) Output

func (obj *StmtImport) Output() (*interfaces.Output, error)

Output returns the output that this include produces. This output is what is used to build the output graph. This only exists for statements. The analogous function for expressions is Value. Those Value functions might get called by this Output function if they are needed to produce the output. This import statement itself produces no output, as it is only used to populate the scope so that others can use that to produce values and output.

func (*StmtImport) SetScope

func (obj *StmtImport) SetScope(*interfaces.Scope) error

SetScope stores the scope for later use in this resource and its children, which it propagates this downwards to.

func (*StmtImport) String

func (obj *StmtImport) String() string

String returns a short representation of this statement.

func (*StmtImport) Unify

func (obj *StmtImport) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

type StmtInclude

type StmtInclude struct {
	Name string
	Args []interfaces.Expr
	// contains filtered or unexported fields
}

StmtInclude causes a user defined class to get used. It's effectively the way to call a class except that it produces output instead of a value. Most of the interesting logic for classes happens here or in StmtProg.

func (*StmtInclude) Apply

func (obj *StmtInclude) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*StmtInclude) Copy

func (obj *StmtInclude) Copy() (interfaces.Stmt, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*StmtInclude) Graph

func (obj *StmtInclude) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. This particular func statement adds its linked expression to the graph.

func (*StmtInclude) Init

func (obj *StmtInclude) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*StmtInclude) Interpolate

func (obj *StmtInclude) Interpolate() (interfaces.Stmt, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents.

func (*StmtInclude) Ordering

func (obj *StmtInclude) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in. TODO: Is Ordering in StmtClass done properly and in sync with this?

func (*StmtInclude) Output

func (obj *StmtInclude) Output() (*interfaces.Output, error)

Output returns the output that this include produces. This output is what is used to build the output graph. This only exists for statements. The analogous function for expressions is Value. Those Value functions might get called by this Output function if they are needed to produce the output. The ultimate source of this output comes from the previously defined StmtClass which should be found in our scope.

func (*StmtInclude) SetScope

func (obj *StmtInclude) SetScope(scope *interfaces.Scope) error

SetScope stores the scope for use in this statement. Since this is the first location where recursion would play an important role, this also detects and handles the recursion scenario.

func (*StmtInclude) String

func (obj *StmtInclude) String() string

String returns a short representation of this statement.

func (*StmtInclude) Unify

func (obj *StmtInclude) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

type StmtProg

type StmtProg struct {
	Prog []interfaces.Stmt
	// contains filtered or unexported fields
}

StmtProg represents a list of stmt's. This usually occurs at the top-level of any program, and often within an if stmt. It also contains the logic so that the bind statement's are correctly applied in this scope, and irrespective of their order of definition.

func (*StmtProg) Apply

func (obj *StmtProg) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*StmtProg) Copy

func (obj *StmtProg) Copy() (interfaces.Stmt, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*StmtProg) Graph

func (obj *StmtProg) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might.

func (*StmtProg) Init

func (obj *StmtProg) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*StmtProg) Interpolate

func (obj *StmtProg) Interpolate() (interfaces.Stmt, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents.

func (*StmtProg) IsModuleUnsafe

func (obj *StmtProg) IsModuleUnsafe() error

IsModuleUnsafe returns whether or not this StmtProg is unsafe to consume as a module scope. IOW, if someone writes a module which is imported and which has statements other than bind, func, class or import, then it is not correct to import, since those other elements wouldn't be used, and might provide a false belief that they'll get included when mgmt imports that module. SetScope should be called before this is used. (TODO: verify this) TODO: return a multierr with all the unsafe elements, to provide better info TODO: technically this could be a method on Stmt, possibly using Apply...

func (*StmtProg) Ordering

func (obj *StmtProg) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in. The interesting part of the Ordering determination happens right here in StmtProg. This first looks at all the children to see what this produces, and then it recursively builds the graph by looking into all the children with this information from the first pass. We link production and consumption via a unique string name which is used to determine flow. Of particular note, all of this happens *before* SetScope, so we cannot follow references in the scope. The input to this method is a mapping of the the produced unique names in the parent "scope", to their associated node pointers. This returns a map of what is consumed in the child AST. The map is reversed, because two different nodes could consume the same variable key. TODO: deal with StmtImport's by returning them as first if necessary?

func (*StmtProg) Output

func (obj *StmtProg) Output() (*interfaces.Output, error)

Output returns the output that this "program" produces. This output is what is used to build the output graph. This only exists for statements. The analogous function for expressions is Value. Those Value functions might get called by this Output function if they are needed to produce the output.

func (*StmtProg) SetScope

func (obj *StmtProg) SetScope(scope *interfaces.Scope) error

SetScope propagates the scope into its list of statements. It does so cleverly by first collecting all bind and func statements and adding those into the scope after checking for any collisions. Finally it pushes the new scope downwards to all child statements. If we support user defined function polymorphism via multiple function definition, then these are built together here. This SetScope is the one which follows the import statements. If it can't follow one (perhaps it wasn't downloaded yet, and is missing) then it leaves some information about these missing imports in the AST and errors, so that a subsequent AST traversal (usually via Apply) can collect this detailed information to be used by the downloader. When it propagates the scope downwards, it first pushes it into all the classes, and then into everything else (including the include stmt's) because the include statements require that the scope already be known so that it can be combined with the include args.

func (*StmtProg) String

func (obj *StmtProg) String() string

String returns a short representation of this statement.

func (*StmtProg) Unify

func (obj *StmtProg) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

type StmtRes

type StmtRes struct {
	Kind     string            // kind of resource, eg: pkg, file, svc, etc...
	Name     interfaces.Expr   // unique name for the res of this kind
	Contents []StmtResContents // list of fields/edges in parsed order
	// contains filtered or unexported fields
}

StmtRes is a representation of a resource and possibly some edges. The `Name` value can be a single string or a list of strings. The former will produce a single resource, the latter produces a list of resources. Using this list mechanism is a safe alternative to traditional flow control like `for` loops. TODO: Consider expanding Name to have this return a list of Res's in the Output function if it is a map[name]struct{}, or even a map[[]name]struct{}.

func (*StmtRes) Apply

func (obj *StmtRes) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*StmtRes) Copy

func (obj *StmtRes) Copy() (interfaces.Stmt, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*StmtRes) Graph

func (obj *StmtRes) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. It is interesting to note that nothing directly adds an edge to the resources created, but rather, once all the values (expressions) with no outgoing edges have produced at least a single value, then the resources know they're able to be built.

This runs right after type unification. For this particular resource, we can do some additional static analysis, but only after unification has been done. Since I don't think it's worth extending the Stmt API for this, we can do the checks here at the beginning, and error out if something was invalid. In this particular case, the issue is one of catching duplicate meta fields.

func (*StmtRes) Init

func (obj *StmtRes) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*StmtRes) Interpolate

func (obj *StmtRes) Interpolate() (interfaces.Stmt, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents.

func (*StmtRes) Ordering

func (obj *StmtRes) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in.

func (*StmtRes) Output

func (obj *StmtRes) Output() (*interfaces.Output, error)

Output returns the output that this "program" produces. This output is what is used to build the output graph. This only exists for statements. The analogous function for expressions is Value. Those Value functions might get called by this Output function if they are needed to produce the output. In the case of this resource statement, this is definitely the case.

func (*StmtRes) SetScope

func (obj *StmtRes) SetScope(scope *interfaces.Scope) error

SetScope stores the scope for later use in this resource and its children, which it propagates this downwards to.

func (*StmtRes) String

func (obj *StmtRes) String() string

String returns a short representation of this statement.

func (*StmtRes) Unify

func (obj *StmtRes) Unify() ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller.

type StmtResContents

type StmtResContents interface {
	interfaces.Node
	Init(*interfaces.Data) error
	Interpolate() (StmtResContents, error) // different!
	Copy() (StmtResContents, error)
	Ordering(map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)
	SetScope(*interfaces.Scope) error
	Unify(kind string) ([]interfaces.Invariant, error) // different!
	Graph() (*pgraph.Graph, error)
}

StmtResContents is the interface that is met by the resource contents. Look closely for while it is similar to the Stmt interface, it is quite different.

type StmtResEdge

type StmtResEdge struct {
	Property  string // TODO: iota constant instead?
	EdgeHalf  *StmtEdgeHalf
	Condition interfaces.Expr // the value will be used if nil or true
}

StmtResEdge represents a single edge property in the parsed resource representation. This does not satisfy the Stmt interface.

func (*StmtResEdge) Apply

func (obj *StmtResEdge) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*StmtResEdge) Copy

func (obj *StmtResEdge) Copy() (StmtResContents, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*StmtResEdge) Graph

func (obj *StmtResEdge) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. It is interesting to note that nothing directly adds an edge to the resources created, but rather, once all the values (expressions) with no outgoing edges have produced at least a single value, then the resources know they're able to be built.

func (*StmtResEdge) Init

func (obj *StmtResEdge) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*StmtResEdge) Interpolate

func (obj *StmtResEdge) Interpolate() (StmtResContents, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents. This interpolate is different It is different from the interpolate found in the Expr and Stmt interfaces because it returns a different type as output.

func (*StmtResEdge) Ordering

func (obj *StmtResEdge) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in.

func (*StmtResEdge) SetScope

func (obj *StmtResEdge) SetScope(scope *interfaces.Scope) error

SetScope stores the scope for later use in this resource and its children, which it propagates this downwards to.

func (*StmtResEdge) String

func (obj *StmtResEdge) String() string

String returns a short representation of this statement.

func (*StmtResEdge) Unify

func (obj *StmtResEdge) Unify(kind string) ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller. It is different from the Unify found in the Expr and Stmt interfaces because it adds an input parameter.

type StmtResField

type StmtResField struct {
	Field     string
	Value     interfaces.Expr
	Condition interfaces.Expr // the value will be used if nil or true
}

StmtResField represents a single field in the parsed resource representation. This does not satisfy the Stmt interface.

func (*StmtResField) Apply

func (obj *StmtResField) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*StmtResField) Copy

func (obj *StmtResField) Copy() (StmtResContents, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*StmtResField) Graph

func (obj *StmtResField) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. It is interesting to note that nothing directly adds an edge to the resources created, but rather, once all the values (expressions) with no outgoing edges have produced at least a single value, then the resources know they're able to be built.

func (*StmtResField) Init

func (obj *StmtResField) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*StmtResField) Interpolate

func (obj *StmtResField) Interpolate() (StmtResContents, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents. This interpolate is different It is different from the interpolate found in the Expr and Stmt interfaces because it returns a different type as output.

func (*StmtResField) Ordering

func (obj *StmtResField) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in.

func (*StmtResField) SetScope

func (obj *StmtResField) SetScope(scope *interfaces.Scope) error

SetScope stores the scope for later use in this resource and its children, which it propagates this downwards to.

func (*StmtResField) String

func (obj *StmtResField) String() string

String returns a short representation of this statement.

func (*StmtResField) Unify

func (obj *StmtResField) Unify(kind string) ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller. It is different from the Unify found in the Expr and Stmt interfaces because it adds an input parameter.

type StmtResMeta

type StmtResMeta struct {
	Property  string // TODO: iota constant instead?
	MetaExpr  interfaces.Expr
	Condition interfaces.Expr // the value will be used if nil or true
}

StmtResMeta represents a single meta value in the parsed resource representation. It can also contain a struct that contains one or more meta parameters. If it contains such a struct, then the `Property` field contains the string found in the MetaField constant, otherwise this field will correspond to the particular meta parameter specified. This does not satisfy the Stmt interface.

func (*StmtResMeta) Apply

func (obj *StmtResMeta) Apply(fn func(interfaces.Node) error) error

Apply is a general purpose iterator method that operates on any AST node. It is not used as the primary AST traversal function because it is less readable and easy to reason about than manually implementing traversal for each node. Nevertheless, it is a useful facility for operations that might only apply to a select number of node types, since they won't need extra noop iterators...

func (*StmtResMeta) Copy

func (obj *StmtResMeta) Copy() (StmtResContents, error)

Copy returns a light copy of this struct. Anything static will not be copied.

func (*StmtResMeta) Graph

func (obj *StmtResMeta) Graph() (*pgraph.Graph, error)

Graph returns the reactive function graph which is expressed by this node. It includes any vertices produced by this node, and the appropriate edges to any vertices that are produced by its children. Nodes which fulfill the Expr interface directly produce vertices (and possible children) where as nodes that fulfill the Stmt interface do not produces vertices, where as their children might. It is interesting to note that nothing directly adds an edge to the resources created, but rather, once all the values (expressions) with no outgoing edges have produced at least a single value, then the resources know they're able to be built.

func (*StmtResMeta) Init

func (obj *StmtResMeta) Init(data *interfaces.Data) error

Init initializes this branch of the AST, and returns an error if it fails to validate.

func (*StmtResMeta) Interpolate

func (obj *StmtResMeta) Interpolate() (StmtResContents, error)

Interpolate returns a new node (aka a copy) once it has been expanded. This generally increases the size of the AST when it is used. It calls Interpolate on any child elements and builds the new node with those new node contents. This interpolate is different It is different from the interpolate found in the Expr and Stmt interfaces because it returns a different type as output.

func (*StmtResMeta) Ordering

func (obj *StmtResMeta) Ordering(produces map[string]interfaces.Node) (*pgraph.Graph, map[interfaces.Node]string, error)

Ordering returns a graph of the scope ordering that represents the data flow. This can be used in SetScope so that it knows the correct order to run it in.

func (*StmtResMeta) SetScope

func (obj *StmtResMeta) SetScope(scope *interfaces.Scope) error

SetScope stores the scope for later use in this resource and its children, which it propagates this downwards to.

func (*StmtResMeta) String

func (obj *StmtResMeta) String() string

String returns a short representation of this statement.

func (*StmtResMeta) Unify

func (obj *StmtResMeta) Unify(kind string) ([]interfaces.Invariant, error)

Unify returns the list of invariants that this node produces. It recursively calls Unify on any children elements that exist in the AST, and returns the collection to the caller. It is different from the Unify found in the Expr and Stmt interfaces because it adds an input parameter. XXX: Allow specifying partial meta param structs and unify the subset type. XXX: The resource fields have the same limitation with field structs.

Directories

Path Synopsis
Package funcs provides a framework for functions that change over time.
Package funcs provides a framework for functions that change over time.
bindata
Package bindata stores core mcl code that is built-in at compile time.
Package bindata stores core mcl code that is built-in at compile time.
facts
Package facts provides a framework for language values that change over time.
Package facts provides a framework for language values that change over time.
vars
Package vars provides a framework for language vars.
Package vars provides a framework for language vars.
Package types provides a framework for our language values and types.
Package types provides a framework for our language values and types.

Jump to

Keyboard shortcuts

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