-
Notifications
You must be signed in to change notification settings - Fork 215
/
cond.go
79 lines (68 loc) · 2.13 KB
/
cond.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// ================================================================
// This is for awkish pattern-action-blocks, like mlr put 'NR > 10 { ... }'.
// Just shorthand for if-statements without elif/else.
// ================================================================
package cst
import (
"fmt"
"github.com/johnkerl/miller/v6/pkg/dsl"
"github.com/johnkerl/miller/v6/pkg/lib"
"github.com/johnkerl/miller/v6/pkg/mlrval"
"github.com/johnkerl/miller/v6/pkg/parsing/token"
"github.com/johnkerl/miller/v6/pkg/runtime"
)
type CondBlockNode struct {
conditionNode IEvaluable
conditionToken *token.Token
statementBlockNode *StatementBlockNode
}
// ----------------------------------------------------------------
// Sample AST:
func (root *RootNode) BuildCondBlockNode(astNode *dsl.ASTNode) (*CondBlockNode, error) {
lib.InternalCodingErrorIf(astNode.Type != dsl.NodeTypeCondBlock)
lib.InternalCodingErrorIf(len(astNode.Children) != 2)
conditionNode, err := root.BuildEvaluableNode(astNode.Children[0])
if err != nil {
return nil, err
}
conditionToken := astNode.Children[0].Token
statementBlockNode, err := root.BuildStatementBlockNode(astNode.Children[1])
if err != nil {
return nil, err
}
condBlockNode := &CondBlockNode{
conditionNode: conditionNode,
conditionToken: conditionToken,
statementBlockNode: statementBlockNode,
}
return condBlockNode, nil
}
// ----------------------------------------------------------------
func (node *CondBlockNode) Execute(
state *runtime.State,
) (*BlockExitPayload, error) {
condition := mlrval.TRUE
if node.conditionNode != nil {
condition = node.conditionNode.Evaluate(state)
}
boolValue, isBool := condition.GetBoolValue()
// Data-heterogeneity case
if condition.IsAbsent() {
boolValue = false
} else if !isBool {
return nil, fmt.Errorf(
"mlr: conditional expression did not evaluate to boolean%s.",
dsl.TokenToLocationInfo(node.conditionToken),
)
}
if boolValue == true {
blockExitPayload, err := node.statementBlockNode.Execute(state)
if err != nil {
return nil, err
}
if blockExitPayload != nil {
return blockExitPayload, nil
}
}
return nil, nil
}