lower

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package lower provides AST → execution IR lowering. Converts declarative members (TransitionMember, EntryMember) to operational graphs (nodes + edges) that executors consume.

Index

Constants

View Source
const NotAVertexFormat = "transition endpoint %s names a %s that is not a vertex of this state machine"

NotAVertexFormat reports an endpoint naming an element outside the machine's vertices, shared by the check reporting it and the lowering backstopping it.

Variables

View Source
var ErrRecursiveStateTyping = errors.New("recursive state typing")

ErrRecursiveStateTyping reports a state definition whose content contains a state typed by that same definition, which has no finite materialization.

View Source
var ErrStatementOutsideFlow = errors.New("has no position in the token flow")

ErrStatementOutsideFlow reports a statement written among an action's own members that no succession binds, so it holds no position in the token flow.

View Source
var ErrUnsupportedStateContent = errors.New("unsupported state machine content")

ErrUnsupportedStateContent reports content of a state machine that lowering cannot represent, rather than dropping it.

Functions

func ActionEndpointAccepted added in v0.3.0

func ActionEndpointAccepted(nodes []ast.Node, hasInitial bool, ref ast.Node, source bool) bool

ActionEndpointAccepted reports whether an action endpoint names a lowered node or one of the implicit start/done markers.

func ActionNodes added in v0.3.0

func ActionNodes(actionDecl ast.Node, scope *symbols.Scope) (nodes []ast.Node, hasInitial bool, err error)

ActionNodes returns the nodes accepted by action lowering and whether the action has an initial node after interpreting `first <node>`.

func BehaviorMembers

func BehaviorMembers(decl ast.Node) ([]ast.Node, error)

BehaviorMembers are the members of a behavior declaration, and an error for a node that declares no behavior.

func BodyStatementMembers added in v0.2.0

func BodyStatementMembers(members []ast.Node) []ast.Node

BodyStatementMembers returns the members of a node body that state work to perform, in declaration order: what a body declares (a parameter, a doc comment) is a feature of the node, not a step of the flow through it.

func FeaturePath

func FeaturePath(node ast.Node) string

FeaturePath renders the feature a node names as a dotted path, so a nested port keeps every segment it was written with. It returns "" for a node that names no feature.

func Returns

func Returns(stmts []Statement) bool

Returns reports whether the statements return a value on some path, so a calculation whose body only computes can be told from one that has no result.

func SendTarget

func SendTarget(node ast.Node) (string, bool)

SendTarget renders a send's target and reports whether it is a feature chain (`alpha.inPort`) rather than a name in a namespace (`R`, `P::R`).

func StatesBehaviorBody

func StatesBehaviorBody(members []ast.Node) bool

StatesBehaviorBody reports whether members state a behavior body rather than only annotating the declaration or binding the behavior's parameters (`exhibit m { in x = y; }`, `exhibit m : M { doc /* … */ }`).

func VertexDecls

func VertexDecls(stateMachineDecl ast.Node, scope *symbols.Scope) (map[ast.Node]bool, error)

VertexDecls returns every declaration a transition of this state machine may name as an endpoint, collected by the pass a lowered graph's vertices are collected by, so a checker reads the same ownership the executor does. scope is the scope the machine's body was declared in.

func VertexKind

func VertexKind(decl ast.Node) string

VertexKind names what an endpoint reached in modelling terms, for a message a modeller reads.

Types

type Accept

type Accept struct {
	ParamName    string
	SignalType   string
	ViaPort      string
	SubsetsEvent string
	Trigger      ast.Node
}

Accept is a lowered accept parameter: `action r accept msg : Warning;`. SignalType is the parameter's declared type, empty when it was declared without one, in which case the node accepts a message of any type.

ViaPort is the port named by `accept msg : Warning via p`, empty when the accept named none. A port-routed message is only offered to an accept on the port it arrived at, so the two forms do not consume each other's messages.

SubsetsEvent is the event feature the payload subsets (`accept :> shutDown`), empty when it subsets none. Such an accept waits for an occurrence of that one event rather than for any occurrence of a type.

Trigger is the time or change event of `accept at t` / `accept after d` / `accept when c`, nil when the accept waits for a message instead.

type ActionEdge added in v0.3.0

type ActionEdge struct {
	Target ast.Node
	Guard  ast.Node
	Decl   ast.Node
}

ActionEdge is one succession out of a node: the target it reaches, the guard it carries, and the declaration it was written as.

type ActionGraph

type ActionGraph struct {
	// Scope is the scope the action's body was declared in, in which every
	// expression written directly among its members resolves its names. A nested
	// node or a body-local block carries its own scope instead.
	Scope *symbols.Scope

	// Attributes are the attribute defaults the action declares, in order.
	Attributes []Attribute

	// Nodes in the graph (InitialNode, FinalNode, ExecutionNode, etc.)
	Nodes []ast.Node

	// Edges: source node → successions in declaration order.
	Edges map[ast.Node][]ActionEdge

	// DataFlows: source node → list of object flows
	DataFlows map[ast.Node][]ObjectFlow

	// Bodies: node → the statements that node executes, in declaration order
	Bodies map[ast.Node][]Statement

	// Accepts: node → the message that node waits for
	Accepts map[ast.Node]Accept

	// Subflows: node → the flow the node's own members state, present only for a
	// node that states one. Its subactions are subperformances of the node, so it
	// completes only when that flow does (action_subflow.go).
	Subflows map[ast.Node]*Subflow

	// InitialNode (required)
	Initial ast.Node

	// FinalNodes (may be multiple)
	Finals []ast.Node

	// Connections are the connectors declared in the action body, which is how
	// a `send ... via <port>` finds the ports it reaches.
	Connections []Connection

	// StatementRuns marks the nodes of a block's own flow that stand for a run of
	// statements rather than for an action node (block_graph.go). Such a node is
	// keyed by the first statement of the run, whose name names no step.
	StatementRuns map[ast.Node]bool
}

ActionGraph is the execution IR for actions. Nodes represent control flow points, edges represent flow paths.

func ToActionGraph

func ToActionGraph(actionDecl ast.Node, scope *symbols.Scope) (*ActionGraph, error)

ToActionGraph converts an action AST (Usage or Definition) to an ActionGraph. scope is the scope the action's body was declared in — the scope the action itself owns — which every expression the graph carries is evaluated in. Returns error if graph is malformed (e.g., no initial node, dangling edges).

type Assign

type Assign struct {
	Target string
	// Chain is the chained target the assignment writes through (`s.reading`),
	// nil when the target was a plain name the body's host binds.
	Chain *AssignTarget
	Value ast.Node
	Node  ast.Node       // the statement itself, for diagnostics
	Scope *symbols.Scope // the scope the statement was declared in
}

Assign is a lowered assignment: `assign <Target> := <Value>`. Target is the feature written — the target's last segment — empty when the target names no feature.

type AssignTarget added in v0.4.0

type AssignTarget struct {
	// Base is the expression the chain starts from, evaluated in the statement's
	// own scope.
	Base ast.Node
	// Steps are the features walked from Base to the object written, in order.
	Steps []string
	// Text is the target as written (`a.b.c`), for diagnostics.
	Text string
}

AssignTarget is a chained assignment target: `assign a.b.c := v` walks `b` from `a` and writes `c` on the object it reaches.

type Attribute

type Attribute struct {
	Name  string
	Value ast.Node
	Node  ast.Node // the declaration itself, for diagnostics
	// Scope is the scope the declaration was written in, in which its default
	// resolves; nil where the owner's own scope resolves it.
	Scope *symbols.Scope
}

Attribute is a lowered attribute default written among a behavior's members (`attribute h : LengthValue = 500.0 [m];`), whose Value resolves in the graph's own scope.

type Binding

type Binding struct {
	Ends  [2]BindingEnd
	Scope *symbols.Scope
	Decl  *ast.Usage
}

Binding is a lowered binding connector with its two endpoint expressions and the scope in which those expressions were declared.

func ToBindings

func ToBindings(decl ast.Node, scope *symbols.Scope) []Binding

ToBindings lowers binding connectors directly declared by a type or usage. Namespace-owned bindings are intentionally left to callers to exclude.

type BindingEnd

type BindingEnd struct {
	Path string
	Expr ast.Node
}

BindingEnd is one binding endpoint. Path is the runtime lvalue path; Expr retains the lossless expression for diagnostics and calc evaluation.

type Block

type Block struct {
	Statements []Statement
	Node       ast.Node // the loop or branch the block belongs to
	// Scope is the block's own scope, which its declarations, and a loop's
	// condition, resolve in.
	Scope *symbols.Scope
	// Graph is the block's own token flow, present where a member of the block is
	// an action node rather than a statement — a nested action declaration, a
	// `perform` — which only a flow of its own executes with the succession
	// semantics it has (block_graph.go). Statements is empty for such a block: the
	// statements are the bodies of the flow's nodes.
	Graph *ActionGraph
}

Block is a lowered body-local statement list: the body of a loop or of one branch of a conditional. It is a namespace of its own (symbols/builder.go), so the names its Declare statements introduce do not leak out of it.

func (Block) Steps

func (block Block) Steps() []Statement

Steps returns the statements the block runs, wherever they live: its statement list, or the bodies of the nodes of its own token flow, in declaration order.

type ClassifierBehavior

type ClassifierBehavior struct {
	Kind ClassifierBehaviorKind
	// Name is the name the behavior answers to on the object, which is the
	// effective name of the declaration binding it.
	Name string
	// Decl is the `exhibit`/`perform` declaration itself.
	Decl *ast.Usage
	// StatesBody reports whether Decl states the behavior's body. A declaration
	// that states none names the element that holds one instead.
	StatesBody bool
	// Arguments are the values the declaration binds to the behavior's
	// parameters (`exhibit m { in controller = vehicleController; }`), in
	// declaration order.
	Arguments []Attribute
}

ClassifierBehavior is a behavior every object of a type runs because the type exhibits or performs it: the declaration that binds it, whether that declaration states a body of its own or names an element holding one, and the values it binds to the behavior's parameters.

func ClassifierBehaviorOf

func ClassifierBehaviorOf(member ast.Node) (ClassifierBehavior, bool)

ClassifierBehaviorOf reports the behavior a type's member binds to every object of that type, and false for a member that binds none: a state or action a type merely owns is not one its objects run.

func ClassifierBehaviorsOf

func ClassifierBehaviorsOf(members []ast.Node) []ClassifierBehavior

ClassifierBehaviorsOf reports the behaviors the given members bind, in declaration order.

type ClassifierBehaviorKind

type ClassifierBehaviorKind int

ClassifierBehaviorKind is how a type binds a behavior to its objects.

const (
	// ExhibitedState is a state machine the type exhibits: `exhibit state m { … }`,
	// `exhibit state m : M;`, `exhibit m;` (SysML v2 §7.16.6, Part::exhibitedStates).
	ExhibitedState ClassifierBehaviorKind = iota
	// PerformedAction is an action the type performs: `perform action a { … }`,
	// `perform action a : A;`, `perform a;` (Part::performedActions).
	PerformedAction
)

func (ClassifierBehaviorKind) String

func (k ClassifierBehaviorKind) String() string

String names the kind in diagnostics.

type Connection

type Connection struct {
	Ends      []string
	Variation string          // variation point the connection is a variant of, empty when it is not
	Variant   string          // name of the variant declaring it, empty when it is not one
	Owner     ConnectionOwner // what declares it, whose selection governs a variant's connection
	Scope     *symbols.Scope  // scope the end paths resolve in, nil when unknown
}

Connection is a lowered connector: the ends it joins, by the name each end resolves to. A `connect a to b` has two ends; a multi-end `connect` has more, and every end is reachable from every other.

A connection a `variant interface` declares joins its ends only where that variant is the one selected, so it carries the variation it belongs to, its own name, and what owns it: routing must ask what that owner bound the variation to before delivering through it (SysML v2 §7.20).

An end keeps the whole path it was written as (`sensor.out`, `p.q`), so a nested port is joined as itself and not as a same-named port elsewhere; Scope is where those paths resolve, which is what routing asks to learn the direction an end's flow features carry.

func ToObjectConnections

func ToObjectConnections(decl ast.Node, scope *symbols.Scope) []Connection

ToObjectConnections lowers the connectors declared in the body of a type an object is of. A `send … via p` of a behavior an object performs routes through the object's connections as well as through the behavior's own, and it is that object's selection that realizes a variant's connection among them.

type ConnectionOwner

type ConnectionOwner int

ConnectionOwner is what a lowered connection belongs to, which decides whose selection governs it when it is a variant's: a behavior activation, or the object performing the behavior.

const (
	// OwnerBehavior marks a connection declared in the behavior's own body.
	OwnerBehavior ConnectionOwner = iota
	// OwnerObject marks a connection declared in the body of a type an object
	// performing the behavior is of.
	OwnerObject
)

type Declare

type Declare struct {
	Name  string
	Value ast.Node
	Node  ast.Node       // the declaration itself, for diagnostics
	Scope *symbols.Scope // the scope the declaration was written in
}

Declare is a lowered declaration in a body-local block: `attribute i = 0;` written inside a loop or an `if` branch. The name it declares is a member of that block, so the executor binds it in the block's own frame and discards it when the block exits. Value is nil when the declaration carried none.

type DeclareUsage

type DeclareUsage struct {
	Name  string
	Node  *ast.Usage     // the declaration itself, for diagnostics
	Scope *symbols.Scope // the scope the usage was declared in
}

DeclareUsage is a calc usage declared in a body-local block: `calc p : Pair { in k = h; }` written inside a loop or an `if` branch. It states no step of the computation; it declares the usage and marks where it becomes reachable, so the statements after it read its outputs from one evaluation of its body per execution of the block.

type Effect

type Effect struct {
	Kind  EffectKind
	Node  ast.Node
	Scope *symbols.Scope // the scope the statement was declared in
}

Effect is a statement acting on the world outside the body — perform, accept, terminate — lowered so a host rejecting it (a calculation) can say so.

type EffectKind

type EffectKind int

EffectKind names a statement that acts on the world outside the body it stands in.

const (
	EffectPerform EffectKind = iota
	EffectAccept
	EffectTerminate
)

func (EffectKind) String

func (k EffectKind) String() string

type EndpointResolver added in v0.4.1

type EndpointResolver interface {
	// Endpoint returns the declaration qn names, written in scope, and whether it
	// names a vertex at all.
	Endpoint(scope *symbols.Scope, qn *ast.QualifiedName) (decl ast.Node, ok bool)
}

EndpointResolver resolves the vertex a transition endpoint names, implemented by the name-resolution tier (*resolve.Resolver) so lowering matches no names itself.

type If

type If struct {
	Condition ast.Node
	Then      Block
	Else      *Block
	Node      ast.Node       // the conditional itself, for diagnostics
	Scope     *symbols.Scope // the scope the conditional, and so its condition, was declared in
}

If is a lowered conditional. The condition is evaluated in the enclosing body, outside both branches. Else is nil when the conditional declared none.

type Loop

type Loop struct {
	Kind      ast.LoopKind
	Condition ast.Node // nil for `for`, and for a `loop` written without `until`
	// Until is the condition a `while` loop's `until` clause tests after each
	// iteration (`while c { … } until d;`), nil when it carries none.
	Until      ast.Node
	Variable   string   // `for` only: the name each element is bound to
	Collection ast.Node // `for` only: the collection iterated over
	Body       Block
	Node       ast.Node // the loop itself, for diagnostics
	// Scope is the scope the loop was declared in, which its collection resolves
	// in; its condition resolves in Body.Scope, which the body declares into.
	Scope *symbols.Scope
}

Loop is a lowered loop statement. Kind says when the condition is tested: before each iteration (`while`), after each iteration (`loop … until`), or not at all, iteration being driven by a collection (`for`).

Condition and Collection stay expressions because their values are only known at execution time. The iteration count is bounded by the executor's step budget, so a loop that never terminates fails the run rather than hanging it.

type ObjectFlow

type ObjectFlow struct {
	// Name is the flow's own name, when it was declared with one
	// (`flow generateToAmplify from a.out to b.in;`), and "" for the anonymous
	// form and for a flow the notation writes as an edge.
	Name      string
	SourcePin string
	TargetPin string
	Target    ast.Node
	// Decl is the declaration the flow was written as, for a consumer that
	// reports where it comes from.
	Decl ast.Node
}

ObjectFlow represents a data flow edge between pins.

type Return

type Return struct {
	Value ast.Node
	Node  ast.Node       // the return itself, for diagnostics
	Scope *symbols.Scope // the scope the returned expression was written in
}

Return is a lowered `return`: the value the enclosing behavior computes, possibly from inside a block. Value is nil when it named no expression.

type Send

type Send struct {
	Message ast.Node
	Target  string
	// TargetPath records that Target is a feature chain (`a.b`) reaching through
	// the sender's features, rather than a name in a namespace (`R`, `P::R`).
	TargetPath bool
	IsVia      bool
	// Receiver is the name addressed by a routed send, empty when omitted.
	Receiver     string
	ReceiverPath bool
	Scope        *symbols.Scope // the scope the statement was declared in
}

Send is a lowered send statement. Message stays an expression because its value is only known at execution time.

Target is the name the send addressed, empty for a broadcast. IsVia records that the name is a port of the sender rather than a receiver, in which case it is the whole path the port was written as and the message goes to whatever the graph's Connections join that port to.

type StateBehavior

type StateBehavior struct {
	// Node is the behavior's declaration, unwrapped of the membership the parser
	// puts it in, and is what a diagnostic about it names.
	Node ast.Node
	// Name is the name the behavior was declared with, "" for an anonymous one.
	Name string
	// Body are the behavior's statements in declaration order. An inline action
	// body is one block, since it is a namespace of its own; every other form
	// lowers to the one statement it states.
	Body []Statement
	// Scope is the scope the behavior was declared in, which its own statements
	// and the action name it performs resolve in.
	Scope *symbols.Scope
	// Owner is the state whose attributes the behavior reads and writes: the
	// state it belongs to, or the source of the transition it is an effect of.
	Owner *ast.StateNode
}

StateBehavior is one behavior a state machine performs: an entry, do or exit behavior of a state, or one effect of a transition. Every form it may be written in — an inline action body, an assignment, a send, a performed action — is lowered into the statements the runtime executes.

func LowerBehaviors

func LowerBehaviors(actions []ast.Node, scope *symbols.Scope) []StateBehavior

LowerBehaviors lowers the actions of an entry, do or exit member, or the effects of a transition, in the scope they were declared in.

type StateBehaviors

type StateBehaviors struct {
	Entry []StateBehavior
	Do    []StateBehavior
	Exit  []StateBehavior
}

StateBehaviors are the lowered entry, do and exit behaviors of one state, each in declaration order.

type StateGraph

type StateGraph struct {
	// Scope is the scope the machine's own body was declared in, in which the
	// expressions written directly among its members resolve their names.
	Scope *symbols.Scope

	// Attributes are the attributes the machine declares, in declaration order.
	Attributes []Attribute

	// StateScopes: state → the scope that state's body was declared in, which is
	// what the names in its entry, do and exit behaviors resolve against.
	StateScopes map[*ast.StateNode]*symbols.Scope

	// Behaviors: state → its lowered entry, do and exit behaviors. The executor
	// runs these rather than the state's AST members, so an inline action body is
	// executable statements by the time it is reached.
	Behaviors map[*ast.StateNode]*StateBehaviors

	// HiddenStates are graph-only composite owners synthesized for parallel
	// regions. They execute behaviors but are not user-visible state visits.
	HiddenStates map[*ast.StateNode]bool

	// HiddenRegionOf: graph-only owner → the region it stands for, so a walk up
	// the parent chain crosses it without losing which region a state is in.
	HiddenRegionOf map[*ast.StateNode]*ast.StateRegion

	// Machine is the graph-only root state for a parallel machine's own entry,
	// do and exit behaviors. Its regions are represented by TopRegions instead.
	Machine *ast.StateNode

	// States in the machine (flat list, includes nested)
	States []*ast.StateNode

	// Pseudostates of the machine in declaration order. Not keyed by name:
	// sibling regions may declare same-named pseudostates.
	Pseudostates []*ast.PseudostateNode

	// PseudostateOwner: pseudostate -> the composite state that declares it,
	// absent for one declared directly in the machine. A history pseudostate
	// restores the configuration of its owner, so the owner must survive lowering.
	PseudostateOwner map[*ast.PseudostateNode]*ast.StateNode

	// Transitions: source node (StateNode or PseudostateNode) → list of transitions
	Transitions map[ast.Node][]*Transition

	// CompositeStates: state → regions
	CompositeStates map[*ast.StateNode][]*ast.StateRegion

	// CompositeStateOrder preserves declaration order for deterministic runtime
	// selection of an active composite owner.
	CompositeStateOrder []*ast.StateNode

	// RegionInitials: region → initial state
	RegionInitials map[*ast.StateRegion]*ast.StateNode

	// ParentState: child → parent
	ParentState map[*ast.StateNode]*ast.StateNode

	// RegionOwner: region → owning composite state
	RegionOwner map[*ast.StateRegion]*ast.StateNode

	// Deferred: state → the triggers it defers while active, normalized the same
	// way transition triggers are.
	Deferred map[*ast.StateNode][]ast.Node

	// TopRegions are the machine's own orthogonal regions, in declaration order.
	// The order is observable: it is the order regions are entered and exited in.
	TopRegions []*ast.StateRegion

	// RegionOf: state → the region that declares it (fork/join need the region a
	// target belongs to)
	RegionOf map[*ast.StateNode]*ast.StateRegion

	// InitialState (required for simple machines, nil for multi-region)
	Initial *ast.StateNode

	// Connections are the connectors declared in the state machine body, which
	// is how a `send ... via <port>` in an entry/do/exit/effect action finds the
	// ports it reaches.
	Connections []Connection

	// StateAttributes: state → the attributes it owns, its own and those it
	// inherits from the definition typing it. Each state owns its values, so two
	// usages of one definition hold two sets of them.
	StateAttributes map[*ast.StateNode][]Attribute
	// contains filtered or unexported fields
}

StateGraph is the execution IR for state machines.

func ToStateGraph

func ToStateGraph(stateMachineDecl ast.Node, scope *symbols.Scope) (*StateGraph, error)

ToStateGraph converts a state machine AST (Usage or Definition) to a StateGraph. scope is the scope the machine's body was declared in — the scope the machine itself owns — from which the scope of every state and transition it carries is derived. Its endpoints resolve against the machine's own symbols; a caller holding the name-resolution tier's uses ToStateGraphWithEndpoints instead.

func ToStateGraphWithEndpoints

func ToStateGraphWithEndpoints(stateMachineDecl ast.Node, scope *symbols.Scope, endpoints EndpointResolver) (*StateGraph, error)

ToStateGraphWithEndpoints lowers a state machine, building its transitions from the endpoints the name-resolution tier already resolved.

func (*StateGraph) AttributeScope added in v0.4.0

func (g *StateGraph) AttributeScope(attr Attribute) *symbols.Scope

AttributeScope is the scope an attribute's value resolves in, which is the body declaring it rather than the machine's when the machine inherits it.

func (*StateGraph) Completes added in v0.3.0

func (g *StateGraph) Completes(state *ast.StateNode) bool

Completes reports whether entering state completes the region it belongs to: it is the `done` end shot of the state or machine whose body names it.

func (*StateGraph) IsInitial added in v0.1.1

func (g *StateGraph) IsInitial(state *ast.StateNode) bool

IsInitial reports whether the machine starts in state, which a transition out of the body's entry action designates.

type StateTypeResolver added in v0.4.1

type StateTypeResolver interface {
	TypeDecl(scope *symbols.Scope, qn *ast.QualifiedName) (ast.Node, *symbols.Scope, bool)
}

StateTypeResolver resolves the declaration a type name reaches and the scope of that declaration's body. The name-resolution tier implements it; lowering falls back to the scope tree for a machine lowered without it.

type Statement

type Statement interface {
	// contains filtered or unexported methods
}

Statement is one lowered statement in an action node's body. Statements are kept in declaration order so the executor never walks the node's members again to find them.

func CalcBody

func CalcBody(members []ast.Node, scope *symbols.Scope) []Statement

CalcBody lowers the computation a calculation body states, in declaration order and in the scope it was written in. A member stating no computation — an input parameter, documentation, a nested definition — is skipped. A result the body declares names the value answered with, not a step, so it runs after the steps; a `return` inside a branch or loop stops the body there.

type Subflow added in v0.4.0

type Subflow struct {
	Graph *ActionGraph
	Err   error
}

Subflow is the flow a nested action node's own members state. Graph is nil when those members state a flow that could not be built, which Err says; the executor reports it at initialize() rather than treating the node as a leaf.

type Transition

type Transition struct {
	// Name is the transition's own name, when it was written with one
	// (`transition maintain first idle then busy`), and "" when it was not.
	Name string
	// Decl is the declaration the transition was written as, for a consumer that
	// reports where it comes from.
	Decl    ast.Node
	Source  ast.Node // *ast.StateNode or *ast.PseudostateNode
	Target  ast.Node // *ast.StateNode or *ast.PseudostateNode
	Trigger ast.Node // TimeEvent, ChangeEvent, SignalEvent, CallEvent, nil = completion
	Guard   ast.Node // guard expression, nil = no guard
	// Effect are the transition's effect behaviors, lowered the same way a state's
	// entry, do and exit behaviors are.
	Effect []StateBehavior
	// Via is the port the accepted occurrence must arrive at
	// (`accept Ping via commPort`), and "" when the trigger names no port, in
	// which case an occurrence reaching the machine by any route fires it.
	Via string

	// Scope is the scope the transition was declared in, in which the expressions
	// its trigger carries — a time event's duration, a change event's condition —
	// resolve their names.
	Scope *symbols.Scope

	// BodyScope is the scope the transition's guard and effect resolve in. It is
	// Scope, except for a call trigger, whose parameters are visible to the guard
	// and effect and nowhere else (`accept setSpeed(v) if v > 0`).
	BodyScope *symbols.Scope
}

Transition represents a state transition (lowered from TransitionEdge or TransitionMember).

type Unsupported

type Unsupported struct {
	Description string
	Node        ast.Node
	Scope       *symbols.Scope // the scope the member was declared in
}

Unsupported is a body member the lowering layer recognizes but cannot yet turn into an executable statement. It is lowered rather than dropped so that reaching it fails the execution with a diagnostic instead of silently producing a wrong answer. Description names the construct.

Jump to

Keyboard shortcuts

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