From 03344a10a89d5e690dfa5cd9a21a7a55356f153f Mon Sep 17 00:00:00 2001 From: John Kerl Date: Mon, 22 Feb 2021 07:10:43 -0500 Subject: [PATCH 1/3] todo --- go/todo.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/go/todo.txt b/go/todo.txt index a0122e852..4c95ac85b 100644 --- a/go/todo.txt +++ b/go/todo.txt @@ -9,8 +9,12 @@ TOP OF LIST: o take care w/ copying (non-pointer) mlrvals though * data-copy reduction: + - literal-type nodes -- why is there even a copy? these should simply be pointing at the literal. + > modify Evaluate to return pointer? 1st arg becomes optional buffer? + - type-gated mv -- should use passed-in storage slot -- ? - prof: - mlr --cpuprofile cpu.pprof -n put -q -s 'iwidth=200' -s iheight=200 -s silent=true -f u/mand.mlr + mlr --cpuprofile cpu.pprof -n put -q -s iwidth=500 -s iheight=500 -s silent=true -f u/mand.mlr + GOGC=off mlr --cpuprofile cpu.pprof -n put -q -s iwidth=500 -s iheight=500 -s silent=true -f u/mand.mlr - MlrvalLessThanForSort - MlrvalGetMeanEB et al. - var delta types.Mlrval for uninits From dd50a3844581f804c8860c7082b82e7ba94bf7af Mon Sep 17 00:00:00 2001 From: John Kerl Date: Mon, 22 Feb 2021 07:58:00 -0500 Subject: [PATCH 2/3] copy-reduction in evaluators --- go/src/dsl/cst/types.go | 2 +- go/src/types/mlrval_functions_base.go | 2 +- go/todo.txt | 11 +++++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/go/src/dsl/cst/types.go b/go/src/dsl/cst/types.go index 5a9801872..ff0aac137 100644 --- a/go/src/dsl/cst/types.go +++ b/go/src/dsl/cst/types.go @@ -62,7 +62,7 @@ type IAssignable interface { // Also, for computed field names on the left-hand side, like '$a . $b' in mlr // put '$[$a . $b]' = $x + $y'. type IEvaluable interface { - Evaluate(output *types.Mlrval, state *runtime.State) + Evaluate(state *runtime.State) *types.Mlrval } // ================================================================ diff --git a/go/src/types/mlrval_functions_base.go b/go/src/types/mlrval_functions_base.go index 0965cd71b..ebd8b7ffb 100644 --- a/go/src/types/mlrval_functions_base.go +++ b/go/src/types/mlrval_functions_base.go @@ -38,7 +38,7 @@ // 'i' for int // 'f' for float64 // 'n' for number return types -- e.g. the auto-overflow from -// int to float plus_n_ii returns MT_INT if integer-additio overflow +// int to float plus_n_ii returns MT_INT if integer-addition overflow // didn't happen, or MT_FLOAT if it did. // 'b' for boolean // 'x' for don't-care slots, e.g. eq_b_sx for comparing MT_STRING diff --git a/go/todo.txt b/go/todo.txt index 4c95ac85b..9ce99ee9c 100644 --- a/go/todo.txt +++ b/go/todo.txt @@ -23,6 +23,17 @@ TOP OF LIST: final perf results. w defer the stack-allocation PR until after +* next round of data-copy reduction: + o $z = min($x, $y) -- needs to return pointer to x or y + o $z = $x + $y -- needs to have space for sum, and return pointer to it + o therefore type BinaryFunc func(input1, input2 *Mlrval) *types.Mlrval + - have the function z-allocate outputs when needed + - the outputs must be on the stack, not statically allocated, to make them re-entrant + and OK for recursive functions + o then IEvaluable: Evaluate(state *runtime.State) *types.Mlrval + o invalidate CopyFrom + o check for under/over copy at Assign + ---------------------------------------------------------------- * regexes o finish stats1 -r From c16f79504e1a09164ebbac59594984d2d777fa91 Mon Sep 17 00:00:00 2001 From: John Kerl Date: Mon, 22 Feb 2021 22:58:03 -0500 Subject: [PATCH 3/3] copy-reduction in evaluators --- go/src/auxents/repl/dsl.go | 2 +- go/src/auxents/repl/session.go | 2 +- go/src/dsl/cst/assignments.go | 6 +- go/src/dsl/cst/block-exit.go | 7 +- go/src/dsl/cst/builtin_functions.go | 152 +++---- go/src/dsl/cst/collections.go | 175 +++----- go/src/dsl/cst/cond.go | 5 +- go/src/dsl/cst/dump.go | 6 +- go/src/dsl/cst/emit_emitp.go | 30 +- go/src/dsl/cst/emitf.go | 8 +- go/src/dsl/cst/env.go | 14 +- go/src/dsl/cst/evaluable.go | 34 +- go/src/dsl/cst/filter.go | 2 +- go/src/dsl/cst/for.go | 15 +- go/src/dsl/cst/if.go | 5 +- go/src/dsl/cst/leaves.go | 140 +++---- go/src/dsl/cst/lvalues.go | 70 ++-- go/src/dsl/cst/print.go | 6 +- go/src/dsl/cst/subroutines.go | 7 +- go/src/dsl/cst/tee.go | 6 +- go/src/dsl/cst/udf.go | 24 +- go/src/dsl/cst/uds.go | 13 +- go/src/dsl/cst/while.go | 7 +- go/src/runtime/state.go | 4 +- go/src/transformers/clean-whitespace.go | 13 +- go/src/transformers/percentile-keeper.go | 14 +- go/src/transformers/seqgen.go | 22 +- go/src/transformers/stats1-accumulators.go | 175 ++++---- go/src/transformers/step.go | 66 ++- go/src/types/mlrmap_accessors.go | 3 +- go/src/types/mlrmap_flatten_unflatten.go | 12 +- go/src/types/mlrval_constants.go | 24 ++ go/src/types/mlrval_function_hashing.go | 24 +- go/src/types/mlrval_functions_arithmetic.go | 405 +++++++++---------- go/src/types/mlrval_functions_base.go | 74 ++-- go/src/types/mlrval_functions_bits.go | 64 +-- go/src/types/mlrval_functions_booleans.go | 267 ++++++------ go/src/types/mlrval_functions_collections.go | 369 ++++++++--------- go/src/types/mlrval_functions_math.go | 12 +- go/src/types/mlrval_functions_mathlib.go | 148 ++++--- go/src/types/mlrval_functions_random.go | 40 +- go/src/types/mlrval_functions_regex.go | 110 +++-- go/src/types/mlrval_functions_stats.go | 21 +- go/src/types/mlrval_functions_strings.go | 139 +++---- go/src/types/mlrval_functions_time.go | 30 +- go/src/types/mlrval_functions_types.go | 268 ++++++------ go/src/types/mlrval_new.go | 20 - go/src/types/mlrval_set.go | 208 +++------- go/src/types/mlrval_typing.go | 5 +- go/todo.txt | 13 + 50 files changed, 1452 insertions(+), 1834 deletions(-) create mode 100644 go/src/types/mlrval_constants.go diff --git a/go/src/auxents/repl/dsl.go b/go/src/auxents/repl/dsl.go index 05fb7fd2d..98e36701d 100644 --- a/go/src/auxents/repl/dsl.go +++ b/go/src/auxents/repl/dsl.go @@ -87,7 +87,7 @@ func (this *Repl) handleDSLStringAux( } else { fmt.Println(filterExpression.String()) } - this.runtimeState.FilterExpression = types.MlrvalFromVoid() + this.runtimeState.FilterExpression = types.MLRVAL_VOID } return nil diff --git a/go/src/auxents/repl/session.go b/go/src/auxents/repl/session.go index a173ec278..8d4c421ab 100644 --- a/go/src/auxents/repl/session.go +++ b/go/src/auxents/repl/session.go @@ -64,7 +64,7 @@ func NewRepl( // interactive expressions to be printed to the terminal. For the main DSL, // the default is types.MlrvalFromTrue(); for the REPL, the default is // types.MlrvalFromVoid(). - runtimeState.FilterExpression = types.MlrvalFromVoid() + runtimeState.FilterExpression = types.MLRVAL_VOID // For control-C handling sysToSignalHandlerChannel := make(chan os.Signal, 1) // Our signal handler reads system notification here diff --git a/go/src/dsl/cst/assignments.go b/go/src/dsl/cst/assignments.go index 704f18d2b..ed0cc7979 100644 --- a/go/src/dsl/cst/assignments.go +++ b/go/src/dsl/cst/assignments.go @@ -8,7 +8,6 @@ import ( "miller/src/dsl" "miller/src/lib" "miller/src/runtime" - "miller/src/types" ) // ================================================================ @@ -60,10 +59,9 @@ func NewAssignmentNode( func (this *AssignmentNode) Execute( state *runtime.State, ) (*BlockExitPayload, error) { - var rvalue types.Mlrval - this.rvalueNode.Evaluate(&rvalue, state) + rvalue := this.rvalueNode.Evaluate(state) if !rvalue.IsAbsent() { - err := this.lvalueNode.Assign(&rvalue, state) + err := this.lvalueNode.Assign(rvalue, state) if err != nil { return nil, err } diff --git a/go/src/dsl/cst/block-exit.go b/go/src/dsl/cst/block-exit.go index d984e43d3..ed019939a 100644 --- a/go/src/dsl/cst/block-exit.go +++ b/go/src/dsl/cst/block-exit.go @@ -11,7 +11,6 @@ import ( "miller/src/dsl" "miller/src/lib" "miller/src/runtime" - "miller/src/types" ) // ---------------------------------------------------------------- @@ -82,12 +81,10 @@ func (this *ReturnNode) Execute(state *runtime.State) (*BlockExitPayload, error) }, nil } else { // The return value can be of type MT_ERROR but we do not use Go-level error return here. - var returnValue types.Mlrval - this.returnValueExpression.Evaluate(&returnValue, state) - // TODO: pending pointer-output refactor + returnValue := this.returnValueExpression.Evaluate(state) return &BlockExitPayload{ BLOCK_EXIT_RETURN_VALUE, - &returnValue, + returnValue.Copy(), }, nil } } diff --git a/go/src/dsl/cst/builtin_functions.go b/go/src/dsl/cst/builtin_functions.go index 318664081..d253bbf54 100644 --- a/go/src/dsl/cst/builtin_functions.go +++ b/go/src/dsl/cst/builtin_functions.go @@ -107,10 +107,9 @@ func (this *RootNode) BuildZaryFunctionCallsiteNode( } func (this *ZaryFunctionCallsiteNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - this.zaryFunc(output) +) *types.Mlrval { + return this.zaryFunc() } // ---------------------------------------------------------------- @@ -149,12 +148,9 @@ func (this *RootNode) BuildUnaryFunctionCallsiteNode( } func (this *UnaryFunctionCallsiteNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - var arg1 types.Mlrval - this.evaluable1.Evaluate(&arg1, state) - this.unaryFunc(output, &arg1) +) *types.Mlrval { + return this.unaryFunc(this.evaluable1.Evaluate(state)) } // ---------------------------------------------------------------- @@ -193,12 +189,9 @@ func (this *RootNode) BuildContextualUnaryFunctionCallsiteNode( } func (this *ContextualUnaryFunctionCallsiteNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - var arg1 types.Mlrval - this.evaluable1.Evaluate(&arg1, state) - this.contextualUnaryFunc(output, &arg1, state.Context) +) *types.Mlrval { + return this.contextualUnaryFunc(this.evaluable1.Evaluate(state), state.Context) } // ---------------------------------------------------------------- @@ -269,13 +262,12 @@ func (this *RootNode) BuildBinaryFunctionCallsiteNode( } func (this *BinaryFunctionCallsiteNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - var arg1, arg2 types.Mlrval - this.evaluable1.Evaluate(&arg1, state) - this.evaluable2.Evaluate(&arg2, state) - this.binaryFunc(output, &arg1, &arg2) +) *types.Mlrval { + return this.binaryFunc( + this.evaluable1.Evaluate(state), + this.evaluable2.Evaluate(state), + ) } // ---------------------------------------------------------------- @@ -335,21 +327,19 @@ func (this *RootNode) BuildTernaryFunctionCallsiteNode( } func (this *TernaryFunctionCallsiteNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - var arg1, arg2, arg3 types.Mlrval - this.evaluable1.Evaluate(&arg1, state) - this.evaluable2.Evaluate(&arg2, state) - this.evaluable3.Evaluate(&arg3, state) - this.ternaryFunc(output, &arg1, &arg2, &arg3) +) *types.Mlrval { + return this.ternaryFunc( + this.evaluable1.Evaluate(state), + this.evaluable2.Evaluate(state), + this.evaluable3.Evaluate(state), + ) } // ---------------------------------------------------------------- type VariadicFunctionCallsiteNode struct { variadicFunc types.VariadicFunc evaluables []IEvaluable - args []*types.Mlrval } func (this *RootNode) BuildVariadicFunctionCallsiteNode( @@ -358,7 +348,6 @@ func (this *RootNode) BuildVariadicFunctionCallsiteNode( ) (IEvaluable, error) { lib.InternalCodingErrorIf(astNode.Children == nil) evaluables := make([]IEvaluable, len(astNode.Children)) - args := make([]*types.Mlrval, len(astNode.Children)) callsiteArity := len(astNode.Children) if callsiteArity < builtinFunctionInfo.minimumVariadicArity { @@ -377,23 +366,21 @@ func (this *RootNode) BuildVariadicFunctionCallsiteNode( if err != nil { return nil, err } - args[i] = types.MlrvalPointerFromError() } return &VariadicFunctionCallsiteNode{ variadicFunc: builtinFunctionInfo.variadicFunc, evaluables: evaluables, - args: args, }, nil } func (this *VariadicFunctionCallsiteNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { +) *types.Mlrval { + args := make([]*types.Mlrval, len(this.evaluables)) for i, _ := range this.evaluables { - this.evaluables[i].Evaluate(this.args[i], state) + args[i] = this.evaluables[i].Evaluate(state) } - this.variadicFunc(output, this.args) + return this.variadicFunc(args) } // ================================================================ @@ -445,40 +432,34 @@ func (this *RootNode) BuildLogicalANDOperatorNode(a, b IEvaluable) *LogicalANDOp // * Return a && b func (this *LogicalANDOperatorNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - var aout, bout types.Mlrval - this.a.Evaluate(&aout, state) +) *types.Mlrval { + aout := this.a.Evaluate(state) atype := aout.GetType() if !(atype == types.MT_ABSENT || atype == types.MT_BOOL) { - output.SetFromError() - return + return types.MLRVAL_ERROR } if atype == types.MT_ABSENT { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } if aout.IsFalse() { // This means false && bogus type evaluates to true, which is sad but // which we MUST do in order to not violate the short-circuiting // property. We would have to evaluate b to know if it were error or // not. - output.CopyFrom(&aout) - return + return aout } - this.b.Evaluate(&bout, state) + bout := this.b.Evaluate(state) btype := bout.GetType() if !(btype == types.MT_ABSENT || btype == types.MT_BOOL) { - output.SetFromError() - return + return types.MLRVAL_ERROR } if btype == types.MT_ABSENT { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } - types.MlrvalLogicalAND(output, &aout, &bout) + + return types.MlrvalLogicalAND(aout, bout) } // ================================================================ @@ -499,40 +480,33 @@ func (this *RootNode) BuildLogicalOROperatorNode(a, b IEvaluable) *LogicalOROper // // See the disposition-matrix discussion for LogicalANDOperator. func (this *LogicalOROperatorNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - var aout, bout types.Mlrval - this.a.Evaluate(&aout, state) +) *types.Mlrval { + aout := this.a.Evaluate(state) atype := aout.GetType() if !(atype == types.MT_ABSENT || atype == types.MT_BOOL) { - output.SetFromError() - return + return types.MLRVAL_ERROR } if atype == types.MT_ABSENT { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } if aout.IsTrue() { // This means true || bogus type evaluates to true, which is sad but // which we MUST do in order to not violate the short-circuiting // property. We would have to evaluate b to know if it were error or // not. - output.CopyFrom(&aout) - return + return aout } - this.b.Evaluate(&bout, state) + bout := this.b.Evaluate(state) btype := bout.GetType() if !(btype == types.MT_ABSENT || btype == types.MT_BOOL) { - output.SetFromError() - return + return types.MLRVAL_ERROR } if btype == types.MT_ABSENT { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } - types.MlrvalLogicalOR(output, &aout, &bout) + return types.MlrvalLogicalOR(aout, bout) } // ================================================================ @@ -548,15 +522,14 @@ func (this *RootNode) BuildAbsentCoalesceOperatorNode(a, b IEvaluable) *AbsentCo // short-circuiting: the second argument is not evaluated if the first // argument is not absent. func (this *AbsentCoalesceOperatorNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - this.a.Evaluate(output, state) - if output.GetType() != types.MT_ABSENT { - return +) *types.Mlrval { + aout := this.a.Evaluate(state) + if aout.GetType() != types.MT_ABSENT { + return aout } - this.b.Evaluate(output, state) + return this.b.Evaluate(state) } // ================================================================ @@ -572,13 +545,14 @@ func (this *RootNode) BuildEmptyCoalesceOperatorNode(a, b IEvaluable) *EmptyCoal // short-circuiting: the second argument is not evaluated if the first // argument is not absent. func (this *EmptyCoalesceOperatorNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - this.a.Evaluate(output, state) - atype := output.GetType() - if atype == types.MT_ABSENT || atype == types.MT_VOID || (atype == types.MT_STRING && output.String() == "") { - this.b.Evaluate(output, state) +) *types.Mlrval { + aout := this.a.Evaluate(state) + atype := aout.GetType() + if atype == types.MT_ABSENT || atype == types.MT_VOID || (atype == types.MT_STRING && aout.String() == "") { + return this.b.Evaluate(state) + } else { + return aout } } @@ -589,22 +563,20 @@ func (this *RootNode) BuildStandardTernaryOperatorNode(a, b, c IEvaluable) *Stan return &StandardTernaryOperatorNode{a: a, b: b, c: c} } func (this *StandardTernaryOperatorNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - this.a.Evaluate(output, state) +) *types.Mlrval { + aout := this.a.Evaluate(state) - boolValue, isBool := output.GetBoolValue() + boolValue, isBool := aout.GetBoolValue() if !isBool { - output.SetFromError() - return + return types.MLRVAL_ERROR } // Short-circuit: defer evaluation unless needed if boolValue == true { - this.b.Evaluate(output, state) + return this.b.Evaluate(state) } else { - this.c.Evaluate(output, state) + return this.c.Evaluate(state) } } @@ -619,12 +591,12 @@ func (this *StandardTernaryOperatorNode) Evaluate( // for the function-manager lookup table to indicate the arity of the function, // even though at runtime these functions should not get invoked. -func BinaryShortCircuitPlaceholder(output, input1, input2 *types.Mlrval) { +func BinaryShortCircuitPlaceholder(input1, input2 *types.Mlrval) *types.Mlrval { lib.InternalCodingErrorPanic("Short-circuting was not correctly implemented") - output.SetFromError() // not reached + return types.MLRVAL_ERROR // not reached } -func TernaryShortCircuitPlaceholder(output, input1, input2, input3 *types.Mlrval) { +func TernaryShortCircuitPlaceholder(input1, input2, input3 *types.Mlrval) *types.Mlrval { lib.InternalCodingErrorPanic("Short-circuting was not correctly implemented") - output.SetFromError() // not reached + return types.MLRVAL_ERROR // not reached } diff --git a/go/src/dsl/cst/collections.go b/go/src/dsl/cst/collections.go index f9711428b..982ee54f7 100644 --- a/go/src/dsl/cst/collections.go +++ b/go/src/dsl/cst/collections.go @@ -15,7 +15,6 @@ import ( // ---------------------------------------------------------------- type ArrayLiteralNode struct { evaluables []IEvaluable - mlrvals []types.Mlrval } func (this *RootNode) BuildArrayLiteralNode( @@ -27,7 +26,6 @@ func (this *RootNode) BuildArrayLiteralNode( lib.InternalCodingErrorIf(astNode.Children == nil) evaluables := make([]IEvaluable, len(astNode.Children)) - mlrvals := make([]types.Mlrval, len(astNode.Children)) for i, astChild := range astNode.Children { element, err := this.BuildEvaluableNode(astChild) @@ -35,23 +33,21 @@ func (this *RootNode) BuildArrayLiteralNode( return nil, err } evaluables[i] = element - mlrvals[i] = types.MlrvalFromError() } return &ArrayLiteralNode{ evaluables: evaluables, - mlrvals: mlrvals, }, nil } func (this *ArrayLiteralNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { +) *types.Mlrval { + mlrvals := make([]types.Mlrval, len(this.evaluables)) for i, _ := range this.evaluables { - this.evaluables[i].Evaluate(&this.mlrvals[i], state) + mlrvals[i] = *this.evaluables[i].Evaluate(state) } - output.SetFromArrayLiteralReference(this.mlrvals) + return types.MlrvalPointerFromArrayLiteralReference(mlrvals) } // ---------------------------------------------------------------- @@ -85,22 +81,22 @@ func (this *RootNode) BuildArrayOrMapIndexAccessNode( } func (this *ArrayOrMapIndexAccessNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - var baseMlrval, indexMlrval types.Mlrval - this.baseEvaluable.Evaluate(&baseMlrval, state) - this.indexEvaluable.Evaluate(&indexMlrval, state) +) *types.Mlrval { + baseMlrval := this.baseEvaluable.Evaluate(state) + indexMlrval := this.indexEvaluable.Evaluate(state) // Base-is-array and index-is-int will be checked there if baseMlrval.IsArray() { - *output = baseMlrval.ArrayGet(&indexMlrval) + output := baseMlrval.ArrayGet(indexMlrval) + return &output } else if baseMlrval.IsMap() { - *output = baseMlrval.MapGet(&indexMlrval) + output := baseMlrval.MapGet(indexMlrval) + return &output } else if baseMlrval.IsAbsent() { - output.SetFromAbsent() + return types.MLRVAL_ABSENT } else { - output.SetFromError() + return types.MLRVAL_ERROR } } @@ -144,35 +140,29 @@ func (this *RootNode) BuildArraySliceAccessNode( } func (this *ArraySliceAccessNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - var baseMlrval, lowerIndexMlrval, upperIndexMlrval types.Mlrval - this.baseEvaluable.Evaluate(&baseMlrval, state) - this.lowerIndexEvaluable.Evaluate(&lowerIndexMlrval, state) - this.upperIndexEvaluable.Evaluate(&upperIndexMlrval, state) +) *types.Mlrval { + baseMlrval := this.baseEvaluable.Evaluate(state) + lowerIndexMlrval := this.lowerIndexEvaluable.Evaluate(state) + upperIndexMlrval := this.upperIndexEvaluable.Evaluate(state) if baseMlrval.IsAbsent() { - output.SetFromAbsent() + return types.MLRVAL_ABSENT } if baseMlrval.IsString() { - types.MlrvalSubstr(output, &baseMlrval, &lowerIndexMlrval, &upperIndexMlrval) - return + return types.MlrvalSubstr(baseMlrval, lowerIndexMlrval, upperIndexMlrval) } array := baseMlrval.GetArray() if array == nil { - output.SetFromError() - return + return types.MLRVAL_ERROR } n := len(array) if lowerIndexMlrval.IsAbsent() { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } if upperIndexMlrval.IsAbsent() { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } lowerIndex, ok := lowerIndexMlrval.GetIntValue() @@ -180,8 +170,7 @@ func (this *ArraySliceAccessNode) Evaluate( if lowerIndexMlrval.IsEmpty() { lowerIndex = 1 } else { - output.SetFromError() - return + return types.MLRVAL_ERROR } } upperIndex, ok := upperIndexMlrval.GetIntValue() @@ -189,8 +178,7 @@ func (this *ArraySliceAccessNode) Evaluate( if upperIndexMlrval.IsEmpty() { upperIndex = n } else { - output.SetFromError() - return + return types.MLRVAL_ERROR } } @@ -201,8 +189,7 @@ func (this *ArraySliceAccessNode) Evaluate( upperZindex, _ := types.UnaliasArrayIndex(&array, upperIndex) if lowerZindex > upperZindex { - output.SetFromArrayLiteralReference(make([]types.Mlrval, 0)) - return + return types.MlrvalPointerFromArrayLiteralReference(make([]types.Mlrval, 0)) } // Say x=[1,2,3,4,5]. Then x[3:10] is [3,4,5]. @@ -223,7 +210,7 @@ func (this *ArraySliceAccessNode) Evaluate( di++ } - output.SetFromArrayLiteralReference(retval) + return types.MlrvalPointerFromArrayLiteralReference(retval) } // ================================================================ @@ -253,29 +240,24 @@ func (this *RootNode) BuildPositionalFieldNameNode( // TODO: code-dedupe these next four Evaluate methods func (this *PositionalFieldNameNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - var indexMlrval types.Mlrval - this.indexEvaluable.Evaluate(&indexMlrval, state) +) *types.Mlrval { + indexMlrval := this.indexEvaluable.Evaluate(state) if indexMlrval.IsAbsent() { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } index, ok := indexMlrval.GetIntValue() if !ok { - output.SetFromError() - return + return types.MLRVAL_ERROR } name, ok := state.Inrec.GetNameAtPositionalIndex(index) if !ok { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } - output.SetFromString(name) + return types.MlrvalPointerFromString(name) } // ================================================================ @@ -304,29 +286,24 @@ func (this *RootNode) BuildPositionalFieldValueNode( } func (this *PositionalFieldValueNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - var indexMlrval types.Mlrval - this.indexEvaluable.Evaluate(&indexMlrval, state) +) *types.Mlrval { + indexMlrval := this.indexEvaluable.Evaluate(state) if indexMlrval.IsAbsent() { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } index, ok := indexMlrval.GetIntValue() if !ok { - output.SetFromError() - return + return types.MLRVAL_ERROR } retval := state.Inrec.GetWithPositionalIndex(index) if retval == nil { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } - output.CopyFrom(retval) + return retval } // ================================================================ @@ -362,52 +339,42 @@ func (this *RootNode) BuildArrayOrMapPositionalNameAccessNode( } func (this *ArrayOrMapPositionalNameAccessNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - var baseMlrval, indexMlrval types.Mlrval - this.baseEvaluable.Evaluate(&baseMlrval, state) - this.indexEvaluable.Evaluate(&indexMlrval, state) +) *types.Mlrval { + baseMlrval := this.baseEvaluable.Evaluate(state) + indexMlrval := this.indexEvaluable.Evaluate(state) if indexMlrval.IsAbsent() { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } index, ok := indexMlrval.GetIntValue() if !ok { - output.SetFromError() - return + return types.MLRVAL_ERROR } if baseMlrval.IsArray() { n, _ := baseMlrval.GetArrayLength() zindex, ok := types.UnaliasArrayLengthIndex(int(n), index) if ok { - output.SetFromInt(zindex + 1) // Miller user-space indices are 1-up - return + return types.MlrvalPointerFromInt(zindex + 1) // Miller user-space indices are 1-up } else { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } } else if baseMlrval.IsMap() { name, ok := baseMlrval.GetMap().GetNameAtPositionalIndex(index) if !ok { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } else { - output.SetFromString(name) - return + return types.MlrvalPointerFromString(name) } } else if baseMlrval.IsAbsent() { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } else { - output.SetFromError() - return + return types.MLRVAL_ERROR } } @@ -444,46 +411,38 @@ func (this *RootNode) BuildArrayOrMapPositionalValueAccessNode( } func (this *ArrayOrMapPositionalValueAccessNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - var baseMlrval, indexMlrval types.Mlrval - this.baseEvaluable.Evaluate(&baseMlrval, state) - this.indexEvaluable.Evaluate(&indexMlrval, state) +) *types.Mlrval { + baseMlrval := this.baseEvaluable.Evaluate(state) + indexMlrval := this.indexEvaluable.Evaluate(state) if indexMlrval.IsAbsent() { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } index, ok := indexMlrval.GetIntValue() if !ok { - output.SetFromError() - return + return types.MLRVAL_ERROR } if baseMlrval.IsArray() { // xxx pending pointer-output refactor - element := baseMlrval.ArrayGet(&indexMlrval) - output.CopyFrom(&element) + retval := baseMlrval.ArrayGet(indexMlrval) + return &retval } else if baseMlrval.IsMap() { value := baseMlrval.GetMap().GetWithPositionalIndex(index) if value == nil { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } - output.CopyFrom(value) - return + return value } else if baseMlrval.IsAbsent() { - output.CopyFrom(&baseMlrval) - return + return types.MLRVAL_ABSENT } else { - output.SetFromError() - return + return types.MLRVAL_ERROR } } @@ -544,18 +503,18 @@ func (this *RootNode) BuildMapLiteralNode( } func (this *MapLiteralNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromEmptyMap() +) *types.Mlrval { + output := types.MlrvalPointerFromEmptyMap() for i, _ := range this.evaluablePairs { - var key, value types.Mlrval - this.evaluablePairs[i].Key.Evaluate(&key, state) - this.evaluablePairs[i].Value.Evaluate(&value, state) + key := this.evaluablePairs[i].Key.Evaluate(state) + value := this.evaluablePairs[i].Value.Evaluate(state) if !value.IsAbsent() { - output.MapPut(&key, &value) + output.MapPut(key, value) } } + + return output } diff --git a/go/src/dsl/cst/cond.go b/go/src/dsl/cst/cond.go index e630952f6..7c4fd8313 100644 --- a/go/src/dsl/cst/cond.go +++ b/go/src/dsl/cst/cond.go @@ -46,10 +46,9 @@ func (this *RootNode) BuildCondBlockNode(astNode *dsl.ASTNode) (*CondBlockNode, func (this *CondBlockNode) Execute( state *runtime.State, ) (*BlockExitPayload, error) { - var condition types.Mlrval - condition.SetFromTrue() + condition := types.MLRVAL_TRUE if this.conditionNode != nil { - this.conditionNode.Evaluate(&condition, state) + condition = this.conditionNode.Evaluate(state) } boolValue, isBool := condition.GetBoolValue() diff --git a/go/src/dsl/cst/dump.go b/go/src/dsl/cst/dump.go index 6b222e7f3..86216f644 100644 --- a/go/src/dsl/cst/dump.go +++ b/go/src/dsl/cst/dump.go @@ -166,10 +166,9 @@ func (this *DumpStatementNode) Execute(state *runtime.State) (*BlockExitPayload, // // Plus: we never have to worry about forgetting to do fflush(). :) var buffer bytes.Buffer - var evaluation types.Mlrval for _, expressionEvaluable := range this.expressionEvaluables { - expressionEvaluable.Evaluate(&evaluation, state) + evaluation := expressionEvaluable.Evaluate(state) if !evaluation.IsAbsent() { s := evaluation.String() buffer.WriteString(s) @@ -215,8 +214,7 @@ func (this *DumpStatementNode) dumpToFileOrPipe( outputString string, state *runtime.State, ) error { - var redirectorTarget types.Mlrval - this.redirectorTargetEvaluable.Evaluate(&redirectorTarget, state) + redirectorTarget := this.redirectorTargetEvaluable.Evaluate(state) if !redirectorTarget.IsString() { return errors.New( fmt.Sprintf( diff --git a/go/src/dsl/cst/emit_emitp.go b/go/src/dsl/cst/emit_emitp.go index 85c3219da..887cfb6ad 100644 --- a/go/src/dsl/cst/emit_emitp.go +++ b/go/src/dsl/cst/emit_emitp.go @@ -59,7 +59,6 @@ type EmitXStatementNode struct { // The "x","y" parts. indexEvaluables []IEvaluable - indices []types.Mlrval // Appropriate function to evaluate statements, depending on indexed or not. executorFunc Executor @@ -111,7 +110,6 @@ func (this *RootNode) buildEmitXStatementNode( var names []string = nil var emitEvaluables []IEvaluable = nil var indexEvaluables []IEvaluable = nil - var indices []types.Mlrval = nil // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Things to be emitted, e.g. $a and $b in 'emit > "foo.dat", $a, $b'. @@ -139,14 +137,12 @@ func (this *RootNode) buildEmitXStatementNode( isIndexed = true numKeys := len(keysNode.Children) indexEvaluables = make([]IEvaluable, numKeys) - indices = make([]types.Mlrval, numKeys) for i, keyNode := range keysNode.Children { indexEvaluable, err := this.BuildEvaluableNode(keyNode) if err != nil { return nil, err } indexEvaluables[i] = indexEvaluable - indices[i] = types.MlrvalFromError() } } @@ -154,7 +150,6 @@ func (this *RootNode) buildEmitXStatementNode( names: names, emitEvaluables: emitEvaluables, indexEvaluables: indexEvaluables, - indices: indices, isEmitP: isEmitP, } @@ -273,19 +268,18 @@ func (this *EmitXStatementNode) executeNonIndexed( newrec := types.NewMlrmapAsRecord() for i, emitEvaluable := range this.emitEvaluables { - var emittable types.Mlrval - emitEvaluable.Evaluate(&emittable, state) + emittable := emitEvaluable.Evaluate(state) if emittable.IsAbsent() { continue } if this.isEmitP { - newrec.PutCopy(this.names[i], &emittable) + newrec.PutCopy(this.names[i], emittable) } else { if emittable.IsMap() { newrec.Merge(emittable.GetMap()) } else { - newrec.PutCopy(this.names[i], &emittable) + newrec.PutCopy(this.names[i], emittable) } } } @@ -301,9 +295,7 @@ func (this *EmitXStatementNode) executeIndexed( ) (*BlockExitPayload, error) { emittableMaps := make([]*types.Mlrmap, len(this.emitEvaluables)) for i, emitEvaluable := range this.emitEvaluables { - var emittable types.Mlrval - - emitEvaluable.Evaluate(&emittable, state) + emittable := emitEvaluable.Evaluate(state) if emittable.IsAbsent() { return nil, nil } @@ -312,14 +304,15 @@ func (this *EmitXStatementNode) executeIndexed( } emittableMaps[i] = emittable.GetMap() } + indices := make([]*types.Mlrval, len(this.indexEvaluables)) // TODO: libify this for i, _ := range this.indexEvaluables { - this.indexEvaluables[i].Evaluate(&this.indices[i], state) - if this.indices[i].IsAbsent() { + indices[i] = this.indexEvaluables[i].Evaluate(state) + if indices[i].IsAbsent() { return nil, nil } - if this.indices[i].IsError() { + if indices[i].IsError() { // TODO: surface this more highly return nil, nil } @@ -329,7 +322,7 @@ func (this *EmitXStatementNode) executeIndexed( this.names, types.NewMlrmapAsRecord(), emittableMaps, - this.indices, + indices, state, ) } @@ -339,7 +332,7 @@ func (this *EmitXStatementNode) executeIndexedAux( mapNames []string, templateRecord *types.Mlrmap, emittableMaps []*types.Mlrmap, - indices []types.Mlrval, + indices []*types.Mlrval, state *runtime.State, ) (*BlockExitPayload, error) { lib.InternalCodingErrorIf(len(indices) < 1) @@ -429,8 +422,7 @@ func (this *EmitXStatementNode) emitToFileOrPipe( outrec *types.Mlrmap, state *runtime.State, ) error { - var redirectorTarget types.Mlrval - this.redirectorTargetEvaluable.Evaluate(&redirectorTarget, state) + redirectorTarget := this.redirectorTargetEvaluable.Evaluate(state) if !redirectorTarget.IsString() { return errors.New( fmt.Sprintf( diff --git a/go/src/dsl/cst/emitf.go b/go/src/dsl/cst/emitf.go index d1e580f95..45c31e24d 100644 --- a/go/src/dsl/cst/emitf.go +++ b/go/src/dsl/cst/emitf.go @@ -140,13 +140,12 @@ func (this *RootNode) BuildEmitFStatementNode(astNode *dsl.ASTNode) (IExecutable func (this *EmitFStatementNode) Execute(state *runtime.State) (*BlockExitPayload, error) { newrec := types.NewMlrmapAsRecord() - var emitfValue types.Mlrval for i, emitfEvaluable := range this.emitfEvaluables { emitfName := this.emitfNames[i] - emitfEvaluable.Evaluate(&emitfValue, state) + emitfValue := emitfEvaluable.Evaluate(state) if !emitfValue.IsAbsent() { - newrec.PutCopy(emitfName, &emitfValue) + newrec.PutCopy(emitfName, emitfValue) } } @@ -196,8 +195,7 @@ func (this *EmitFStatementNode) emitfToFileOrPipe( outrec *types.Mlrmap, state *runtime.State, ) error { - var redirectorTarget types.Mlrval - this.redirectorTargetEvaluable.Evaluate(&redirectorTarget, state) + redirectorTarget := this.redirectorTargetEvaluable.Evaluate(state) if !redirectorTarget.IsString() { return errors.New( fmt.Sprintf( diff --git a/go/src/dsl/cst/env.go b/go/src/dsl/cst/env.go index ed7c13417..1f34c1b16 100644 --- a/go/src/dsl/cst/env.go +++ b/go/src/dsl/cst/env.go @@ -34,19 +34,15 @@ func (this *RootNode) BuildEnvironmentVariableNode(astNode *dsl.ASTNode) (*Envir } func (this *EnvironmentVariableNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - var name types.Mlrval - this.nameEvaluable.Evaluate(&name, state) +) *types.Mlrval { + name := this.nameEvaluable.Evaluate(state) if name.IsAbsent() { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } if !name.IsString() { - output.SetFromError() - return + return types.MLRVAL_ERROR } - output.SetFromString(os.Getenv(name.String())) + return types.MlrvalPointerFromString(os.Getenv(name.String())) } diff --git a/go/src/dsl/cst/evaluable.go b/go/src/dsl/cst/evaluable.go index 154863a11..37f674110 100644 --- a/go/src/dsl/cst/evaluable.go +++ b/go/src/dsl/cst/evaluable.go @@ -94,14 +94,11 @@ func (this *RootNode) BuildIndirectFieldValueNode( }, nil } func (this *IndirectFieldValueNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { // TODO: err - var fieldName types.Mlrval - this.fieldNameEvaluable.Evaluate(&fieldName, state) +) *types.Mlrval { // TODO: err + fieldName := this.fieldNameEvaluable.Evaluate(state) if fieldName.IsAbsent() { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } // For normal DSL use the CST validator will prohibit this from being @@ -110,11 +107,10 @@ func (this *IndirectFieldValueNode) Evaluate( // print inrec attributes. Also, a UDF/UDS invoked from begin/end could try // to access the inrec, and that would get past the validator. if state.Inrec == nil { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } - value, err := state.Inrec.GetWithMlrvalIndex(&fieldName) + value, err := state.Inrec.GetWithMlrvalIndex(fieldName) if err != nil { // Key isn't int or string. // TODO: needs error-return in the API @@ -122,10 +118,9 @@ func (this *IndirectFieldValueNode) Evaluate( os.Exit(1) } if value == nil { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } - output.CopyFrom(value) + return value } // ---------------------------------------------------------------- @@ -149,20 +144,17 @@ func (this *RootNode) BuildIndirectOosvarValueNode( } func (this *IndirectOosvarValueNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { // TODO: err - var oosvarName types.Mlrval - this.oosvarNameEvaluable.Evaluate(&oosvarName, state) +) *types.Mlrval { // TODO: err + oosvarName := this.oosvarNameEvaluable.Evaluate(state) if oosvarName.IsAbsent() { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } value := state.Oosvars.Get(oosvarName.String()) if value == nil { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } - output.CopyFrom(value) + + return value } diff --git a/go/src/dsl/cst/filter.go b/go/src/dsl/cst/filter.go index 55a464881..cebb87338 100644 --- a/go/src/dsl/cst/filter.go +++ b/go/src/dsl/cst/filter.go @@ -32,6 +32,6 @@ func (this *RootNode) BuildFilterStatementNode(astNode *dsl.ASTNode) (IExecutabl } func (this *FilterStatementNode) Execute(state *runtime.State) (*BlockExitPayload, error) { - this.filterEvaluable.Evaluate(&state.FilterExpression, state) + state.FilterExpression = this.filterEvaluable.Evaluate(state).Copy() return nil, nil } diff --git a/go/src/dsl/cst/for.go b/go/src/dsl/cst/for.go index 0902bb5c6..c60f691c9 100644 --- a/go/src/dsl/cst/for.go +++ b/go/src/dsl/cst/for.go @@ -116,8 +116,7 @@ func (this *RootNode) BuildForLoopOneVariableNode(astNode *dsl.ASTNode) (*ForLoo // func (this *ForLoopOneVariableNode) Execute(state *runtime.State) (*BlockExitPayload, error) { - var indexMlrval types.Mlrval - this.indexableNode.Evaluate(&indexMlrval, state) + indexMlrval := this.indexableNode.Evaluate(state) if indexMlrval.IsMap() { @@ -300,8 +299,7 @@ func (this *RootNode) BuildForLoopTwoVariableNode(astNode *dsl.ASTNode) (*ForLoo // func (this *ForLoopTwoVariableNode) Execute(state *runtime.State) (*BlockExitPayload, error) { - var indexMlrval types.Mlrval - this.indexableNode.Evaluate(&indexMlrval, state) + indexMlrval := this.indexableNode.Evaluate(state) if indexMlrval.IsMap() { @@ -497,8 +495,7 @@ func (this *RootNode) BuildForLoopMultivariableNode( // func (this *ForLoopMultivariableNode) Execute(state *runtime.State) (*BlockExitPayload, error) { - var indexMlrval types.Mlrval - this.indexableNode.Evaluate(&indexMlrval, state) + indexMlrval := this.indexableNode.Evaluate(state) // Make a frame for the loop variables state.Stack.PushStackFrame() @@ -509,7 +506,7 @@ func (this *ForLoopMultivariableNode) Execute(state *runtime.State) (*BlockExitP // from any of the latter is a break from all. However, at this point, the // break has been "broken" and should not be returned to the caller. // Return-statements should, though. - blockExitPayload, err := this.executeOuter(&indexMlrval, this.keyVariableNames, state) + blockExitPayload, err := this.executeOuter(indexMlrval, this.keyVariableNames, state) if blockExitPayload == nil { return nil, err } else { @@ -857,13 +854,11 @@ func (this *TripleForLoopNode) Execute(state *runtime.State) (*BlockExitPayload, return nil, err } - var continuationValue types.Mlrval - for { // state.Stack.Dump() // empty is true if this.continuationExpressionNode != nil { - this.continuationExpressionNode.Evaluate(&continuationValue, state) + continuationValue := this.continuationExpressionNode.Evaluate(state) boolValue, isBool := continuationValue.GetBoolValue() if !isBool { // TODO: propagate line-number context diff --git a/go/src/dsl/cst/if.go b/go/src/dsl/cst/if.go index 6338e4e6a..5cbbf02b5 100644 --- a/go/src/dsl/cst/if.go +++ b/go/src/dsl/cst/if.go @@ -119,11 +119,10 @@ func (this *RootNode) BuildIfChainNode(astNode *dsl.ASTNode) (*IfChainNode, erro // ---------------------------------------------------------------- func (this *IfChainNode) Execute(state *runtime.State) (*BlockExitPayload, error) { - var condition types.Mlrval for _, ifItem := range this.ifItems { - condition.SetFromTrue() + condition := types.MLRVAL_TRUE if ifItem.conditionNode != nil { - ifItem.conditionNode.Evaluate(&condition, state) + condition = ifItem.conditionNode.Evaluate(state) } boolValue, isBool := condition.GetBoolValue() if !isBool { diff --git a/go/src/dsl/cst/leaves.go b/go/src/dsl/cst/leaves.go index 00f731205..bac507ef2 100644 --- a/go/src/dsl/cst/leaves.go +++ b/go/src/dsl/cst/leaves.go @@ -97,23 +97,21 @@ func (this *RootNode) BuildDirectFieldRvalueNode(fieldName string) *DirectFieldR } } func (this *DirectFieldRvalueNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { +) *types.Mlrval { // For normal DSL use the CST validator will prohibit this from being // called in places the current record is undefined (begin and end blocks). // However in the REPL people can read past end of stream and still try to // print inrec attributes. Also, a UDF/UDS invoked from begin/end could try // to access the inrec, and that would get past the validator. if state.Inrec == nil { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } value := state.Inrec.Get(this.fieldName) if value == nil { - output.SetFromAbsent() + return types.MLRVAL_ABSENT } else { - output.CopyFrom(value) + return value } } @@ -125,18 +123,17 @@ func (this *RootNode) BuildFullSrecRvalueNode() *FullSrecRvalueNode { return &FullSrecRvalueNode{} } func (this *FullSrecRvalueNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { +) *types.Mlrval { // For normal DSL use the CST validator will prohibit this from being // called in places the current record is undefined (begin and end blocks). // However in the REPL people can read past end of stream and still try to // print inrec attributes. Also, a UDF/UDS invoked from begin/end could try // to access the inrec, and that would get past the validator. if state.Inrec == nil { - output.SetFromAbsent() + return types.MLRVAL_ABSENT } else { - output.SetFromMap(state.Inrec) + return types.MlrvalPointerFromMap(state.Inrec) } } @@ -151,14 +148,13 @@ func (this *RootNode) BuildDirectOosvarRvalueNode(variableName string) *DirectOo } } func (this *DirectOosvarRvalueNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { +) *types.Mlrval { value := state.Oosvars.Get(this.variableName) if value == nil { - output.SetFromAbsent() + return types.MLRVAL_ABSENT } else { - output.CopyFrom(value) + return value } } @@ -170,10 +166,9 @@ func (this *RootNode) BuildFullOosvarRvalueNode() *FullOosvarRvalueNode { return &FullOosvarRvalueNode{} } func (this *FullOosvarRvalueNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromMap(state.Oosvars) +) *types.Mlrval { + return types.MlrvalPointerFromMap(state.Oosvars) } // ---------------------------------------------------------------- @@ -187,14 +182,13 @@ func (this *RootNode) BuildLocalVariableNode(variableName string) *LocalVariable } } func (this *LocalVariableNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { +) *types.Mlrval { value := state.Stack.Get(this.variableName) if value == nil { - output.SetFromAbsent() + return types.MLRVAL_ABSENT } else { - output.CopyFrom(value) + return value } } @@ -209,10 +203,9 @@ func (this *RootNode) BuildStringLiteralNode(literal string) *StringLiteralNode } } func (this *StringLiteralNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.CopyFrom(&this.literal) +) *types.Mlrval { + return &this.literal } // ---------------------------------------------------------------- @@ -226,10 +219,9 @@ func (this *RootNode) BuildIntLiteralNode(literal string) *IntLiteralNode { } } func (this *IntLiteralNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.CopyFrom(&this.literal) +) *types.Mlrval { + return &this.literal } // ---------------------------------------------------------------- @@ -243,10 +235,9 @@ func (this *RootNode) BuildFloatLiteralNode(literal string) *FloatLiteralNode { } } func (this *FloatLiteralNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.CopyFrom(&this.literal) +) *types.Mlrval { + return &this.literal } // ---------------------------------------------------------------- @@ -260,10 +251,9 @@ func (this *RootNode) BuildBoolLiteralNode(literal string) *BoolLiteralNode { } } func (this *BoolLiteralNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.CopyFrom(&this.literal) +) *types.Mlrval { + return &this.literal } // ================================================================ @@ -328,10 +318,9 @@ func (this *RootNode) BuildFILENAMENode() *FILENAMENode { return &FILENAMENode{} } func (this *FILENAMENode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromString(state.Context.FILENAME) +) *types.Mlrval { + return types.MlrvalPointerFromString(state.Context.FILENAME) } // ---------------------------------------------------------------- @@ -342,10 +331,9 @@ func (this *RootNode) BuildFILENUMNode() *FILENUMNode { return &FILENUMNode{} } func (this *FILENUMNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromInt(state.Context.FILENUM) +) *types.Mlrval { + return types.MlrvalPointerFromInt(state.Context.FILENUM) } // ---------------------------------------------------------------- @@ -356,10 +344,9 @@ func (this *RootNode) BuildNFNode() *NFNode { return &NFNode{} } func (this *NFNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromInt(state.Inrec.FieldCount) +) *types.Mlrval { + return types.MlrvalPointerFromInt(state.Inrec.FieldCount) } // ---------------------------------------------------------------- @@ -370,10 +357,9 @@ func (this *RootNode) BuildNRNode() *NRNode { return &NRNode{} } func (this *NRNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromInt(state.Context.NR) +) *types.Mlrval { + return types.MlrvalPointerFromInt(state.Context.NR) } // ---------------------------------------------------------------- @@ -384,10 +370,9 @@ func (this *RootNode) BuildFNRNode() *FNRNode { return &FNRNode{} } func (this *FNRNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromInt(state.Context.FNR) +) *types.Mlrval { + return types.MlrvalPointerFromInt(state.Context.FNR) } // ---------------------------------------------------------------- @@ -398,10 +383,9 @@ func (this *RootNode) BuildIRSNode() *IRSNode { return &IRSNode{} } func (this *IRSNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromString(state.Context.IRS) +) *types.Mlrval { + return types.MlrvalPointerFromString(state.Context.IRS) } // ---------------------------------------------------------------- @@ -412,10 +396,9 @@ func (this *RootNode) BuildIFSNode() *IFSNode { return &IFSNode{} } func (this *IFSNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromString(state.Context.IFS) +) *types.Mlrval { + return types.MlrvalPointerFromString(state.Context.IFS) } // ---------------------------------------------------------------- @@ -426,10 +409,9 @@ func (this *RootNode) BuildIPSNode() *IPSNode { return &IPSNode{} } func (this *IPSNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromString(state.Context.IPS) +) *types.Mlrval { + return types.MlrvalPointerFromString(state.Context.IPS) } // ---------------------------------------------------------------- @@ -440,10 +422,9 @@ func (this *RootNode) BuildORSNode() *ORSNode { return &ORSNode{} } func (this *ORSNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromString(state.Context.ORS) +) *types.Mlrval { + return types.MlrvalPointerFromString(state.Context.ORS) } // ---------------------------------------------------------------- @@ -454,10 +435,9 @@ func (this *RootNode) BuildOFSNode() *OFSNode { return &OFSNode{} } func (this *OFSNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromString(state.Context.OFS) +) *types.Mlrval { + return types.MlrvalPointerFromString(state.Context.OFS) } // ---------------------------------------------------------------- @@ -468,10 +448,9 @@ func (this *RootNode) BuildOPSNode() *OPSNode { return &OPSNode{} } func (this *OPSNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromString(state.Context.OPS) +) *types.Mlrval { + return types.MlrvalPointerFromString(state.Context.OPS) } // ---------------------------------------------------------------- @@ -482,10 +461,9 @@ func (this *RootNode) BuildOFLATSEPNode() *OFLATSEPNode { return &OFLATSEPNode{} } func (this *OFLATSEPNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromString(state.Context.OFLATSEP) +) *types.Mlrval { + return types.MlrvalPointerFromString(state.Context.OFLATSEP) } // ================================================================ @@ -517,10 +495,9 @@ func (this *RootNode) BuildMathPINode() *MathPINode { return &MathPINode{} } func (this *MathPINode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromFloat64(math.Pi) +) *types.Mlrval { + return types.MlrvalPointerFromFloat64(math.Pi) } // ---------------------------------------------------------------- @@ -531,10 +508,9 @@ func (this *RootNode) BuildMathENode() *MathENode { return &MathENode{} } func (this *MathENode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromFloat64(math.E) +) *types.Mlrval { + return types.MlrvalPointerFromFloat64(math.E) } // ================================================================ @@ -550,10 +526,9 @@ func (this *RootNode) BuildArraySliceEmptyLowerIndexNode( return &LiteralOneNode{}, nil } func (this *LiteralOneNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromInt(1) +) *types.Mlrval { + return types.MlrvalPointerFromInt(1) } // ================================================================ @@ -571,10 +546,9 @@ func (this *RootNode) BuildArraySliceEmptyUpperIndexNode( return &LiteralEmptyStringNode{}, nil } func (this *LiteralEmptyStringNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { - output.SetFromString("") +) *types.Mlrval { + return types.MlrvalPointerFromString("") } // ---------------------------------------------------------------- @@ -589,8 +563,8 @@ func (this *RootNode) BuildPanicNode(astNode *dsl.ASTNode) (*PanicNode, error) { return &PanicNode{}, nil } func (this *PanicNode) Evaluate( - output *types.Mlrval, state *runtime.State, -) { +) *types.Mlrval { lib.InternalCodingErrorPanic("Panic token was evaluated, not short-circuited.") + return nil // not reached } diff --git a/go/src/dsl/cst/lvalues.go b/go/src/dsl/cst/lvalues.go index 4e645887a..3430aee08 100644 --- a/go/src/dsl/cst/lvalues.go +++ b/go/src/dsl/cst/lvalues.go @@ -206,7 +206,6 @@ func (this *IndirectFieldValueLvalueNode) AssignIndexed( indices []*types.Mlrval, state *runtime.State, ) error { - var lhsFieldName types.Mlrval // AssignmentNode checks for absentness of the rvalue, so we just assign // whatever we get lib.InternalCodingErrorIf(rvalue.IsAbsent()) @@ -220,10 +219,10 @@ func (this *IndirectFieldValueLvalueNode) AssignIndexed( return errors.New("There is no current record to assign to.") } - this.lhsFieldNameExpression.Evaluate(&lhsFieldName, state) + lhsFieldName := this.lhsFieldNameExpression.Evaluate(state) if indices == nil { - err := state.Inrec.PutCopyWithMlrvalIndex(&lhsFieldName, rvalue) + err := state.Inrec.PutCopyWithMlrvalIndex(lhsFieldName, rvalue) if err != nil { return err } @@ -246,7 +245,6 @@ func (this *IndirectFieldValueLvalueNode) UnassignIndexed( indices []*types.Mlrval, state *runtime.State, ) { - var lhsFieldName types.Mlrval // For normal DSL use the CST validator will prohibit this from being // called in places the current record is undefined (begin and end blocks). // However in the REPL people can read past end of stream and still try to @@ -256,7 +254,7 @@ func (this *IndirectFieldValueLvalueNode) UnassignIndexed( return } - this.lhsFieldNameExpression.Evaluate(&lhsFieldName, state) + lhsFieldName := this.lhsFieldNameExpression.Evaluate(state) if indices == nil { name := lhsFieldName.String() state.Inrec.Remove(name) @@ -301,7 +299,6 @@ func (this *PositionalFieldNameLvalueNode) Assign( rvalue *types.Mlrval, state *runtime.State, ) error { - var lhsFieldIndex types.Mlrval // AssignmentNode checks for absentness of the rvalue, so we just assign // whatever we get lib.InternalCodingErrorIf(rvalue.IsAbsent()) @@ -315,7 +312,7 @@ func (this *PositionalFieldNameLvalueNode) Assign( return errors.New("There is no current record to assign to.") } - this.lhsFieldIndexExpression.Evaluate(&lhsFieldIndex, state) + lhsFieldIndex := this.lhsFieldIndexExpression.Evaluate(state) index, ok := lhsFieldIndex.GetIntValue() if ok { @@ -354,8 +351,7 @@ func (this *PositionalFieldNameLvalueNode) UnassignIndexed( indices []*types.Mlrval, state *runtime.State, ) { - var lhsFieldIndex types.Mlrval - this.lhsFieldIndexExpression.Evaluate(&lhsFieldIndex, state) + lhsFieldIndex := this.lhsFieldIndexExpression.Evaluate(state) // For normal DSL use the CST validator will prohibit this from being // called in places the current record is undefined (begin and end blocks). @@ -376,7 +372,7 @@ func (this *PositionalFieldNameLvalueNode) UnassignIndexed( } else { // xxx positional state.Inrec.RemoveIndexed( - append([]*types.Mlrval{&lhsFieldIndex}, indices...), + append([]*types.Mlrval{lhsFieldIndex}, indices...), ) } } @@ -423,7 +419,6 @@ func (this *PositionalFieldValueLvalueNode) AssignIndexed( indices []*types.Mlrval, state *runtime.State, ) error { - var lhsFieldIndex types.Mlrval // AssignmentNode checks for absentness of the rvalue, so we just assign // whatever we get lib.InternalCodingErrorIf(rvalue.IsAbsent()) @@ -437,7 +432,7 @@ func (this *PositionalFieldValueLvalueNode) AssignIndexed( return errors.New("There is no current record to assign to.") } - this.lhsFieldIndexExpression.Evaluate(&lhsFieldIndex, state) + lhsFieldIndex := this.lhsFieldIndexExpression.Evaluate(state) if indices == nil { index, ok := lhsFieldIndex.GetIntValue() @@ -461,7 +456,7 @@ func (this *PositionalFieldValueLvalueNode) AssignIndexed( } else { // xxx positional return state.Inrec.PutIndexed( - append([]*types.Mlrval{&lhsFieldIndex}, indices...), + append([]*types.Mlrval{lhsFieldIndex}, indices...), rvalue, ) } @@ -487,9 +482,8 @@ func (this *PositionalFieldValueLvalueNode) UnassignIndexed( if state.Inrec == nil { return } - var lhsFieldIndex types.Mlrval - this.lhsFieldIndexExpression.Evaluate(&lhsFieldIndex, state) + lhsFieldIndex := this.lhsFieldIndexExpression.Evaluate(state) if indices == nil { index, ok := lhsFieldIndex.GetIntValue() if ok { @@ -500,7 +494,7 @@ func (this *PositionalFieldValueLvalueNode) UnassignIndexed( } else { // xxx positional state.Inrec.RemoveIndexed( - append([]*types.Mlrval{&lhsFieldIndex}, indices...), + append([]*types.Mlrval{lhsFieldIndex}, indices...), ) } } @@ -685,15 +679,14 @@ func (this *IndirectOosvarValueLvalueNode) AssignIndexed( indices []*types.Mlrval, state *runtime.State, ) error { - var lhsOosvarName types.Mlrval // AssignmentNode checks for absentness of the rvalue, so we just assign // whatever we get lib.InternalCodingErrorIf(rvalue.IsAbsent()) - this.lhsOosvarNameExpression.Evaluate(&lhsOosvarName, state) + lhsOosvarName := this.lhsOosvarNameExpression.Evaluate(state) if indices == nil { - err := state.Oosvars.PutCopyWithMlrvalIndex(&lhsOosvarName, rvalue) + err := state.Oosvars.PutCopyWithMlrvalIndex(lhsOosvarName, rvalue) if err != nil { return err } @@ -716,15 +709,14 @@ func (this *IndirectOosvarValueLvalueNode) UnassignIndexed( indices []*types.Mlrval, state *runtime.State, ) { - var lhsOosvarName types.Mlrval - this.lhsOosvarNameExpression.Evaluate(&lhsOosvarName, state) + lhsOosvarName := this.lhsOosvarNameExpression.Evaluate(state) if indices == nil { sname := lhsOosvarName.String() state.Oosvars.Remove(sname) } else { state.Oosvars.RemoveIndexed( - append([]*types.Mlrval{&lhsOosvarName}, indices...), + append([]*types.Mlrval{lhsOosvarName}, indices...), ) } } @@ -891,7 +883,6 @@ func (this *LocalVariableLvalueNode) UnassignIndexed( type IndexedLvalueNode struct { baseLvalue IAssignable indexEvaluables []IEvaluable - indices []*types.Mlrval // malloc-avoidance } func (this *RootNode) BuildIndexedLvalueNode(astNode *dsl.ASTNode) (IAssignable, error) { @@ -900,7 +891,6 @@ func (this *RootNode) BuildIndexedLvalueNode(astNode *dsl.ASTNode) (IAssignable, var baseLvalue IAssignable = nil indexEvaluables := make([]IEvaluable, 0) - indices := make([]*types.Mlrval, 0) var err error = nil // $ mlr -n put -v '$x[1][2]=3' @@ -927,9 +917,7 @@ func (this *RootNode) BuildIndexedLvalueNode(astNode *dsl.ASTNode) (IAssignable, if err != nil { return nil, err } - index := types.MlrvalFromError() indexEvaluables = append([]IEvaluable{indexEvaluable}, indexEvaluables...) - indices = append([]*types.Mlrval{&index}, indices...) walkerNode = walkerNode.Children[0] } else { baseLvalue, err = this.BuildAssignableNode(walkerNode) @@ -939,18 +927,16 @@ func (this *RootNode) BuildIndexedLvalueNode(astNode *dsl.ASTNode) (IAssignable, break } } - return NewIndexedLvalueNode(baseLvalue, indexEvaluables, indices), nil + return NewIndexedLvalueNode(baseLvalue, indexEvaluables), nil } func NewIndexedLvalueNode( baseLvalue IAssignable, indexEvaluables []IEvaluable, - indices []*types.Mlrval, ) *IndexedLvalueNode { return &IndexedLvalueNode{ baseLvalue: baseLvalue, indexEvaluables: indexEvaluables, - indices: indices, } } @@ -961,21 +947,22 @@ func (this *IndexedLvalueNode) Assign( rvalue *types.Mlrval, state *runtime.State, ) error { + indices := make([]*types.Mlrval, len(this.indexEvaluables)) - for i, indexEvaluable := range this.indexEvaluables { - indexEvaluable.Evaluate(this.indices[i], state) - if this.indices[i].IsAbsent() { + for i, _ := range this.indexEvaluables { + indices[i] = this.indexEvaluables[i].Evaluate(state) + if indices[i].IsAbsent() { return nil } } // This lets the user do '$y[ ["a", "b", "c"] ] = $x' in lieu of // '$y["a"]["b"]["c"] = $x'. - if len(this.indices) == 1 && this.indices[0].IsArray() { - this.indices = types.MakePointerArray(this.indices[0].GetArray()) + if len(indices) == 1 && indices[0].IsArray() { + indices = types.MakePointerArray(indices[0].GetArray()) } - return this.baseLvalue.AssignIndexed(rvalue, this.indices, state) + return this.baseLvalue.AssignIndexed(rvalue, indices, state) } func (this *IndexedLvalueNode) AssignIndexed( @@ -991,11 +978,12 @@ func (this *IndexedLvalueNode) AssignIndexed( func (this *IndexedLvalueNode) Unassign( state *runtime.State, ) { - for i, indexEvaluable := range this.indexEvaluables { - indexEvaluable.Evaluate(this.indices[i], state) + indices := make([]*types.Mlrval, len(this.indexEvaluables)) + for i, _ := range this.indexEvaluables { + indices[i] = this.indexEvaluables[i].Evaluate(state) } - this.baseLvalue.UnassignIndexed(this.indices, state) + this.baseLvalue.UnassignIndexed(indices, state) } func (this *IndexedLvalueNode) UnassignIndexed( @@ -1035,12 +1023,11 @@ func (this *EnvironmentVariableLvalueNode) Assign( rvalue *types.Mlrval, state *runtime.State, ) error { - var name types.Mlrval // AssignmentNode checks for absentness of the rvalue, so we just assign // whatever we get lib.InternalCodingErrorIf(rvalue.IsAbsent()) - this.nameExpression.Evaluate(&name, state) + name := this.nameExpression.Evaluate(state) if name.IsAbsent() { return nil } @@ -1070,8 +1057,7 @@ func (this *EnvironmentVariableLvalueNode) AssignIndexed( func (this *EnvironmentVariableLvalueNode) Unassign( state *runtime.State, ) { - var name types.Mlrval - this.nameExpression.Evaluate(&name, state) + name := this.nameExpression.Evaluate(state) if name.IsAbsent() { return } diff --git a/go/src/dsl/cst/print.go b/go/src/dsl/cst/print.go index b2ccd321e..881f0e352 100644 --- a/go/src/dsl/cst/print.go +++ b/go/src/dsl/cst/print.go @@ -312,13 +312,12 @@ func (this *PrintStatementNode) Execute(state *runtime.State) (*BlockExitPayload // // Plus: we never have to worry about forgetting to do fflush(). :) var buffer bytes.Buffer - var evaluation types.Mlrval for i, expressionEvaluable := range this.expressionEvaluables { if i > 0 { buffer.WriteString(" ") } - expressionEvaluable.Evaluate(&evaluation, state) + evaluation := expressionEvaluable.Evaluate(state) if !evaluation.IsAbsent() { buffer.WriteString(evaluation.String()) } @@ -361,8 +360,7 @@ func (this *PrintStatementNode) printToFileOrPipe( outputString string, state *runtime.State, ) error { - var redirectorTarget types.Mlrval // malloc-avoidance - this.redirectorTargetEvaluable.Evaluate(&redirectorTarget, state) + redirectorTarget := this.redirectorTargetEvaluable.Evaluate(state) if !redirectorTarget.IsString() { return errors.New( fmt.Sprintf( diff --git a/go/src/dsl/cst/subroutines.go b/go/src/dsl/cst/subroutines.go index ab724fde8..187d8bc91 100644 --- a/go/src/dsl/cst/subroutines.go +++ b/go/src/dsl/cst/subroutines.go @@ -11,7 +11,6 @@ package cst import ( "miller/src/dsl" "miller/src/lib" - "miller/src/types" ) // ---------------------------------------------------------------- @@ -55,14 +54,12 @@ func (this *RootNode) BuildSubroutineCallsiteNode(astNode *dsl.ASTNode) (IExecut // Here we need to make an array of our arguments at the callsite, to be // paired up with the parameters within he subroutine definition at runtime. argumentNodes := make([]IEvaluable, callsiteArity) - arguments := make([]types.Mlrval, callsiteArity) for i, argumentASTNode := range astNode.Children { argumentNode, err := this.BuildEvaluableNode(argumentASTNode) if err != nil { return nil, err } argumentNodes[i] = argumentNode - arguments[i] = types.MlrvalFromError() } if uds == nil { @@ -71,11 +68,11 @@ func (this *RootNode) BuildSubroutineCallsiteNode(astNode *dsl.ASTNode) (IExecut // this callsite. This happens example when a subroutine is called before // it's defined. uds = NewUnresolvedUDS(subroutineName, callsiteArity) - udsCallsiteNode := NewUDSCallsite(argumentNodes, arguments, uds) + udsCallsiteNode := NewUDSCallsite(argumentNodes, uds) this.rememberUnresolvedSubroutineCallsite(udsCallsiteNode) return udsCallsiteNode, nil } else { - udsCallsiteNode := NewUDSCallsite(argumentNodes, arguments, uds) + udsCallsiteNode := NewUDSCallsite(argumentNodes, uds) return udsCallsiteNode, nil } } diff --git a/go/src/dsl/cst/tee.go b/go/src/dsl/cst/tee.go index 26be06395..4f5fca29d 100644 --- a/go/src/dsl/cst/tee.go +++ b/go/src/dsl/cst/tee.go @@ -141,8 +141,7 @@ func (this *RootNode) BuildTeeStatementNode(astNode *dsl.ASTNode) (IExecutable, // ---------------------------------------------------------------- func (this *TeeStatementNode) Execute(state *runtime.State) (*BlockExitPayload, error) { - var expression types.Mlrval - this.expressionEvaluable.Evaluate(&expression, state) + expression := this.expressionEvaluable.Evaluate(state) if !expression.IsMap() { return nil, errors.New( fmt.Sprintf( @@ -160,8 +159,7 @@ func (this *TeeStatementNode) teeToFileOrPipe( outrec *types.Mlrmap, state *runtime.State, ) error { - var redirectorTarget types.Mlrval // malloc-avoidance - this.redirectorTargetEvaluable.Evaluate(&redirectorTarget, state) + redirectorTarget := this.redirectorTargetEvaluable.Evaluate(state) if !redirectorTarget.IsString() { return errors.New( fmt.Sprintf( diff --git a/go/src/dsl/cst/udf.go b/go/src/dsl/cst/udf.go index 1ecfbeee5..2155c1583 100644 --- a/go/src/dsl/cst/udf.go +++ b/go/src/dsl/cst/udf.go @@ -59,9 +59,8 @@ func NewUDFCallsite( } func (this *UDFCallsite) Evaluate( - output *types.Mlrval, state *runtime.State, -) { +) *types.Mlrval { lib.InternalCodingErrorIf(this.argumentNodes == nil) lib.InternalCodingErrorIf(this.udf == nil) lib.InternalCodingErrorIf(this.udf.functionBody == nil) @@ -111,12 +110,12 @@ func (this *UDFCallsite) Evaluate( // Evaluate the arguments numArguments := len(this.udf.signature.typeGatedParameterNames) - arguments := make([]types.Mlrval, numArguments) + arguments := make([]*types.Mlrval, numArguments) - for i, typeGatedParameterName := range this.udf.signature.typeGatedParameterNames { - this.argumentNodes[i].Evaluate(&arguments[i], state) + for i, _ := range this.udf.signature.typeGatedParameterNames { + arguments[i] = this.argumentNodes[i].Evaluate(state) - err := typeGatedParameterName.Check(&arguments[i]) + err := this.udf.signature.typeGatedParameterNames[i].Check(arguments[i]) if err != nil { // TODO: put error-return in the Evaluate API fmt.Fprint(os.Stderr, err) @@ -132,7 +131,7 @@ func (this *UDFCallsite) Evaluate( err := state.Stack.DefineTypedAtScope( this.udf.signature.typeGatedParameterNames[i].Name, this.udf.signature.typeGatedParameterNames[i].TypeName, - &arguments[i], + arguments[i], ) // TODO: put error-return in the Evaluate API if err != nil { @@ -148,22 +147,19 @@ func (this *UDFCallsite) Evaluate( // being MT_ERROR should be mapped to MT_ERROR here (nominally, // data-dependent). But error-return could be something not data-dependent. if err != nil { - output.SetFromError() - return + return types.MLRVAL_ERROR } // Fell off end of function with no return if blockExitPayload == nil { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } // TODO: should be an internal coding error. This would be break or // continue not in a loop, or return-void, both of which should have been // reported as syntax errors during the parsing pass. if blockExitPayload.blockExitStatus != BLOCK_EXIT_RETURN_VALUE { - output.SetFromAbsent() - return + return types.MLRVAL_ABSENT } // Definitely a Miller internal coding error if the user put 'return x' in @@ -180,7 +176,7 @@ func (this *UDFCallsite) Evaluate( os.Exit(1) } - output.CopyFrom(blockExitPayload.blockReturnValue) + return blockExitPayload.blockReturnValue.Copy() } // ---------------------------------------------------------------- diff --git a/go/src/dsl/cst/uds.go b/go/src/dsl/cst/uds.go index 93d36cfb6..3df093bc1 100644 --- a/go/src/dsl/cst/uds.go +++ b/go/src/dsl/cst/uds.go @@ -44,25 +44,21 @@ func NewUnresolvedUDS( // ---------------------------------------------------------------- type UDSCallsite struct { argumentNodes []IEvaluable - arguments []types.Mlrval // malloc-avoidance uds *UDS } func NewUDSCallsite( argumentNodes []IEvaluable, - arguments []types.Mlrval, uds *UDS, ) *UDSCallsite { return &UDSCallsite{ argumentNodes: argumentNodes, - arguments: arguments, uds: uds, } } func (this *UDSCallsite) Execute(state *runtime.State) (*BlockExitPayload, error) { lib.InternalCodingErrorIf(this.argumentNodes == nil) - lib.InternalCodingErrorIf(this.arguments == nil) lib.InternalCodingErrorIf(this.uds == nil) lib.InternalCodingErrorIf(this.uds.subroutineBody == nil) @@ -110,11 +106,12 @@ func (this *UDSCallsite) Execute(state *runtime.State) (*BlockExitPayload, error // we push a new frameset and DefineTypedAtScope using the callee's frameset. // Evaluate the arguments + arguments := make([]*types.Mlrval, len(this.uds.signature.typeGatedParameterNames)) for i, typeGatedParameterName := range this.uds.signature.typeGatedParameterNames { - this.argumentNodes[i].Evaluate(&this.arguments[i], state) + arguments[i] = this.argumentNodes[i].Evaluate(state) - err := typeGatedParameterName.Check(&this.arguments[i]) + err := typeGatedParameterName.Check(arguments[i]) if err != nil { return nil, err } @@ -124,11 +121,11 @@ func (this *UDSCallsite) Execute(state *runtime.State) (*BlockExitPayload, error state.Stack.PushStackFrameSet() defer state.Stack.PopStackFrameSet() - for i, _ := range this.arguments { + for i, _ := range arguments { err := state.Stack.DefineTypedAtScope( this.uds.signature.typeGatedParameterNames[i].Name, this.uds.signature.typeGatedParameterNames[i].TypeName, - &this.arguments[i], + arguments[i], ) if err != nil { return nil, err diff --git a/go/src/dsl/cst/while.go b/go/src/dsl/cst/while.go index 46d214b25..e2965e55d 100644 --- a/go/src/dsl/cst/while.go +++ b/go/src/dsl/cst/while.go @@ -10,7 +10,6 @@ import ( "miller/src/dsl" "miller/src/lib" "miller/src/runtime" - "miller/src/types" ) // ================================================================ @@ -50,9 +49,8 @@ func (this *RootNode) BuildWhileLoopNode(astNode *dsl.ASTNode) (*WhileLoopNode, // ---------------------------------------------------------------- func (this *WhileLoopNode) Execute(state *runtime.State) (*BlockExitPayload, error) { - var condition types.Mlrval for { - this.conditionNode.Evaluate(&condition, state) + condition := this.conditionNode.Evaluate(state) boolValue, isBool := condition.GetBoolValue() if !isBool { // TODO: line-number/token info for the DSL expression. @@ -121,7 +119,6 @@ func (this *RootNode) BuildDoWhileLoopNode(astNode *dsl.ASTNode) (*DoWhileLoopNo // ---------------------------------------------------------------- func (this *DoWhileLoopNode) Execute(state *runtime.State) (*BlockExitPayload, error) { - var condition types.Mlrval for { blockExitPayload, err := this.statementBlockNode.Execute(state) if err != nil { @@ -143,7 +140,7 @@ func (this *DoWhileLoopNode) Execute(state *runtime.State) (*BlockExitPayload, e // TODO: handle return statements // TODO: runtime errors for any other types - this.conditionNode.Evaluate(&condition, state) + condition := this.conditionNode.Evaluate(state) boolValue, isBool := condition.GetBoolValue() if !isBool { // TODO: line-number/token info for the DSL expression. diff --git a/go/src/runtime/state.go b/go/src/runtime/state.go index ddfdd3c7d..1dec3cd7b 100644 --- a/go/src/runtime/state.go +++ b/go/src/runtime/state.go @@ -13,7 +13,7 @@ type State struct { Inrec *types.Mlrmap Context *types.Context Oosvars *types.Mlrmap - FilterExpression types.Mlrval + FilterExpression *types.Mlrval Stack *Stack OutputChannel chan<- *types.RecordAndContext } @@ -24,7 +24,7 @@ func NewEmptyState() *State { Inrec: nil, Context: nil, Oosvars: oosvars, - FilterExpression: types.MlrvalFromTrue(), + FilterExpression: types.MLRVAL_TRUE, Stack: NewStack(), // OutputChannel is assigned after construction } diff --git a/go/src/transformers/clean-whitespace.go b/go/src/transformers/clean-whitespace.go index dd7b522c2..469d2f3f1 100644 --- a/go/src/transformers/clean-whitespace.go +++ b/go/src/transformers/clean-whitespace.go @@ -138,12 +138,10 @@ func (this *TransformerCleanWhitespace) cleanWhitespaceInKeysAndValues( for pe := inrecAndContext.Record.Head; pe != nil; pe = pe.Next { oldKey := types.MlrvalFromString(pe.Key) // xxx temp - newKey := types.MlrvalFromAbsent() - newValue := types.MlrvalFromAbsent() - types.MlrvalCleanWhitespace(&newKey, &oldKey) - types.MlrvalCleanWhitespace(&newValue, pe.Value) + newKey := types.MlrvalCleanWhitespace(&oldKey) + newValue := types.MlrvalCleanWhitespace(pe.Value) // Transferring ownership from old record to new record; no copy needed - newrec.PutReference(newKey.String(), &newValue) + newrec.PutReference(newKey.String(), newValue) } outputChannel <- types.NewRecordAndContext(newrec, &inrecAndContext.Context) @@ -163,8 +161,7 @@ func (this *TransformerCleanWhitespace) cleanWhitespaceInKeys( for pe := inrecAndContext.Record.Head; pe != nil; pe = pe.Next { oldKey := types.MlrvalFromString(pe.Key) // xxx temp - newKey := types.MlrvalFromAbsent() - types.MlrvalCleanWhitespace(&newKey, &oldKey) + newKey := types.MlrvalCleanWhitespace(&oldKey) // Transferring ownership from old record to new record; no copy needed newrec.PutReference(newKey.String(), pe.Value) } @@ -182,7 +179,7 @@ func (this *TransformerCleanWhitespace) cleanWhitespaceInValues( ) { if !inrecAndContext.EndOfStream { for pe := inrecAndContext.Record.Head; pe != nil; pe = pe.Next { - types.MlrvalCleanWhitespace(pe.Value, pe.Value) + pe.Value = types.MlrvalCleanWhitespace(pe.Value) } outputChannel <- inrecAndContext } else { diff --git a/go/src/transformers/percentile-keeper.go b/go/src/transformers/percentile-keeper.go index d767a7192..0aa664fa5 100644 --- a/go/src/transformers/percentile-keeper.go +++ b/go/src/transformers/percentile-keeper.go @@ -241,16 +241,10 @@ func getPercentileLinearlyInterpolated(array []*types.Mlrval, n int, p float64) } else { // array[iindex] + frac * (array[iindex+1] - array[iindex]) // TODO: just do this in float64. - frac := types.MlrvalFromError() - diff := types.MlrvalFromError() - prod := types.MlrvalFromError() - output := types.MlrvalFromError() - - frac.SetFromFloat64(findex - float64(iindex)) - types.MlrvalBinaryMinus(&diff, array[iindex+1], array[iindex]) - types.MlrvalTimes(&prod, &frac, &diff) - types.MlrvalBinaryPlus(&output, array[iindex], &prod) - return output + frac := types.MlrvalPointerFromFloat64(findex - float64(iindex)) + diff := types.MlrvalBinaryMinus(array[iindex+1], array[iindex]) + prod := types.MlrvalTimes(frac, diff) + return *types.MlrvalBinaryPlus(array[iindex], prod) } } diff --git a/go/src/transformers/seqgen.go b/go/src/transformers/seqgen.go index 8cf57b606..4554bad13 100644 --- a/go/src/transformers/seqgen.go +++ b/go/src/transformers/seqgen.go @@ -112,11 +112,11 @@ func transformerSeqgenParseCLI( // ---------------------------------------------------------------- type TransformerSeqgen struct { fieldName string - start types.Mlrval - stop types.Mlrval - step types.Mlrval + start *types.Mlrval + stop *types.Mlrval + step *types.Mlrval doneComparator types.BinaryFunc - mdone types.Mlrval + mdone *types.Mlrval } // ---------------------------------------------------------------- @@ -126,9 +126,9 @@ func NewTransformerSeqgen( stopString string, stepString string, ) (*TransformerSeqgen, error) { - start := types.MlrvalFromInferredType(startString) - stop := types.MlrvalFromInferredType(stopString) - step := types.MlrvalFromInferredType(stepString) + start := types.MlrvalPointerFromInferredType(startString) + stop := types.MlrvalPointerFromInferredType(stopString) + step := types.MlrvalPointerFromInferredType(stepString) var doneComparator types.BinaryFunc = nil fstart, startIsNumeric := start.GetNumericToFloatValue() @@ -181,7 +181,7 @@ func NewTransformerSeqgen( stop: stop, step: step, doneComparator: doneComparator, - mdone: types.MlrvalFromBool(false), + mdone: types.MLRVAL_FALSE, }, nil } @@ -195,21 +195,21 @@ func (this *TransformerSeqgen) Transform( context.UpdateForStartOfFile("seqgen") for { - this.doneComparator(&this.mdone, &counter, &this.stop) + this.mdone = this.doneComparator(counter, this.stop) done, _ := this.mdone.GetBoolValue() if done { break } outrec := types.NewMlrmapAsRecord() - outrec.PutCopy(this.fieldName, &counter) + outrec.PutCopy(this.fieldName, counter) context.UpdateForInputRecord() outrecAndContext := types.NewRecordAndContext(outrec, context) outputChannel <- outrecAndContext - types.MlrvalBinaryPlus(&counter, &counter, &this.step) + counter = types.MlrvalBinaryPlus(counter, this.step) } outputChannel <- types.NewEndOfStreamMarker(context) diff --git a/go/src/transformers/stats1-accumulators.go b/go/src/transformers/stats1-accumulators.go index ec8c69454..a001905fb 100644 --- a/go/src/transformers/stats1-accumulators.go +++ b/go/src/transformers/stats1-accumulators.go @@ -363,16 +363,16 @@ func (this *Stats1AntimodeAccumulator) Emit() types.Mlrval { // ---------------------------------------------------------------- type Stats1SumAccumulator struct { - sum types.Mlrval + sum *types.Mlrval } func NewStats1SumAccumulator() IStats1Accumulator { return &Stats1SumAccumulator{ - sum: types.MlrvalFromInt(0), + sum: types.MlrvalPointerFromInt(0), } } func (this *Stats1SumAccumulator) Ingest(value *types.Mlrval) { - types.MlrvalBinaryPlus(&this.sum, &this.sum, value) + this.sum = types.MlrvalBinaryPlus(this.sum, value) } // xxx pending output-pointer refactor @@ -382,45 +382,43 @@ func (this *Stats1SumAccumulator) Emit() types.Mlrval { // ---------------------------------------------------------------- type Stats1MeanAccumulator struct { - sum types.Mlrval + sum *types.Mlrval count int } func NewStats1MeanAccumulator() IStats1Accumulator { return &Stats1MeanAccumulator{ - sum: types.MlrvalFromInt(0), + sum: types.MlrvalPointerFromInt(0), count: 0, } } func (this *Stats1MeanAccumulator) Ingest(value *types.Mlrval) { - types.MlrvalBinaryPlus(&this.sum, &this.sum, value) + this.sum = types.MlrvalBinaryPlus(this.sum, value) this.count++ } // xxx pending output-pointer refactor func (this *Stats1MeanAccumulator) Emit() types.Mlrval { if this.count == 0 { - return types.MlrvalFromVoid() + return *types.MLRVAL_VOID } else { - mcount := types.MlrvalFromInt(this.count) - output := types.MlrvalFromError() - types.MlrvalDivide(&output, &this.sum, &mcount) - return output + // TODO: pointer-only refactor + return *types.MlrvalDivide(this.sum, types.MlrvalPointerFromInt(this.count)) } } // ---------------------------------------------------------------- type Stats1MinAccumulator struct { - min types.Mlrval + min *types.Mlrval } func NewStats1MinAccumulator() IStats1Accumulator { return &Stats1MinAccumulator{ - min: types.MlrvalFromAbsent(), + min: types.MLRVAL_ABSENT, } } func (this *Stats1MinAccumulator) Ingest(value *types.Mlrval) { - types.MlrvalBinaryMin(&this.min, &this.min, value) + this.min = types.MlrvalBinaryMin(this.min, value) } func (this *Stats1MinAccumulator) Emit() types.Mlrval { return *this.min.Copy() @@ -428,16 +426,16 @@ func (this *Stats1MinAccumulator) Emit() types.Mlrval { // ---------------------------------------------------------------- type Stats1MaxAccumulator struct { - max types.Mlrval + max *types.Mlrval } func NewStats1MaxAccumulator() IStats1Accumulator { return &Stats1MaxAccumulator{ - max: types.MlrvalFromAbsent(), + max: types.MLRVAL_ABSENT, } } func (this *Stats1MaxAccumulator) Ingest(value *types.Mlrval) { - types.MlrvalBinaryMax(&this.max, &this.max, value) + this.max = types.MlrvalBinaryMax(this.max, value) } func (this *Stats1MaxAccumulator) Emit() types.Mlrval { return *this.max.Copy() @@ -445,153 +443,140 @@ func (this *Stats1MaxAccumulator) Emit() types.Mlrval { // ---------------------------------------------------------------- type Stats1VarAccumulator struct { - count int - sum types.Mlrval - sum2 types.Mlrval - value2 types.Mlrval // malloc-avoidance + count int + sum *types.Mlrval + sum2 *types.Mlrval } func NewStats1VarAccumulator() IStats1Accumulator { return &Stats1VarAccumulator{ - count: 0, - sum: types.MlrvalFromInt(0), - sum2: types.MlrvalFromInt(0), - value2: types.MlrvalFromInt(0), + count: 0, + sum: types.MlrvalPointerFromInt(0), + sum2: types.MlrvalPointerFromInt(0), } } func (this *Stats1VarAccumulator) Ingest(value *types.Mlrval) { - types.MlrvalTimes(&this.value2, value, value) + value2 := types.MlrvalTimes(value, value) this.count++ - types.MlrvalBinaryPlus(&this.sum, &this.sum, value) - types.MlrvalBinaryPlus(&this.sum2, &this.sum2, &this.value2) + this.sum = types.MlrvalBinaryPlus(this.sum, value) + this.sum2 = types.MlrvalBinaryPlus(this.sum2, value2) } func (this *Stats1VarAccumulator) Emit() types.Mlrval { mcount := types.MlrvalFromInt(this.count) - return types.MlrvalGetVar(&mcount, &this.sum, &this.sum2) + // TODO: pointer-only refactor + return *types.MlrvalGetVar(&mcount, this.sum, this.sum2) } // ---------------------------------------------------------------- type Stats1StddevAccumulator struct { - count int - sum types.Mlrval - sum2 types.Mlrval - value2 types.Mlrval // malloc-avoidance + count int + sum *types.Mlrval + sum2 *types.Mlrval } func NewStats1StddevAccumulator() IStats1Accumulator { return &Stats1StddevAccumulator{ - count: 0, - sum: types.MlrvalFromInt(0), - sum2: types.MlrvalFromInt(0), - value2: types.MlrvalFromInt(0), + count: 0, + sum: types.MlrvalPointerFromInt(0), + sum2: types.MlrvalPointerFromInt(0), } } func (this *Stats1StddevAccumulator) Ingest(value *types.Mlrval) { - types.MlrvalTimes(&this.value2, value, value) + value2 := types.MlrvalTimes(value, value) this.count++ - types.MlrvalBinaryPlus(&this.sum, &this.sum, value) - types.MlrvalBinaryPlus(&this.sum2, &this.sum2, &this.value2) + this.sum = types.MlrvalBinaryPlus(this.sum, value) + this.sum2 = types.MlrvalBinaryPlus(this.sum2, value2) } func (this *Stats1StddevAccumulator) Emit() types.Mlrval { mcount := types.MlrvalFromInt(this.count) - return types.MlrvalGetStddev(&mcount, &this.sum, &this.sum2) + return *types.MlrvalGetStddev(&mcount, this.sum, this.sum2) } // ---------------------------------------------------------------- type Stats1MeanEBAccumulator struct { - count int - sum types.Mlrval - sum2 types.Mlrval - value2 types.Mlrval // malloc-avoidance + count int + sum *types.Mlrval + sum2 *types.Mlrval } func NewStats1MeanEBAccumulator() IStats1Accumulator { return &Stats1MeanEBAccumulator{ - count: 0, - sum: types.MlrvalFromInt(0), - sum2: types.MlrvalFromInt(0), - value2: types.MlrvalFromInt(0), + count: 0, + sum: types.MlrvalPointerFromInt(0), + sum2: types.MlrvalPointerFromInt(0), } } func (this *Stats1MeanEBAccumulator) Ingest(value *types.Mlrval) { - types.MlrvalTimes(&this.value2, value, value) + value2 := types.MlrvalTimes(value, value) this.count++ - types.MlrvalBinaryPlus(&this.sum, &this.sum, value) - types.MlrvalBinaryPlus(&this.sum2, &this.sum2, &this.value2) + this.sum = types.MlrvalBinaryPlus(this.sum, value) + this.sum2 = types.MlrvalBinaryPlus(this.sum2, value2) } func (this *Stats1MeanEBAccumulator) Emit() types.Mlrval { - mcount := types.MlrvalFromInt(this.count) - return types.MlrvalGetMeanEB(&mcount, &this.sum, &this.sum2) + mcount := types.MlrvalPointerFromInt(this.count) + return *types.MlrvalGetMeanEB(mcount, this.sum, this.sum2) } // ---------------------------------------------------------------- type Stats1SkewnessAccumulator struct { - count int - sum types.Mlrval - sum2 types.Mlrval - sum3 types.Mlrval - value2 types.Mlrval // malloc-avoidance - value3 types.Mlrval // malloc-avoidance + count int + sum *types.Mlrval + sum2 *types.Mlrval + sum3 *types.Mlrval } func NewStats1SkewnessAccumulator() IStats1Accumulator { return &Stats1SkewnessAccumulator{ count: 0, - sum: types.MlrvalFromInt(0), - sum2: types.MlrvalFromInt(0), - sum3: types.MlrvalFromInt(0), + sum: types.MlrvalPointerFromInt(0), + sum2: types.MlrvalPointerFromInt(0), + sum3: types.MlrvalPointerFromInt(0), } } func (this *Stats1SkewnessAccumulator) Ingest(value *types.Mlrval) { - types.MlrvalTimes(&this.value2, value, value) - types.MlrvalTimes(&this.value3, value, &this.value2) + value2 := types.MlrvalTimes(value, value) + value3 := types.MlrvalTimes(value, value2) this.count++ - types.MlrvalBinaryPlus(&this.sum, &this.sum, value) - types.MlrvalBinaryPlus(&this.sum2, &this.sum2, &this.value2) - types.MlrvalBinaryPlus(&this.sum3, &this.sum3, &this.value3) + this.sum = types.MlrvalBinaryPlus(this.sum, value) + this.sum2 = types.MlrvalBinaryPlus(this.sum2, value2) + this.sum3 = types.MlrvalBinaryPlus(this.sum3, value3) } func (this *Stats1SkewnessAccumulator) Emit() types.Mlrval { - mcount := types.MlrvalFromInt(this.count) - return types.MlrvalGetSkewness(&mcount, &this.sum, &this.sum2, &this.sum3) + mcount := types.MlrvalPointerFromInt(this.count) + return types.MlrvalGetSkewness(mcount, this.sum, this.sum2, this.sum3) } // ---------------------------------------------------------------- type Stats1KurtosisAccumulator struct { - count int - sum types.Mlrval - sum2 types.Mlrval - sum3 types.Mlrval - sum4 types.Mlrval - value2 types.Mlrval // malloc-avoidancce - value3 types.Mlrval // malloc-avoidancce - value4 types.Mlrval // malloc-avoidancce + count int + sum *types.Mlrval + sum2 *types.Mlrval + sum3 *types.Mlrval + sum4 *types.Mlrval } func NewStats1KurtosisAccumulator() IStats1Accumulator { return &Stats1KurtosisAccumulator{ - count: 0, - sum: types.MlrvalFromInt(0), - sum2: types.MlrvalFromInt(0), - sum3: types.MlrvalFromInt(0), - sum4: types.MlrvalFromInt(0), - value2: types.MlrvalFromInt(0), - value3: types.MlrvalFromInt(0), - value4: types.MlrvalFromInt(0), + count: 0, + sum: types.MlrvalPointerFromInt(0), + sum2: types.MlrvalPointerFromInt(0), + sum3: types.MlrvalPointerFromInt(0), + sum4: types.MlrvalPointerFromInt(0), } } func (this *Stats1KurtosisAccumulator) Ingest(value *types.Mlrval) { - types.MlrvalTimes(&this.value2, value, value) - types.MlrvalTimes(&this.value3, value, &this.value2) - types.MlrvalTimes(&this.value4, value, &this.value3) + value2 := types.MlrvalTimes(value, value) + value3 := types.MlrvalTimes(value, value2) + value4 := types.MlrvalTimes(value, value3) this.count++ - types.MlrvalBinaryPlus(&this.sum, &this.sum, value) - types.MlrvalBinaryPlus(&this.sum2, &this.sum2, &this.value2) - types.MlrvalBinaryPlus(&this.sum3, &this.sum3, &this.value3) - types.MlrvalBinaryPlus(&this.sum4, &this.sum4, &this.value4) + this.sum = types.MlrvalBinaryPlus(this.sum, value) + this.sum2 = types.MlrvalBinaryPlus(this.sum2, value2) + this.sum3 = types.MlrvalBinaryPlus(this.sum3, value3) + this.sum4 = types.MlrvalBinaryPlus(this.sum4, value4) } func (this *Stats1KurtosisAccumulator) Emit() types.Mlrval { - mcount := types.MlrvalFromInt(this.count) - return types.MlrvalGetKurtosis(&mcount, &this.sum, &this.sum2, &this.sum3, &this.sum4) + mcount := types.MlrvalPointerFromInt(this.count) + return types.MlrvalGetKurtosis(mcount, this.sum, this.sum2, this.sum3, this.sum4) } // ---------------------------------------------------------------- diff --git a/go/src/transformers/step.go b/go/src/transformers/step.go index ba447b4ac..d40cfa96e 100644 --- a/go/src/transformers/step.go +++ b/go/src/transformers/step.go @@ -368,13 +368,11 @@ func (this *tStepperDelta) process( valueFieldValue *types.Mlrval, inrec *types.Mlrmap, ) { - var delta types.Mlrval - if this.previous == nil { - delta.SetFromInt(0) - } else { - types.MlrvalBinaryMinus(&delta, valueFieldValue, this.previous) + delta := types.MlrvalPointerFromInt(0) + if this.previous != nil { + delta = types.MlrvalBinaryMinus(valueFieldValue, this.previous) } - inrec.PutCopy(this.outputFieldName, &delta) + inrec.PutCopy(this.outputFieldName, delta) this.previous = valueFieldValue.Copy() @@ -434,14 +432,13 @@ func (this *tStepperFromFirst) process( valueFieldValue *types.Mlrval, inrec *types.Mlrmap, ) { - var fromFirst types.Mlrval + fromFirst := types.MlrvalPointerFromInt(0) if this.first == nil { - fromFirst.SetFromInt(0) this.first = valueFieldValue.Copy() } else { - types.MlrvalBinaryMinus(&fromFirst, valueFieldValue, this.first) + fromFirst = types.MlrvalBinaryMinus(valueFieldValue, this.first) } - inrec.PutCopy(this.outputFieldName, &fromFirst) + inrec.PutCopy(this.outputFieldName, fromFirst) } // ================================================================ @@ -465,20 +462,18 @@ func (this *tStepperRatio) process( valueFieldValue *types.Mlrval, inrec *types.Mlrmap, ) { - var ratio types.Mlrval - if this.previous == nil { - ratio.SetFromInt(1) - } else { - types.MlrvalDivide(&ratio, valueFieldValue, this.previous) + ratio := types.MlrvalPointerFromInt(1) + if this.previous != nil { + ratio = types.MlrvalDivide(valueFieldValue, this.previous) } - inrec.PutCopy(this.outputFieldName, &ratio) + inrec.PutCopy(this.outputFieldName, ratio) this.previous = valueFieldValue.Copy() } // ================================================================ type tStepperRsum struct { - rsum types.Mlrval + rsum *types.Mlrval outputFieldName string } @@ -488,7 +483,7 @@ func stepperRsumAlloc( _unused2 []string, ) tStepper { return &tStepperRsum{ - rsum: types.MlrvalFromInt(0), + rsum: types.MlrvalPointerFromInt(0), outputFieldName: inputFieldName + "_rsum", } } @@ -497,14 +492,14 @@ func (this *tStepperRsum) process( valueFieldValue *types.Mlrval, inrec *types.Mlrmap, ) { - types.MlrvalBinaryPlus(&this.rsum, valueFieldValue, &this.rsum) - inrec.PutCopy(this.outputFieldName, &this.rsum) + this.rsum = types.MlrvalBinaryPlus(valueFieldValue, this.rsum) + inrec.PutCopy(this.outputFieldName, this.rsum) } // ================================================================ type tStepperCounter struct { - counter types.Mlrval - one types.Mlrval + counter *types.Mlrval + one *types.Mlrval outputFieldName string } @@ -514,8 +509,8 @@ func stepperCounterAlloc( _unused2 []string, ) tStepper { return &tStepperCounter{ - counter: types.MlrvalFromInt(0), - one: types.MlrvalFromInt(1), + counter: types.MlrvalPointerFromInt(0), + one: types.MlrvalPointerFromInt(1), outputFieldName: inputFieldName + "_counter", } } @@ -524,8 +519,8 @@ func (this *tStepperCounter) process( valueFieldValue *types.Mlrval, inrec *types.Mlrmap, ) { - types.MlrvalBinaryPlus(&this.counter, &this.counter, &this.one) - inrec.PutCopy(this.outputFieldName, &this.counter) + this.counter = types.MlrvalBinaryPlus(this.counter, this.one) + inrec.PutCopy(this.outputFieldName, this.counter) } // ---------------------------------------------------------------- @@ -535,7 +530,7 @@ func (this *tStepperCounter) process( type tStepperEWMA struct { alphas []types.Mlrval oneMinusAlphas []types.Mlrval - prevs []types.Mlrval + prevs []*types.Mlrval outputFieldNames []string havePrevs bool } @@ -552,7 +547,7 @@ func stepperEWMAAlloc( alphas := make([]types.Mlrval, n) oneMinusAlphas := make([]types.Mlrval, n) - prevs := make([]types.Mlrval, n) + prevs := make([]*types.Mlrval, n) outputFieldNames := make([]string, n) suffixes := stringAlphas @@ -574,7 +569,7 @@ func stepperEWMAAlloc( } alphas[i] = types.MlrvalFromFloat64(dalpha) oneMinusAlphas[i] = types.MlrvalFromFloat64(1.0 - dalpha) - prevs[i] = types.MlrvalFromFloat64(0.0) + prevs[i] = types.MlrvalPointerFromFloat64(0.0) outputFieldNames[i] = inputFieldName + "_ewma_" + suffix } @@ -594,20 +589,17 @@ func (this *tStepperEWMA) process( if !this.havePrevs { for i, _ := range this.alphas { inrec.PutCopy(this.outputFieldNames[i], valueFieldValue) - this.prevs[i] = *valueFieldValue.Copy() + this.prevs[i] = valueFieldValue.Copy() } this.havePrevs = true } else { for i, _ := range this.alphas { curr := valueFieldValue.Copy() // xxx pending pointer-output refactor - var product1 types.Mlrval - var product2 types.Mlrval - var next types.Mlrval - types.MlrvalTimes(&product1, curr, &this.alphas[i]) - types.MlrvalTimes(&product2, &this.prevs[i], &this.oneMinusAlphas[i]) - types.MlrvalBinaryPlus(&next, &product1, &product2) - inrec.PutCopy(this.outputFieldNames[i], &next) + product1 := types.MlrvalTimes(curr, &this.alphas[i]) + product2 := types.MlrvalTimes(this.prevs[i], &this.oneMinusAlphas[i]) + next := types.MlrvalBinaryPlus(product1, product2) + inrec.PutCopy(this.outputFieldNames[i], next) this.prevs[i] = next } } diff --git a/go/src/types/mlrmap_accessors.go b/go/src/types/mlrmap_accessors.go index db05711e1..ea818cc87 100644 --- a/go/src/types/mlrmap_accessors.go +++ b/go/src/types/mlrmap_accessors.go @@ -294,8 +294,7 @@ func (this *Mlrmap) Contains(that *Mlrmap) bool { } thisval := this.Get(pe.Key) thatval := pe.Value - meq := MlrvalFromError() - MlrvalEquals(&meq, thisval, thatval) + meq := MlrvalEquals(thisval, thatval) eq, ok := meq.GetBoolValue() lib.InternalCodingErrorIf(!ok) if !eq { diff --git a/go/src/types/mlrmap_flatten_unflatten.go b/go/src/types/mlrmap_flatten_unflatten.go index ecd275661..5d73b68a8 100644 --- a/go/src/types/mlrmap_flatten_unflatten.go +++ b/go/src/types/mlrmap_flatten_unflatten.go @@ -102,8 +102,7 @@ func (this *Mlrmap) Unflatten(separator string) { for pe := this.Head; pe != nil; pe = pe.Next { if strings.Contains(pe.Key, separator) { - arrayOfIndices := MlrvalFromError() - mlrvalSplitAXHelper(&arrayOfIndices, pe.Key, separator) + arrayOfIndices := mlrvalSplitAXHelper(pe.Key, separator) that.PutIndexed( MakePointerArray(arrayOfIndices.arrayval), unflattenTerminal(pe.Value).Copy(), @@ -126,8 +125,7 @@ func (this *Mlrmap) UnflattenFields( for pe := this.Head; pe != nil; pe = pe.Next { if strings.Contains(pe.Key, separator) { - arrayOfIndices := MlrvalFromError() - mlrvalSplitAXHelper(&arrayOfIndices, pe.Key, separator) + arrayOfIndices := mlrvalSplitAXHelper(pe.Key, separator) lib.InternalCodingErrorIf(len(arrayOfIndices.arrayval) < 1) baseIndex := arrayOfIndices.arrayval[0].String() if fieldNameSet[baseIndex] { @@ -159,12 +157,10 @@ func unflattenTerminal(input *Mlrval) *Mlrval { return input } if input.printrep == "{}" { - retval := MlrvalFromMapReferenced(NewMlrmap()) - return &retval + return MlrvalPointerFromMapReferenced(NewMlrmap()) } if input.printrep == "[]" { - retval := MlrvalFromArrayLiteralReference(make([]Mlrval, 0)) - return &retval + return MlrvalPointerFromArrayLiteralReference(make([]Mlrval, 0)) } return input } diff --git a/go/src/types/mlrval_constants.go b/go/src/types/mlrval_constants.go new file mode 100644 index 000000000..5fb612076 --- /dev/null +++ b/go/src/types/mlrval_constants.go @@ -0,0 +1,24 @@ +// ================================================================ +// TODO: comment how these are part of the copy-reduction project. + +package types + +var value_MLRVAL_ERROR = MlrvalFromError() +var value_MLRVAL_ABSENT = MlrvalFromAbsent() +var value_MLRVAL_VOID = MlrvalFromVoid() +var value_MLRVAL_INT_0 = MlrvalFromInt(0) +var value_MLRVAL_INT_1 = MlrvalFromInt(1) +var value_MLRVAL_FLOAT_0 = MlrvalFromFloat64(0) +var value_MLRVAL_FLOAT_1 = MlrvalFromFloat64(1) +var value_MLRVAL_TRUE = MlrvalFromTrue() +var value_MLRVAL_FALSE = MlrvalFromFalse() + +var MLRVAL_ERROR = &value_MLRVAL_ERROR +var MLRVAL_ABSENT = &value_MLRVAL_ABSENT +var MLRVAL_VOID = &value_MLRVAL_VOID +var MLRVAL_INT_0 = &value_MLRVAL_INT_0 +var MLRVAL_INT_1 = &value_MLRVAL_INT_1 +var MLRVAL_FLOAT_0 = &value_MLRVAL_FLOAT_0 +var MLRVAL_FLOAT_1 = &value_MLRVAL_FLOAT_1 +var MLRVAL_TRUE = &value_MLRVAL_TRUE +var MLRVAL_FALSE = &value_MLRVAL_FALSE diff --git a/go/src/types/mlrval_function_hashing.go b/go/src/types/mlrval_function_hashing.go index 5722f5d9e..0d846496d 100644 --- a/go/src/types/mlrval_function_hashing.go +++ b/go/src/types/mlrval_function_hashing.go @@ -8,11 +8,11 @@ import ( "fmt" ) -func MlrvalMD5(output, input1 *Mlrval) { +func MlrvalMD5(input1 *Mlrval) *Mlrval { if !input1.IsStringOrVoid() { - output.SetFromError() + return MLRVAL_ERROR } else { - output.SetFromString( + return MlrvalPointerFromString( fmt.Sprintf( "%x", md5.Sum([]byte(input1.printrep)), @@ -21,11 +21,11 @@ func MlrvalMD5(output, input1 *Mlrval) { } } -func MlrvalSHA1(output, input1 *Mlrval) { +func MlrvalSHA1(input1 *Mlrval) *Mlrval { if !input1.IsStringOrVoid() { - output.SetFromError() + return MLRVAL_ERROR } else { - output.SetFromString( + return MlrvalPointerFromString( fmt.Sprintf( "%x", sha1.Sum([]byte(input1.printrep)), @@ -34,11 +34,11 @@ func MlrvalSHA1(output, input1 *Mlrval) { } } -func MlrvalSHA256(output, input1 *Mlrval) { +func MlrvalSHA256(input1 *Mlrval) *Mlrval { if !input1.IsStringOrVoid() { - output.SetFromError() + return MLRVAL_ERROR } else { - output.SetFromString( + return MlrvalPointerFromString( fmt.Sprintf( "%x", sha256.Sum256([]byte(input1.printrep)), @@ -47,11 +47,11 @@ func MlrvalSHA256(output, input1 *Mlrval) { } } -func MlrvalSHA512(output, input1 *Mlrval) { +func MlrvalSHA512(input1 *Mlrval) *Mlrval { if !input1.IsStringOrVoid() { - output.SetFromError() + return MLRVAL_ERROR } else { - output.SetFromString( + return MlrvalPointerFromString( fmt.Sprintf( "%x", sha512.Sum512([]byte(input1.printrep)), diff --git a/go/src/types/mlrval_functions_arithmetic.go b/go/src/types/mlrval_functions_arithmetic.go index aeee2b138..24f4c7e75 100644 --- a/go/src/types/mlrval_functions_arithmetic.go +++ b/go/src/types/mlrval_functions_arithmetic.go @@ -19,19 +19,19 @@ var upos_dispositions = [MT_DIM]UnaryFunc{ /*MAP */ _absn1, } -func MlrvalUnaryPlus(output, input1 *Mlrval) { - upos_dispositions[input1.mvtype](output, input1) +func MlrvalUnaryPlus(input1 *Mlrval) *Mlrval { + return upos_dispositions[input1.mvtype](input1) } // ================================================================ // Unary minus operator -func uneg_i_i(output, input1 *Mlrval) { - output.SetFromInt(-input1.intval) +func uneg_i_i(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromInt(-input1.intval) } -func uneg_f_f(output, input1 *Mlrval) { - output.SetFromFloat64(-input1.floatval) +func uneg_f_f(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(-input1.floatval) } var uneg_dispositions = [MT_DIM]UnaryFunc{ @@ -46,18 +46,18 @@ var uneg_dispositions = [MT_DIM]UnaryFunc{ /*MAP */ _absn1, } -func MlrvalUnaryMinus(output, input1 *Mlrval) { - uneg_dispositions[input1.mvtype](output, input1) +func MlrvalUnaryMinus(input1 *Mlrval) *Mlrval { + return uneg_dispositions[input1.mvtype](input1) } // ================================================================ // Logical NOT operator -func MlrvalLogicalNOT(output, input1 *Mlrval) { +func MlrvalLogicalNOT(input1 *Mlrval) *Mlrval { if input1.mvtype == MT_BOOL { - output.SetFromBool(!input1.boolval) + return MlrvalPointerFromBool(!input1.boolval) } else { - output.SetFromError() + return MLRVAL_ERROR } } @@ -67,7 +67,7 @@ func MlrvalLogicalNOT(output, input1 *Mlrval) { // Auto-overflows up to float. Additions & subtractions overflow by at most // one bit so it suffices to check sign-changes. -func plus_n_ii(output, input1, input2 *Mlrval) { +func plus_n_ii(input1, input2 *Mlrval) *Mlrval { a := input1.intval b := input2.intval c := a + b @@ -84,20 +84,20 @@ func plus_n_ii(output, input1, input2 *Mlrval) { } if overflowed { - output.SetFromFloat64(float64(a) + float64(b)) + return MlrvalPointerFromFloat64(float64(a) + float64(b)) } else { - output.SetFromInt(c) + return MlrvalPointerFromInt(c) } } -func plus_f_if(output, input1, input2 *Mlrval) { - output.SetFromFloat64(float64(input1.intval) + input2.floatval) +func plus_f_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(float64(input1.intval) + input2.floatval) } -func plus_f_fi(output, input1, input2 *Mlrval) { - output.SetFromFloat64(input1.floatval + float64(input2.intval)) +func plus_f_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(input1.floatval + float64(input2.intval)) } -func plus_f_ff(output, input1, input2 *Mlrval) { - output.SetFromFloat64(input1.floatval + input2.floatval) +func plus_f_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(input1.floatval + input2.floatval) } var plus_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -113,8 +113,8 @@ var plus_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalBinaryPlus(output, input1, input2 *Mlrval) { - plus_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalBinaryPlus(input1, input2 *Mlrval) *Mlrval { + return plus_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ================================================================ @@ -123,7 +123,7 @@ func MlrvalBinaryPlus(output, input1, input2 *Mlrval) { // Adds & subtracts overflow by at most one bit so it suffices to check // sign-changes. -func minus_n_ii(output, input1, input2 *Mlrval) { +func minus_n_ii(input1, input2 *Mlrval) *Mlrval { a := input1.intval b := input2.intval c := a - b @@ -140,20 +140,20 @@ func minus_n_ii(output, input1, input2 *Mlrval) { } if overflowed { - output.SetFromFloat64(float64(a) - float64(b)) + return MlrvalPointerFromFloat64(float64(a) - float64(b)) } else { - output.SetFromInt(c) + return MlrvalPointerFromInt(c) } } -func minus_f_if(output, input1, input2 *Mlrval) { - output.SetFromFloat64(float64(input1.intval) - input2.floatval) +func minus_f_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(float64(input1.intval) - input2.floatval) } -func minus_f_fi(output, input1, input2 *Mlrval) { - output.SetFromFloat64(input1.floatval - float64(input2.intval)) +func minus_f_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(input1.floatval - float64(input2.intval)) } -func minus_f_ff(output, input1, input2 *Mlrval) { - output.SetFromFloat64(input1.floatval - input2.floatval) +func minus_f_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(input1.floatval - input2.floatval) } var minus_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -169,8 +169,8 @@ var minus_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalBinaryMinus(output, input1, input2 *Mlrval) { - minus_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalBinaryMinus(input1, input2 *Mlrval) *Mlrval { + return minus_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ================================================================ @@ -206,26 +206,26 @@ func MlrvalBinaryMinus(output, input1, input2 *Mlrval) { // double less than 2**63. (An alterative would be to do all integer multiplies // using handcrafted multi-word 128-bit arithmetic). -func times_n_ii(output, input1, input2 *Mlrval) { +func times_n_ii(input1, input2 *Mlrval) *Mlrval { a := input1.intval b := input2.intval c := float64(a) * float64(b) if math.Abs(c) > 9223372036854774784.0 { - output.SetFromFloat64(c) + return MlrvalPointerFromFloat64(c) } else { - output.SetFromInt(a * b) + return MlrvalPointerFromInt(a * b) } } -func times_f_if(output, input1, input2 *Mlrval) { - output.SetFromFloat64(float64(input1.intval) * input2.floatval) +func times_f_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(float64(input1.intval) * input2.floatval) } -func times_f_fi(output, input1, input2 *Mlrval) { - output.SetFromFloat64(input1.floatval * float64(input2.intval)) +func times_f_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(input1.floatval * float64(input2.intval)) } -func times_f_ff(output, input1, input2 *Mlrval) { - output.SetFromFloat64(input1.floatval * input2.floatval) +func times_f_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(input1.floatval * input2.floatval) } var times_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -241,8 +241,8 @@ var times_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalTimes(output, input1, input2 *Mlrval) { - times_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalTimes(input1, input2 *Mlrval) *Mlrval { + return times_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ================================================================ @@ -262,42 +262,39 @@ func MlrvalTimes(output, input1, input2 *Mlrval) { // $ echo 'x=1e-300,y=1e300' | mlr put '$z=$y/$x' // x=1e-300,y=1e300,z=+Inf -func divide_n_ii(output, input1, input2 *Mlrval) { +func divide_n_ii(input1, input2 *Mlrval) *Mlrval { a := input1.intval b := input2.intval if b == 0 { // Compute inf/nan as with floats rather than fatal runtime FPE on integer divide by zero - output.SetFromFloat64(float64(a) / float64(b)) - return + return MlrvalPointerFromFloat64(float64(a) / float64(b)) } // Pythonic division, not C division. if a%b == 0 { - output.SetFromInt(a / b) - return + return MlrvalPointerFromInt(a / b) } else { - output.SetFromFloat64(float64(a) / float64(b)) - return + return MlrvalPointerFromFloat64(float64(a) / float64(b)) } c := float64(a) * float64(b) if math.Abs(c) > 9223372036854774784.0 { - output.SetFromFloat64(c) + return MlrvalPointerFromFloat64(c) } else { - output.SetFromInt(a * b) + return MlrvalPointerFromInt(a * b) } } -func divide_f_if(output, input1, input2 *Mlrval) { - output.SetFromFloat64(float64(input1.intval) / input2.floatval) +func divide_f_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(float64(input1.intval) / input2.floatval) } -func divide_f_fi(output, input1, input2 *Mlrval) { - output.SetFromFloat64(input1.floatval / float64(input2.intval)) +func divide_f_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(input1.floatval / float64(input2.intval)) } -func divide_f_ff(output, input1, input2 *Mlrval) { - output.SetFromFloat64(input1.floatval / input2.floatval) +func divide_f_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(input1.floatval / input2.floatval) } var divide_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -313,22 +310,21 @@ var divide_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalDivide(output, input1, input2 *Mlrval) { - divide_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalDivide(input1, input2 *Mlrval) *Mlrval { + return divide_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ================================================================ // Integer division: DSL operator '//' as in Python. See also // http://johnkerl.org/miller/doc/reference.html#Arithmetic. -func int_divide_n_ii(output, input1, input2 *Mlrval) { +func int_divide_n_ii(input1, input2 *Mlrval) *Mlrval { a := input1.intval b := input2.intval if b == 0 { // Compute inf/nan as with floats rather than fatal runtime FPE on integer divide by zero - output.SetFromFloat64(float64(a) / float64(b)) - return + return MlrvalPointerFromFloat64(float64(a) / float64(b)) } // Pythonic division, not C division. @@ -347,17 +343,17 @@ func int_divide_n_ii(output, input1, input2 *Mlrval) { } } } - output.SetFromInt(q) + return MlrvalPointerFromInt(q) } -func int_divide_f_if(output, input1, input2 *Mlrval) { - output.SetFromFloat64(math.Floor(float64(input1.intval) / input2.floatval)) +func int_divide_f_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(math.Floor(float64(input1.intval) / input2.floatval)) } -func int_divide_f_fi(output, input1, input2 *Mlrval) { - output.SetFromFloat64(math.Floor(input1.floatval / float64(input2.intval))) +func int_divide_f_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(math.Floor(input1.floatval / float64(input2.intval))) } -func int_divide_f_ff(output, input1, input2 *Mlrval) { - output.SetFromFloat64(math.Floor(input1.floatval / input2.floatval)) +func int_divide_f_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(math.Floor(input1.floatval / input2.floatval)) } var int_divide_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -373,25 +369,25 @@ var int_divide_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalIntDivide(output, input1, input2 *Mlrval) { - int_divide_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalIntDivide(input1, input2 *Mlrval) *Mlrval { + return int_divide_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ================================================================ // Non-auto-overflowing addition: DSL operator '.+'. See also // http://johnkerl.org/miller/doc/reference.html#Arithmetic. -func dotplus_i_ii(output, input1, input2 *Mlrval) { - output.SetFromInt(input1.intval + input2.intval) +func dotplus_i_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromInt(input1.intval + input2.intval) } -func dotplus_f_if(output, input1, input2 *Mlrval) { - output.SetFromFloat64(float64(input1.intval) + input2.floatval) +func dotplus_f_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(float64(input1.intval) + input2.floatval) } -func dotplus_f_fi(output, input1, input2 *Mlrval) { - output.SetFromFloat64(input1.floatval + float64(input2.intval)) +func dotplus_f_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(input1.floatval + float64(input2.intval)) } -func dotplus_f_ff(output, input1, input2 *Mlrval) { - output.SetFromFloat64(input1.floatval + input2.floatval) +func dotplus_f_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(input1.floatval + input2.floatval) } var dot_plus_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -407,25 +403,25 @@ var dot_plus_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalDotPlus(output, input1, input2 *Mlrval) { - dot_plus_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalDotPlus(input1, input2 *Mlrval) *Mlrval { + return dot_plus_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ================================================================ // Non-auto-overflowing subtraction: DSL operator '.-'. See also // http://johnkerl.org/miller/doc/reference.html#Arithmetic. -func dotminus_i_ii(output, input1, input2 *Mlrval) { - output.SetFromInt(input1.intval - input2.intval) +func dotminus_i_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromInt(input1.intval - input2.intval) } -func dotminus_f_if(output, input1, input2 *Mlrval) { - output.SetFromFloat64(float64(input1.intval) - input2.floatval) +func dotminus_f_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(float64(input1.intval) - input2.floatval) } -func dotminus_f_fi(output, input1, input2 *Mlrval) { - output.SetFromFloat64(input1.floatval - float64(input2.intval)) +func dotminus_f_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(input1.floatval - float64(input2.intval)) } -func dotminus_f_ff(output, input1, input2 *Mlrval) { - output.SetFromFloat64(input1.floatval - input2.floatval) +func dotminus_f_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(input1.floatval - input2.floatval) } var dotminus_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -441,25 +437,25 @@ var dotminus_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalDotMinus(output, input1, input2 *Mlrval) { - dotminus_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalDotMinus(input1, input2 *Mlrval) *Mlrval { + return dotminus_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ---------------------------------------------------------------- // Non-auto-overflowing multiplication: DSL operator '.*'. See also // http://johnkerl.org/miller/doc/reference.html#Arithmetic. -func dottimes_i_ii(output, input1, input2 *Mlrval) { - output.SetFromInt(input1.intval * input2.intval) +func dottimes_i_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromInt(input1.intval * input2.intval) } -func dottimes_f_if(output, input1, input2 *Mlrval) { - output.SetFromFloat64(float64(input1.intval) * input2.floatval) +func dottimes_f_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(float64(input1.intval) * input2.floatval) } -func dottimes_f_fi(output, input1, input2 *Mlrval) { - output.SetFromFloat64(input1.floatval * float64(input2.intval)) +func dottimes_f_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(input1.floatval * float64(input2.intval)) } -func dottimes_f_ff(output, input1, input2 *Mlrval) { - output.SetFromFloat64(input1.floatval * input2.floatval) +func dottimes_f_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(input1.floatval * input2.floatval) } var dottimes_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -475,25 +471,25 @@ var dottimes_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalDotTimes(output, input1, input2 *Mlrval) { - dottimes_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalDotTimes(input1, input2 *Mlrval) *Mlrval { + return dottimes_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ---------------------------------------------------------------- // 64-bit integer division: DSL operator './'. See also // http://johnkerl.org/miller/doc/reference.html#Arithmetic. -func dotdivide_i_ii(output, input1, input2 *Mlrval) { - output.SetFromInt(input1.intval / input2.intval) +func dotdivide_i_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromInt(input1.intval / input2.intval) } -func dotdivide_f_if(output, input1, input2 *Mlrval) { - output.SetFromFloat64(float64(input1.intval) / input2.floatval) +func dotdivide_f_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(float64(input1.intval) / input2.floatval) } -func dotdivide_f_fi(output, input1, input2 *Mlrval) { - output.SetFromFloat64(input1.floatval / float64(input2.intval)) +func dotdivide_f_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(input1.floatval / float64(input2.intval)) } -func dotdivide_f_ff(output, input1, input2 *Mlrval) { - output.SetFromFloat64(input1.floatval / input2.floatval) +func dotdivide_f_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(input1.floatval / input2.floatval) } var dotdivide_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -509,22 +505,21 @@ var dotdivide_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalDotDivide(output, input1, input2 *Mlrval) { - dotdivide_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalDotDivide(input1, input2 *Mlrval) *Mlrval { + return dotdivide_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ---------------------------------------------------------------- // 64-bit integer division: DSL operator './/'. See also // http://johnkerl.org/miller/doc/reference.html#Arithmetic. -func dotidivide_i_ii(output, input1, input2 *Mlrval) { +func dotidivide_i_ii(input1, input2 *Mlrval) *Mlrval { a := input1.intval b := input2.intval if b == 0 { // Compute inf/nan as with floats rather than fatal runtime FPE on integer divide by zero - output.SetFromFloat64(float64(a) / float64(b)) - return + return MlrvalPointerFromFloat64(float64(a) / float64(b)) } // Pythonic division, not C division. @@ -543,17 +538,17 @@ func dotidivide_i_ii(output, input1, input2 *Mlrval) { } } } - output.SetFromInt(q) + return MlrvalPointerFromInt(q) } -func dotidivide_f_if(output, input1, input2 *Mlrval) { - output.SetFromFloat64(math.Floor(float64(input1.intval) / input2.floatval)) +func dotidivide_f_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(math.Floor(float64(input1.intval) / input2.floatval)) } -func dotidivide_f_fi(output, input1, input2 *Mlrval) { - output.SetFromFloat64(math.Floor(input1.floatval / float64(input2.intval))) +func dotidivide_f_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(math.Floor(input1.floatval / float64(input2.intval))) } -func dotidivide_f_ff(output, input1, input2 *Mlrval) { - output.SetFromFloat64(math.Floor(input1.floatval / input2.floatval)) +func dotidivide_f_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(math.Floor(input1.floatval / input2.floatval)) } var dotidivide_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -569,21 +564,20 @@ var dotidivide_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalDotIntDivide(output, input1, input2 *Mlrval) { - dotidivide_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalDotIntDivide(input1, input2 *Mlrval) *Mlrval { + return dotidivide_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ---------------------------------------------------------------- // Modulus -func modulus_i_ii(output, input1, input2 *Mlrval) { +func modulus_i_ii(input1, input2 *Mlrval) *Mlrval { a := input1.intval b := input2.intval if b == 0 { // Compute inf/nan as with floats rather than fatal runtime FPE on integer divide by zero - output.SetFromFloat64(float64(a) / float64(b)) - return + return MlrvalPointerFromFloat64(float64(a) / float64(b)) } // Pythonic division, not C division. @@ -598,25 +592,25 @@ func modulus_i_ii(output, input1, input2 *Mlrval) { } } - output.SetFromInt(m) + return MlrvalPointerFromInt(m) } -func modulus_f_fi(output, input1, input2 *Mlrval) { +func modulus_f_fi(input1, input2 *Mlrval) *Mlrval { a := input1.floatval b := float64(input2.intval) - output.SetFromFloat64(a - b*math.Floor(a/b)) + return MlrvalPointerFromFloat64(a - b*math.Floor(a/b)) } -func modulus_f_if(output, input1, input2 *Mlrval) { +func modulus_f_if(input1, input2 *Mlrval) *Mlrval { a := float64(input1.intval) b := input2.floatval - output.SetFromFloat64(a - b*math.Floor(a/b)) + return MlrvalPointerFromFloat64(a - b*math.Floor(a/b)) } -func modulus_f_ff(output, input1, input2 *Mlrval) { +func modulus_f_ff(input1, input2 *Mlrval) *Mlrval { a := input1.floatval b := input2.floatval - output.SetFromFloat64(a - b*math.Floor(a/b)) + return MlrvalPointerFromFloat64(a - b*math.Floor(a/b)) } var modulus_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -632,8 +626,8 @@ var modulus_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalModulus(output, input1, input2 *Mlrval) { - modulus_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalModulus(input1, input2 *Mlrval) *Mlrval { + return modulus_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ================================================================ @@ -681,54 +675,47 @@ func imodexp(a, e, m int) int { return c } -func imodop(output, input1, input2, input3 *Mlrval, iop i_iii_func) { +func imodop(input1, input2, input3 *Mlrval, iop i_iii_func) *Mlrval { if !input1.IsLegit() { - output.CopyFrom(input1) - return + return input1 } if !input2.IsLegit() { - output.CopyFrom(input2) - return + return input2 } if !input3.IsLegit() { - output.CopyFrom(input3) - return + return input3 } if !input1.IsInt() { - output.SetFromError() - return + return MLRVAL_ERROR } if !input2.IsInt() { - output.SetFromError() - return + return MLRVAL_ERROR } if !input3.IsInt() { - output.SetFromError() - return + return MLRVAL_ERROR } - output.SetFromInt(iop(input1.intval, input2.intval, input3.intval)) + return MlrvalPointerFromInt(iop(input1.intval, input2.intval, input3.intval)) } -func MlrvalModAdd(output, input1, input2, input3 *Mlrval) { - imodop(output, input1, input2, input3, imodadd) +func MlrvalModAdd(input1, input2, input3 *Mlrval) *Mlrval { + return imodop(input1, input2, input3, imodadd) } -func MlrvalModSub(output, input1, input2, input3 *Mlrval) { - imodop(output, input1, input2, input3, imodsub) +func MlrvalModSub(input1, input2, input3 *Mlrval) *Mlrval { + return imodop(input1, input2, input3, imodsub) } -func MlrvalModMul(output, input1, input2, input3 *Mlrval) { - imodop(output, input1, input2, input3, imodmul) +func MlrvalModMul(input1, input2, input3 *Mlrval) *Mlrval { + return imodop(input1, input2, input3, imodmul) } -func MlrvalModExp(output, input1, input2, input3 *Mlrval) { +func MlrvalModExp(input1, input2, input3 *Mlrval) *Mlrval { // Pre-check for negative exponent if input2.mvtype == MT_INT && input2.intval < 0 { - output.SetFromError() - return + return MLRVAL_ERROR } - imodop(output, input1, input2, input3, imodexp) + return imodop(input1, input2, input3, imodexp) } // ================================================================ @@ -746,31 +733,31 @@ func MlrvalModExp(output, input1, input2, input3 *Mlrval) { // * empty-null always loses against numbers // ---------------------------------------------------------------- -func min_f_ff(output, input1, input2 *Mlrval) { +func min_f_ff(input1, input2 *Mlrval) *Mlrval { var a float64 = input1.floatval var b float64 = input2.floatval - output.SetFromFloat64(math.Min(a, b)) + return MlrvalPointerFromFloat64(math.Min(a, b)) } -func min_f_fi(output, input1, input2 *Mlrval) { +func min_f_fi(input1, input2 *Mlrval) *Mlrval { var a float64 = input1.floatval var b float64 = float64(input2.intval) - output.SetFromFloat64(math.Min(a, b)) + return MlrvalPointerFromFloat64(math.Min(a, b)) } -func min_f_if(output, input1, input2 *Mlrval) { +func min_f_if(input1, input2 *Mlrval) *Mlrval { var a float64 = float64(input1.intval) var b float64 = input2.floatval - output.SetFromFloat64(math.Min(a, b)) + return MlrvalPointerFromFloat64(math.Min(a, b)) } -func min_i_ii(output, input1, input2 *Mlrval) { +func min_i_ii(input1, input2 *Mlrval) *Mlrval { var a int = input1.intval var b int = input2.intval if a < b { - output.CopyFrom(input1) + return input1 } else { - output.CopyFrom(input2) + return input2 } } @@ -778,21 +765,21 @@ func min_i_ii(output, input1, input2 *Mlrval) { // --- + ----- ----- // a=F | min=a min=a // a=T | min=b min=b -func min_b_bb(output, input1, input2 *Mlrval) { +func min_b_bb(input1, input2 *Mlrval) *Mlrval { if input1.boolval == false { - output.CopyFrom(input1) + return input1 } else { - output.CopyFrom(input2) + return input2 } } -func min_s_ss(output, input1, input2 *Mlrval) { +func min_s_ss(input1, input2 *Mlrval) *Mlrval { var a string = input1.printrep var b string = input2.printrep if a < b { - output.CopyFrom(input1) + return input1 } else { - output.CopyFrom(input2) + return input2 } } @@ -809,48 +796,50 @@ var min_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalBinaryMin(output, input1, input2 *Mlrval) { - (min_dispositions[input1.mvtype][input2.mvtype])(output, input1, input2) +func MlrvalBinaryMin(input1, input2 *Mlrval) *Mlrval { + return (min_dispositions[input1.mvtype][input2.mvtype])(input1, input2) } -func MlrvalVariadicMin(output *Mlrval, mlrvals []*Mlrval) { +func MlrvalVariadicMin(mlrvals []*Mlrval) *Mlrval { if len(mlrvals) == 0 { - output.SetFromVoid() + return MLRVAL_VOID } else { - retval := *mlrvals[0] - for _, mlrval := range mlrvals[1:] { - MlrvalBinaryMin(&retval, &retval, mlrval) + retval := mlrvals[0] + for i, _ := range mlrvals { + if i > 0 { + retval = MlrvalBinaryMin(retval, mlrvals[i]) + } } - output.CopyFrom(&retval) + return retval } } // ---------------------------------------------------------------- -func max_f_ff(output, input1, input2 *Mlrval) { +func max_f_ff(input1, input2 *Mlrval) *Mlrval { var a float64 = input1.floatval var b float64 = input2.floatval - output.SetFromFloat64(math.Max(a, b)) + return MlrvalPointerFromFloat64(math.Max(a, b)) } -func max_f_fi(output, input1, input2 *Mlrval) { +func max_f_fi(input1, input2 *Mlrval) *Mlrval { var a float64 = input1.floatval var b float64 = float64(input2.intval) - output.SetFromFloat64(math.Max(a, b)) + return MlrvalPointerFromFloat64(math.Max(a, b)) } -func max_f_if(output, input1, input2 *Mlrval) { +func max_f_if(input1, input2 *Mlrval) *Mlrval { var a float64 = float64(input1.intval) var b float64 = input2.floatval - output.SetFromFloat64(math.Max(a, b)) + return MlrvalPointerFromFloat64(math.Max(a, b)) } -func max_i_ii(output, input1, input2 *Mlrval) { +func max_i_ii(input1, input2 *Mlrval) *Mlrval { var a int = input1.intval var b int = input2.intval if a > b { - output.CopyFrom(input1) + return input1 } else { - output.CopyFrom(input2) + return input2 } } @@ -858,21 +847,21 @@ func max_i_ii(output, input1, input2 *Mlrval) { // --- + ----- ----- // a=F | max=a max=b // a=T | max=a max=b -func max_b_bb(output, input1, input2 *Mlrval) { +func max_b_bb(input1, input2 *Mlrval) *Mlrval { if input2.boolval == false { - output.CopyFrom(input1) + return input1 } else { - output.CopyFrom(input2) + return input2 } } -func max_s_ss(output, input1, input2 *Mlrval) { +func max_s_ss(input1, input2 *Mlrval) *Mlrval { var a string = input1.printrep var b string = input2.printrep if a > b { - output.CopyFrom(input1) + return input1 } else { - output.CopyFrom(input2) + return input2 } } @@ -889,18 +878,20 @@ var max_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalBinaryMax(output, input1, input2 *Mlrval) { - (max_dispositions[input1.mvtype][input2.mvtype])(output, input1, input2) +func MlrvalBinaryMax(input1, input2 *Mlrval) *Mlrval { + return (max_dispositions[input1.mvtype][input2.mvtype])(input1, input2) } -func MlrvalVariadicMax(output *Mlrval, mlrvals []*Mlrval) { +func MlrvalVariadicMax(mlrvals []*Mlrval) *Mlrval { if len(mlrvals) == 0 { - output.SetFromVoid() + return MLRVAL_VOID } else { - retval := *mlrvals[0] - for _, mlrval := range mlrvals[1:] { - MlrvalBinaryMax(&retval, &retval, mlrval) + retval := mlrvals[0] + for i, _ := range mlrvals { + if i > 0 { + retval = MlrvalBinaryMax(retval, mlrvals[i]) + } } - output.CopyFrom(&retval) + return retval } } diff --git a/go/src/types/mlrval_functions_base.go b/go/src/types/mlrval_functions_base.go index ebd8b7ffb..964958fd6 100644 --- a/go/src/types/mlrval_functions_base.go +++ b/go/src/types/mlrval_functions_base.go @@ -48,28 +48,28 @@ package types // Function-pointer type for zary functions. -type ZaryFunc func(output *Mlrval) +type ZaryFunc func() *Mlrval // Function-pointer type for unary-operator disposition vectors. -type UnaryFunc func(output, input1 *Mlrval) +type UnaryFunc func(input1 *Mlrval) *Mlrval // The asserting_{type} need access to the context to say things like 'Assertion ... failed // at filename {FILENAME} record number {NR}'. -type ContextualUnaryFunc func(output, input1 *Mlrval, context *Context) +type ContextualUnaryFunc func(input1 *Mlrval, context *Context) *Mlrval // Helps keystroke-saving for wrapping Go math-library functions // Examples: cos, sin, etc. type mathLibUnaryFunc func(float64) float64 -type mathLibUnaryFuncWrapper func(output, input1 *Mlrval, f mathLibUnaryFunc) +type mathLibUnaryFuncWrapper func(input1 *Mlrval, f mathLibUnaryFunc) *Mlrval // Function-pointer type for binary-operator disposition matrices. -type BinaryFunc func(output, input1, input2 *Mlrval) +type BinaryFunc func(input1, input2 *Mlrval) *Mlrval // Function-pointer type for ternary functions -type TernaryFunc func(output, input1, input2, input3 *Mlrval) +type TernaryFunc func(input1, input2, input3 *Mlrval) *Mlrval // Function-pointer type for variadic functions. -type VariadicFunc func(output *Mlrval, inputs []*Mlrval) +type VariadicFunc func(inputs []*Mlrval) *Mlrval // Function-pointer type for sorting. Returns < 0 if a < b, 0 if a == b, > 0 if a > b. type ComparatorFunc func(*Mlrval, *Mlrval) int @@ -82,77 +82,77 @@ type ComparatorFunc func(*Mlrval, *Mlrval) int // ---------------------------------------------------------------- // Return error (unary) -func _erro1(output, input1 *Mlrval) { - output.SetFromError() +func _erro1(input1 *Mlrval) *Mlrval { + return MLRVAL_ERROR } // Return absent (unary) -func _absn1(output, input1 *Mlrval) { - output.SetFromAbsent() +func _absn1(input1 *Mlrval) *Mlrval { + return MLRVAL_ABSENT } // Return void (unary) -func _void1(output, input1 *Mlrval) { - output.SetFromVoid() +func _void1(input1 *Mlrval) *Mlrval { + return MLRVAL_VOID } // Return argument (unary) -func _1u___(output, input1 *Mlrval) { - output.CopyFrom(input1) +func _1u___(input1 *Mlrval) *Mlrval { + return input1 } // ---------------------------------------------------------------- // Return error (binary) -func _erro(output, input1, input2 *Mlrval) { - output.SetFromError() +func _erro(input1, input2 *Mlrval) *Mlrval { + return MLRVAL_ERROR } // Return absent (binary) -func _absn(output, input1, input2 *Mlrval) { - output.SetFromAbsent() +func _absn(input1, input2 *Mlrval) *Mlrval { + return MLRVAL_ABSENT } // Return void (binary) -func _void(output, input1, input2 *Mlrval) { - output.SetFromVoid() +func _void(input1, input2 *Mlrval) *Mlrval { + return MLRVAL_VOID } // Return first argument (binary) -func _1___(output, input1, input2 *Mlrval) { - output.CopyFrom(input1) +func _1___(input1, input2 *Mlrval) *Mlrval { + return input1 } // Return second argument (binary) -func _2___(output, input1, input2 *Mlrval) { - output.CopyFrom(input2) +func _2___(input1, input2 *Mlrval) *Mlrval { + return input2 } // Return first argument, as string (binary) -func _s1__(output, input1, input2 *Mlrval) { - output.SetFromString(input1.String()) +func _s1__(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromString(input1.String()) } // Return second argument, as string (binary) -func _s2__(output, input1, input2 *Mlrval) { - output.SetFromString(input2.String()) +func _s2__(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromString(input2.String()) } // Return integer zero (binary) -func _i0__(output, input1, input2 *Mlrval) { - output.SetFromInt(0) +func _i0__(input1, input2 *Mlrval) *Mlrval { + return MLRVAL_INT_0 } // Return float zero (binary) -func _f0__(output, input1, input2 *Mlrval) { - output.SetFromFloat64(0.0) +func _f0__(input1, input2 *Mlrval) *Mlrval { + return MLRVAL_FLOAT_0 } // Return boolean true (binary) -func _true(output, input1, input2 *Mlrval) { - output.SetFromBool(true) +func _true(input1, input2 *Mlrval) *Mlrval { + return MLRVAL_TRUE } // Return boolean false (binary) -func _fals(output, input1, input2 *Mlrval) { - output.SetFromBool(false) +func _fals(input1, input2 *Mlrval) *Mlrval { + return MLRVAL_FALSE } diff --git a/go/src/types/mlrval_functions_bits.go b/go/src/types/mlrval_functions_bits.go index cfe8c5156..b9dd47ceb 100644 --- a/go/src/types/mlrval_functions_bits.go +++ b/go/src/types/mlrval_functions_bits.go @@ -3,8 +3,8 @@ package types // ================================================================ // Bitwise NOT -func bitwise_not_i_i(output, input1 *Mlrval) { - output.SetFromInt(^input1.intval) +func bitwise_not_i_i(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromInt(^input1.intval) } var bitwise_not_dispositions = [MT_DIM]UnaryFunc{ @@ -19,8 +19,8 @@ var bitwise_not_dispositions = [MT_DIM]UnaryFunc{ /*MAP */ _absn1, } -func MlrvalBitwiseNOT(output, input1 *Mlrval) { - bitwise_not_dispositions[input1.mvtype](output, input1) +func MlrvalBitwiseNOT(input1 *Mlrval) *Mlrval { + return bitwise_not_dispositions[input1.mvtype](input1) } // ================================================================ @@ -34,7 +34,7 @@ const _m08 uint64 = 0x00ff00ff00ff00ff const _m16 uint64 = 0x0000ffff0000ffff const _m32 uint64 = 0x00000000ffffffff -func bitcount_i_i(output, input1 *Mlrval) { +func bitcount_i_i(input1 *Mlrval) *Mlrval { a := uint64(input1.intval) a = (a & _m01) + ((a >> 1) & _m01) a = (a & _m02) + ((a >> 2) & _m02) @@ -42,7 +42,7 @@ func bitcount_i_i(output, input1 *Mlrval) { a = (a & _m08) + ((a >> 8) & _m08) a = (a & _m16) + ((a >> 16) & _m16) a = (a & _m32) + ((a >> 32) & _m32) - output.SetFromInt(int(a)) + return MlrvalPointerFromInt(int(a)) } var bitcount_dispositions = [MT_DIM]UnaryFunc{ @@ -57,15 +57,15 @@ var bitcount_dispositions = [MT_DIM]UnaryFunc{ /*MAP */ _absn1, } -func MlrvalBitCount(output, input1 *Mlrval) { - bitcount_dispositions[input1.mvtype](output, input1) +func MlrvalBitCount(input1 *Mlrval) *Mlrval { + return bitcount_dispositions[input1.mvtype](input1) } // ================================================================ // Bitwise AND -func bitwise_and_i_ii(output, input1, input2 *Mlrval) { - output.SetFromInt(input1.intval & input2.intval) +func bitwise_and_i_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromInt(input1.intval & input2.intval) } var bitwise_and_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -81,15 +81,15 @@ var bitwise_and_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalBitwiseAND(output, input1, input2 *Mlrval) { - bitwise_and_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalBitwiseAND(input1, input2 *Mlrval) *Mlrval { + return bitwise_and_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ---------------------------------------------------------------- // Bitwise OR -func bitwise_or_i_ii(output, input1, input2 *Mlrval) { - output.SetFromInt(input1.intval | input2.intval) +func bitwise_or_i_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromInt(input1.intval | input2.intval) } var bitwise_or_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -105,15 +105,15 @@ var bitwise_or_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalBitwiseOR(output, input1, input2 *Mlrval) { - bitwise_or_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalBitwiseOR(input1, input2 *Mlrval) *Mlrval { + return bitwise_or_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ---------------------------------------------------------------- // Bitwise XOR -func bitwise_xor_i_ii(output, input1, input2 *Mlrval) { - output.SetFromInt(input1.intval ^ input2.intval) +func bitwise_xor_i_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromInt(input1.intval ^ input2.intval) } var bitwise_xor_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -129,15 +129,15 @@ var bitwise_xor_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalBitwiseXOR(output, input1, input2 *Mlrval) { - bitwise_xor_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalBitwiseXOR(input1, input2 *Mlrval) *Mlrval { + return bitwise_xor_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ---------------------------------------------------------------- // Left shift -func lsh_i_ii(output, input1, input2 *Mlrval) { - output.SetFromInt(input1.intval << uint64(input2.intval)) +func lsh_i_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromInt(input1.intval << uint64(input2.intval)) } var left_shift_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -153,15 +153,15 @@ var left_shift_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalLeftShift(output, input1, input2 *Mlrval) { - left_shift_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalLeftShift(input1, input2 *Mlrval) *Mlrval { + return left_shift_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ---------------------------------------------------------------- // Signed right shift -func srsh_i_ii(output, input1, input2 *Mlrval) { - output.SetFromInt(input1.intval >> uint64(input2.intval)) +func srsh_i_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromInt(input1.intval >> uint64(input2.intval)) } var signed_right_shift_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -177,18 +177,18 @@ var signed_right_shift_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalSignedRightShift(output, input1, input2 *Mlrval) { - signed_right_shift_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalSignedRightShift(input1, input2 *Mlrval) *Mlrval { + return signed_right_shift_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ---------------------------------------------------------------- // Unsigned right shift -func ursh_i_ii(output, input1, input2 *Mlrval) { +func ursh_i_ii(input1, input2 *Mlrval) *Mlrval { var ua uint64 = uint64(input1.intval) var ub uint64 = uint64(input2.intval) var uc = ua >> ub - output.SetFromInt(int(uc)) + return MlrvalPointerFromInt(int(uc)) } var unsigned_right_shift_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -204,6 +204,6 @@ var unsigned_right_shift_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalUnsignedRightShift(output, input1, input2 *Mlrval) { - unsigned_right_shift_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalUnsignedRightShift(input1, input2 *Mlrval) *Mlrval { + return unsigned_right_shift_dispositions[input1.mvtype][input2.mvtype](input1, input2) } diff --git a/go/src/types/mlrval_functions_booleans.go b/go/src/types/mlrval_functions_booleans.go index 566fd290c..7589fa38c 100644 --- a/go/src/types/mlrval_functions_booleans.go +++ b/go/src/types/mlrval_functions_booleans.go @@ -9,204 +9,201 @@ import ( ) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -func eq_b_ss(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.printrep == input2.printrep) +func eq_b_ss(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.printrep == input2.printrep) } -func ne_b_ss(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.printrep != input2.printrep) +func ne_b_ss(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.printrep != input2.printrep) } -func gt_b_ss(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.printrep > input2.printrep) +func gt_b_ss(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.printrep > input2.printrep) } -func ge_b_ss(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.printrep >= input2.printrep) +func ge_b_ss(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.printrep >= input2.printrep) } -func lt_b_ss(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.printrep < input2.printrep) +func lt_b_ss(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.printrep < input2.printrep) } -func le_b_ss(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.printrep <= input2.printrep) +func le_b_ss(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.printrep <= input2.printrep) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -func eq_b_xs(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.String() == input2.printrep) +func eq_b_xs(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.String() == input2.printrep) } -func ne_b_xs(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.String() != input2.printrep) +func ne_b_xs(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.String() != input2.printrep) } -func gt_b_xs(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.String() > input2.printrep) +func gt_b_xs(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.String() > input2.printrep) } -func ge_b_xs(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.String() >= input2.printrep) +func ge_b_xs(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.String() >= input2.printrep) } -func lt_b_xs(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.String() < input2.printrep) +func lt_b_xs(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.String() < input2.printrep) } -func le_b_xs(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.String() <= input2.printrep) +func le_b_xs(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.String() <= input2.printrep) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -func eq_b_sx(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.printrep == input2.String()) +func eq_b_sx(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.printrep == input2.String()) } -func ne_b_sx(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.printrep != input2.String()) +func ne_b_sx(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.printrep != input2.String()) } -func gt_b_sx(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.printrep > input2.String()) +func gt_b_sx(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.printrep > input2.String()) } -func ge_b_sx(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.printrep >= input2.String()) +func ge_b_sx(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.printrep >= input2.String()) } -func lt_b_sx(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.printrep < input2.String()) +func lt_b_sx(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.printrep < input2.String()) } -func le_b_sx(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.printrep <= input2.String()) +func le_b_sx(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.printrep <= input2.String()) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -func eq_b_ii(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.intval == input2.intval) +func eq_b_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.intval == input2.intval) } -func ne_b_ii(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.intval != input2.intval) +func ne_b_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.intval != input2.intval) } -func gt_b_ii(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.intval > input2.intval) +func gt_b_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.intval > input2.intval) } -func ge_b_ii(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.intval >= input2.intval) +func ge_b_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.intval >= input2.intval) } -func lt_b_ii(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.intval < input2.intval) +func lt_b_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.intval < input2.intval) } -func le_b_ii(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.intval <= input2.intval) +func le_b_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.intval <= input2.intval) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -func eq_b_if(output, input1, input2 *Mlrval) { - output.SetFromBool(float64(input1.intval) == input2.floatval) +func eq_b_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(float64(input1.intval) == input2.floatval) } -func ne_b_if(output, input1, input2 *Mlrval) { - output.SetFromBool(float64(input1.intval) != input2.floatval) +func ne_b_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(float64(input1.intval) != input2.floatval) } -func gt_b_if(output, input1, input2 *Mlrval) { - output.SetFromBool(float64(input1.intval) > input2.floatval) +func gt_b_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(float64(input1.intval) > input2.floatval) } -func ge_b_if(output, input1, input2 *Mlrval) { - output.SetFromBool(float64(input1.intval) >= input2.floatval) +func ge_b_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(float64(input1.intval) >= input2.floatval) } -func lt_b_if(output, input1, input2 *Mlrval) { - output.SetFromBool(float64(input1.intval) < input2.floatval) +func lt_b_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(float64(input1.intval) < input2.floatval) } -func le_b_if(output, input1, input2 *Mlrval) { - output.SetFromBool(float64(input1.intval) <= input2.floatval) +func le_b_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(float64(input1.intval) <= input2.floatval) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -func eq_b_fi(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.floatval == float64(input2.intval)) +func eq_b_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.floatval == float64(input2.intval)) } -func ne_b_fi(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.floatval != float64(input2.intval)) +func ne_b_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.floatval != float64(input2.intval)) } -func gt_b_fi(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.floatval > float64(input2.intval)) +func gt_b_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.floatval > float64(input2.intval)) } -func ge_b_fi(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.floatval >= float64(input2.intval)) +func ge_b_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.floatval >= float64(input2.intval)) } -func lt_b_fi(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.floatval < float64(input2.intval)) +func lt_b_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.floatval < float64(input2.intval)) } -func le_b_fi(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.floatval <= float64(input2.intval)) +func le_b_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.floatval <= float64(input2.intval)) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -func eq_b_ff(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.floatval == input2.floatval) +func eq_b_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.floatval == input2.floatval) } -func ne_b_ff(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.floatval != input2.floatval) +func ne_b_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.floatval != input2.floatval) } -func gt_b_ff(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.floatval > input2.floatval) +func gt_b_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.floatval > input2.floatval) } -func ge_b_ff(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.floatval >= input2.floatval) +func ge_b_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.floatval >= input2.floatval) } -func lt_b_ff(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.floatval < input2.floatval) +func lt_b_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.floatval < input2.floatval) } -func le_b_ff(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.floatval <= input2.floatval) +func le_b_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.floatval <= input2.floatval) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -func eq_b_bb(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.boolval == input2.boolval) +func eq_b_bb(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.boolval == input2.boolval) } -func ne_b_bb(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.boolval != input2.boolval) +func ne_b_bb(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.boolval != input2.boolval) } // We could say ordering on bool is error, but, Miller allows // sorting on bool so it should allow ordering on bool. -func gt_b_bb(output, input1, input2 *Mlrval) { - output.SetFromBool(lib.BoolToInt(input1.boolval) > lib.BoolToInt(input2.boolval)) +func gt_b_bb(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(lib.BoolToInt(input1.boolval) > lib.BoolToInt(input2.boolval)) } -func ge_b_bb(output, input1, input2 *Mlrval) { - output.SetFromBool(lib.BoolToInt(input1.boolval) >= lib.BoolToInt(input2.boolval)) +func ge_b_bb(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(lib.BoolToInt(input1.boolval) >= lib.BoolToInt(input2.boolval)) } -func lt_b_bb(output, input1, input2 *Mlrval) { - output.SetFromBool(lib.BoolToInt(input1.boolval) < lib.BoolToInt(input2.boolval)) +func lt_b_bb(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(lib.BoolToInt(input1.boolval) < lib.BoolToInt(input2.boolval)) } -func le_b_bb(output, input1, input2 *Mlrval) { - output.SetFromBool(lib.BoolToInt(input1.boolval) <= lib.BoolToInt(input2.boolval)) +func le_b_bb(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(lib.BoolToInt(input1.boolval) <= lib.BoolToInt(input2.boolval)) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -func eq_b_aa(output, input1, input2 *Mlrval) { +func eq_b_aa(input1, input2 *Mlrval) *Mlrval { a := input1.arrayval b := input2.arrayval // Different-length arrays are not equal if len(a) != len(b) { - output.SetFromBool(false) // stub - return + return MLRVAL_FALSE } // Same-length arrays: return false if any slot is not equal, else true. for i := range a { - eq := MlrvalFromError() - MlrvalEquals(&eq, &a[i], &b[i]) + eq := MlrvalEquals(&a[i], &b[i]) lib.InternalCodingErrorIf(eq.mvtype != MT_BOOL) if eq.boolval == false { - output.SetFromBool(false) - return + return MLRVAL_FALSE } } - output.SetFromBool(true) + return MLRVAL_TRUE } -func ne_b_aa(output, input1, input2 *Mlrval) { - eq_b_aa(output, input1, input2) - output.SetFromBool(!output.boolval) +func ne_b_aa(input1, input2 *Mlrval) *Mlrval { + output := eq_b_aa(input1, input2) + return MlrvalPointerFromBool(!output.boolval) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -func eq_b_mm(output, input1, input2 *Mlrval) { - output.SetFromBool(input1.mapval.Equals(input2.mapval)) +func eq_b_mm(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mapval.Equals(input2.mapval)) } -func ne_b_mm(output, input1, input2 *Mlrval) { - output.SetFromBool(!input1.mapval.Equals(input2.mapval)) +func ne_b_mm(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(!input1.mapval.Equals(input2.mapval)) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -307,56 +304,56 @@ var le_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_erro, _absn, _fals, _fals, _fals, _fals, _fals, _fals, _erro}, } -func MlrvalEquals(output, input1, input2 *Mlrval) { - eq_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalEquals(input1, input2 *Mlrval) *Mlrval { + return eq_dispositions[input1.mvtype][input2.mvtype](input1, input2) } -func MlrvalNotEquals(output, input1, input2 *Mlrval) { - ne_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalNotEquals(input1, input2 *Mlrval) *Mlrval { + return ne_dispositions[input1.mvtype][input2.mvtype](input1, input2) } -func MlrvalGreaterThan(output, input1, input2 *Mlrval) { - gt_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalGreaterThan(input1, input2 *Mlrval) *Mlrval { + return gt_dispositions[input1.mvtype][input2.mvtype](input1, input2) } -func MlrvalGreaterThanOrEquals(output, input1, input2 *Mlrval) { - ge_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalGreaterThanOrEquals(input1, input2 *Mlrval) *Mlrval { + return ge_dispositions[input1.mvtype][input2.mvtype](input1, input2) } -func MlrvalLessThan(output, input1, input2 *Mlrval) { - lt_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalLessThan(input1, input2 *Mlrval) *Mlrval { + return lt_dispositions[input1.mvtype][input2.mvtype](input1, input2) } -func MlrvalLessThanOrEquals(output, input1, input2 *Mlrval) { - le_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalLessThanOrEquals(input1, input2 *Mlrval) *Mlrval { + return le_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // For Go's sort.Slice func MlrvalLessThanForSort(input1, input2 *Mlrval) bool { - // xxx refactor to avoid copy - mretval := MlrvalFromFalse() - lt_dispositions[input1.mvtype][input2.mvtype](&mretval, input1, input2) + // TODO refactor to avoid copy + // This is a hot path for sort GC and is worth significant hand-optimization + mretval := lt_dispositions[input1.mvtype][input2.mvtype](input1, input2) retval, ok := mretval.GetBoolValue() lib.InternalCodingErrorIf(!ok) return retval } // ---------------------------------------------------------------- -func MlrvalLogicalAND(output, input1, input2 *Mlrval) { +func MlrvalLogicalAND(input1, input2 *Mlrval) *Mlrval { if input1.mvtype == MT_BOOL && input2.mvtype == MT_BOOL { - output.SetFromBool(input1.boolval && input2.boolval) + return MlrvalPointerFromBool(input1.boolval && input2.boolval) } else { - output.SetFromError() + return MLRVAL_ERROR } } -func MlrvalLogicalOR(output, input1, input2 *Mlrval) { +func MlrvalLogicalOR(input1, input2 *Mlrval) *Mlrval { if input1.mvtype == MT_BOOL && input2.mvtype == MT_BOOL { - output.SetFromBool(input1.boolval || input2.boolval) + return MlrvalPointerFromBool(input1.boolval || input2.boolval) } else { - output.SetFromError() + return MLRVAL_ERROR } } -func MlrvalLogicalXOR(output, input1, input2 *Mlrval) { +func MlrvalLogicalXOR(input1, input2 *Mlrval) *Mlrval { if input1.mvtype == MT_BOOL && input2.mvtype == MT_BOOL { - output.SetFromBool(input1.boolval != input2.boolval) + return MlrvalPointerFromBool(input1.boolval != input2.boolval) } else { - output.SetFromError() + return MLRVAL_ERROR } } diff --git a/go/src/types/mlrval_functions_collections.go b/go/src/types/mlrval_functions_collections.go index c85653aad..277833a59 100644 --- a/go/src/types/mlrval_functions_collections.go +++ b/go/src/types/mlrval_functions_collections.go @@ -10,58 +10,54 @@ import ( // ================================================================ // Map/array count. Scalars (including strings) have length 1. -func MlrvalLength(output, input1 *Mlrval) { +func MlrvalLength(input1 *Mlrval) *Mlrval { switch input1.mvtype { case MT_ERROR: - output.SetFromInt(0) + return MlrvalPointerFromInt(0) break case MT_ABSENT: - output.SetFromInt(0) + return MlrvalPointerFromInt(0) break case MT_ARRAY: - output.SetFromInt(int(len(input1.arrayval))) + return MlrvalPointerFromInt(int(len(input1.arrayval))) break case MT_MAP: - output.SetFromInt(int(input1.mapval.FieldCount)) - break - default: - output.SetFromInt(1) + return MlrvalPointerFromInt(int(input1.mapval.FieldCount)) break } + return MlrvalPointerFromInt(1) } // ================================================================ -func depth_from_array(output, input1 *Mlrval) { +func depth_from_array(input1 *Mlrval) *Mlrval { maxChildDepth := 0 for _, child := range input1.arrayval { - childDepth := MlrvalFromAbsent() - MlrvalDepth(&childDepth, &child) + childDepth := MlrvalDepth(&child) lib.InternalCodingErrorIf(childDepth.mvtype != MT_INT) iChildDepth := int(childDepth.intval) if iChildDepth > maxChildDepth { maxChildDepth = iChildDepth } } - output.SetFromInt(int(1 + maxChildDepth)) + return MlrvalPointerFromInt(int(1 + maxChildDepth)) } -func depth_from_map(output, input1 *Mlrval) { +func depth_from_map(input1 *Mlrval) *Mlrval { maxChildDepth := 0 for pe := input1.mapval.Head; pe != nil; pe = pe.Next { child := pe.Value - childDepth := MlrvalFromAbsent() - MlrvalDepth(&childDepth, child) + childDepth := MlrvalDepth(child) lib.InternalCodingErrorIf(childDepth.mvtype != MT_INT) iChildDepth := int(childDepth.intval) if iChildDepth > maxChildDepth { maxChildDepth = iChildDepth } } - output.SetFromInt(int(1 + maxChildDepth)) + return MlrvalPointerFromInt(int(1 + maxChildDepth)) } -func depth_from_scalar(output, input1 *Mlrval) { - output.SetFromInt(0) +func depth_from_scalar(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromInt(0) } // We get a Golang "initialization loop" due to recursive depth computation @@ -82,32 +78,32 @@ func init() { } } -func MlrvalDepth(output, input1 *Mlrval) { - depth_dispositions[input1.mvtype](output, input1) +func MlrvalDepth(input1 *Mlrval) *Mlrval { + return depth_dispositions[input1.mvtype](input1) } // ================================================================ -func leafcount_from_array(output, input1 *Mlrval) { +func leafcount_from_array(input1 *Mlrval) *Mlrval { sumChildLeafCount := 0 for _, child := range input1.arrayval { // Golang initialization loop if we do this :( // childLeafCount := MlrvalLeafCount(&child) - childLeafCount := MlrvalFromInt(1) + childLeafCount := MLRVAL_INT_1 if child.mvtype == MT_ARRAY { - leafcount_from_array(&childLeafCount, &child) + childLeafCount = leafcount_from_array(&child) } else if child.mvtype == MT_MAP { - leafcount_from_map(&childLeafCount, &child) + childLeafCount = leafcount_from_map(&child) } lib.InternalCodingErrorIf(childLeafCount.mvtype != MT_INT) iChildLeafCount := int(childLeafCount.intval) sumChildLeafCount += iChildLeafCount } - output.SetFromInt(int(sumChildLeafCount)) + return MlrvalPointerFromInt(int(sumChildLeafCount)) } -func leafcount_from_map(output, input1 *Mlrval) { +func leafcount_from_map(input1 *Mlrval) *Mlrval { sumChildLeafCount := 0 for pe := input1.mapval.Head; pe != nil; pe = pe.Next { child := pe.Value @@ -115,22 +111,22 @@ func leafcount_from_map(output, input1 *Mlrval) { // Golang initialization loop if we do this :( // childLeafCount := MlrvalLeafCount(child) - childLeafCount := MlrvalFromInt(1) + childLeafCount := MLRVAL_INT_1 if child.mvtype == MT_ARRAY { - leafcount_from_array(&childLeafCount, child) + childLeafCount = leafcount_from_array(child) } else if child.mvtype == MT_MAP { - leafcount_from_map(&childLeafCount, child) + childLeafCount = leafcount_from_map(child) } lib.InternalCodingErrorIf(childLeafCount.mvtype != MT_INT) iChildLeafCount := int(childLeafCount.intval) sumChildLeafCount += iChildLeafCount } - output.SetFromInt(int(sumChildLeafCount)) + return MlrvalPointerFromInt(int(sumChildLeafCount)) } -func leafcount_from_scalar(output, input1 *Mlrval) { - output.SetFromInt(1) +func leafcount_from_scalar(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromInt(1) } var leafcount_dispositions = [MT_DIM]UnaryFunc{ @@ -145,51 +141,47 @@ var leafcount_dispositions = [MT_DIM]UnaryFunc{ /*MAP */ leafcount_from_map, } -func MlrvalLeafCount(output, input1 *Mlrval) { - leafcount_dispositions[input1.mvtype](output, input1) +func MlrvalLeafCount(input1 *Mlrval) *Mlrval { + return leafcount_dispositions[input1.mvtype](input1) } // ---------------------------------------------------------------- -func has_key_in_array(output, input1, input2 *Mlrval) { +func has_key_in_array(input1, input2 *Mlrval) *Mlrval { if input2.mvtype == MT_STRING { - output.SetFromFalse() - return + return MLRVAL_FALSE } if input2.mvtype != MT_INT { - output.SetFromError() - return + return MLRVAL_ERROR } _, ok := UnaliasArrayIndex(&input1.arrayval, input2.intval) - output.SetFromBool(ok) + return MlrvalPointerFromBool(ok) } -func has_key_in_map(output, input1, input2 *Mlrval) { +func has_key_in_map(input1, input2 *Mlrval) *Mlrval { if input2.mvtype == MT_STRING || input2.mvtype == MT_INT { - output.SetFromBool(input1.mapval.Has(input2.String())) + return MlrvalPointerFromBool(input1.mapval.Has(input2.String())) } else { - output.SetFromError() + return MLRVAL_ERROR } } -func MlrvalHasKey(output, input1, input2 *Mlrval) { +func MlrvalHasKey(input1, input2 *Mlrval) *Mlrval { if input1.mvtype == MT_ARRAY { - has_key_in_array(output, input1, input2) + return has_key_in_array(input1, input2) } else if input1.mvtype == MT_MAP { - has_key_in_map(output, input1, input2) + return has_key_in_map(input1, input2) } else { - output.SetFromError() + return MLRVAL_ERROR } } // ================================================================ -func MlrvalMapSelect(output *Mlrval, mlrvals []*Mlrval) { +func MlrvalMapSelect(mlrvals []*Mlrval) *Mlrval { if len(mlrvals) < 1 { - output.SetFromError() - return + return MLRVAL_ERROR } if mlrvals[0].mvtype != MT_MAP { - output.SetFromError() - return + return MLRVAL_ERROR } oldmap := mlrvals[0].mapval newMap := NewMlrmap() @@ -203,13 +195,11 @@ func MlrvalMapSelect(output *Mlrval, mlrvals []*Mlrval) { if element.mvtype == MT_STRING { newKeys[element.printrep] = true } else { - output.SetFromError() - return + return MLRVAL_ERROR } } } else { - output.SetFromError() - return + return MLRVAL_ERROR } } @@ -221,18 +211,16 @@ func MlrvalMapSelect(output *Mlrval, mlrvals []*Mlrval) { } } - output.SetFromMap(newMap) + return MlrvalPointerFromMap(newMap) } // ---------------------------------------------------------------- -func MlrvalMapExcept(output *Mlrval, mlrvals []*Mlrval) { +func MlrvalMapExcept(mlrvals []*Mlrval) *Mlrval { if len(mlrvals) < 1 { - output.SetFromError() - return + return MLRVAL_ERROR } if mlrvals[0].mvtype != MT_MAP { - output.SetFromError() - return + return MLRVAL_ERROR } newMap := mlrvals[0].mapval.Copy() @@ -244,39 +232,33 @@ func MlrvalMapExcept(output *Mlrval, mlrvals []*Mlrval) { if element.mvtype == MT_STRING { newMap.Remove(element.printrep) } else { - output.SetFromError() - return + return MLRVAL_ERROR } } } else { - output.SetFromError() - return + return MLRVAL_ERROR } } - output.SetFromMap(newMap) + return MlrvalPointerFromMap(newMap) } // ---------------------------------------------------------------- -func MlrvalMapSum(output *Mlrval, mlrvals []*Mlrval) { +func MlrvalMapSum(mlrvals []*Mlrval) *Mlrval { if len(mlrvals) == 0 { - output.SetFromEmptyMap() - return + return MlrvalPointerFromEmptyMap() } if len(mlrvals) == 1 { - output.CopyFrom(mlrvals[0]) - return + return mlrvals[0] } if mlrvals[0].mvtype != MT_MAP { - output.SetFromError() - return + return MLRVAL_ERROR } newMap := mlrvals[0].mapval.Copy() for _, otherMapArg := range mlrvals[1:] { if otherMapArg.mvtype != MT_MAP { - output.SetFromError() - return + return MLRVAL_ERROR } for pe := otherMapArg.mapval.Head; pe != nil; pe = pe.Next { @@ -284,29 +266,25 @@ func MlrvalMapSum(output *Mlrval, mlrvals []*Mlrval) { } } - output.SetFromMap(newMap) + return MlrvalPointerFromMap(newMap) } // ---------------------------------------------------------------- -func MlrvalMapDiff(output *Mlrval, mlrvals []*Mlrval) { +func MlrvalMapDiff(mlrvals []*Mlrval) *Mlrval { if len(mlrvals) == 0 { - output.SetFromEmptyMap() - return + return MlrvalPointerFromEmptyMap() } if len(mlrvals) == 1 { - output.CopyFrom(mlrvals[0]) - return + return mlrvals[0] } if mlrvals[0].mvtype != MT_MAP { - output.SetFromError() - return + return MLRVAL_ERROR } newMap := mlrvals[0].mapval.Copy() for _, otherMapArg := range mlrvals[1:] { if otherMapArg.mvtype != MT_MAP { - output.SetFromError() - return + return MLRVAL_ERROR } for pe := otherMapArg.mapval.Head; pe != nil; pe = pe.Next { @@ -314,16 +292,15 @@ func MlrvalMapDiff(output *Mlrval, mlrvals []*Mlrval) { } } - output.SetFromMap(newMap) + return MlrvalPointerFromMap(newMap) } // ================================================================ // joink([1,2,3], ",") -> "1,2,3" // joink({"a":3,"b":4,"c":5}, ",") -> "a,b,c" -func MlrvalJoinK(output, input1, input2 *Mlrval) { +func MlrvalJoinK(input1, input2 *Mlrval) *Mlrval { if input2.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } fieldSeparator := input2.printrep if input1.mvtype == MT_MAP { @@ -336,7 +313,7 @@ func MlrvalJoinK(output, input1, input2 *Mlrval) { } } - output.SetFromString(buffer.String()) + return MlrvalPointerFromString(buffer.String()) } else if input1.mvtype == MT_ARRAY { var buffer bytes.Buffer @@ -348,19 +325,18 @@ func MlrvalJoinK(output, input1, input2 *Mlrval) { buffer.WriteString(strconv.Itoa(i + 1)) } - output.SetFromString(buffer.String()) + return MlrvalPointerFromString(buffer.String()) } else { - output.SetFromError() + return MLRVAL_ERROR } } // ---------------------------------------------------------------- // joinv([3,4,5], ",") -> "3,4,5" // joinv({"a":3,"b":4,"c":5}, ",") -> "3,4,5" -func MlrvalJoinV(output, input1, input2 *Mlrval) { +func MlrvalJoinV(input1, input2 *Mlrval) *Mlrval { if input2.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } fieldSeparator := input2.printrep @@ -374,7 +350,7 @@ func MlrvalJoinV(output, input1, input2 *Mlrval) { } } - output.SetFromString(buffer.String()) + return MlrvalPointerFromString(buffer.String()) } else if input1.mvtype == MT_ARRAY { var buffer bytes.Buffer @@ -385,24 +361,22 @@ func MlrvalJoinV(output, input1, input2 *Mlrval) { buffer.WriteString(element.String()) } - output.SetFromString(buffer.String()) + return MlrvalPointerFromString(buffer.String()) } else { - output.SetFromError() + return MLRVAL_ERROR } } // ---------------------------------------------------------------- // joinkv([3,4,5], "=", ",") -> "1=3,2=4,3=5" // joinkv({"a":3,"b":4,"c":5}, "=", ",") -> "a=3,b=4,c=5" -func MlrvalJoinKV(output, input1, input2, input3 *Mlrval) { +func MlrvalJoinKV(input1, input2, input3 *Mlrval) *Mlrval { if input2.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } pairSeparator := input2.printrep if input3.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } fieldSeparator := input3.printrep @@ -418,7 +392,7 @@ func MlrvalJoinKV(output, input1, input2, input3 *Mlrval) { } } - output.SetFromString(buffer.String()) + return MlrvalPointerFromString(buffer.String()) } else if input1.mvtype == MT_ARRAY { var buffer bytes.Buffer @@ -432,31 +406,28 @@ func MlrvalJoinKV(output, input1, input2, input3 *Mlrval) { buffer.WriteString(element.String()) } - output.SetFromString(buffer.String()) + return MlrvalPointerFromString(buffer.String()) } else { - output.SetFromError() + return MLRVAL_ERROR } } // ================================================================ // splitkv("a=3,b=4,c=5", "=", ",") -> {"a":3,"b":4,"c":5} -func MlrvalSplitKV(output, input1, input2, input3 *Mlrval) { +func MlrvalSplitKV(input1, input2, input3 *Mlrval) *Mlrval { if input1.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } if input2.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } pairSeparator := input2.printrep if input3.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } fieldSeparator := input3.printrep - *output = MlrvalEmptyMap() + output := MlrvalPointerFromEmptyMap() fields := lib.SplitString(input1.printrep, fieldSeparator) for i, field := range fields { @@ -473,27 +444,25 @@ func MlrvalSplitKV(output, input1, input2, input3 *Mlrval) { lib.InternalCodingErrorIf(true) } } + return output } // ---------------------------------------------------------------- // splitkvx("a=3,b=4,c=5", "=", ",") -> {"a":"3","b":"4","c":"5"} -func MlrvalSplitKVX(output, input1, input2, input3 *Mlrval) { +func MlrvalSplitKVX(input1, input2, input3 *Mlrval) *Mlrval { if input1.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } if input2.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } pairSeparator := input2.printrep if input3.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } fieldSeparator := input3.printrep - *output = MlrvalEmptyMap() + output := MlrvalPointerFromEmptyMap() fields := lib.SplitString(input1.printrep, fieldSeparator) for i, field := range fields { @@ -510,21 +479,21 @@ func MlrvalSplitKVX(output, input1, input2, input3 *Mlrval) { lib.InternalCodingErrorIf(true) } } + + return output } // ---------------------------------------------------------------- // splitnv("a,b,c", ",") -> {"1":"a","2":"b","3":"c"} -func MlrvalSplitNV(output, input1, input2 *Mlrval) { +func MlrvalSplitNV(input1, input2 *Mlrval) *Mlrval { if input1.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } if input2.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } - *output = MlrvalEmptyMap() + output := MlrvalPointerFromEmptyMap() fields := lib.SplitString(input1.printrep, input2.printrep) for i, field := range fields { @@ -532,21 +501,21 @@ func MlrvalSplitNV(output, input1, input2 *Mlrval) { value := MlrvalFromInferredType(field) output.mapval.PutReference(key, &value) } + + return output } // ---------------------------------------------------------------- // splitnvx("3,4,5", ",") -> {"1":"3","2":"4","3":"5"} -func MlrvalSplitNVX(output, input1, input2 *Mlrval) { +func MlrvalSplitNVX(input1, input2 *Mlrval) *Mlrval { if input1.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } if input2.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } - *output = MlrvalEmptyMap() + output := MlrvalPointerFromEmptyMap() fields := lib.SplitString(input1.printrep, input2.printrep) for i, field := range fields { @@ -554,114 +523,120 @@ func MlrvalSplitNVX(output, input1, input2 *Mlrval) { value := MlrvalFromString(field) output.mapval.PutReference(key, &value) } + + return output } // ---------------------------------------------------------------- // splita("3,4,5", ",") -> [3,4,5] -func MlrvalSplitA(output, input1, input2 *Mlrval) { +func MlrvalSplitA(input1, input2 *Mlrval) *Mlrval { if input1.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } if input2.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } fieldSeparator := input2.printrep fields := lib.SplitString(input1.printrep, fieldSeparator) - *output = *NewSizedMlrvalArray(int(len(fields))) + output := NewSizedMlrvalArray(int(len(fields))) for i, field := range fields { value := MlrvalFromInferredType(field) output.arrayval[i] = value } + + return output } // ---------------------------------------------------------------- // splitax("3,4,5", ",") -> ["3","4","5"] -func MlrvalSplitAX(output, input1, input2 *Mlrval) { +func MlrvalSplitAX(input1, input2 *Mlrval) *Mlrval { if input1.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } if input2.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } input := input1.printrep fieldSeparator := input2.printrep - mlrvalSplitAXHelper(output, input, fieldSeparator) + return mlrvalSplitAXHelper(input, fieldSeparator) } // Split out for MlrvalSplitAX and MlrvalUnflatten -func mlrvalSplitAXHelper(output *Mlrval, input string, separator string) { +func mlrvalSplitAXHelper(input string, separator string) *Mlrval { fields := lib.SplitString(input, separator) - *output = *NewSizedMlrvalArray(int(len(fields))) + output := NewSizedMlrvalArray(int(len(fields))) for i, field := range fields { value := MlrvalFromString(field) output.arrayval[i] = value } + + return output } // ---------------------------------------------------------------- -func MlrvalGetKeys(output, input1 *Mlrval) { +func MlrvalGetKeys(input1 *Mlrval) *Mlrval { if input1.mvtype == MT_MAP { // TODO: make a ReferenceFrom with commenbs - *output = *NewSizedMlrvalArray(input1.mapval.FieldCount) + output := NewSizedMlrvalArray(input1.mapval.FieldCount) i := 0 for pe := input1.mapval.Head; pe != nil; pe = pe.Next { output.arrayval[i] = MlrvalFromString(pe.Key) i++ } + return output } else if input1.mvtype == MT_ARRAY { - *output = *NewSizedMlrvalArray(int(len(input1.arrayval))) + output := NewSizedMlrvalArray(int(len(input1.arrayval))) for i, _ := range input1.arrayval { output.arrayval[i] = MlrvalFromInt(int(i + 1)) // Miller user-space indices are 1-up } + return output } else { - output.SetFromError() + return MLRVAL_ERROR } } // ---------------------------------------------------------------- -func MlrvalGetValues(output, input1 *Mlrval) { +func MlrvalGetValues(input1 *Mlrval) *Mlrval { if input1.mvtype == MT_MAP { // TODO: make a ReferenceFrom with commenbs - *output = *NewSizedMlrvalArray(input1.mapval.FieldCount) + output := NewSizedMlrvalArray(input1.mapval.FieldCount) i := 0 for pe := input1.mapval.Head; pe != nil; pe = pe.Next { output.arrayval[i] = *pe.Value.Copy() i++ } + return output } else if input1.mvtype == MT_ARRAY { - *output = *NewSizedMlrvalArray(int(len(input1.arrayval))) + output := NewSizedMlrvalArray(int(len(input1.arrayval))) for i, value := range input1.arrayval { output.arrayval[i] = *value.Copy() } + return output } else { - output.SetFromError() + return MLRVAL_ERROR } } // ---------------------------------------------------------------- -func MlrvalAppend(output, input1, input2 *Mlrval) { +func MlrvalAppend(input1, input2 *Mlrval) *Mlrval { if input1.mvtype != MT_ARRAY { - output.SetFromError() - return + return MLRVAL_ERROR } - *output = *input1.Copy() + output := input1.Copy() output.ArrayAppend(input2.Copy()) + return output } // ---------------------------------------------------------------- @@ -670,43 +645,39 @@ func MlrvalAppend(output, input1, input2 *Mlrval) { // Third argument is map or array. // flatten("a", ".", {"b": { "c": 4 }}) is {"a.b.c" : 4}. // flatten("", ".", {"a": { "b": 3 }}) is {"a.b" : 3}. -func MlrvalFlatten(output, input1, input2, input3 *Mlrval) { +func MlrvalFlatten(input1, input2, input3 *Mlrval) *Mlrval { if input3.mvtype == MT_MAP || input3.mvtype == MT_ARRAY { if input1.mvtype != MT_STRING && input1.mvtype != MT_VOID { - output.SetFromError() - return + return MLRVAL_ERROR } prefix := input1.printrep if input2.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } delimiter := input2.printrep - temp := input3.FlattenToMap(prefix, delimiter) - output.CopyFrom(&temp) + retval := input3.FlattenToMap(prefix, delimiter) + return &retval } else { - output.CopyFrom(input3) + return input3 } } // flatten($*, ".") is the same as flatten("", ".", $*) -func MlrvalFlattenBinary(output, input1, input2 *Mlrval) { - MlrvalFlatten(output, MlrvalPointerFromVoid(), input2, input1) +func MlrvalFlattenBinary(input1, input2 *Mlrval) *Mlrval { + return MlrvalFlatten(MLRVAL_VOID, input2, input1) } // ---------------------------------------------------------------- // First argument is a map. // Second argument is a delimiter string. // unflatten({"a.b.c", ".") is {"a": { "b": { "c": 4}}}. -func MlrvalUnflatten(output, input1, input2 *Mlrval) { +func MlrvalUnflatten(input1, input2 *Mlrval) *Mlrval { if input2.mvtype != MT_STRING { - output.SetFromError() - return + return MLRVAL_ERROR } if input1.mvtype != MT_MAP { - output.CopyFrom(input1) - return + return input1 } oldmap := input1.mapval separator := input2.printrep @@ -714,16 +685,15 @@ func MlrvalUnflatten(output, input1, input2 *Mlrval) { for pe := oldmap.Head; pe != nil; pe = pe.Next { // TODO: factor out a shared helper function bewteen here and MlrvalSplitAX. - arrayOfIndices := MlrvalFromError() - mlrvalSplitAXHelper(&arrayOfIndices, pe.Key, separator) + arrayOfIndices := mlrvalSplitAXHelper(pe.Key, separator) newmap.PutIndexed(MakePointerArray(arrayOfIndices.arrayval), pe.Value.Copy()) } - output.SetFromMapReferenced(newmap) + return MlrvalPointerFromMapReferenced(newmap) } // ---------------------------------------------------------------- // Converts maps with "1", "2", ... keys into arrays. Recurses nested data structures. -func MlrvalArrayify(output, input1 *Mlrval) { +func MlrvalArrayify(input1 *Mlrval) *Mlrval { if input1.mvtype == MT_MAP { convertible := true i := 0 @@ -733,7 +703,7 @@ func MlrvalArrayify(output, input1 *Mlrval) { if pe.Key != sval { convertible = false } - MlrvalArrayify(pe.Value, pe.Value) + pe.Value = MlrvalArrayify(pe.Value) } if convertible { @@ -743,54 +713,55 @@ func MlrvalArrayify(output, input1 *Mlrval) { arrayval[i] = *pe.Value.Copy() i++ } - output.SetFromArrayLiteralReference(arrayval) + return MlrvalPointerFromArrayLiteralReference(arrayval) } else { - output.CopyFrom(input1) + return input1 } } else if input1.mvtype == MT_ARRAY { // TODO: comment (or rethink) that this modifies its inputs!! + output := input1.Copy() for i, _ := range input1.arrayval { - MlrvalArrayify(&input1.arrayval[i], &input1.arrayval[i]) + output.arrayval[i] = *MlrvalArrayify(&output.arrayval[i]) } - output.CopyFrom(input1) + return output } else { - output.CopyFrom(input1) + return input1 } } // ---------------------------------------------------------------- -func MlrvalJSONParse(output, input1 *Mlrval) { +func MlrvalJSONParse(input1 *Mlrval) *Mlrval { if input1.mvtype == MT_VOID { - output.CopyFrom(input1) + return input1 } else if input1.mvtype != MT_STRING { - output.SetFromError() + return MLRVAL_ERROR } else { - *output = MlrvalFromPending() + output := MlrvalPointerFromPending() err := output.UnmarshalJSON([]byte(input1.printrep)) if err != nil { - output.SetFromError() + return MLRVAL_ERROR } + return output } } -func MlrvalJSONStringifyUnary(output, input1 *Mlrval) { +func MlrvalJSONStringifyUnary(input1 *Mlrval) *Mlrval { outputBytes, err := input1.MarshalJSON(JSON_SINGLE_LINE) if err != nil { - output.SetFromError() + return MLRVAL_ERROR } else { - output.SetFromString(string(outputBytes)) + return MlrvalPointerFromString(string(outputBytes)) } } -func MlrvalJSONStringifyBinary(output, input1, input2 *Mlrval) { +func MlrvalJSONStringifyBinary(input1, input2 *Mlrval) *Mlrval { var jsonFormatting TJSONFormatting = JSON_SINGLE_LINE useMultiline, ok := input2.GetBoolValue() if !ok { - output.SetFromError() - return + return MLRVAL_ERROR } if useMultiline { jsonFormatting = JSON_MULTILINE @@ -798,8 +769,8 @@ func MlrvalJSONStringifyBinary(output, input1, input2 *Mlrval) { outputBytes, err := input1.MarshalJSON(jsonFormatting) if err != nil { - output.SetFromError() + return MLRVAL_ERROR } else { - output.SetFromString(string(outputBytes)) + return MlrvalPointerFromString(string(outputBytes)) } } diff --git a/go/src/types/mlrval_functions_math.go b/go/src/types/mlrval_functions_math.go index e3d17b68a..0ed9802e7 100644 --- a/go/src/types/mlrval_functions_math.go +++ b/go/src/types/mlrval_functions_math.go @@ -1,16 +1,16 @@ package types // Return error (unary math-library func) -func _math_unary_erro1(output, input1 *Mlrval, f mathLibUnaryFunc) { - output.SetFromError() +func _math_unary_erro1(input1 *Mlrval, f mathLibUnaryFunc) *Mlrval { + return MLRVAL_ERROR } // Return absent (unary math-library func) -func _math_unary_absn1(output, input1 *Mlrval, f mathLibUnaryFunc) { - output.SetFromAbsent() +func _math_unary_absn1(input1 *Mlrval, f mathLibUnaryFunc) *Mlrval { + return MLRVAL_ABSENT } // Return void (unary math-library func) -func _math_unary_void1(output, input1 *Mlrval, f mathLibUnaryFunc) { - output.SetFromAbsent() +func _math_unary_void1(input1 *Mlrval, f mathLibUnaryFunc) *Mlrval { + return MLRVAL_VOID } diff --git a/go/src/types/mlrval_functions_mathlib.go b/go/src/types/mlrval_functions_mathlib.go index 19abb6a14..3d7106b0e 100644 --- a/go/src/types/mlrval_functions_mathlib.go +++ b/go/src/types/mlrval_functions_mathlib.go @@ -90,11 +90,11 @@ func mlrInvqnorm(x float64) float64 { } // ---------------------------------------------------------------- -func math_unary_f_i(output, input1 *Mlrval, f mathLibUnaryFunc) { - output.SetFromFloat64(f(float64(input1.intval))) +func math_unary_f_i(input1 *Mlrval, f mathLibUnaryFunc) *Mlrval { + return MlrvalPointerFromFloat64(f(float64(input1.intval))) } -func math_unary_f_f(output, input1 *Mlrval, f mathLibUnaryFunc) { - output.SetFromFloat64(f(input1.floatval)) +func math_unary_f_f(input1 *Mlrval, f mathLibUnaryFunc) *Mlrval { + return MlrvalPointerFromFloat64(f(input1.floatval)) } // Disposition vector for unary mathlib functions @@ -110,52 +110,50 @@ var mudispo = [MT_DIM]mathLibUnaryFuncWrapper{ /*MAP */ _math_unary_absn1, } -func MlrvalAbs(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Abs) } -func MlrvalAcos(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Acos) } -func MlrvalAcosh(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Acosh) } -func MlrvalAsin(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Asin) } -func MlrvalAsinh(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Asinh) } -func MlrvalAtan(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Atan) } -func MlrvalAtanh(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Atanh) } -func MlrvalCbrt(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Cbrt) } -func MlrvalCeil(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Ceil) } -func MlrvalCos(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Cos) } -func MlrvalCosh(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Cosh) } -func MlrvalErf(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Erf) } -func MlrvalErfc(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Erfc) } -func MlrvalExp(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Exp) } -func MlrvalExpm1(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Expm1) } -func MlrvalFloor(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Floor) } -func MlrvalInvqnorm(output, input1 *Mlrval) { - mudispo[input1.mvtype](output, input1, mlrInvqnorm) -} -func MlrvalLog(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Log) } -func MlrvalLog10(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Log10) } -func MlrvalLog1p(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Log1p) } -func MlrvalQnorm(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, mlrQnorm) } -func MlrvalRound(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Round) } -func MlrvalSgn(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, mlrSgn) } -func MlrvalSin(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Sin) } -func MlrvalSinh(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Sinh) } -func MlrvalSqrt(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Sqrt) } -func MlrvalTan(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Tan) } -func MlrvalTanh(output, input1 *Mlrval) { mudispo[input1.mvtype](output, input1, math.Tanh) } +func MlrvalAbs(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Abs) } +func MlrvalAcos(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Acos) } +func MlrvalAcosh(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Acosh) } +func MlrvalAsin(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Asin) } +func MlrvalAsinh(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Asinh) } +func MlrvalAtan(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Atan) } +func MlrvalAtanh(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Atanh) } +func MlrvalCbrt(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Cbrt) } +func MlrvalCeil(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Ceil) } +func MlrvalCos(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Cos) } +func MlrvalCosh(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Cosh) } +func MlrvalErf(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Erf) } +func MlrvalErfc(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Erfc) } +func MlrvalExp(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Exp) } +func MlrvalExpm1(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Expm1) } +func MlrvalFloor(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Floor) } +func MlrvalInvqnorm(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, mlrInvqnorm) } +func MlrvalLog(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Log) } +func MlrvalLog10(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Log10) } +func MlrvalLog1p(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Log1p) } +func MlrvalQnorm(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, mlrQnorm) } +func MlrvalRound(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Round) } +func MlrvalSgn(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, mlrSgn) } +func MlrvalSin(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Sin) } +func MlrvalSinh(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Sinh) } +func MlrvalSqrt(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Sqrt) } +func MlrvalTan(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Tan) } +func MlrvalTanh(input1 *Mlrval) *Mlrval { return mudispo[input1.mvtype](input1, math.Tanh) } // ================================================================ // Exponentiation: DSL operator '**'. See also // http://johnkerl.org/miller/doc/reference.html#Arithmetic. -func pow_f_ii(output, input1, input2 *Mlrval) { - output.SetFromFloat64(math.Pow(float64(input1.intval), float64(input2.intval))) +func pow_f_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(math.Pow(float64(input1.intval), float64(input2.intval))) } -func pow_f_if(output, input1, input2 *Mlrval) { - output.SetFromFloat64(math.Pow(float64(input1.intval), input2.floatval)) +func pow_f_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(math.Pow(float64(input1.intval), input2.floatval)) } -func pow_f_fi(output, input1, input2 *Mlrval) { - output.SetFromFloat64(math.Pow(input1.floatval, float64(input2.intval))) +func pow_f_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(math.Pow(input1.floatval, float64(input2.intval))) } -func pow_f_ff(output, input1, input2 *Mlrval) { - output.SetFromFloat64(math.Pow(input1.floatval, input2.floatval)) +func pow_f_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(math.Pow(input1.floatval, input2.floatval)) } var pow_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -171,22 +169,22 @@ var pow_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalPow(output, input1, input2 *Mlrval) { - pow_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalPow(input1, input2 *Mlrval) *Mlrval { + return pow_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ================================================================ -func atan2_f_ii(output, input1, input2 *Mlrval) { - output.SetFromFloat64(math.Atan2(float64(input1.intval), float64(input2.intval))) +func atan2_f_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(math.Atan2(float64(input1.intval), float64(input2.intval))) } -func atan2_f_if(output, input1, input2 *Mlrval) { - output.SetFromFloat64(math.Atan2(float64(input1.intval), input2.floatval)) +func atan2_f_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(math.Atan2(float64(input1.intval), input2.floatval)) } -func atan2_f_fi(output, input1, input2 *Mlrval) { - output.SetFromFloat64(math.Atan2(input1.floatval, float64(input2.intval))) +func atan2_f_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(math.Atan2(input1.floatval, float64(input2.intval))) } -func atan2_f_ff(output, input1, input2 *Mlrval) { - output.SetFromFloat64(math.Atan2(input1.floatval, input2.floatval)) +func atan2_f_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(math.Atan2(input1.floatval, input2.floatval)) } var atan2_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -202,8 +200,8 @@ var atan2_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalAtan2(output, input1, input2 *Mlrval) { - atan2_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalAtan2(input1, input2 *Mlrval) *Mlrval { + return atan2_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ================================================================ @@ -211,17 +209,17 @@ func mlr_roundm(x, m float64) float64 { return math.Round(x/m) * m } -func roundm_f_ii(output, input1, input2 *Mlrval) { - output.SetFromFloat64(mlr_roundm(float64(input1.intval), float64(input2.intval))) +func roundm_f_ii(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(mlr_roundm(float64(input1.intval), float64(input2.intval))) } -func roundm_f_if(output, input1, input2 *Mlrval) { - output.SetFromFloat64(mlr_roundm(float64(input1.intval), input2.floatval)) +func roundm_f_if(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(mlr_roundm(float64(input1.intval), input2.floatval)) } -func roundm_f_fi(output, input1, input2 *Mlrval) { - output.SetFromFloat64(mlr_roundm(input1.floatval, float64(input2.intval))) +func roundm_f_fi(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(mlr_roundm(input1.floatval, float64(input2.intval))) } -func roundm_f_ff(output, input1, input2 *Mlrval) { - output.SetFromFloat64(mlr_roundm(input1.floatval, input2.floatval)) +func roundm_f_ff(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(mlr_roundm(input1.floatval, input2.floatval)) } var roundm_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -237,41 +235,35 @@ var roundm_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn}, } -func MlrvalRoundm(output, input1, input2 *Mlrval) { - roundm_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalRoundm(input1, input2 *Mlrval) *Mlrval { + return roundm_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ================================================================ -func MlrvalLogifit(output, input1, input2, input3 *Mlrval) { +func MlrvalLogifit(input1, input2, input3 *Mlrval) *Mlrval { if !input1.IsLegit() { - output.CopyFrom(input1) - return + return input1 } if !input2.IsLegit() { - output.CopyFrom(input2) - return + return input2 } if !input3.IsLegit() { - output.CopyFrom(input3) - return + return input3 } // int/float OK; rest not x, xok := input1.GetNumericToFloatValue() if !xok { - output.SetFromError() - return + return MLRVAL_ERROR } m, mok := input2.GetNumericToFloatValue() if !mok { - output.SetFromError() - return + return MLRVAL_ERROR } b, bok := input3.GetNumericToFloatValue() if !bok { - output.SetFromError() - return + return MLRVAL_ERROR } - output.SetFromFloat64(1.0 / (1.0 + math.Exp(-m*x-b))) + return MlrvalPointerFromFloat64(1.0 / (1.0 + math.Exp(-m*x-b))) } diff --git a/go/src/types/mlrval_functions_random.go b/go/src/types/mlrval_functions_random.go index 4d64cfbc5..00a7d6cb7 100644 --- a/go/src/types/mlrval_functions_random.go +++ b/go/src/types/mlrval_functions_random.go @@ -6,14 +6,14 @@ import ( "miller/src/lib" ) -func MlrvalUrand(output *Mlrval) { - output.SetFromFloat64( +func MlrvalUrand() *Mlrval { + return MlrvalPointerFromFloat64( lib.RandFloat64(), ) } -func MlrvalUrand32(output *Mlrval) { - output.SetFromInt( +func MlrvalUrand32() *Mlrval { + return MlrvalPointerFromInt( int( lib.RandUint32(), ), @@ -21,22 +21,18 @@ func MlrvalUrand32(output *Mlrval) { } // TODO: use a disposition matrix -func MlrvalUrandInt(output, input1, input2 *Mlrval) { +func MlrvalUrandInt(input1, input2 *Mlrval) *Mlrval { if !input1.IsLegit() { - output.CopyFrom(input1) - return + return input1 } if !input2.IsLegit() { - output.CopyFrom(input2) - return + return input2 } if !input1.IsInt() { - output.SetFromError() - return + return MLRVAL_ERROR } if !input2.IsInt() { - output.SetFromError() - return + return MLRVAL_ERROR } a := input1.intval @@ -52,29 +48,25 @@ func MlrvalUrandInt(output, input1, input2 *Mlrval) { hi = a + 1 } u := int(math.Floor(float64(lo) + float64((hi-lo))*lib.RandFloat64())) - output.SetFromInt(u) + return MlrvalPointerFromInt(u) } -func MlrvalUrandRange(output, input1, input2 *Mlrval) { +func MlrvalUrandRange(input1, input2 *Mlrval) *Mlrval { if !input1.IsLegit() { - output.CopyFrom(input1) - return + return input1 } if !input2.IsLegit() { - output.CopyFrom(input2) - return + return input2 } a, aok := input1.GetNumericToFloatValue() b, bok := input2.GetNumericToFloatValue() if !aok { - output.SetFromError() - return + return MLRVAL_ERROR } if !bok { - output.SetFromError() - return + return MLRVAL_ERROR } - output.SetFromFloat64( + return MlrvalPointerFromFloat64( a + (b-a)*lib.RandFloat64(), ) } diff --git a/go/src/types/mlrval_functions_regex.go b/go/src/types/mlrval_functions_regex.go index 0d11fd6a9..48b34dc32 100644 --- a/go/src/types/mlrval_functions_regex.go +++ b/go/src/types/mlrval_functions_regex.go @@ -7,21 +7,21 @@ import ( ) // ================================================================ -func MlrvalSsub(output, input1, input2, input3 *Mlrval) { +func MlrvalSsub(input1, input2, input3 *Mlrval) *Mlrval { if input1.IsErrorOrAbsent() { - output.CopyFrom(input1) + return input1 } else if input2.IsErrorOrAbsent() { - output.CopyFrom(input2) + return input2 } else if input3.IsErrorOrAbsent() { - output.CopyFrom(input3) + return input3 } else if !input1.IsStringOrVoid() { - output.SetFromError() + return MLRVAL_ERROR } else if !input2.IsStringOrVoid() { - output.SetFromError() + return MLRVAL_ERROR } else if !input3.IsStringOrVoid() { - output.SetFromError() + return MLRVAL_ERROR } else { - output.SetFromString( + return MlrvalPointerFromString( strings.Replace(input1.printrep, input2.printrep, input3.printrep, 1), ) } @@ -30,70 +30,58 @@ func MlrvalSsub(output, input1, input2, input3 *Mlrval) { // ================================================================ // TODO: make a variant which allows compiling the regexp once and reusing it // on each record -func MlrvalSub(output, input1, input2, input3 *Mlrval) { +func MlrvalSub(input1, input2, input3 *Mlrval) *Mlrval { if input1.IsErrorOrAbsent() { - output.CopyFrom(input1) - return + return input1 } if input2.IsErrorOrAbsent() { - output.CopyFrom(input2) - return + return input2 } if input3.IsErrorOrAbsent() { - output.CopyFrom(input3) - return + return input3 } if !input1.IsStringOrVoid() { - output.SetFromError() - return + return MLRVAL_ERROR } if !input2.IsStringOrVoid() { - output.SetFromError() - return + return MLRVAL_ERROR } if !input3.IsStringOrVoid() { - output.SetFromError() - return + return MLRVAL_ERROR } // TODO: better exception-handling re := lib.CompileMillerRegexOrDie(input2.printrep) replacement := lib.RegexReplaceOnce(re, input1.printrep, input3.printrep) - output.SetFromString(replacement) + return MlrvalPointerFromString(replacement) } // ================================================================ // TODO: make a variant which allows compiling the regexp once and reusing it // on each record -func MlrvalGsub(output, input1, input2, input3 *Mlrval) { +func MlrvalGsub(input1, input2, input3 *Mlrval) *Mlrval { if input1.IsErrorOrAbsent() { - output.CopyFrom(input1) - return + return input1 } if input2.IsErrorOrAbsent() { - output.CopyFrom(input2) - return + return input2 } if input3.IsErrorOrAbsent() { - output.CopyFrom(input3) - return + return input3 } if !input1.IsStringOrVoid() { - output.SetFromError() - return + return MLRVAL_ERROR } if !input2.IsStringOrVoid() { - output.SetFromError() - return + return MLRVAL_ERROR } if !input3.IsStringOrVoid() { - output.SetFromError() - return + return MLRVAL_ERROR } // TODO: better exception-handling re := lib.CompileMillerRegexOrDie(input2.printrep) - output.SetFromString( + return MlrvalPointerFromString( re.ReplaceAllString(input1.printrep, input3.printrep), ) } @@ -101,73 +89,67 @@ func MlrvalGsub(output, input1, input2, input3 *Mlrval) { // ================================================================ // TODO: make a variant which allows compiling the regexp once and reusing it // on each record -func MlrvalStringMatchesRegexp(output, input1, input2 *Mlrval) { +func MlrvalStringMatchesRegexp(input1, input2 *Mlrval) *Mlrval { if !input1.IsLegit() { - output.CopyFrom(input1) - return + return input1 } if !input2.IsLegit() { - output.CopyFrom(input2) - return + return input2 } if !input1.IsStringOrVoid() { - output.SetFromError() - return + return MLRVAL_ERROR } if !input2.IsStringOrVoid() { - output.SetFromError() - return + return MLRVAL_ERROR } // TODO: better exception-handling re := lib.CompileMillerRegexOrDie(input2.printrep) - output.SetFromBool( + return MlrvalPointerFromBool( re.MatchString(input1.printrep), ) } -func MlrvalStringDoesNotMatchRegexp(output, input1, input2 *Mlrval) { - MlrvalStringMatchesRegexp(output, input1, input2) +func MlrvalStringDoesNotMatchRegexp(input1, input2 *Mlrval) *Mlrval { + output := MlrvalStringMatchesRegexp(input1, input2) if output.mvtype == MT_BOOL { - output.SetFromBool(!output.boolval) + return MlrvalPointerFromBool(!output.boolval) + } else { + // else leave it as error, absent, etc. + return output } - // else leave it as error, absent, etc. } // TODO: find a way to keep and stash a precompiled regex, somewhere in the CST ... -func MlrvalRegextract(output, input1, input2 *Mlrval) { +func MlrvalRegextract(input1, input2 *Mlrval) *Mlrval { if !input1.IsString() { - output.SetFromError() - return + return MLRVAL_ERROR } if !input2.IsString() { - output.SetFromError() - return + return MLRVAL_ERROR } regex := lib.CompileMillerRegexOrDie(input2.printrep) // TODO: See if we need FindStringIndex or FindStringSubmatch to distinguish from matching "". match := regex.FindString(input1.printrep) if match != "" { - output.SetFromString(match) + return MlrvalPointerFromString(match) } else { - output.SetFromAbsent() + return MLRVAL_ABSENT } } -func MlrvalRegextractOrElse(output, input1, input2, input3 *Mlrval) { +func MlrvalRegextractOrElse(input1, input2, input3 *Mlrval) *Mlrval { if !input1.IsString() { - output.SetFromError() - return + return MLRVAL_ERROR } if !input2.IsString() { - output.SetFromError() - return + return MLRVAL_ERROR } regex := lib.CompileMillerRegexOrDie(input2.printrep) // TODO: See if we need FindStringIndex or FindStringSubmatch to distinguish from matching "". found := regex.FindString(input1.printrep) if found != "" { - output.SetFromString(found) + return MlrvalPointerFromString(found) } else { - output.CopyFrom(input3) + return input3 } } diff --git a/go/src/types/mlrval_functions_stats.go b/go/src/types/mlrval_functions_stats.go index b6f3a53f6..a34cd5a63 100644 --- a/go/src/types/mlrval_functions_stats.go +++ b/go/src/types/mlrval_functions_stats.go @@ -23,7 +23,7 @@ import ( // output = [m, b, math.sqrt(var_m), math.sqrt(var_b)] // ---------------------------------------------------------------- -func MlrvalGetVar(mn, msum, msum2 *Mlrval) Mlrval { +func MlrvalGetVar(mn, msum, msum2 *Mlrval) *Mlrval { n, isInt := mn.GetIntValue() lib.InternalCodingErrorIf(!isInt) sum, isNumber := msum.GetNumericToFloatValue() @@ -32,7 +32,7 @@ func MlrvalGetVar(mn, msum, msum2 *Mlrval) Mlrval { lib.InternalCodingErrorIf(!isNumber) if n < 2 { - return MlrvalFromVoid() + return MLRVAL_VOID } mean := float64(sum) / float64(n) @@ -41,32 +41,25 @@ func MlrvalGetVar(mn, msum, msum2 *Mlrval) Mlrval { numerator = 0.0 } denominator := float64(n - 1) - return MlrvalFromFloat64(numerator / denominator) + return MlrvalPointerFromFloat64(numerator / denominator) } // ---------------------------------------------------------------- -func MlrvalGetStddev(mn, msum, msum2 *Mlrval) Mlrval { +func MlrvalGetStddev(mn, msum, msum2 *Mlrval) *Mlrval { mvar := MlrvalGetVar(mn, msum, msum2) if mvar.IsVoid() { return mvar } - // xxx temp - output := MlrvalFromAbsent() - MlrvalSqrt(&output, &mvar) - return output + return MlrvalSqrt(mvar) } // ---------------------------------------------------------------- -// xxx refactor -func MlrvalGetMeanEB(mn, msum, msum2 *Mlrval) Mlrval { +func MlrvalGetMeanEB(mn, msum, msum2 *Mlrval) *Mlrval { mvar := MlrvalGetVar(mn, msum, msum2) if mvar.IsVoid() { return mvar } - output := MlrvalFromError() - MlrvalDivide(&output, &mvar, mn) - MlrvalSqrt(&output, &output) - return output + return MlrvalSqrt(MlrvalDivide(mvar, mn)) } // ---------------------------------------------------------------- diff --git a/go/src/types/mlrval_functions_strings.go b/go/src/types/mlrval_functions_strings.go index c47894828..98ff92ed9 100644 --- a/go/src/types/mlrval_functions_strings.go +++ b/go/src/types/mlrval_functions_strings.go @@ -11,17 +11,17 @@ import ( ) // ================================================================ -func MlrvalStrlen(output, input1 *Mlrval) { +func MlrvalStrlen(input1 *Mlrval) *Mlrval { if !input1.IsStringOrVoid() { - output.SetFromError() + return MLRVAL_ERROR } else { - output.SetFromInt(int(utf8.RuneCountInString(input1.printrep))) + return MlrvalPointerFromInt(int(utf8.RuneCountInString(input1.printrep))) } } // ================================================================ -func MlrvalToString(output, input1 *Mlrval) { - output.SetFromString(input1.String()) +func MlrvalToString(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromString(input1.String()) } // ================================================================ @@ -38,8 +38,8 @@ func MlrvalToString(output, input1 *Mlrval) { // should be: always the string concatenation of the string representations of // the two arguments. So, we do the string-cast for the user. -func dot_s_xx(output, input1, input2 *Mlrval) { - output.SetFromString(input1.String() + input2.String()) +func dot_s_xx(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromString(input1.String() + input2.String()) } var dot_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ @@ -55,23 +55,22 @@ var dot_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_absn, _absn, _absn, dot_s_xx, dot_s_xx, dot_s_xx, dot_s_xx, dot_s_xx, dot_s_xx}, } -func MlrvalDot(output, input1, input2 *Mlrval) { - dot_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalDot(input1, input2 *Mlrval) *Mlrval { + return dot_dispositions[input1.mvtype][input2.mvtype](input1, input2) } // ================================================================ // substr(s,m,n) gives substring of s from 1-up position m to n inclusive. // Negative indices -len .. -1 alias to 0 .. len-1. -func MlrvalSubstr(output, input1, input2, input3 *Mlrval) { +func MlrvalSubstr(input1, input2, input3 *Mlrval) *Mlrval { if !input1.IsStringOrVoid() { if input1.IsNumeric() { // JIT-stringify, if not already (e.g. intval scanned from string // in input-file data) input1.setPrintRep() } else { - output.SetFromError() - return + return MLRVAL_ERROR } } // TODO: fix this with regard to UTF-8 and runes. @@ -81,8 +80,7 @@ func MlrvalSubstr(output, input1, input2, input3 *Mlrval) { // empty in the DSL expression it comes in here as a 1. But when the upper // index is empty in the DSL expression it comes in here as "". if !input2.IsInt() { - output.SetFromError() - return + return MLRVAL_ERROR } lowerMindex := input2.intval @@ -90,8 +88,7 @@ func MlrvalSubstr(output, input1, input2, input3 *Mlrval) { if input3.IsEmpty() { // Keep strlen } else if !input3.IsInt() { - output.SetFromError() - return + return MLRVAL_ERROR } else { upperMindex = input3.intval } @@ -101,84 +98,79 @@ func MlrvalSubstr(output, input1, input2, input3 *Mlrval) { n, nok := UnaliasArrayLengthIndex(strlen, upperMindex) if !mok || !nok { - output.SetFromString("") + return MlrvalPointerFromString("") } else if m > n { - output.SetFromError() + return MLRVAL_ERROR } else { // Note Golang slice indices are 0-up, and the 1st index is inclusive // while the 2nd is exclusive. For Miller, indices are 1-up and both // are inclusive. - output.SetFromString(input1.printrep[m : n+1]) + return MlrvalPointerFromString(input1.printrep[m : n+1]) } } // ================================================================ -func MlrvalTruncate(output, input1, input2 *Mlrval) { +func MlrvalTruncate(input1, input2 *Mlrval) *Mlrval { if input1.IsErrorOrAbsent() { - output.CopyFrom(input1) - return + return input1 } if input2.IsErrorOrAbsent() { - output.CopyFrom(input2) - return + return input2 } if !input1.IsStringOrVoid() { - output.SetFromError() - return + return MLRVAL_ERROR } if !input2.IsInt() { - output.SetFromError() - return + return MLRVAL_ERROR } if input2.intval < 0 { - output.SetFromError() - return + return MLRVAL_ERROR } oldLength := int(len(input1.printrep)) maxLength := input2.intval if oldLength <= maxLength { - output.CopyFrom(input1) + return input1 } else { - output.SetFromString(input1.printrep[0:maxLength]) + return MlrvalPointerFromString(input1.printrep[0:maxLength]) } } // ================================================================ -func MlrvalLStrip(output, input1 *Mlrval) { +func MlrvalLStrip(input1 *Mlrval) *Mlrval { if input1.mvtype == MT_STRING { - output.SetFromString(strings.TrimLeft(input1.printrep, " \t")) + return MlrvalPointerFromString(strings.TrimLeft(input1.printrep, " \t")) } else { - output.CopyFrom(input1) + return input1 } } -func MlrvalRStrip(output, input1 *Mlrval) { +func MlrvalRStrip(input1 *Mlrval) *Mlrval { if input1.mvtype == MT_STRING { - output.SetFromString(strings.TrimRight(input1.printrep, " \t")) + return MlrvalPointerFromString(strings.TrimRight(input1.printrep, " \t")) } else { - output.CopyFrom(input1) + return input1 } } -func MlrvalStrip(output, input1 *Mlrval) { +func MlrvalStrip(input1 *Mlrval) *Mlrval { if input1.mvtype == MT_STRING { - output.SetFromString(strings.Trim(input1.printrep, " \t")) + return MlrvalPointerFromString(strings.Trim(input1.printrep, " \t")) } else { - output.CopyFrom(input1) + return input1 } } // ---------------------------------------------------------------- -func MlrvalCollapseWhitespace(output, input1 *Mlrval) { - MlrvalCollapseWhitespaceRegexp(output, input1, WhitespaceRegexp()) +func MlrvalCollapseWhitespace(input1 *Mlrval) *Mlrval { + return MlrvalCollapseWhitespaceRegexp(input1, WhitespaceRegexp()) } -func MlrvalCollapseWhitespaceRegexp(output, input1 *Mlrval, whitespaceRegexp *regexp.Regexp) { +func MlrvalCollapseWhitespaceRegexp(input1 *Mlrval, whitespaceRegexp *regexp.Regexp) *Mlrval { if input1.mvtype == MT_STRING { - output.SetFromString(whitespaceRegexp.ReplaceAllString(input1.printrep, " ")) + return MlrvalPointerFromString(whitespaceRegexp.ReplaceAllString(input1.printrep, " ")) } else { - output.CopyFrom(input1) + return input1 } } @@ -187,61 +179,64 @@ func WhitespaceRegexp() *regexp.Regexp { } // ================================================================ -func MlrvalToUpper(output, input1 *Mlrval) { +func MlrvalToUpper(input1 *Mlrval) *Mlrval { if input1.mvtype == MT_STRING { - output.SetFromString(strings.ToUpper(input1.printrep)) + return MlrvalPointerFromString(strings.ToUpper(input1.printrep)) } else if input1.mvtype == MT_VOID { - output.CopyFrom(input1) + return input1 } else { - output.CopyFrom(input1) + return input1 } } -func MlrvalToLower(output, input1 *Mlrval) { +func MlrvalToLower(input1 *Mlrval) *Mlrval { if input1.mvtype == MT_STRING { - output.SetFromString(strings.ToLower(input1.printrep)) + return MlrvalPointerFromString(strings.ToLower(input1.printrep)) } else if input1.mvtype == MT_VOID { - output.CopyFrom(input1) + return input1 } else { - output.CopyFrom(input1) + return input1 } } -func MlrvalCapitalize(output, input1 *Mlrval) { +func MlrvalCapitalize(input1 *Mlrval) *Mlrval { if input1.mvtype == MT_STRING { if input1.printrep == "" { - output.CopyFrom(input1) + return input1 } else { runes := []rune(input1.printrep) rfirst := runes[0] rrest := runes[1:] sfirst := strings.ToUpper(string(rfirst)) srest := string(rrest) - output.SetFromString(sfirst + srest) + return MlrvalPointerFromString(sfirst + srest) } } else { - output.CopyFrom(input1) + return input1 } } // ---------------------------------------------------------------- -func MlrvalCleanWhitespace(output, input1 *Mlrval) { - MlrvalCollapseWhitespaceRegexp(output, input1, WhitespaceRegexp()) - MlrvalStrip(output, output) +func MlrvalCleanWhitespace(input1 *Mlrval) *Mlrval { + return MlrvalStrip( + MlrvalCollapseWhitespaceRegexp( + input1, WhitespaceRegexp(), + ), + ) } // ================================================================ -func MlrvalHexfmt(output, input1 *Mlrval) { +func MlrvalHexfmt(input1 *Mlrval) *Mlrval { if input1.mvtype == MT_INT { - output.SetFromString("0x" + strconv.FormatUint(uint64(input1.intval), 16)) + return MlrvalPointerFromString("0x" + strconv.FormatUint(uint64(input1.intval), 16)) } else { - output.CopyFrom(input1) + return input1 } } // ---------------------------------------------------------------- -func fmtnum_is(output, input1, input2 *Mlrval) { - output.SetFromString( +func fmtnum_is(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromString( fmt.Sprintf( input2.printrep, input1.intval, @@ -249,8 +244,8 @@ func fmtnum_is(output, input1, input2 *Mlrval) { ) } -func fmtnum_fs(output, input1, input2 *Mlrval) { - output.SetFromString( +func fmtnum_fs(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromString( fmt.Sprintf( input2.printrep, input1.floatval, @@ -258,8 +253,8 @@ func fmtnum_fs(output, input1, input2 *Mlrval) { ) } -func fmtnum_bs(output, input1, input2 *Mlrval) { - output.SetFromString( +func fmtnum_bs(input1, input2 *Mlrval) *Mlrval { + return MlrvalPointerFromString( fmt.Sprintf( input2.printrep, lib.BoolToInt(input1.boolval), @@ -280,6 +275,6 @@ var fmtnum_dispositions = [MT_DIM][MT_DIM]BinaryFunc{ /*MAP */ {_erro, _absn, _erro, _erro, _erro, _erro, _erro, _erro, _erro}, } -func MlrvalFmtNum(output, input1, input2 *Mlrval) { - fmtnum_dispositions[input1.mvtype][input2.mvtype](output, input1, input2) +func MlrvalFmtNum(input1, input2 *Mlrval) *Mlrval { + return fmtnum_dispositions[input1.mvtype][input2.mvtype](input1, input2) } diff --git a/go/src/types/mlrval_functions_time.go b/go/src/types/mlrval_functions_time.go index ec842b750..2d82f3edc 100644 --- a/go/src/types/mlrval_functions_time.go +++ b/go/src/types/mlrval_functions_time.go @@ -7,13 +7,13 @@ import ( ) // ================================================================ -func MlrvalSystime(output *Mlrval) { - output.SetFromFloat64( +func MlrvalSystime() *Mlrval { + return MlrvalPointerFromFloat64( float64(time.Now().UnixNano()) / 1.0e9, ) } -func MlrvalSystimeInt(output *Mlrval) { - output.SetFromInt(int(time.Now().Unix())) +func MlrvalSystimeInt() *Mlrval { + return MlrvalPointerFromInt(int(time.Now().Unix())) } var startTime float64 @@ -21,32 +21,32 @@ var startTime float64 func init() { startTime = float64(time.Now().UnixNano()) / 1.0e9 } -func MlrvalUptime(output *Mlrval) { - output.SetFromFloat64( +func MlrvalUptime() *Mlrval { + return MlrvalPointerFromFloat64( float64(time.Now().UnixNano())/1.0e9 - startTime, ) } // ================================================================ -func MlrvalSec2GMTUnary(output, input1 *Mlrval) { +func MlrvalSec2GMTUnary(input1 *Mlrval) *Mlrval { if input1.mvtype == MT_FLOAT { - output.SetFromString(lib.Sec2GMT(input1.floatval, 0)) + return MlrvalPointerFromString(lib.Sec2GMT(input1.floatval, 0)) } else if input1.mvtype == MT_INT { - output.SetFromString(lib.Sec2GMT(float64(input1.intval), 0)) + return MlrvalPointerFromString(lib.Sec2GMT(float64(input1.intval), 0)) } else { - output.CopyFrom(input1) + return input1 } } // ---------------------------------------------------------------- -func MlrvalSec2GMTBinary(output, input1, input2 *Mlrval) { +func MlrvalSec2GMTBinary(input1, input2 *Mlrval) *Mlrval { if input2.mvtype != MT_INT { - output.SetFromError() + return MLRVAL_ERROR } else if input1.mvtype == MT_FLOAT { - output.SetFromString(lib.Sec2GMT(input1.floatval, int(input2.intval))) + return MlrvalPointerFromString(lib.Sec2GMT(input1.floatval, int(input2.intval))) } else if input1.mvtype == MT_INT { - output.SetFromString(lib.Sec2GMT(float64(input1.intval), int(input2.intval))) + return MlrvalPointerFromString(lib.Sec2GMT(float64(input1.intval), int(input2.intval))) } else { - output.CopyFrom(input1) + return input1 } } diff --git a/go/src/types/mlrval_functions_types.go b/go/src/types/mlrval_functions_types.go index 68bf45774..5b71ecc83 100644 --- a/go/src/types/mlrval_functions_types.go +++ b/go/src/types/mlrval_functions_types.go @@ -8,29 +8,29 @@ import ( ) // ================================================================ -func MlrvalTypeof(output, input1 *Mlrval) { - output.SetFromString(input1.GetTypeName()) +func MlrvalTypeof(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromString(input1.GetTypeName()) } // ---------------------------------------------------------------- -func string_to_int(output, input1 *Mlrval) { +func string_to_int(input1 *Mlrval) *Mlrval { i, ok := lib.TryIntFromString(input1.printrep) if ok { - output.SetFromInt(i) + return MlrvalPointerFromInt(i) } else { - output.SetFromError() + return MLRVAL_ERROR } } -func float_to_int(output, input1 *Mlrval) { - output.SetFromInt(int(input1.floatval)) +func float_to_int(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromInt(int(input1.floatval)) } -func bool_to_int(output, input1 *Mlrval) { +func bool_to_int(input1 *Mlrval) *Mlrval { if input1.boolval == true { - output.SetFromInt(1) + return MlrvalPointerFromInt(1) } else { - output.SetFromInt(0) + return MlrvalPointerFromInt(0) } } @@ -46,29 +46,29 @@ var to_int_dispositions = [MT_DIM]UnaryFunc{ /*MAP */ _erro1, } -func MlrvalToInt(output, input1 *Mlrval) { - to_int_dispositions[input1.mvtype](output, input1) +func MlrvalToInt(input1 *Mlrval) *Mlrval { + return to_int_dispositions[input1.mvtype](input1) } // ---------------------------------------------------------------- -func string_to_float(output, input1 *Mlrval) { +func string_to_float(input1 *Mlrval) *Mlrval { f, ok := lib.TryFloat64FromString(input1.printrep) if ok { - output.SetFromFloat64(f) + return MlrvalPointerFromFloat64(f) } else { - output.SetFromError() + return MLRVAL_ERROR } } -func int_to_float(output, input1 *Mlrval) { - output.SetFromFloat64(float64(input1.intval)) +func int_to_float(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromFloat64(float64(input1.intval)) } -func bool_to_float(output, input1 *Mlrval) { +func bool_to_float(input1 *Mlrval) *Mlrval { if input1.boolval == true { - output.SetFromFloat64(1.0) + return MlrvalPointerFromFloat64(1.0) } else { - output.SetFromFloat64(0.0) + return MlrvalPointerFromFloat64(0.0) } } @@ -84,26 +84,26 @@ var to_float_dispositions = [MT_DIM]UnaryFunc{ /*MAP */ _erro1, } -func MlrvalToFloat(output, input1 *Mlrval) { - to_float_dispositions[input1.mvtype](output, input1) +func MlrvalToFloat(input1 *Mlrval) *Mlrval { + return to_float_dispositions[input1.mvtype](input1) } // ---------------------------------------------------------------- -func string_to_boolean(output, input1 *Mlrval) { +func string_to_boolean(input1 *Mlrval) *Mlrval { b, ok := lib.TryBoolFromBoolString(input1.printrep) if ok { - output.SetFromBool(b) + return MlrvalPointerFromBool(b) } else { - output.SetFromError() + return MLRVAL_ERROR } } -func int_to_bool(output, input1 *Mlrval) { - output.SetFromBool(input1.intval != 0) +func int_to_bool(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.intval != 0) } -func float_to_bool(output, input1 *Mlrval) { - output.SetFromBool(input1.floatval != 0.0) +func float_to_bool(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.floatval != 0.0) } var to_boolean_dispositions = [MT_DIM]UnaryFunc{ @@ -118,91 +118,91 @@ var to_boolean_dispositions = [MT_DIM]UnaryFunc{ /*MAP */ _erro1, } -func MlrvalToBoolean(output, input1 *Mlrval) { - to_boolean_dispositions[input1.mvtype](output, input1) +func MlrvalToBoolean(input1 *Mlrval) *Mlrval { + return to_boolean_dispositions[input1.mvtype](input1) } // ---------------------------------------------------------------- -func MlrvalIsAbsent(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype == MT_ABSENT) +func MlrvalIsAbsent(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype == MT_ABSENT) } -func MlrvalIsError(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype == MT_ERROR) +func MlrvalIsError(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype == MT_ERROR) } -func MlrvalIsBool(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype == MT_BOOL) +func MlrvalIsBool(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype == MT_BOOL) } -func MlrvalIsBoolean(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype == MT_BOOL) +func MlrvalIsBoolean(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype == MT_BOOL) } -func MlrvalIsEmpty(output, input1 *Mlrval) { +func MlrvalIsEmpty(input1 *Mlrval) *Mlrval { if input1.mvtype == MT_VOID { - output.SetFromTrue() + return MLRVAL_TRUE } else if input1.mvtype == MT_STRING { if input1.printrep == "" { - output.SetFromTrue() + return MLRVAL_TRUE } else { - output.SetFromFalse() + return MLRVAL_FALSE } } else { - output.SetFromFalse() + return MLRVAL_FALSE } } -func MlrvalIsEmptyMap(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype == MT_MAP && input1.mapval.FieldCount == 0) +func MlrvalIsEmptyMap(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype == MT_MAP && input1.mapval.FieldCount == 0) } -func MlrvalIsFloat(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype == MT_FLOAT) +func MlrvalIsFloat(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype == MT_FLOAT) } -func MlrvalIsInt(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype == MT_INT) +func MlrvalIsInt(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype == MT_INT) } -func MlrvalIsMap(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype == MT_MAP) +func MlrvalIsMap(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype == MT_MAP) } -func MlrvalIsArray(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype == MT_ARRAY) +func MlrvalIsArray(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype == MT_ARRAY) } -func MlrvalIsNonEmptyMap(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype == MT_MAP && input1.mapval.FieldCount != 0) +func MlrvalIsNonEmptyMap(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype == MT_MAP && input1.mapval.FieldCount != 0) } -func MlrvalIsNotEmpty(output, input1 *Mlrval) { +func MlrvalIsNotEmpty(input1 *Mlrval) *Mlrval { if input1.mvtype == MT_VOID { - output.SetFromFalse() + return MLRVAL_FALSE } else if input1.mvtype == MT_STRING { if input1.printrep == "" { - output.SetFromFalse() + return MLRVAL_FALSE } else { - output.SetFromTrue() + return MLRVAL_TRUE } } else { - output.SetFromTrue() + return MLRVAL_TRUE } } -func MlrvalIsNotMap(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype != MT_MAP) +func MlrvalIsNotMap(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype != MT_MAP) } -func MlrvalIsNotArray(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype != MT_ARRAY) +func MlrvalIsNotArray(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype != MT_ARRAY) } -func MlrvalIsNotNull(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype != MT_ABSENT && input1.mvtype != MT_VOID) +func MlrvalIsNotNull(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype != MT_ABSENT && input1.mvtype != MT_VOID) } -func MlrvalIsNull(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype == MT_ABSENT || input1.mvtype == MT_VOID) +func MlrvalIsNull(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype == MT_ABSENT || input1.mvtype == MT_VOID) } -func MlrvalIsNumeric(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype == MT_INT || input1.mvtype == MT_FLOAT) +func MlrvalIsNumeric(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype == MT_INT || input1.mvtype == MT_FLOAT) } -func MlrvalIsPresent(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype != MT_ABSENT) +func MlrvalIsPresent(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype != MT_ABSENT) } -func MlrvalIsString(output, input1 *Mlrval) { - output.SetFromBool(input1.mvtype == MT_STRING || input1.mvtype == MT_VOID) +func MlrvalIsString(input1 *Mlrval) *Mlrval { + return MlrvalPointerFromBool(input1.mvtype == MT_STRING || input1.mvtype == MT_VOID) } // ---------------------------------------------------------------- -func assertingCommon(output, input1, check *Mlrval, description string, context *Context) { +func assertingCommon(input1, check *Mlrval, description string, context *Context) *Mlrval { if check.IsFalse() { // TODO: get context as in the C impl //fprintf(stderr, "%s: %s type-assertion failed at NR=%lld FNR=%lld FILENAME=%s\n", @@ -218,101 +218,63 @@ func assertingCommon(output, input1, check *Mlrval, description string, context ) os.Exit(1) } - output.CopyFrom(input1) + return input1 } -func MlrvalAssertingAbsent(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsAbsent(&check, input1) - assertingCommon(output, input1, &check, "is_absent", context) +func MlrvalAssertingAbsent(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsAbsent(input1), "is_absent", context) } -func MlrvalAssertingError(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsError(&check, input1) - assertingCommon(output, input1, &check, "is_error", context) +func MlrvalAssertingError(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsError(input1), "is_error", context) } -func MlrvalAssertingBool(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsBool(&check, input1) - assertingCommon(output, input1, &check, "is_bool", context) +func MlrvalAssertingBool(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsBool(input1), "is_bool", context) } -func MlrvalAssertingBoolean(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsBoolean(&check, input1) - assertingCommon(output, input1, &check, "is_boolean", context) +func MlrvalAssertingBoolean(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsBoolean(input1), "is_boolean", context) } -func MlrvalAssertingEmpty(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsEmpty(&check, input1) - assertingCommon(output, input1, &check, "is_empty", context) +func MlrvalAssertingEmpty(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsEmpty(input1), "is_empty", context) } -func MlrvalAssertingEmptyMap(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsEmptyMap(&check, input1) - assertingCommon(output, input1, &check, "is_empty_map", context) +func MlrvalAssertingEmptyMap(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsEmptyMap(input1), "is_empty_map", context) } -func MlrvalAssertingFloat(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsFloat(&check, input1) - assertingCommon(output, input1, &check, "is_float", context) +func MlrvalAssertingFloat(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsFloat(input1), "is_float", context) } -func MlrvalAssertingInt(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsInt(&check, input1) - assertingCommon(output, input1, &check, "is_int", context) +func MlrvalAssertingInt(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsInt(input1), "is_int", context) } -func MlrvalAssertingMap(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsMap(&check, input1) - assertingCommon(output, input1, &check, "is_map", context) +func MlrvalAssertingMap(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsMap(input1), "is_map", context) } -func MlrvalAssertingArray(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsArray(&check, input1) - assertingCommon(output, input1, &check, "is_array", context) +func MlrvalAssertingArray(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsArray(input1), "is_array", context) } -func MlrvalAssertingNonEmptyMap(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsNonEmptyMap(&check, input1) - assertingCommon(output, input1, &check, "is_non_empty_map", context) +func MlrvalAssertingNonEmptyMap(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsNonEmptyMap(input1), "is_non_empty_map", context) } -func MlrvalAssertingNotEmpty(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsNotEmpty(&check, input1) - assertingCommon(output, input1, &check, "is_not_empty", context) +func MlrvalAssertingNotEmpty(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsNotEmpty(input1), "is_not_empty", context) } -func MlrvalAssertingNotMap(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsNotMap(&check, input1) - assertingCommon(output, input1, &check, "is_not_map", context) +func MlrvalAssertingNotMap(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsNotMap(input1), "is_not_map", context) } -func MlrvalAssertingNotArray(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsNotArray(&check, input1) - assertingCommon(output, input1, &check, "is_not_array", context) +func MlrvalAssertingNotArray(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsNotArray(input1), "is_not_array", context) } -func MlrvalAssertingNotNull(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsNotNull(&check, input1) - assertingCommon(output, input1, &check, "is_not_null", context) +func MlrvalAssertingNotNull(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsNotNull(input1), "is_not_null", context) } -func MlrvalAssertingNull(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsNull(&check, input1) - assertingCommon(output, input1, &check, "is_null", context) +func MlrvalAssertingNull(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsNull(input1), "is_null", context) } -func MlrvalAssertingNumeric(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsNumeric(&check, input1) - assertingCommon(output, input1, &check, "is_numeric", context) +func MlrvalAssertingNumeric(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsNumeric(input1), "is_numeric", context) } -func MlrvalAssertingPresent(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsPresent(&check, input1) - assertingCommon(output, input1, &check, "is_present", context) +func MlrvalAssertingPresent(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsPresent(input1), "is_present", context) } -func MlrvalAssertingString(output, input1 *Mlrval, context *Context) { - check := MlrvalFromAbsent() - MlrvalIsString(&check, input1) - assertingCommon(output, input1, &check, "is_string", context) +func MlrvalAssertingString(input1 *Mlrval, context *Context) *Mlrval { + return assertingCommon(input1, MlrvalIsString(input1), "is_string", context) } diff --git a/go/src/types/mlrval_new.go b/go/src/types/mlrval_new.go index 1e8450abf..fe9dcf76d 100644 --- a/go/src/types/mlrval_new.go +++ b/go/src/types/mlrval_new.go @@ -50,21 +50,6 @@ func MlrvalFromAbsent() Mlrval { } } -func MlrvalPointerFromError() *Mlrval { - retval := MlrvalFromError() - return &retval -} - -func MlrvalPointerFromAbsent() *Mlrval { - retval := MlrvalFromAbsent() - return &retval -} - -func MlrvalPointerFromVoid() *Mlrval { - retval := MlrvalFromVoid() - return &retval -} - func MlrvalFromVoid() Mlrval { return Mlrval{ mvtype: MT_VOID, @@ -95,11 +80,6 @@ func MlrvalFromString(input string) Mlrval { } } -func MlrvalPointerFromString(input string) *Mlrval { - retval := MlrvalFromString(input) - return &retval -} - // xxx comment why two -- one for from parsed user data; other for from math ops func MlrvalFromIntString(input string) Mlrval { ival, ok := lib.TryIntFromString(input) diff --git a/go/src/types/mlrval_set.go b/go/src/types/mlrval_set.go index 61cc1bb56..a23d60f14 100644 --- a/go/src/types/mlrval_set.go +++ b/go/src/types/mlrval_set.go @@ -8,243 +8,167 @@ import ( "miller/src/lib" ) -// ---------------------------------------------------------------- -func (this *Mlrval) CopyFrom(that *Mlrval) { - *this = *that - if this.mvtype == MT_MAP { - this.mapval = that.mapval.Copy() - } else if this.mvtype == MT_ARRAY { - this.arrayval = CopyMlrvalArray(that.arrayval) - } -} - -// TODO: experimental -- no performance improvement was found. -// Idea: profiling shows that data-copies of mlrvals consumes much of the time -// for the u/mand.mlr benchmark. Instead of copying all mlrval attributes, copy -// only those appropriate for the mvtype. - -//type mlrvalCopyFunc func(output, input *Mlrval) -// -//func mlrvalCopyError(output, input *Mlrval) { -// output.printrep = input.printrep -// output.printrepValid = input.printrepValid -//} -//func mlrvalCopyAbsent(output, input *Mlrval) { -// output.printrep = input.printrep -// output.printrepValid = input.printrepValid -//} -//func mlrvalCopyVoid(output, input *Mlrval) { -// output.printrep = input.printrep -// output.printrepValid = input.printrepValid -//} -//func mlrvalCopyString(output, input *Mlrval) { -// output.printrep = input.printrep -// output.printrepValid = input.printrepValid -//} -//func mlrvalCopyInt(output, input *Mlrval) { -// output.intval = input.intval -// output.printrepValid = false -//} -//func mlrvalCopyFloat(output, input *Mlrval) { -// output.floatval = input.floatval -// output.printrepValid = false -//} -//func mlrvalCopyBool(output, input *Mlrval) { -// output.boolval = input.boolval -// output.printrepValid = false -//} -//func mlrvalCopyArray(output, input *Mlrval) { -// output.arrayval = CopyMlrvalArray(input.arrayval) -// output.printrepValid = false -//} -//func mlrvalCopyMap(output, input *Mlrval) { -// output.mapval = input.mapval.Copy() -// output.printrepValid = false -//} -// -//var mlrvalCopyDispositions = [MT_DIM]UnaryFunc{ -// /*ERROR */ mlrvalCopyError, -// /*ABSENT */ mlrvalCopyAbsent, -// /*VOID */ mlrvalCopyVoid, -// /*STRING */ mlrvalCopyString, -// /*INT */ mlrvalCopyInt, -// /*FLOAT */ mlrvalCopyFloat, -// /*BOOL */ mlrvalCopyBool, -// /*ARRAY */ mlrvalCopyArray, -// /*MAP */ mlrvalCopyMap, -//} -// +//// ---------------------------------------------------------------- //func (this *Mlrval) CopyFrom(that *Mlrval) { -// this.mvtype = that.mvtype -// mlrvalCopyDispositions[that.mvtype](this, that) +// *this = *that +// if this.mvtype == MT_MAP { +// this.mapval = that.mapval.Copy() +// } else if this.mvtype == MT_ARRAY { +// this.arrayval = CopyMlrvalArray(that.arrayval) +// } //} -// ---------------------------------------------------------------- -func (this *Mlrval) SetFromPending() { - this.mvtype = MT_PENDING - this.printrep = "(bug-if-you-see-this-pending-type)" - this.printrepValid = false -} - -func (this *Mlrval) SetFromError() { - this.mvtype = MT_ERROR - this.printrep = "(error)" // xxx const somewhere - this.printrepValid = true -} - -func (this *Mlrval) SetFromAbsent() { - this.mvtype = MT_ABSENT - this.printrep = "(absent)" - this.printrepValid = true -} - -func (this *Mlrval) SetFromVoid() { - this.mvtype = MT_VOID - this.printrep = "" - this.printrepValid = true -} - -func (this *Mlrval) SetFromString(input string) { +func MlrvalPointerFromString(input string) *Mlrval { if input == "" { - this.SetFromVoid() - } else { - this.mvtype = MT_STRING - this.printrep = input - this.printrepValid = true + return MLRVAL_VOID } + var this Mlrval + this.mvtype = MT_STRING + this.printrep = input + this.printrepValid = true + return &this } // xxx comment why two -- one for from parsed user data; other for from math ops -func (this *Mlrval) SetFromIntString(input string) { +func MlrvalPointerFromIntString(input string) *Mlrval { ival, ok := lib.TryIntFromString(input) // xxx comment assummption is input-string already deemed parseable so no error return lib.InternalCodingErrorIf(!ok) + var this Mlrval this.mvtype = MT_INT this.printrep = input this.printrepValid = true this.intval = ival + return &this } -func (this *Mlrval) SetFromInt(input int) { +func MlrvalPointerFromInt(input int) *Mlrval { + var this Mlrval this.mvtype = MT_INT this.printrepValid = false this.intval = input + return &this } // xxx comment why two -- one for from parsed user data; other for from math ops // xxx comment assummption is input-string already deemed parseable so no error return -func (this *Mlrval) SetFromFloat64String(input string) { +func MlrvalPointerFromFloat64String(input string) *Mlrval { fval, ok := lib.TryFloat64FromString(input) // xxx comment assummption is input-string already deemed parseable so no error return lib.InternalCodingErrorIf(!ok) + var this Mlrval this.mvtype = MT_FLOAT this.printrep = input this.printrepValid = true this.floatval = fval + return &this } -func (this *Mlrval) SetFromFloat64(input float64) { +func MlrvalPointerFromFloat64(input float64) *Mlrval { + var this Mlrval this.mvtype = MT_FLOAT this.printrepValid = false this.floatval = input + return &this } -func (this *Mlrval) SetFromTrue() { - this.mvtype = MT_BOOL - this.printrep = "true" - this.printrepValid = true - this.boolval = true -} - -func (this *Mlrval) SetFromFalse() { - this.mvtype = MT_BOOL - this.printrep = "false" - this.printrepValid = true - this.boolval = false -} - -func (this *Mlrval) SetFromBool(input bool) { +func MlrvalPointerFromBool(input bool) *Mlrval { if input == true { - this.SetFromTrue() + return MLRVAL_TRUE } else { - this.SetFromFalse() + return MLRVAL_FALSE } } -func (this *Mlrval) SetFromBoolString(input string) { +func MlrvalPointerFromBoolString(input string) *Mlrval { if input == "true" { - this.SetFromTrue() + return MLRVAL_TRUE + } else if input == "false" { + return MLRVAL_FALSE } else { - this.SetFromFalse() + lib.InternalCodingErrorIf(true) + return MLRVAL_ERROR // not reached } - // else panic } -func (this *Mlrval) SetFromInferredType(input string) { +func MlrvalPointerFromInferredType(input string) *Mlrval { // xxx the parsing has happened so stash it ... // xxx emphasize the invariant that a non-invalid printrep always // matches the nval ... if input == "" { - this.SetFromVoid() + return MLRVAL_VOID } _, iok := lib.TryIntFromString(input) if iok { - this.SetFromIntString(input) + return MlrvalPointerFromIntString(input) } _, fok := lib.TryFloat64FromString(input) if fok { - this.SetFromFloat64String(input) + return MlrvalPointerFromFloat64String(input) } _, bok := lib.TryBoolFromBoolString(input) if bok { - this.SetFromBoolString(input) + return MlrvalPointerFromBoolString(input) } - this.SetFromString(input) + return MlrvalPointerFromString(input) } -func (this *Mlrval) SetFromEmptyMap() { +func MlrvalPointerFromEmptyMap() *Mlrval { + var this Mlrval this.mvtype = MT_MAP this.printrepValid = false this.mapval = NewMlrmap() + return &this } // ---------------------------------------------------------------- -// Does not copy the data. We can make a (this *Mlrval) SetFromArrayLiteralCopy if needed +// Does not copy the data. We can make a SetFromArrayLiteralCopy if needed // using values.CopyMlrvalArray(). -func (this *Mlrval) SetFromArrayLiteralReference(input []Mlrval) { +func MlrvalPointerFromArrayLiteralReference(input []Mlrval) *Mlrval { + var this Mlrval this.mvtype = MT_ARRAY this.printrepValid = false this.arrayval = input + return &this } -func (this *Mlrval) SetFromMap(that *Mlrmap) { - this.SetFromEmptyMap() +func MlrvalPointerFromMap(that *Mlrmap) *Mlrval { + this := MlrvalPointerFromEmptyMap() if that == nil { - // xxx maybe return 2nd-arg error in the API - this.SetFromError() - return + // TODO maybe return 2nd-arg error in the API + return MLRVAL_ERROR } for pe := that.Head; pe != nil; pe = pe.Next { this.mapval.PutCopy(pe.Key, pe.Value) } + return this } // Like previous but doesn't copy. Only safe when the argument's sole purpose // is to be passed into here. -func (this *Mlrval) SetFromMapReferenced(that *Mlrmap) { - this.SetFromEmptyMap() +func MlrvalPointerFromMapReferenced(that *Mlrmap) *Mlrval { + this := MlrvalPointerFromEmptyMap() if that == nil { // xxx maybe return 2nd-arg error in the API - this.SetFromError() - return + return MLRVAL_ERROR } for pe := that.Head; pe != nil; pe = pe.Next { this.mapval.PutReference(pe.Key, pe.Value) } + return this +} + +// TODO: comment not MLRVAL_PENDING constants since this intended to be mutated +// by the JSON parser. +func MlrvalPointerFromPending() *Mlrval { + var this Mlrval + this.mvtype = MT_PENDING + this.printrepValid = false + return &this } diff --git a/go/src/types/mlrval_typing.go b/go/src/types/mlrval_typing.go index d33fcf340..36204fc27 100644 --- a/go/src/types/mlrval_typing.go +++ b/go/src/types/mlrval_typing.go @@ -91,10 +91,11 @@ func (this *TypeGatedMlrvalVariable) Assign(value *Mlrval) error { return err } - this.value.CopyFrom(value) + // TODO: revisit copy-reduction + this.value = value.Copy() return nil } func (this *TypeGatedMlrvalVariable) Unassign() { - this.value = MlrvalPointerFromAbsent() + this.value = MLRVAL_ABSENT } diff --git a/go/todo.txt b/go/todo.txt index 9ce99ee9c..6c9110c90 100644 --- a/go/todo.txt +++ b/go/todo.txt @@ -12,9 +12,12 @@ TOP OF LIST: - literal-type nodes -- why is there even a copy? these should simply be pointing at the literal. > modify Evaluate to return pointer? 1st arg becomes optional buffer? - type-gated mv -- should use passed-in storage slot -- ? + - MLRVAL_INT_0 et al. are dangerous & should be rid of. (too easy to mutate?). + > and/or all MLRVAL_X -> MLRVAL_X() - prof: mlr --cpuprofile cpu.pprof -n put -q -s iwidth=500 -s iheight=500 -s silent=true -f u/mand.mlr GOGC=off mlr --cpuprofile cpu.pprof -n put -q -s iwidth=500 -s iheight=500 -s silent=true -f u/mand.mlr + - check 'malloc-avoidance' comment - MlrvalLessThanForSort - MlrvalGetMeanEB et al. - var delta types.Mlrval for uninits @@ -22,6 +25,8 @@ TOP OF LIST: profilng methods, GC readings/findings, before-and-after CST data structures, final perf results. w defer the stack-allocation PR until after + - bonus: return MlrvalSqrt(MlrvalDivide(input1, input2)) + - maybe MT_PENDING_MUTABLE -- ? * next round of data-copy reduction: o $z = min($x, $y) -- needs to return pointer to x or y @@ -30,9 +35,17 @@ TOP OF LIST: - have the function z-allocate outputs when needed - the outputs must be on the stack, not statically allocated, to make them re-entrant and OK for recursive functions + - var output types.Mlrval w/ field-setters, rather than return &Mlrval{... all of them ...} o then IEvaluable: Evaluate(state *runtime.State) *types.Mlrval o invalidate CopyFrom o check for under/over copy at Assign + o global *ERROR / *ABSENT / etc + + ! GAH!! rethink MlrvalFromX(...) + +g/(output, input.*{$/s/{$/ *Mlrval {/ + +g/(output, input.*{$/s/(output, input/(input/ ---------------------------------------------------------------- * regexes