consolidate mlrval-constructor source files

This commit is contained in:
John Kerl 2021-02-23 09:31:16 -05:00
parent 4e0f4e1401
commit 093a58d783
23 changed files with 276 additions and 379 deletions

View file

@ -80,7 +80,7 @@ func (this *Repl) handleDSLStringAux(
// statment like 'true' or '$x > 0.5' etc. For the REPL, we re-use this for
// 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().
// types.MLRVAL_VOID.
filterExpression := this.runtimeState.FilterExpression
if filterExpression.IsVoid() {
// nothing to print

View file

@ -63,7 +63,7 @@ func NewRepl(
// statment like 'true' or '$x > 0.5' etc. For the REPL, we re-use this for
// 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().
// types.MLRVAL_VOID.
runtimeState.FilterExpression = types.MLRVAL_VOID
// For control-C handling

View file

@ -210,34 +210,34 @@ func (this *StringLiteralNode) Evaluate(
// ----------------------------------------------------------------
type IntLiteralNode struct {
literal types.Mlrval
literal *types.Mlrval
}
func (this *RootNode) BuildIntLiteralNode(literal string) *IntLiteralNode {
return &IntLiteralNode{
literal: types.MlrvalFromIntString(literal),
literal: types.MlrvalPointerFromIntString(literal),
}
}
func (this *IntLiteralNode) Evaluate(
state *runtime.State,
) *types.Mlrval {
return &this.literal
return this.literal
}
// ----------------------------------------------------------------
type FloatLiteralNode struct {
literal types.Mlrval
literal *types.Mlrval
}
func (this *RootNode) BuildFloatLiteralNode(literal string) *FloatLiteralNode {
return &FloatLiteralNode{
literal: types.MlrvalFromFloat64String(literal),
literal: types.MlrvalPointerFromFloat64String(literal),
}
}
func (this *FloatLiteralNode) Evaluate(
state *runtime.State,
) *types.Mlrval {
return &this.literal
return this.literal
}
// ----------------------------------------------------------------

View file

@ -120,8 +120,8 @@ func (this *RecordReaderCSV) processHandle(
if nh == nd {
for i := 0; i < nh; i++ {
key := header[i]
value := types.MlrvalFromInferredType(csvRecord[i])
record.PutReference(key, &value)
value := types.MlrvalPointerFromInferredType(csvRecord[i])
record.PutReference(key, value)
}
} else {
@ -140,14 +140,14 @@ func (this *RecordReaderCSV) processHandle(
n := lib.IntMin2(nh, nd)
for i = 0; i < n; i++ {
key := header[i]
value := types.MlrvalFromInferredType(csvRecord[i])
record.PutReference(key, &value)
value := types.MlrvalPointerFromInferredType(csvRecord[i])
record.PutReference(key, value)
}
if nh < nd {
// if header shorter than data: use 1-up itoa keys
key := strconv.Itoa(i + 1)
value := types.MlrvalFromInferredType(csvRecord[i])
record.PutCopy(key, &value)
value := types.MlrvalPointerFromInferredType(csvRecord[i])
record.PutCopy(key, value)
}
if nh > nd {
// if header longer than data: use "" values

View file

@ -172,8 +172,8 @@ func (this *RecordReaderCSVLite) processHandleExplicitCSVHeader(
record := types.NewMlrmap()
if !this.allowRaggedCSVInput {
for i, field := range fields {
value := types.MlrvalFromInferredType(field)
record.PutCopy(headerStrings[i], &value)
value := types.MlrvalPointerFromInferredType(field)
record.PutCopy(headerStrings[i], value)
}
} else {
nh := len(headerStrings)
@ -181,15 +181,15 @@ func (this *RecordReaderCSVLite) processHandleExplicitCSVHeader(
n := lib.IntMin2(nh, nd)
var i int
for i = 0; i < n; i++ {
value := types.MlrvalFromInferredType(fields[i])
record.PutCopy(headerStrings[i], &value)
value := types.MlrvalPointerFromInferredType(fields[i])
record.PutCopy(headerStrings[i], value)
}
if nh < nd {
// if header shorter than data: use 1-up itoa keys
for i = nh; i < nd; i++ {
key := strconv.Itoa(i + 1)
value := types.MlrvalFromInferredType(fields[i])
record.PutCopy(key, &value)
value := types.MlrvalPointerFromInferredType(fields[i])
record.PutCopy(key, value)
}
}
if nh > nd {
@ -267,8 +267,8 @@ func (this *RecordReaderCSVLite) processHandleImplicitCSVHeader(
record := types.NewMlrmap()
if !this.allowRaggedCSVInput {
for i, field := range fields {
value := types.MlrvalFromInferredType(field)
record.PutCopy(headerStrings[i], &value)
value := types.MlrvalPointerFromInferredType(field)
record.PutCopy(headerStrings[i], value)
}
} else {
nh := len(headerStrings)
@ -276,14 +276,14 @@ func (this *RecordReaderCSVLite) processHandleImplicitCSVHeader(
n := lib.IntMin2(nh, nd)
var i int
for i = 0; i < n; i++ {
value := types.MlrvalFromInferredType(fields[i])
record.PutCopy(headerStrings[i], &value)
value := types.MlrvalPointerFromInferredType(fields[i])
record.PutCopy(headerStrings[i], value)
}
if nh < nd {
// if header shorter than data: use 1-up itoa keys
key := strconv.Itoa(i + 1)
value := types.MlrvalFromInferredType(fields[i])
record.PutCopy(key, &value)
value := types.MlrvalPointerFromInferredType(fields[i])
record.PutCopy(key, value)
}
if nh > nd {
// if header longer than data: use "" values

View file

@ -97,12 +97,12 @@ func recordFromDKVPLine(
// "a=". Here we use the positional index as the key. This way
// DKVP is a generalization of NIDX.
key := strconv.Itoa(i + 1) // Miller userspace indices are 1-up
value := types.MlrvalFromInferredType(kv[0])
record.PutReference(key, &value)
value := types.MlrvalPointerFromInferredType(kv[0])
record.PutReference(key, value)
} else {
key := kv[0]
value := types.MlrvalFromInferredType(kv[1])
record.PutReference(key, &value)
value := types.MlrvalPointerFromInferredType(kv[1])
record.PutReference(key, value)
}
}
return record

View file

@ -94,8 +94,8 @@ func recordFromNIDXLine(
for _, value := range values {
i++
key := strconv.Itoa(i)
mval := types.MlrvalFromInferredType(value)
record.PutReference(key, &mval)
mval := types.MlrvalPointerFromInferredType(value)
record.PutReference(key, mval)
}
return record
}

View file

@ -136,11 +136,11 @@ func (this *RecordReaderXTAB) recordFromXTABLines(
key := kv[0]
if len(kv) == 1 {
value := types.MlrvalFromVoid()
record.PutReference(key, &value)
value := types.MLRVAL_VOID
record.PutReference(key, value)
} else {
value := types.MlrvalFromInferredType(kv[1])
record.PutReference(key, &value)
value := types.MlrvalPointerFromInferredType(kv[1])
record.PutReference(key, value)
}
}

View file

@ -269,7 +269,7 @@ func (this *PercentileKeeper) Emit(percentile float64) types.Mlrval {
func (this *PercentileKeeper) EmitNonInterpolated(percentile float64) types.Mlrval {
if len(this.data) == 0 {
return types.MlrvalFromAbsent()
return *types.MLRVAL_ABSENT
}
this.sortIfNecessary()
return *this.data[computeIndexNoninterpolated(int(len(this.data)), percentile)].Copy()
@ -277,7 +277,7 @@ func (this *PercentileKeeper) EmitNonInterpolated(percentile float64) types.Mlrv
func (this *PercentileKeeper) EmitLinearlyInterpolated(percentile float64) types.Mlrval {
if len(this.data) == 0 {
return types.MlrvalFromAbsent()
return *types.MLRVAL_ABSENT
}
this.sortIfNecessary()
output := getPercentileLinearlyInterpolated(this.data, int(len(this.data)), percentile)

View file

@ -338,8 +338,8 @@ func NewTransformerPut(
}
key := pair[0]
svalue := pair[1]
mvalue := types.MlrvalFromInferredType(svalue)
runtimeState.Oosvars.PutCopy(key, &mvalue)
mvalue := types.MlrvalPointerFromInferredType(svalue)
runtimeState.Oosvars.PutCopy(key, mvalue)
}
}

View file

@ -308,7 +308,7 @@ func (this *Stats1ModeAccumulator) Ingest(value *types.Mlrval) {
}
func (this *Stats1ModeAccumulator) Emit() types.Mlrval {
if this.countsByValue.FieldCount == 0 {
return types.MlrvalFromError()
return *types.MLRVAL_ERROR
}
maxValue := ""
var maxCount = int(0)
@ -346,7 +346,7 @@ func (this *Stats1AntimodeAccumulator) Ingest(value *types.Mlrval) {
}
func (this *Stats1AntimodeAccumulator) Emit() types.Mlrval {
if this.countsByValue.FieldCount == 0 {
return types.MlrvalFromError()
return *types.MLRVAL_ERROR
}
minValue := ""
var minCount = int(0)

View file

@ -402,8 +402,8 @@ func (this *tStepperShift) process(
inrec *types.Mlrmap,
) {
if this.previous == nil {
shift := types.MlrvalFromVoid()
inrec.PutCopy(this.outputFieldName, &shift)
shift := types.MLRVAL_VOID
inrec.PutCopy(this.outputFieldName, shift)
} else {
inrec.PutCopy(this.outputFieldName, this.previous)
this.previous = valueFieldValue.Copy()

View file

@ -144,11 +144,9 @@ func (this *mlrmapEntry) JSONStringifyInPlace(
) {
outputBytes, err := this.Value.MarshalJSON(jsonFormatting)
if err != nil {
newValue := MlrvalFromError()
this.Value = &newValue
this.Value = MLRVAL_ERROR
} else {
newValue := MlrvalFromString(string(outputBytes))
this.Value = &newValue
this.Value = MlrvalPointerFromString(string(outputBytes))
}
}
@ -158,8 +156,6 @@ func (this *mlrmapEntry) JSONParseInPlace() {
input := this.Value.String()
err := this.Value.UnmarshalJSON([]byte(input))
if err != nil {
// TODO: make a pointer-return method and simplify callsites
newValue := MlrvalFromError()
this.Value = &newValue
this.Value = MLRVAL_ERROR
}
}

View file

@ -77,16 +77,17 @@ import (
)
// ================================================================
// TODO: copy-reduction refactor
func (this *Mlrval) ArrayGet(mindex *Mlrval) Mlrval {
if this.mvtype != MT_ARRAY {
return MlrvalFromError()
return *MLRVAL_ERROR
}
if mindex.mvtype != MT_INT {
return MlrvalFromError()
return *MLRVAL_ERROR
}
value := arrayGetAliased(&this.arrayval, mindex.intval)
if value == nil {
return MlrvalFromAbsent()
return *MLRVAL_ABSENT
} else {
return *value
}
@ -218,15 +219,15 @@ func (this *Mlrval) ArrayAppend(value *Mlrval) {
// ================================================================
func (this *Mlrval) MapGet(key *Mlrval) Mlrval {
if this.mvtype != MT_MAP {
return MlrvalFromError()
return *MLRVAL_ERROR
}
mval, err := this.mapval.GetWithMlrvalIndex(key)
if err != nil { // xxx maybe error-return in the API
return MlrvalFromError()
return *MLRVAL_ERROR
}
if mval == nil {
return MlrvalFromAbsent()
return *MLRVAL_ABSENT
}
// This returns a reference, not a (deep) copy. In general in Miller, we
// copy only on write/put.

View file

@ -1,24 +0,0 @@
// ================================================================
// 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

View file

@ -139,12 +139,12 @@ func _s2__(input1, input2 *Mlrval) *Mlrval {
// Return integer zero (binary)
func _i0__(input1, input2 *Mlrval) *Mlrval {
return MLRVAL_INT_0
return MlrvalPointerFromInt(0)
}
// Return float zero (binary)
func _f0__(input1, input2 *Mlrval) *Mlrval {
return MLRVAL_FLOAT_0
return MlrvalPointerFromFloat64(0)
}
// Return boolean true (binary)

View file

@ -89,7 +89,7 @@ func leafcount_from_array(input1 *Mlrval) *Mlrval {
// Golang initialization loop if we do this :(
// childLeafCount := MlrvalLeafCount(&child)
childLeafCount := MLRVAL_INT_1
childLeafCount := MlrvalPointerFromInt(1)
if child.mvtype == MT_ARRAY {
childLeafCount = leafcount_from_array(&child)
} else if child.mvtype == MT_MAP {
@ -111,7 +111,7 @@ func leafcount_from_map(input1 *Mlrval) *Mlrval {
// Golang initialization loop if we do this :(
// childLeafCount := MlrvalLeafCount(child)
childLeafCount := MLRVAL_INT_1
childLeafCount := MlrvalPointerFromInt(1)
if child.mvtype == MT_ARRAY {
childLeafCount = leafcount_from_array(child)
} else if child.mvtype == MT_MAP {
@ -434,12 +434,12 @@ func MlrvalSplitKV(input1, input2, input3 *Mlrval) *Mlrval {
pair := strings.SplitN(field, pairSeparator, 2)
if len(pair) == 1 {
key := strconv.Itoa(i + 1) // Miller user-space indices are 1-up
value := MlrvalFromInferredType(pair[0])
output.mapval.PutReference(key, &value)
value := MlrvalPointerFromInferredType(pair[0])
output.mapval.PutReference(key, value)
} else if len(pair) == 2 {
key := pair[0]
value := MlrvalFromInferredType(pair[1])
output.mapval.PutReference(key, &value)
value := MlrvalPointerFromInferredType(pair[1])
output.mapval.PutReference(key, value)
} else {
lib.InternalCodingErrorIf(true)
}
@ -498,8 +498,8 @@ func MlrvalSplitNV(input1, input2 *Mlrval) *Mlrval {
fields := lib.SplitString(input1.printrep, input2.printrep)
for i, field := range fields {
key := strconv.Itoa(i + 1) // Miller user-space indices are 1-up
value := MlrvalFromInferredType(field)
output.mapval.PutReference(key, &value)
value := MlrvalPointerFromInferredType(field)
output.mapval.PutReference(key, value)
}
return output
@ -543,8 +543,8 @@ func MlrvalSplitA(input1, input2 *Mlrval) *Mlrval {
output := NewSizedMlrvalArray(int(len(fields)))
for i, field := range fields {
value := MlrvalFromInferredType(field)
output.arrayval[i] = value
value := MlrvalPointerFromInferredType(field)
output.arrayval[i] = *value
}
return output

View file

@ -90,7 +90,7 @@ func MlrvalGetSkewness(mn, msum, msum2, msum3 *Mlrval) Mlrval {
n, isInt := mn.GetIntValue()
lib.InternalCodingErrorIf(!isInt)
if n < 2 {
return MlrvalFromVoid()
return *MLRVAL_VOID
}
fn := float64(n)
sum, isNumber := msum.GetNumericToFloatValue()
@ -127,7 +127,7 @@ func MlrvalGetKurtosis(mn, msum, msum2, msum3, msum4 *Mlrval) Mlrval {
n, isInt := mn.GetIntValue()
lib.InternalCodingErrorIf(!isInt)
if n < 2 {
return MlrvalFromVoid()
return *MLRVAL_VOID
}
fn := float64(n)
sum, isNumber := msum.GetNumericToFloatValue()

View file

@ -34,9 +34,9 @@ func TestComparctors(t *testing.T) {
sabc := MlrvalFromString("abc")
sdef := MlrvalFromString("def")
e := MlrvalFromError()
e := *MLRVAL_ERROR
a := MlrvalFromAbsent()
a := *MLRVAL_ABSENT
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Within-type lexical comparisons

View file

@ -134,8 +134,7 @@ func MlrvalDecodeFromJSON(decoder *json.Decoder) (
delimiter, isDelim := startToken.(json.Delim)
if !isDelim {
if startToken == nil {
mlrval := MlrvalFromVoid()
return &mlrval, false, nil
return MLRVAL_VOID, false, nil
}
sval, ok := startToken.(string)
@ -152,8 +151,8 @@ func MlrvalDecodeFromJSON(decoder *json.Decoder) (
nval, ok := startToken.(json.Number)
if ok {
mlrval := MlrvalFromInferredType(nval.String())
return &mlrval, false, nil
mlrval := MlrvalPointerFromInferredType(nval.String())
return mlrval, false, nil
}
return nil, false, errors.New(

View file

@ -11,6 +11,178 @@ import (
)
// ----------------------------------------------------------------
// TODO: comment how these are part of the copy-reduction project.
var value_MLRVAL_ERROR = mlrvalFromError()
var value_MLRVAL_ABSENT = mlrvalFromAbsent()
var value_MLRVAL_VOID = mlrvalFromVoid()
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_TRUE = &value_MLRVAL_TRUE
var MLRVAL_FALSE = &value_MLRVAL_FALSE
// ----------------------------------------------------------------
func MlrvalPointerFromString(input string) *Mlrval {
if input == "" {
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 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 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 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 MlrvalPointerFromFloat64(input float64) *Mlrval {
var this Mlrval
this.mvtype = MT_FLOAT
this.printrepValid = false
this.floatval = input
return &this
}
func MlrvalPointerFromBool(input bool) *Mlrval {
if input == true {
return MLRVAL_TRUE
} else {
return MLRVAL_FALSE
}
}
func MlrvalPointerFromBoolString(input string) *Mlrval {
if input == "true" {
return MLRVAL_TRUE
} else if input == "false" {
return MLRVAL_FALSE
} else {
lib.InternalCodingErrorIf(true)
return MLRVAL_ERROR // not reached
}
}
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 == "" {
return MLRVAL_VOID
}
_, iok := lib.TryIntFromString(input)
if iok {
return MlrvalPointerFromIntString(input)
}
_, fok := lib.TryFloat64FromString(input)
if fok {
return MlrvalPointerFromFloat64String(input)
}
_, bok := lib.TryBoolFromBoolString(input)
if bok {
return MlrvalPointerFromBoolString(input)
}
return MlrvalPointerFromString(input)
}
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 SetFromArrayLiteralCopy if needed
// using values.CopyMlrvalArray().
func MlrvalPointerFromArrayLiteralReference(input []Mlrval) *Mlrval {
var this Mlrval
this.mvtype = MT_ARRAY
this.printrepValid = false
this.arrayval = input
return &this
}
func MlrvalPointerFromMap(that *Mlrmap) *Mlrval {
this := MlrvalPointerFromEmptyMap()
if that == nil {
// 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 MlrvalPointerFromMapReferenced(that *Mlrmap) *Mlrval {
this := MlrvalPointerFromEmptyMap()
if that == nil {
// xxx maybe return 2nd-arg error in the API
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
}
// ----------------------------------------------------------------
// TODO: comment about being designed to be mutated for JSON API.
func MlrvalFromPending() Mlrval {
return Mlrval{
mvtype: MT_PENDING,
@ -24,7 +196,7 @@ func MlrvalFromPending() Mlrval {
}
}
func MlrvalFromError() Mlrval {
func mlrvalFromError() Mlrval {
return Mlrval{
mvtype: MT_ERROR,
printrep: "(error)", // xxx const somewhere
@ -37,7 +209,7 @@ func MlrvalFromError() Mlrval {
}
}
func MlrvalFromAbsent() Mlrval {
func mlrvalFromAbsent() Mlrval {
return Mlrval{
mvtype: MT_ABSENT,
printrep: "(absent)",
@ -50,7 +222,7 @@ func MlrvalFromAbsent() Mlrval {
}
}
func MlrvalFromVoid() Mlrval {
func mlrvalFromVoid() Mlrval {
return Mlrval{
mvtype: MT_VOID,
printrep: "",
@ -65,7 +237,7 @@ func MlrvalFromVoid() Mlrval {
func MlrvalFromString(input string) Mlrval {
if input == "" {
return MlrvalFromVoid()
return mlrvalFromVoid()
} else {
return Mlrval{
mvtype: MT_STRING,
@ -80,23 +252,6 @@ func MlrvalFromString(input string) Mlrval {
}
}
// 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)
// xxx comment assummption is input-string already deemed parseable so no error return
lib.InternalCodingErrorIf(!ok)
return Mlrval{
mvtype: MT_INT,
printrep: input,
printrepValid: true,
intval: ival,
floatval: 0.0,
boolval: false,
arrayval: nil,
mapval: nil,
}
}
func MlrvalFromInt(input int) Mlrval {
return Mlrval{
mvtype: MT_INT,
@ -110,24 +265,6 @@ func MlrvalFromInt(input int) Mlrval {
}
}
// 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 MlrvalFromFloat64String(input string) Mlrval {
fval, ok := lib.TryFloat64FromString(input)
// xxx comment assummption is input-string already deemed parseable so no error return
lib.InternalCodingErrorIf(!ok)
return Mlrval{
mvtype: MT_FLOAT,
printrep: input,
printrepValid: true,
intval: 0,
floatval: fval,
boolval: false,
arrayval: nil,
mapval: nil,
}
}
func MlrvalFromFloat64(input float64) Mlrval {
return Mlrval{
mvtype: MT_FLOAT,
@ -141,7 +278,7 @@ func MlrvalFromFloat64(input float64) Mlrval {
}
}
func MlrvalFromTrue() Mlrval {
func mlrvalFromTrue() Mlrval {
return Mlrval{
mvtype: MT_BOOL,
printrep: "true",
@ -154,7 +291,7 @@ func MlrvalFromTrue() Mlrval {
}
}
func MlrvalFromFalse() Mlrval {
func mlrvalFromFalse() Mlrval {
return Mlrval{
mvtype: MT_BOOL,
printrep: "false",
@ -169,62 +306,24 @@ func MlrvalFromFalse() Mlrval {
func MlrvalFromBool(input bool) Mlrval {
if input == true {
return MlrvalFromTrue()
return mlrvalFromTrue()
} else {
return MlrvalFromFalse()
return mlrvalFromFalse()
}
}
func MlrvalFromBoolString(input string) Mlrval {
if input == "true" {
return MlrvalFromTrue()
return mlrvalFromTrue()
} else {
return MlrvalFromFalse()
return mlrvalFromFalse()
}
// else panic
}
func MlrvalFromInferredType(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 == "" {
return MlrvalFromVoid()
}
_, iok := lib.TryIntFromString(input)
if iok {
return MlrvalFromIntString(input)
}
_, fok := lib.TryFloat64FromString(input)
if fok {
return MlrvalFromFloat64String(input)
}
_, bok := lib.TryBoolFromBoolString(input)
if bok {
return MlrvalFromBoolString(input)
}
return MlrvalFromString(input)
}
// ----------------------------------------------------------------
// Does not copy the data. We can make a MlrvalFromArrayLiteralCopy if needed,
// using values.CopyMlrvalArray().
func MlrvalFromArrayLiteralReference(input []Mlrval) Mlrval {
return Mlrval{
mvtype: MT_ARRAY,
printrep: "(bug-if-you-see-this-array-type)",
printrepValid: false,
intval: 0,
floatval: 0.0,
boolval: false,
arrayval: input,
mapval: nil,
}
}
func MlrvalEmptyArray() Mlrval {
return Mlrval{
@ -297,27 +396,13 @@ func MlrvalEmptyMap() Mlrval {
}
}
func MlrvalFromMap(that *Mlrmap) Mlrval {
this := MlrvalEmptyMap()
if that == nil {
// xxx maybe return 2nd-arg error in the API
return MlrvalFromError()
}
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 MlrvalFromMapReferenced(that *Mlrmap) Mlrval {
this := MlrvalEmptyMap()
if that == nil {
// xxx maybe return 2nd-arg error in the API
return MlrvalFromError()
return *MLRVAL_ERROR
}
for pe := that.Head; pe != nil; pe = pe.Next {

View file

@ -1,174 +0,0 @@
// ================================================================
// Constructors
// ================================================================
package types
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)
// }
//}
func MlrvalPointerFromString(input string) *Mlrval {
if input == "" {
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 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 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 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 MlrvalPointerFromFloat64(input float64) *Mlrval {
var this Mlrval
this.mvtype = MT_FLOAT
this.printrepValid = false
this.floatval = input
return &this
}
func MlrvalPointerFromBool(input bool) *Mlrval {
if input == true {
return MLRVAL_TRUE
} else {
return MLRVAL_FALSE
}
}
func MlrvalPointerFromBoolString(input string) *Mlrval {
if input == "true" {
return MLRVAL_TRUE
} else if input == "false" {
return MLRVAL_FALSE
} else {
lib.InternalCodingErrorIf(true)
return MLRVAL_ERROR // not reached
}
}
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 == "" {
return MLRVAL_VOID
}
_, iok := lib.TryIntFromString(input)
if iok {
return MlrvalPointerFromIntString(input)
}
_, fok := lib.TryFloat64FromString(input)
if fok {
return MlrvalPointerFromFloat64String(input)
}
_, bok := lib.TryBoolFromBoolString(input)
if bok {
return MlrvalPointerFromBoolString(input)
}
return MlrvalPointerFromString(input)
}
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 SetFromArrayLiteralCopy if needed
// using values.CopyMlrvalArray().
func MlrvalPointerFromArrayLiteralReference(input []Mlrval) *Mlrval {
var this Mlrval
this.mvtype = MT_ARRAY
this.printrepValid = false
this.arrayval = input
return &this
}
func MlrvalPointerFromMap(that *Mlrmap) *Mlrval {
this := MlrvalPointerFromEmptyMap()
if that == nil {
// 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 MlrvalPointerFromMapReferenced(that *Mlrmap) *Mlrval {
this := MlrvalPointerFromEmptyMap()
if that == nil {
// xxx maybe return 2nd-arg error in the API
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
}

View file

@ -28,6 +28,26 @@ TOP OF LIST:
- bonus: return MlrvalSqrt(MlrvalDivide(input1, input2))
- maybe MT_PENDING_MUTABLE -- ?
info:
for i in 100 200 500 1000 2000 5000 10000 20000; do echo $i; justtime GOGC=$i mlr -n put -q
100 TIME IN SECONDS 21.046 -- GOGC=100 mlr -n put -q -s silent=true -f u/mand.mlr
200 TIME IN SECONDS 17.233 -- GOGC=200 mlr -n put -q -s silent=true -f u/mand.mlr
500 TIME IN SECONDS 15.535 -- GOGC=500 mlr -n put -q -s silent=true -f u/mand.mlr
1000 TIME IN SECONDS 15.125 -- GOGC=1000 mlr -n put -q -s silent=true -f u/mand.mlr
2000 TIME IN SECONDS 15.428 -- GOGC=2000 mlr -n put -q -s silent=true -f u/mand.mlr
5000 TIME IN SECONDS 15.083 -- GOGC=5000 mlr -n put -q -s silent=true -f u/mand.mlr
10000 TIME IN SECONDS 15.175 -- GOGC=10000 mlr -n put -q -s silent=true -f u/mand.mlr
20000 TIME IN SECONDS 15.419 -- GOGC=20000 mlr -n put -q -s silent=true -f u/mand.mlr
mlr --cpuprofile cpu.pprof --from ~tmp/big sort -f a -nr x then nothing
GOGC=1000 mlr --cpuprofile cpu.pprof --from /Users/kerl/tmp/huge sort -f a -nr x then nothing
wc -l ~/tmp/big
1000000 /Users/kerl/tmp/big
wc -l ~/tmp/huge
10000000 /Users/kerl/tmp/huge
* 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
@ -41,12 +61,6 @@ TOP OF LIST:
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
o finish stats1 -r