mirror of
https://github.com/johnkerl/miller.git
synced 2026-01-23 02:14:13 +00:00
112 lines
2.5 KiB
Go
112 lines
2.5 KiB
Go
// ================================================================
|
|
// CST build/execute for assignment and unset statements.
|
|
// ================================================================
|
|
|
|
package cst
|
|
|
|
import (
|
|
"github.com/johnkerl/miller/internal/pkg/dsl"
|
|
"github.com/johnkerl/miller/internal/pkg/lib"
|
|
"github.com/johnkerl/miller/internal/pkg/runtime"
|
|
)
|
|
|
|
// ================================================================
|
|
func (root *RootNode) BuildAssignmentNode(
|
|
astNode *dsl.ASTNode,
|
|
) (*AssignmentNode, error) {
|
|
|
|
lib.InternalCodingErrorIf(astNode.Type != dsl.NodeTypeAssignment)
|
|
err := astNode.CheckArity(2)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
lhsASTNode := astNode.Children[0]
|
|
rhsASTNode := astNode.Children[1]
|
|
|
|
lvalueNode, err := root.BuildAssignableNode(lhsASTNode)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rvalueNode, err := root.BuildEvaluableNode(rhsASTNode)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &AssignmentNode{
|
|
lvalueNode: lvalueNode,
|
|
rvalueNode: rvalueNode,
|
|
}, nil
|
|
}
|
|
|
|
// ----------------------------------------------------------------
|
|
type AssignmentNode struct {
|
|
lvalueNode IAssignable
|
|
rvalueNode IEvaluable
|
|
}
|
|
|
|
func NewAssignmentNode(
|
|
lvalueNode IAssignable,
|
|
rvalueNode IEvaluable,
|
|
) *AssignmentNode {
|
|
return &AssignmentNode{
|
|
lvalueNode: lvalueNode,
|
|
rvalueNode: rvalueNode,
|
|
}
|
|
}
|
|
|
|
func (node *AssignmentNode) Execute(
|
|
state *runtime.State,
|
|
) (*BlockExitPayload, error) {
|
|
rvalue := node.rvalueNode.Evaluate(state)
|
|
if !rvalue.IsAbsent() {
|
|
err := node.lvalueNode.Assign(rvalue, state)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
// ================================================================
|
|
func (root *RootNode) BuildUnsetNode(
|
|
astNode *dsl.ASTNode,
|
|
) (*UnsetNode, error) {
|
|
|
|
lib.InternalCodingErrorIf(astNode.Type != dsl.NodeTypeUnset)
|
|
|
|
lvalueNodes := make([]IAssignable, len(astNode.Children))
|
|
|
|
for i, lhsASTNode := range astNode.Children {
|
|
lvalueNode, err := root.BuildAssignableNode(lhsASTNode)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
lvalueNodes[i] = lvalueNode
|
|
}
|
|
|
|
return &UnsetNode{
|
|
lvalueNodes: lvalueNodes,
|
|
}, nil
|
|
}
|
|
|
|
// ----------------------------------------------------------------
|
|
type UnsetNode struct {
|
|
lvalueNodes []IAssignable
|
|
}
|
|
|
|
func NewUnsetNode(
|
|
lvalueNodes []IAssignable,
|
|
) *UnsetNode {
|
|
return &UnsetNode{
|
|
lvalueNodes: lvalueNodes,
|
|
}
|
|
}
|
|
|
|
func (node *UnsetNode) Execute(state *runtime.State) (*BlockExitPayload, error) {
|
|
for _, lvalueNode := range node.lvalueNodes {
|
|
lvalueNode.Unassign(state)
|
|
}
|
|
return nil, nil
|
|
}
|