1// ================================================================
2// Main type definitions for CST build/execute
3// ================================================================
4
5package cst
6
7import (
8	"container/list"
9
10	"miller/src/cliutil"
11	"miller/src/dsl"
12	"miller/src/runtime"
13	"miller/src/types"
14)
15
16// ----------------------------------------------------------------
17// Please see root.go for context and comments.
18type RootNode struct {
19	beginBlocks                   []*StatementBlockNode
20	mainBlock                     *StatementBlockNode
21	replImmediateBlock            *StatementBlockNode
22	endBlocks                     []*StatementBlockNode
23	udfManager                    *UDFManager
24	udsManager                    *UDSManager
25	allowUDFUDSRedefinitions      bool
26	unresolvedFunctionCallsites   *list.List
27	unresolvedSubroutineCallsites *list.List
28	outputHandlerManagers         *list.List
29	recordWriterOptions           *cliutil.TWriterOptions
30}
31
32// ----------------------------------------------------------------
33// Many functions have this signature. This type-alias is for function-name
34// lookup tables.
35type NodeBuilder func(astNode *dsl.ASTNode) (IEvaluable, error)
36
37// ----------------------------------------------------------------
38// This is for all statements and statemnt blocks within the CST.
39type IExecutable interface {
40	Execute(state *runtime.State) (*BlockExitPayload, error)
41}
42
43type Executor func(state *runtime.State) (*BlockExitPayload, error)
44
45// ================================================================
46// This is for any left-hand side (LHS or Lvalue) of an assignment statement.
47type IAssignable interface {
48	Assign(rvalue *types.Mlrval, state *runtime.State) error
49
50	// 'foo = "bar"' or 'foo[3]["abc"] = "bar"'
51	// For non-indexed assignment, which is the normal case, indices can be
52	// zero-length or nil.
53	AssignIndexed(rvalue *types.Mlrval, indices []*types.Mlrval, state *runtime.State) error
54
55	Unassign(state *runtime.State)
56
57	UnassignIndexed(indices []*types.Mlrval, state *runtime.State)
58}
59
60// ================================================================
61// This is for any right-hand side (RHS or Rvalue) of an assignment statement.
62// Also, for computed field names on the left-hand side, like '$a . $b' in mlr
63// put '$[$a . $b]' = $x + $y'.
64type IEvaluable interface {
65	Evaluate(state *runtime.State) *types.Mlrval
66}
67
68// ================================================================
69// For blocks of statements: the main put/filter block; begin/end blocks;
70// for/while-loop bodies; user-defined functions/subroutines.
71
72// ----------------------------------------------------------------
73// Also implements IExecutable
74type StatementBlockNode struct {
75	executables []IExecutable
76}
77
78// ----------------------------------------------------------------
79// Things a block of statements can do:
80// * execute all the way to the end without a return
81// * break
82// * continue
83// * (throw an exception if the Miller DSL were to support that)
84// * return void
85// * return a value
86type BlockExitStatus int
87
88const (
89	// BLOCK_EXIT_RUN_TO_END is implemented as *BlockExitPayload being nil
90	BLOCK_EXIT_BREAK        BlockExitStatus = 1
91	BLOCK_EXIT_CONTINUE                     = 2
92	BLOCK_EXIT_RETURN_VOID                  = 3
93	BLOCK_EXIT_RETURN_VALUE                 = 4
94)
95
96type BlockExitPayload struct {
97	blockExitStatus BlockExitStatus
98	// No multiple return yet in the Miller DSL -- if there were, this would be
99	// an array.
100	blockReturnValue *types.Mlrval // TODO: TypeGatedMlrval
101}
102