mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-28 18:21:52 +00:00
Merge pull request #425 from johnkerl/copy-reduction-in-evaluators
Copy reduction in evaluators
This commit is contained in:
commit
8db1f7488f
51 changed files with 1470 additions and 1837 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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()))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
24
go/src/types/mlrval_constants.go
Normal file
24
go/src/types/mlrval_constants.go
Normal file
|
|
@ -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
|
||||
|
|
@ -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)),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
30
go/todo.txt
30
go/todo.txt
|
|
@ -9,8 +9,15 @@ 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 -- ?
|
||||
- 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=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
|
||||
- check 'malloc-avoidance' comment
|
||||
- MlrvalLessThanForSort
|
||||
- MlrvalGetMeanEB et al.
|
||||
- var delta types.Mlrval for uninits
|
||||
|
|
@ -18,6 +25,27 @@ 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
|
||||
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
|
||||
- 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue