Fatal-on-data-error mlr -x option (#1373)

* Fatal-on-data-error `mlr -x` option [WIP]

* arithmetic.go error-reason propagation

* more

* more

* more

* renames

* doc page

* namefix

* fix broken test

* make dev
This commit is contained in:
John Kerl 2023-08-30 19:39:22 -04:00 committed by GitHub
parent 879f272f79
commit 0493a0debd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
63 changed files with 1648 additions and 852 deletions

6
docs/src/data-error.csv Normal file
View file

@ -0,0 +1,6 @@
x
1
2
3
text
4
1 x
2 1
3 2
4 3
5 text
6 4

View file

@ -603,6 +603,9 @@ MILLER(1) MILLER(1)
-s {file name} Take command-line flags from file name. For more
information please see
https://miller.readthedocs.io/en/latest/scripting/.
-x If any record has an error value in it, report it and
stop the process. The default is to print the field
value as `(error)` and continue.
1mOUTPUT-COLORIZATION FLAGS0m
Miller uses colors to highlight outputs. You can specify color preferences.

View file

@ -582,6 +582,9 @@ MILLER(1) MILLER(1)
-s {file name} Take command-line flags from file name. For more
information please see
https://miller.readthedocs.io/en/latest/scripting/.
-x If any record has an error value in it, report it and
stop the process. The default is to print the field
value as `(error)` and continue.
1mOUTPUT-COLORIZATION FLAGS0m
Miller uses colors to highlight outputs. You can specify color preferences.

View file

@ -127,6 +127,8 @@ If you `mlr --csv cat` this, you'll get an error message:
<b>mlr --csv cat data/het/ragged.csv</b>
</pre>
<pre class="pre-non-highlight-in-pair">
a,b,c
1,2,3
mlr: mlr: CSV header/data length mismatch 3 != 2 at filename data/het/ragged.csv row 3.
.
</pre>

View file

@ -16,6 +16,55 @@ Quick links:
</div>
# DSL errors and transparency
# Handling for data errors
By default, Miller doesn't stop data processing for a single cell error. For example:
<pre class="pre-highlight-in-pair">
<b>mlr --csv --from data-error.csv cat</b>
</pre>
<pre class="pre-non-highlight-in-pair">
x
1
2
3
text
4
</pre>
<pre class="pre-highlight-in-pair">
<b>mlr --csv --from data-error.csv put '$y = log10($x)'</b>
</pre>
<pre class="pre-non-highlight-in-pair">
x,y
1,0
2,0.3010299956639812
3,0.4771212547196624
text,(error)
4,0.6020599913279624
</pre>
If you do want to stop processing, though, you have three options. The first is the `mlr -x` flag:
<pre class="pre-highlight-in-pair">
<b>mlr -x --csv --from data-error.csv put '$y = log10($x)'</b>
</pre>
<pre class="pre-non-highlight-in-pair">
x,y
1,0
2,0.3010299956639812
3,0.4771212547196624
mlr: data error at NR=4 FNR=4 FILENAME=data-error.csv
mlr: field y: log10: unacceptable type string with value "text"
mlr: exiting due to data error.
</pre>
The second is to put `-x` into your [`~/.mlrrc` file](customization.md).
The third is to set the `MLR_FAIL_ON_DATA_ERROR` environment variable, which makes `-x` implicit.
# Common causes of syntax errors
As soon as you have a [programming language](miller-programming-language.md), you start having the problem *What is my code doing, and why?* This includes getting syntax errors -- which are always annoying -- as well as the even more annoying problem of a program which parses without syntax error but doesn't do what you expect.
The syntax-error message gives you line/column position for the syntax that couldn't be parsed. The cause may be clear from that information, or perhaps not. Here are some common causes of syntax errors:
@ -26,7 +75,7 @@ The syntax-error message gives you line/column position for the syntax that coul
* Curly braces are required for the bodies of `if`/`while`/`for` blocks, even when the body is a single statement.
As for transparency:
# Transparency
* As in any language, you can do `print`, or `eprint` to print to stderr. See [Print statements](reference-dsl-output-statements.md#print-statements); see also [Dump statements](reference-dsl-output-statements.md#dump-statements) and [Emit statements](reference-dsl-output-statements.md#emit-statements).

View file

@ -1,5 +1,29 @@
# DSL errors and transparency
# Handling for data errors
By default, Miller doesn't stop data processing for a single cell error. For example:
GENMD-RUN-COMMAND
mlr --csv --from data-error.csv cat
GENMD-EOF
GENMD-RUN-COMMAND
mlr --csv --from data-error.csv put '$y = log10($x)'
GENMD-EOF
If you do want to stop processing, though, you have three options. The first is the `mlr -x` flag:
GENMD-RUN-COMMAND-TOLERATING-ERROR
mlr -x --csv --from data-error.csv put '$y = log10($x)'
GENMD-EOF
The second is to put `-x` into your [`~/.mlrrc` file](customization.md).
The third is to set the `MLR_FAIL_ON_DATA_ERROR` environment variable, which makes `-x` implicit.
# Common causes of syntax errors
As soon as you have a [programming language](miller-programming-language.md), you start having the problem *What is my code doing, and why?* This includes getting syntax errors -- which are always annoying -- as well as the even more annoying problem of a program which parses without syntax error but doesn't do what you expect.
The syntax-error message gives you line/column position for the syntax that couldn't be parsed. The cause may be clear from that information, or perhaps not. Here are some common causes of syntax errors:
@ -10,7 +34,7 @@ The syntax-error message gives you line/column position for the syntax that coul
* Curly braces are required for the bodies of `if`/`while`/`for` blocks, even when the body is a single statement.
As for transparency:
# Transparency
* As in any language, you can do `print`, or `eprint` to print to stderr. See [Print statements](reference-dsl-output-statements.md#print-statements); see also [Dump statements](reference-dsl-output-statements.md#dump-statements) and [Emit statements](reference-dsl-output-statements.md#emit-statements).

View file

@ -289,6 +289,7 @@ These are flags which don't fit into any other category.
* `-I`: Process files in-place. For each file name on the command line, output is written to a temp file in the same directory, which is then renamed over the original. Each file is processed in isolation: if the output format is CSV, CSV headers will be present in each output file, statistics are only over each file's own records; and so on.
* `-n`: Process no input files, nor standard input either. Useful for `mlr put` with `begin`/`end` statements only. (Same as `--from /dev/null`.) Also useful in `mlr -n put -v '...'` for analyzing abstract syntax trees (if that's your thing).
* `-s {file name}`: Take command-line flags from file name. For more information please see https://miller.readthedocs.io/en/latest/scripting/.
* `-x`: If any record has an error value in it, report it and stop the process. The default is to print the field value as `(error)` and continue.
## Output-colorization flags

View file

@ -1,6 +1,7 @@
package bifs
import (
"fmt"
"math"
"github.com/johnkerl/miller/internal/pkg/lib"
@ -10,16 +11,20 @@ import (
// ================================================================
// Unary plus operator
func upos_te(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorUnary("+", input1)
}
var upos_dispositions = [mlrval.MT_DIM]UnaryFunc{
/*INT */ _1u___,
/*FLOAT */ _1u___,
/*BOOL */ _erro1,
/*BOOL */ upos_te,
/*VOID */ _zero1,
/*STRING */ _erro1,
/*STRING */ upos_te,
/*ARRAY */ _absn1,
/*MAP */ _absn1,
/*FUNC */ _erro1,
/*ERROR */ _erro1,
/*FUNC */ upos_te,
/*ERROR */ upos_te,
/*NULL */ _null1,
/*ABSENT */ _absn1,
}
@ -31,6 +36,10 @@ func BIF_plus_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
// ================================================================
// Unary minus operator
func uneg_te(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorUnary("-", input1)
}
func uneg_i_i(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromInt(-input1.AcquireIntValue())
}
@ -42,13 +51,13 @@ func uneg_f_f(input1 *mlrval.Mlrval) *mlrval.Mlrval {
var uneg_dispositions = [mlrval.MT_DIM]UnaryFunc{
/*INT */ uneg_i_i,
/*FLOAT */ uneg_f_f,
/*BOOL */ _erro1,
/*BOOL */ uneg_te,
/*VOID */ _zero1,
/*STRING */ _erro1,
/*STRING */ uneg_te,
/*ARRAY */ _absn1,
/*MAP */ _absn1,
/*FUNC */ _erro1,
/*ERROR */ _erro1,
/*FUNC */ uneg_te,
/*ERROR */ uneg_te,
/*NULL */ _null1,
/*ABSENT */ _absn1,
}
@ -96,19 +105,23 @@ func plus_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromFloat(input1.AcquireFloatValue() + input2.AcquireFloatValue())
}
func plste(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("+", input1, input2)
}
var plus_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {plus_n_ii, plus_f_if, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___},
/*FLOAT */ {plus_f_fi, plus_f_ff, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_2___, _2___, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_2___, _2___, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _null, _absn},
/*ABSENT */ {_2___, _2___, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {plus_n_ii, plus_f_if, plste, _1___, plste, _absn, _absn, plste, plste, _1___, _1___},
/*FLOAT */ {plus_f_fi, plus_f_ff, plste, _1___, plste, _absn, _absn, plste, plste, _1___, _1___},
/*BOOL */ {plste, plste, plste, plste, plste, _absn, _absn, plste, plste, plste, plste},
/*VOID */ {_2___, _2___, plste, _void, plste, _absn, _absn, plste, plste, plste, _absn},
/*STRING */ {plste, plste, plste, plste, plste, _absn, _absn, plste, plste, plste, plste},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, plste, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, plste, _absn, _absn, _absn},
/*FUNC */ {plste, plste, plste, plste, plste, plste, plste, plste, plste, plste, plste},
/*ERROR */ {plste, plste, plste, plste, plste, _absn, _absn, plste, plste, plste, plste},
/*NULL */ {_2___, _2___, plste, plste, plste, _absn, _absn, plste, plste, _null, _absn},
/*ABSENT */ {_2___, _2___, plste, _absn, plste, _absn, _absn, plste, plste, _absn, _absn},
}
func BIF_plus_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -154,19 +167,23 @@ func minus_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromFloat(input1.AcquireFloatValue() - input2.AcquireFloatValue())
}
func mnste(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("-", input1, input2)
}
var minus_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {minus_n_ii, minus_f_if, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___},
/*FLOAT */ {minus_f_fi, minus_f_ff, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_n2__, _n2__, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_2___, _2___, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _null, _absn},
/*ABSENT */ {_2___, _2___, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {minus_n_ii, minus_f_if, mnste, _1___, mnste, _absn, _absn, mnste, mnste, _1___, _1___},
/*FLOAT */ {minus_f_fi, minus_f_ff, mnste, _1___, mnste, _absn, _absn, mnste, mnste, _1___, _1___},
/*BOOL */ {mnste, mnste, mnste, mnste, mnste, _absn, _absn, mnste, mnste, mnste, mnste},
/*VOID */ {_n2__, _n2__, mnste, _void, mnste, _absn, _absn, mnste, mnste, mnste, _absn},
/*STRING */ {mnste, mnste, mnste, mnste, mnste, _absn, _absn, mnste, mnste, mnste, mnste},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, mnste, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, mnste, _absn, _absn, _absn},
/*FUNC */ {mnste, mnste, mnste, mnste, mnste, mnste, mnste, mnste, mnste, mnste, mnste},
/*ERROR */ {mnste, mnste, mnste, mnste, mnste, _absn, _absn, mnste, mnste, mnste, mnste},
/*NULL */ {_2___, _2___, mnste, mnste, mnste, _absn, _absn, mnste, mnste, _null, _absn},
/*ABSENT */ {_2___, _2___, mnste, _absn, mnste, _absn, _absn, mnste, mnste, _absn, _absn},
}
func BIF_minus_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -228,19 +245,23 @@ func times_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromFloat(input1.AcquireFloatValue() * input2.AcquireFloatValue())
}
func tmste(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("*", input1, input2)
}
var times_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {times_n_ii, times_f_if, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___},
/*FLOAT */ {times_f_fi, times_f_ff, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_2___, _2___, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_2___, _2___, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _null, _absn},
/*ABSENT */ {_2___, _2___, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {times_n_ii, times_f_if, tmste, _1___, tmste, _absn, _absn, tmste, tmste, _1___, _1___},
/*FLOAT */ {times_f_fi, times_f_ff, tmste, _1___, tmste, _absn, _absn, tmste, tmste, _1___, _1___},
/*BOOL */ {tmste, tmste, tmste, tmste, tmste, _absn, _absn, tmste, tmste, tmste, tmste},
/*VOID */ {_2___, _2___, tmste, _void, tmste, _absn, _absn, tmste, tmste, tmste, _absn},
/*STRING */ {tmste, tmste, tmste, tmste, tmste, _absn, _absn, tmste, tmste, tmste, tmste},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, tmste, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, tmste, _absn, _absn, _absn},
/*FUNC */ {tmste, tmste, tmste, tmste, tmste, tmste, tmste, tmste, tmste, tmste, tmste},
/*ERROR */ {tmste, tmste, tmste, tmste, tmste, _absn, _absn, tmste, tmste, tmste, tmste},
/*NULL */ {_2___, _2___, tmste, tmste, tmste, _absn, _absn, tmste, tmste, _null, _absn},
/*ABSENT */ {_2___, _2___, tmste, _absn, tmste, _absn, _absn, tmste, tmste, _absn, _absn},
}
func BIF_times(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -291,19 +312,23 @@ func divide_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromFloat(input1.AcquireFloatValue() / input2.AcquireFloatValue())
}
func dvdte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("/", input1, input2)
}
var divide_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {divide_n_ii, divide_f_if, _erro, _void, _erro, _absn, _absn, _erro, _erro, _1___, _1___},
/*FLOAT */ {divide_f_fi, divide_f_ff, _erro, _void, _erro, _absn, _absn, _erro, _erro, _1___, _1___},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_i0__, _f0__, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*ABSENT */ {_i0__, _f0__, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {divide_n_ii, divide_f_if, dvdte, _void, dvdte, _absn, _absn, dvdte, dvdte, _1___, _1___},
/*FLOAT */ {divide_f_fi, divide_f_ff, dvdte, _void, dvdte, _absn, _absn, dvdte, dvdte, _1___, _1___},
/*BOOL */ {dvdte, dvdte, dvdte, dvdte, dvdte, _absn, _absn, dvdte, dvdte, dvdte, dvdte},
/*VOID */ {_void, _void, dvdte, _void, dvdte, _absn, _absn, dvdte, dvdte, dvdte, _absn},
/*STRING */ {dvdte, dvdte, dvdte, dvdte, dvdte, _absn, _absn, dvdte, dvdte, dvdte, dvdte},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, dvdte, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, dvdte, _absn, _absn, _absn},
/*FUNC */ {dvdte, dvdte, dvdte, dvdte, dvdte, dvdte, dvdte, dvdte, dvdte, dvdte, dvdte},
/*ERROR */ {dvdte, dvdte, dvdte, dvdte, dvdte, _absn, _absn, dvdte, dvdte, dvdte, dvdte},
/*NULL */ {_i0__, _f0__, dvdte, dvdte, dvdte, _absn, _absn, dvdte, dvdte, dvdte, _absn},
/*ABSENT */ {_i0__, _f0__, dvdte, _absn, dvdte, _absn, _absn, dvdte, dvdte, _absn, _absn},
}
func BIF_divide(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -352,19 +377,23 @@ func int_divide_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromFloat(math.Floor(input1.AcquireFloatValue() / input2.AcquireFloatValue()))
}
func idvte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("//", input1, input2)
}
var int_divide_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {int_divide_n_ii, int_divide_f_if, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*FLOAT */ {int_divide_f_fi, int_divide_f_ff, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*ABSENT */ {_i0__, _f0__, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {int_divide_n_ii, int_divide_f_if, idvte, _void, idvte, _absn, _absn, idvte, idvte, idvte, _1___},
/*FLOAT */ {int_divide_f_fi, int_divide_f_ff, idvte, _void, idvte, _absn, _absn, idvte, idvte, idvte, _1___},
/*BOOL */ {idvte, idvte, idvte, idvte, idvte, _absn, _absn, idvte, idvte, idvte, idvte},
/*VOID */ {_void, _void, idvte, _void, idvte, _absn, _absn, idvte, idvte, idvte, _absn},
/*STRING */ {idvte, idvte, idvte, idvte, idvte, _absn, _absn, idvte, idvte, idvte, idvte},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, idvte, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, idvte, _absn, _absn, _absn},
/*FUNC */ {idvte, idvte, idvte, idvte, idvte, idvte, idvte, idvte, idvte, idvte, idvte},
/*ERROR */ {idvte, idvte, idvte, idvte, idvte, _absn, _absn, idvte, idvte, idvte, idvte},
/*NULL */ {idvte, idvte, idvte, idvte, idvte, _absn, _absn, idvte, idvte, idvte, _absn},
/*ABSENT */ {_i0__, _f0__, idvte, _absn, idvte, _absn, _absn, idvte, idvte, _absn, _absn},
}
func BIF_int_divide(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -388,19 +417,23 @@ func dotplus_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromFloat(input1.AcquireFloatValue() + input2.AcquireFloatValue())
}
func dplte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary(".+", input1, input2)
}
var dot_plus_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {dotplus_i_ii, dotplus_f_if, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___},
/*FLOAT */ {dotplus_f_fi, dotplus_f_ff, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_2___, _2___, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_2___, _2___, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _null, _absn},
/*ABSENT */ {_2___, _2___, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {dotplus_i_ii, dotplus_f_if, dplte, _1___, dplte, _absn, _absn, dplte, dplte, _1___, _1___},
/*FLOAT */ {dotplus_f_fi, dotplus_f_ff, dplte, _1___, dplte, _absn, _absn, dplte, dplte, _1___, _1___},
/*BOOL */ {dplte, dplte, dplte, dplte, dplte, _absn, _absn, dplte, dplte, dplte, dplte},
/*VOID */ {_2___, _2___, dplte, _void, dplte, _absn, _absn, dplte, dplte, dplte, _absn},
/*STRING */ {dplte, dplte, dplte, dplte, dplte, _absn, _absn, dplte, dplte, dplte, dplte},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, dplte, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, dplte, _absn, _absn, _absn},
/*FUNC */ {dplte, dplte, dplte, dplte, dplte, dplte, dplte, dplte, dplte, dplte, dplte},
/*ERROR */ {dplte, dplte, dplte, dplte, dplte, _absn, _absn, dplte, dplte, dplte, dplte},
/*NULL */ {_2___, _2___, dplte, dplte, dplte, _absn, _absn, dplte, dplte, _null, _absn},
/*ABSENT */ {_2___, _2___, dplte, _absn, dplte, _absn, _absn, dplte, dplte, _absn, _absn},
}
func BIF_dot_plus(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -424,19 +457,23 @@ func dotminus_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromFloat(input1.AcquireFloatValue() - input2.AcquireFloatValue())
}
func dmnte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary(".-", input1, input2)
}
var dotminus_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {dotminus_i_ii, dotminus_f_if, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___},
/*FLOAT */ {dotminus_f_fi, dotminus_f_ff, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_n2__, _n2__, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_n2__, _n2__, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _null, _absn},
/*ABSENT */ {_n2__, _n2__, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {dotminus_i_ii, dotminus_f_if, dmnte, _1___, dmnte, _absn, _absn, dmnte, dmnte, _1___, _1___},
/*FLOAT */ {dotminus_f_fi, dotminus_f_ff, dmnte, _1___, dmnte, _absn, _absn, dmnte, dmnte, _1___, _1___},
/*BOOL */ {dmnte, dmnte, dmnte, dmnte, dmnte, _absn, _absn, dmnte, dmnte, dmnte, dmnte},
/*VOID */ {_n2__, _n2__, dmnte, _void, dmnte, _absn, _absn, dmnte, dmnte, dmnte, _absn},
/*STRING */ {dmnte, dmnte, dmnte, dmnte, dmnte, _absn, _absn, dmnte, dmnte, dmnte, dmnte},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, dmnte, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, dmnte, _absn, _absn, _absn},
/*FUNC */ {dmnte, dmnte, dmnte, dmnte, dmnte, dmnte, dmnte, dmnte, dmnte, dmnte, dmnte},
/*ERROR */ {dmnte, dmnte, dmnte, dmnte, dmnte, _absn, _absn, dmnte, dmnte, dmnte, dmnte},
/*NULL */ {_n2__, _n2__, dmnte, dmnte, dmnte, _absn, _absn, dmnte, dmnte, _null, _absn},
/*ABSENT */ {_n2__, _n2__, dmnte, _absn, dmnte, _absn, _absn, dmnte, dmnte, _absn, _absn},
}
func BIF_dot_minus(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -460,19 +497,23 @@ func dottimes_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromFloat(input1.AcquireFloatValue() * input2.AcquireFloatValue())
}
func dttte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary(".*", input1, input2)
}
var dottimes_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {dottimes_i_ii, dottimes_f_if, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___},
/*FLOAT */ {dottimes_f_fi, dottimes_f_ff, _erro, _1___, _erro, _absn, _absn, _erro, _erro, _1___, _1___},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_n2__, _n2__, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_2___, _2___, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*ABSENT */ {_2___, _2___, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {dottimes_i_ii, dottimes_f_if, dttte, _1___, dttte, _absn, _absn, dttte, dttte, _1___, _1___},
/*FLOAT */ {dottimes_f_fi, dottimes_f_ff, dttte, _1___, dttte, _absn, _absn, dttte, dttte, _1___, _1___},
/*BOOL */ {dttte, dttte, dttte, dttte, dttte, _absn, _absn, dttte, dttte, dttte, dttte},
/*VOID */ {_n2__, _n2__, dttte, _void, dttte, _absn, _absn, dttte, dttte, dttte, _absn},
/*STRING */ {dttte, dttte, dttte, dttte, dttte, _absn, _absn, dttte, dttte, dttte, dttte},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, dttte, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, dttte, _absn, _absn, _absn},
/*FUNC */ {dttte, dttte, dttte, dttte, dttte, dttte, dttte, dttte, dttte, dttte, dttte},
/*ERROR */ {dttte, dttte, dttte, dttte, dttte, _absn, _absn, dttte, dttte, dttte, dttte},
/*NULL */ {_2___, _2___, dttte, dttte, dttte, _absn, _absn, dttte, dttte, dttte, _absn},
/*ABSENT */ {_2___, _2___, dttte, _absn, dttte, _absn, _absn, dttte, dttte, _absn, _absn},
}
func BIF_dot_times(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -496,19 +537,23 @@ func dotdivide_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromFloat(input1.AcquireFloatValue() / input2.AcquireFloatValue())
}
func ddvte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("./", input1, input2)
}
var dotdivide_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {dotdivide_i_ii, dotdivide_f_if, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*FLOAT */ {dotdivide_f_fi, dotdivide_f_ff, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*ABSENT */ {_2___, _2___, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {dotdivide_i_ii, dotdivide_f_if, ddvte, _void, ddvte, _absn, _absn, ddvte, ddvte, ddvte, _1___},
/*FLOAT */ {dotdivide_f_fi, dotdivide_f_ff, ddvte, _void, ddvte, _absn, _absn, ddvte, ddvte, ddvte, _1___},
/*BOOL */ {ddvte, ddvte, ddvte, ddvte, ddvte, _absn, _absn, ddvte, ddvte, ddvte, ddvte},
/*VOID */ {_void, _void, ddvte, _void, ddvte, _absn, _absn, ddvte, ddvte, ddvte, _absn},
/*STRING */ {ddvte, ddvte, ddvte, ddvte, ddvte, _absn, _absn, ddvte, ddvte, ddvte, ddvte},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, ddvte, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, ddvte, _absn, _absn, _absn},
/*FUNC */ {ddvte, ddvte, ddvte, ddvte, ddvte, ddvte, ddvte, ddvte, ddvte, ddvte, ddvte},
/*ERROR */ {ddvte, ddvte, ddvte, ddvte, ddvte, _absn, _absn, ddvte, ddvte, ddvte, ddvte},
/*NULL */ {ddvte, ddvte, ddvte, ddvte, ddvte, _absn, _absn, ddvte, ddvte, ddvte, _absn},
/*ABSENT */ {_2___, _2___, ddvte, _absn, ddvte, _absn, _absn, ddvte, ddvte, _absn, _absn},
}
func BIF_dot_divide(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -557,19 +602,23 @@ func dotidivide_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromFloat(math.Floor(input1.AcquireFloatValue() / input2.AcquireFloatValue()))
}
func didte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary(".//", input1, input2)
}
var dotidivide_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {dotidivide_i_ii, dotidivide_f_if, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*FLOAT */ {dotidivide_f_fi, dotidivide_f_ff, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*ABSENT */ {_2___, _2___, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*INT */ {dotidivide_i_ii, dotidivide_f_if, didte, _void, didte, _absn, _absn, didte, didte, didte, _1___},
/*FLOAT */ {dotidivide_f_fi, dotidivide_f_ff, didte, _void, didte, _absn, _absn, didte, didte, didte, _1___},
/*BOOL */ {didte, didte, didte, didte, didte, _absn, _absn, didte, didte, didte, didte},
/*VOID */ {_void, _void, didte, _void, didte, _absn, _absn, didte, didte, didte, _absn},
/*STRING */ {didte, didte, didte, didte, didte, _absn, _absn, didte, didte, didte, didte},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, didte, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, didte, _absn, _absn, _absn},
/*FUNC */ {didte, didte, didte, didte, didte, didte, didte, didte, didte, didte, didte},
/*ERROR */ {didte, didte, didte, didte, didte, _absn, _absn, didte, didte, didte, didte},
/*NULL */ {didte, didte, didte, didte, didte, _absn, _absn, didte, didte, didte, _absn},
/*ABSENT */ {_2___, _2___, didte, _absn, didte, _absn, _absn, didte, didte, didte, _absn},
}
func BIF_dot_int_divide(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -621,19 +670,23 @@ func modulus_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromFloat(a - b*math.Floor(a/b))
}
func modte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("%", input1, input2)
}
var modulus_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {modulus_i_ii, modulus_f_if, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*FLOAT */ {modulus_f_fi, modulus_f_ff, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*ABSENT */ {_i0__, _f0__, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {modulus_i_ii, modulus_f_if, modte, _void, modte, _absn, _absn, modte, modte, modte, _1___},
/*FLOAT */ {modulus_f_fi, modulus_f_ff, modte, _void, modte, _absn, _absn, modte, modte, modte, _1___},
/*BOOL */ {modte, modte, modte, modte, modte, _absn, _absn, modte, modte, modte, modte},
/*VOID */ {_void, _void, modte, _void, modte, _absn, _absn, modte, modte, modte, _absn},
/*STRING */ {modte, modte, modte, modte, modte, _absn, _absn, modte, modte, modte, modte},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, modte, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, modte, _absn, _absn, _absn},
/*FUNC */ {modte, modte, modte, modte, modte, modte, modte, modte, modte, modte, modte},
/*ERROR */ {modte, modte, modte, modte, modte, _absn, _absn, modte, modte, modte, modte},
/*NULL */ {modte, modte, modte, modte, modte, _absn, _absn, modte, modte, modte, _absn},
/*ABSENT */ {_i0__, _f0__, modte, _absn, modte, _absn, _absn, modte, modte, _absn, _absn},
}
func BIF_modulus(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -685,7 +738,7 @@ func imodexp(a, e, m int64) int64 {
return c
}
func imodop(input1, input2, input3 *mlrval.Mlrval, iop i_iii_func) *mlrval.Mlrval {
func imodop(input1, input2, input3 *mlrval.Mlrval, iop i_iii_func, funcname string) *mlrval.Mlrval {
if !input1.IsLegit() {
return input1
}
@ -695,37 +748,42 @@ func imodop(input1, input2, input3 *mlrval.Mlrval, iop i_iii_func) *mlrval.Mlrva
if !input3.IsLegit() {
return input3
}
if !input1.IsInt() {
return mlrval.ERROR
}
if !input2.IsInt() {
return mlrval.ERROR
}
if !input3.IsInt() {
return mlrval.ERROR
if !input1.IsInt() || !input2.IsInt() || !input3.IsInt() {
return mlrval.FromTypeErrorTernary(funcname, input1, input2, input3)
}
return mlrval.FromInt(iop(input1.AcquireIntValue(), input2.AcquireIntValue(), input3.AcquireIntValue()))
return mlrval.FromInt(
iop(
input1.AcquireIntValue(),
input2.AcquireIntValue(),
input3.AcquireIntValue(),
),
)
}
func BIF_mod_add(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
return imodop(input1, input2, input3, imodadd)
return imodop(input1, input2, input3, imodadd, "madd")
}
func BIF_mod_sub(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
return imodop(input1, input2, input3, imodsub)
return imodop(input1, input2, input3, imodsub, "msub")
}
func BIF_mod_mul(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
return imodop(input1, input2, input3, imodmul)
return imodop(input1, input2, input3, imodmul, "mmul")
}
func BIF_mod_exp(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
// Pre-check for negative exponent
if input2.IsInt() && input2.AcquireIntValue() < 0 {
return mlrval.ERROR
i2, ok := input2.GetIntValue()
if ok && i2 < 0 {
return mlrval.FromError(
fmt.Errorf(
"mexp: negative exponent disallowed; got %d", i2,
),
)
}
return imodop(input1, input2, input3, imodexp)
return imodop(input1, input2, input3, imodexp, "mexp")
}
// ================================================================
@ -793,19 +851,23 @@ func min_s_ss(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
}
}
func min_te(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("min", input1, input2)
}
var min_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {min_i_ii, min_f_if, _1___, _1___, _1___, _absn, _absn, _erro, _erro, _1___, _1___},
/*FLOAT */ {min_f_fi, min_f_ff, _1___, _1___, _1___, _absn, _absn, _erro, _erro, _1___, _1___},
/*BOOL */ {_2___, _2___, min_b_bb, _1___, _1___, _absn, _absn, _erro, _erro, _1___, _1___},
/*VOID */ {_2___, _2___, _2___, _void, _void, _absn, _absn, _erro, _erro, _1___, _1___},
/*STRING */ {_2___, _2___, _2___, _void, min_s_ss, _absn, _absn, _erro, _erro, _1___, _1___},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_2___, _2___, _2___, _2___, _2___, _absn, _absn, _erro, _erro, _null, _null},
/*ABSENT */ {_2___, _2___, _2___, _2___, _2___, _absn, _absn, _erro, _erro, _null, _absn},
/*INT */ {min_i_ii, min_f_if, _1___, _1___, _1___, _absn, _absn, min_te, min_te, _1___, _1___},
/*FLOAT */ {min_f_fi, min_f_ff, _1___, _1___, _1___, _absn, _absn, min_te, min_te, _1___, _1___},
/*BOOL */ {_2___, _2___, min_b_bb, _1___, _1___, _absn, _absn, min_te, min_te, _1___, _1___},
/*VOID */ {_2___, _2___, _2___, _void, _void, _absn, _absn, min_te, min_te, _1___, _1___},
/*STRING */ {_2___, _2___, _2___, _void, min_s_ss, _absn, _absn, min_te, min_te, _1___, _1___},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, min_te, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, min_te, _absn, _absn, _absn},
/*FUNC */ {min_te, min_te, min_te, min_te, min_te, min_te, min_te, min_te, min_te, min_te, min_te},
/*ERROR */ {min_te, min_te, min_te, min_te, min_te, _absn, _absn, min_te, min_te, min_te, min_te},
/*NULL */ {_2___, _2___, _2___, _2___, _2___, _absn, _absn, min_te, min_te, _null, _null},
/*ABSENT */ {_2___, _2___, _2___, _2___, _2___, _absn, _absn, min_te, min_te, _null, _absn},
}
// BIF_min_binary is not a direct DSL function. It's a helper here,
@ -853,6 +915,10 @@ func bif_min_unary_map(input1 *mlrval.Mlrval) *mlrval.Mlrval {
// if this is defined statically. So, we use a "package init" function.
var min_unary_dispositions = [mlrval.MT_DIM]UnaryFunc{}
func min_unary_te(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorUnary("min", input1)
}
func init() {
min_unary_dispositions = [mlrval.MT_DIM]UnaryFunc{
/*INT */ _1u___,
@ -862,8 +928,8 @@ func init() {
/*STRING */ _1u___,
/*ARRAY */ bif_min_unary_array,
/*MAP */ bif_min_unary_map,
/*FUNC */ _erro1,
/*ERROR */ _erro1,
/*FUNC */ min_unary_te,
/*ERROR */ min_unary_te,
/*NULL */ _null1,
/*ABSENT */ _absn1,
}
@ -955,19 +1021,23 @@ func max_s_ss(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
}
}
func max_te(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("max", input1, input2)
}
var max_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {max_i_ii, max_f_if, _2___, _2___, _2___, _absn, _absn, _erro, _erro, _null, _1___},
/*FLOAT */ {max_f_fi, max_f_ff, _2___, _2___, _2___, _absn, _absn, _erro, _erro, _null, _1___},
/*BOOL */ {_1___, _1___, max_b_bb, _2___, _2___, _absn, _absn, _erro, _erro, _null, _1___},
/*VOID */ {_1___, _1___, _1___, _void, _2___, _absn, _absn, _erro, _erro, _null, _1___},
/*STRING */ {_1___, _1___, _1___, _1___, max_s_ss, _absn, _absn, _erro, _erro, _null, _1___},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _null, _erro},
/*NULL */ {_null, _null, _null, _null, _null, _absn, _absn, _erro, _null, _null, _absn},
/*ABSENT */ {_2___, _2___, _2___, _2___, _2___, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {max_i_ii, max_f_if, _2___, _2___, _2___, _absn, _absn, max_te, max_te, _null, _1___},
/*FLOAT */ {max_f_fi, max_f_ff, _2___, _2___, _2___, _absn, _absn, max_te, max_te, _null, _1___},
/*BOOL */ {_1___, _1___, max_b_bb, _2___, _2___, _absn, _absn, max_te, max_te, _null, _1___},
/*VOID */ {_1___, _1___, _1___, _void, _2___, _absn, _absn, max_te, max_te, _null, _1___},
/*STRING */ {_1___, _1___, _1___, _1___, max_s_ss, _absn, _absn, max_te, max_te, _null, _1___},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, max_te, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, max_te, _absn, _absn, _absn},
/*FUNC */ {max_te, max_te, max_te, max_te, max_te, max_te, max_te, max_te, max_te, max_te, max_te},
/*ERROR */ {max_te, max_te, max_te, max_te, max_te, _absn, _absn, max_te, max_te, _null, max_te},
/*NULL */ {_null, _null, _null, _null, _null, _absn, _absn, max_te, _null, _null, _absn},
/*ABSENT */ {_2___, _2___, _2___, _2___, _2___, _absn, _absn, max_te, max_te, _absn, _absn},
}
// BIF_max_binary is not a direct DSL function. It's a helper here,
@ -1015,6 +1085,10 @@ func bif_max_unary_map(input1 *mlrval.Mlrval) *mlrval.Mlrval {
// if this is defined statically. So, we use a "package init" function.
var max_unary_dispositions = [mlrval.MT_DIM]UnaryFunc{}
func max_unary_te(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorUnary("max", input1)
}
func init() {
max_unary_dispositions = [mlrval.MT_DIM]UnaryFunc{
/*INT */ _1u___,
@ -1024,8 +1098,8 @@ func init() {
/*STRING */ _1u___,
/*ARRAY */ bif_max_unary_array,
/*MAP */ bif_max_unary_map,
/*FUNC */ _erro1,
/*ERROR */ _erro1,
/*FUNC */ max_unary_te,
/*ERROR */ max_unary_te,
/*NULL */ _null1,
/*ABSENT */ _absn1,
}

View file

@ -48,6 +48,8 @@
package bifs
import (
"fmt"
"github.com/johnkerl/miller/internal/pkg/lib"
"github.com/johnkerl/miller/internal/pkg/mlrval"
"github.com/johnkerl/miller/internal/pkg/types"
@ -70,7 +72,7 @@ type RegexCaptureBinaryFunc func(input *mlrval.Mlrval, sregex *mlrval.Mlrval) (*
// Helps keystroke-saving for wrapping Go math-library functions
// Examples: cos, sin, etc.
type mathLibUnaryFunc func(float64) float64
type mathLibUnaryFuncWrapper func(input1 *mlrval.Mlrval, f mathLibUnaryFunc) *mlrval.Mlrval
type mathLibUnaryFuncWrapper func(input1 *mlrval.Mlrval, f mathLibUnaryFunc, fname string) *mlrval.Mlrval
// Function-pointer type for binary-operator disposition matrices.
type BinaryFunc func(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval
@ -91,11 +93,6 @@ type ComparatorFunc func(*mlrval.Mlrval, *mlrval.Mlrval) int
// reasonable rectangular even after gofmt has been run.
// ----------------------------------------------------------------
// Return error (unary)
func _erro1(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.ERROR
}
// Return absent (unary)
func _absn1(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.ABSENT
@ -126,12 +123,6 @@ func _1u___(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return input1
}
// ----------------------------------------------------------------
// Return error (binary)
func _erro(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.ERROR
}
// Return absent (binary)
func _absn(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.ABSENT
@ -254,3 +245,21 @@ func recurseBinaryFuncOnInput1(binaryFunc BinaryFunc, input1, input2 *mlrval.Mlr
return binaryFunc(input1, input2)
}
}
func type_error_named_argument(
funcname string,
expected_type_name string,
varname string,
varval *mlrval.Mlrval,
) *mlrval.Mlrval {
return mlrval.FromError(
fmt.Errorf(
"%s: %s should be a %s; got type %s with value %s",
funcname,
varname,
expected_type_name,
varval.GetTypeName(),
varval.StringMaybeQuoted(),
),
)
}

View file

@ -11,16 +11,20 @@ func bitwise_not_i_i(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromInt(^input1.AcquireIntValue())
}
func bitwise_not_te(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorUnary("~", input1)
}
var bitwise_not_dispositions = [mlrval.MT_DIM]UnaryFunc{
/*INT */ bitwise_not_i_i,
/*FLOAT */ _erro1,
/*BOOL */ _erro1,
/*FLOAT */ bitwise_not_te,
/*BOOL */ bitwise_not_te,
/*VOID */ _void1,
/*STRING */ _erro1,
/*STRING */ bitwise_not_te,
/*ARRAY */ _absn1,
/*MAP */ _absn1,
/*FUNC */ _erro1,
/*ERROR */ _erro1,
/*FUNC */ bitwise_not_te,
/*ERROR */ bitwise_not_te,
/*NULL */ _null1,
/*ABSENT */ _absn1,
}
@ -51,16 +55,20 @@ func bitcount_i_i(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromInt(int64(a))
}
func bitcount_te(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorUnary("bitcount", input1)
}
var bitcount_dispositions = [mlrval.MT_DIM]UnaryFunc{
/*INT */ bitcount_i_i,
/*FLOAT */ _erro1,
/*BOOL */ _erro1,
/*FLOAT */ bitcount_te,
/*BOOL */ bitcount_te,
/*VOID */ _void1,
/*STRING */ _erro1,
/*STRING */ bitcount_te,
/*ARRAY */ _absn1,
/*MAP */ _absn1,
/*FUNC */ _erro1,
/*ERROR */ _erro1,
/*FUNC */ bitcount_te,
/*ERROR */ bitcount_te,
/*NULL */ _zero1,
/*ABSENT */ _absn1,
}
@ -76,19 +84,23 @@ func bitwise_and_i_ii(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromInt(input1.AcquireIntValue() & input2.AcquireIntValue())
}
func bwandte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("&", input1, input2)
}
var bitwise_and_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {bitwise_and_i_ii, _erro, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*FLOAT */ {_erro, _erro, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _erro, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _erro, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _absn},
/*ABSENT */ {_2___, _erro, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {bitwise_and_i_ii, bwandte, bwandte, _void, bwandte, _absn, _absn, bwandte, bwandte, bwandte, _1___},
/*FLOAT */ {bwandte, bwandte, bwandte, _void, bwandte, _absn, _absn, bwandte, bwandte, bwandte, bwandte},
/*BOOL */ {bwandte, bwandte, bwandte, bwandte, bwandte, _absn, _absn, bwandte, bwandte, bwandte, bwandte},
/*VOID */ {_void, _void, bwandte, _void, bwandte, _absn, _absn, bwandte, bwandte, bwandte, _absn},
/*STRING */ {bwandte, bwandte, bwandte, bwandte, bwandte, _absn, _absn, bwandte, bwandte, bwandte, bwandte},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, bwandte, _absn, bwandte, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, bwandte, _absn, bwandte, _absn},
/*FUNC */ {bwandte, bwandte, bwandte, bwandte, bwandte, bwandte, bwandte, bwandte, bwandte, bwandte, bwandte},
/*ERROR */ {bwandte, bwandte, bwandte, bwandte, bwandte, _absn, _absn, bwandte, bwandte, bwandte, bwandte},
/*NULL */ {bwandte, bwandte, bwandte, bwandte, bwandte, bwandte, bwandte, bwandte, bwandte, bwandte, _absn},
/*ABSENT */ {_2___, bwandte, bwandte, _absn, bwandte, _absn, _absn, bwandte, bwandte, _absn, _absn},
}
func BIF_bitwise_and(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -102,19 +114,23 @@ func bitwise_or_i_ii(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromInt(input1.AcquireIntValue() | input2.AcquireIntValue())
}
func bworte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("|", input1, input2)
}
var bitwise_or_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {bitwise_or_i_ii, _erro, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*FLOAT */ {_erro, _erro, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _erro, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _erro, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _absn},
/*ABSENT */ {_2___, _erro, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {bitwise_or_i_ii, bworte, bworte, _void, bworte, _absn, _absn, bworte, bworte, bworte, _1___},
/*FLOAT */ {bworte, bworte, bworte, _void, bworte, _absn, _absn, bworte, bworte, bworte, bworte},
/*BOOL */ {bworte, bworte, bworte, bworte, bworte, _absn, _absn, bworte, bworte, bworte, bworte},
/*VOID */ {_void, _void, bworte, _void, bworte, _absn, _absn, bworte, bworte, bworte, _absn},
/*STRING */ {bworte, bworte, bworte, bworte, bworte, _absn, _absn, bworte, bworte, bworte, bworte},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, bworte, _absn, bworte, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, bworte, _absn, bworte, _absn},
/*FUNC */ {bworte, bworte, bworte, bworte, bworte, bworte, bworte, bworte, bworte, bworte, bworte},
/*ERROR */ {bworte, bworte, bworte, bworte, bworte, _absn, _absn, bworte, bworte, bworte, bworte},
/*NULL */ {bworte, bworte, bworte, bworte, bworte, bworte, bworte, bworte, bworte, bworte, _absn},
/*ABSENT */ {_2___, bworte, bworte, _absn, bworte, _absn, _absn, bworte, bworte, _absn, _absn},
}
func BIF_bitwise_or(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -128,19 +144,23 @@ func bitwise_xor_i_ii(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromInt(input1.AcquireIntValue() ^ input2.AcquireIntValue())
}
func bwxorte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("^", input1, input2)
}
var bitwise_xor_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {bitwise_xor_i_ii, _erro, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*FLOAT */ {_erro, _erro, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _absn},
/*ABSENT */ {_2___, _erro, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {bitwise_xor_i_ii, bwxorte, bwxorte, _void, bwxorte, _absn, _absn, bwxorte, bwxorte, bwxorte, _1___},
/*FLOAT */ {bwxorte, bwxorte, bwxorte, _void, bwxorte, _absn, _absn, bwxorte, bwxorte, bwxorte, bwxorte},
/*BOOL */ {bwxorte, bwxorte, bwxorte, bwxorte, bwxorte, _absn, _absn, bwxorte, bwxorte, bwxorte, bwxorte},
/*VOID */ {_void, _void, bwxorte, _void, bwxorte, _absn, _absn, bwxorte, bwxorte, bwxorte, _absn},
/*STRING */ {bwxorte, bwxorte, bwxorte, bwxorte, bwxorte, _absn, _absn, bwxorte, bwxorte, bwxorte, bwxorte},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, bwxorte, _absn, _absn, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, bwxorte, _absn, _absn, _absn},
/*FUNC */ {bwxorte, bwxorte, bwxorte, bwxorte, bwxorte, bwxorte, bwxorte, bwxorte, bwxorte, bwxorte, bwxorte},
/*ERROR */ {bwxorte, bwxorte, bwxorte, bwxorte, bwxorte, _absn, _absn, bwxorte, bwxorte, bwxorte, bwxorte},
/*NULL */ {bwxorte, bwxorte, bwxorte, bwxorte, bwxorte, bwxorte, bwxorte, bwxorte, bwxorte, bwxorte, _absn},
/*ABSENT */ {_2___, bwxorte, bwxorte, _absn, bwxorte, _absn, _absn, bwxorte, bwxorte, _absn, _absn},
}
func BIF_bitwise_xor(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -154,19 +174,23 @@ func lsh_i_ii(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromInt(input1.AcquireIntValue() << uint64(input2.AcquireIntValue()))
}
func lshfte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("<<", input1, input2)
}
var left_shift_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {lsh_i_ii, _erro, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*FLOAT */ {_erro, _erro, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _erro, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _erro, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _absn},
/*ABSENT */ {_2___, _erro, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {lsh_i_ii, lshfte, lshfte, _void, lshfte, _absn, _absn, lshfte, lshfte, lshfte, _1___},
/*FLOAT */ {lshfte, lshfte, lshfte, _void, lshfte, _absn, _absn, lshfte, lshfte, lshfte, lshfte},
/*BOOL */ {lshfte, lshfte, lshfte, lshfte, lshfte, _absn, _absn, lshfte, lshfte, lshfte, lshfte},
/*VOID */ {_void, _void, lshfte, _void, lshfte, _absn, _absn, lshfte, lshfte, lshfte, _absn},
/*STRING */ {lshfte, lshfte, lshfte, lshfte, lshfte, _absn, _absn, lshfte, lshfte, lshfte, lshfte},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, lshfte, _absn, lshfte, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, lshfte, _absn, lshfte, _absn},
/*FUNC */ {lshfte, lshfte, lshfte, lshfte, lshfte, lshfte, lshfte, lshfte, lshfte, lshfte, lshfte},
/*ERROR */ {lshfte, lshfte, lshfte, lshfte, lshfte, _absn, _absn, lshfte, lshfte, lshfte, lshfte},
/*NULL */ {lshfte, lshfte, lshfte, lshfte, lshfte, lshfte, lshfte, lshfte, lshfte, lshfte, _absn},
/*ABSENT */ {_2___, lshfte, lshfte, _absn, lshfte, _absn, _absn, lshfte, lshfte, _absn, _absn},
}
func BIF_left_shift(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -180,19 +204,23 @@ func srsh_i_ii(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromInt(input1.AcquireIntValue() >> uint64(input2.AcquireIntValue()))
}
func srste(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary(">>>", input1, input2)
}
var signed_right_shift_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {srsh_i_ii, _erro, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*FLOAT */ {_erro, _erro, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _erro, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _erro, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _absn},
/*ABSENT */ {_2___, _erro, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {srsh_i_ii, srste, srste, _void, srste, _absn, _absn, srste, srste, srste, _1___},
/*FLOAT */ {srste, srste, srste, _void, srste, _absn, _absn, srste, srste, srste, srste},
/*BOOL */ {srste, srste, srste, srste, srste, _absn, _absn, srste, srste, srste, srste},
/*VOID */ {_void, _void, srste, _void, srste, _absn, _absn, srste, srste, srste, _absn},
/*STRING */ {srste, srste, srste, srste, srste, _absn, _absn, srste, srste, srste, srste},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, srste, _absn, srste, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, srste, _absn, srste, _absn},
/*FUNC */ {srste, srste, srste, srste, srste, srste, srste, srste, srste, srste, srste},
/*ERROR */ {srste, srste, srste, srste, srste, _absn, _absn, srste, srste, srste, srste},
/*NULL */ {srste, srste, srste, srste, srste, srste, srste, srste, srste, srste, _absn},
/*ABSENT */ {_2___, srste, srste, _absn, srste, _absn, _absn, srste, srste, _absn, _absn},
}
func BIF_signed_right_shift(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -209,19 +237,23 @@ func ursh_i_ii(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromInt(int64(uc))
}
func rste(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary(">>", input1, input2)
}
var unsigned_right_shift_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {ursh_i_ii, _erro, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*FLOAT */ {_erro, _erro, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _erro, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _erro, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _absn},
/*ABSENT */ {_2___, _erro, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {ursh_i_ii, rste, rste, _void, rste, _absn, _absn, rste, rste, rste, _1___},
/*FLOAT */ {rste, rste, rste, _void, rste, _absn, _absn, rste, rste, rste, rste},
/*BOOL */ {rste, rste, rste, rste, rste, _absn, _absn, rste, rste, rste, rste},
/*VOID */ {_void, _void, rste, _void, rste, _absn, _absn, rste, rste, rste, _absn},
/*STRING */ {rste, rste, rste, rste, rste, _absn, _absn, rste, rste, rste, rste},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, rste, _absn, rste, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, rste, _absn, rste, _absn},
/*FUNC */ {rste, rste, rste, rste, rste, rste, rste, rste, rste, rste, rste},
/*ERROR */ {rste, rste, rste, rste, rste, _absn, _absn, rste, rste, rste, rste},
/*NULL */ {rste, rste, rste, rste, rste, rste, rste, rste, rste, rste, _absn},
/*ABSENT */ {_2___, rste, rste, _absn, rste, _absn, _absn, rste, rste, _absn, _absn},
}
func BIF_unsigned_right_shift(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {

View file

@ -12,7 +12,7 @@ func BIF_logical_NOT(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if input1.IsBool() {
return mlrval.FromBool(!input1.AcquireBoolValue())
} else {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("!", input1)
}
}
@ -20,7 +20,7 @@ func BIF_logical_AND(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if input1.IsBool() && input2.IsBool() {
return mlrval.FromBool(input1.AcquireBoolValue() && input2.AcquireBoolValue())
} else {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("&&", input1)
}
}
@ -28,7 +28,7 @@ func BIF_logical_OR(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if input1.IsBool() && input2.IsBool() {
return mlrval.FromBool(input1.AcquireBoolValue() || input2.AcquireBoolValue())
} else {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("||", input1)
}
}
@ -36,6 +36,6 @@ func BIF_logical_XOR(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if input1.IsBool() && input2.IsBool() {
return mlrval.FromBool(input1.AcquireBoolValue() != input2.AcquireBoolValue())
} else {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("^^", input1)
}
}

View file

@ -270,111 +270,139 @@ func ne_b_mm(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
// if this is defined statically. So, we use a "package init" function.
var eq_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{}
func eqte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("==", input1, input2)
}
func init() {
eq_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {eq_b_ii, eq_b_if, _fals, eq_b_xs, eq_b_xs, _fals, _fals, _erro, _erro, _fals, _absn},
/*FLOAT */ {eq_b_fi, eq_b_ff, _fals, eq_b_xs, eq_b_xs, _fals, _fals, _erro, _erro, _fals, _absn},
/*BOOL */ {_fals, _fals, eq_b_bb, _fals, _fals, _fals, _fals, _erro, _erro, _fals, _absn},
/*VOID */ {eq_b_sx, eq_b_sx, _fals, eq_b_ss, eq_b_ss, _fals, _fals, _erro, _erro, _fals, _absn},
/*STRING */ {eq_b_sx, eq_b_sx, _fals, eq_b_ss, eq_b_ss, _fals, _fals, _erro, _erro, _fals, _absn},
/*ARRAY */ {_fals, _fals, _fals, _fals, _fals, eq_b_aa, _fals, _erro, _erro, _fals, _absn},
/*MAP */ {_fals, _fals, _fals, _fals, _fals, _fals, eq_b_mm, _erro, _erro, _fals, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*NULL */ {_fals, _fals, _fals, _fals, _fals, _fals, _fals, _erro, _erro, _true, _absn},
/*ABSENT */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {eq_b_ii, eq_b_if, _fals, eq_b_xs, eq_b_xs, _fals, _fals, eqte, eqte, _fals, _absn},
/*FLOAT */ {eq_b_fi, eq_b_ff, _fals, eq_b_xs, eq_b_xs, _fals, _fals, eqte, eqte, _fals, _absn},
/*BOOL */ {_fals, _fals, eq_b_bb, _fals, _fals, _fals, _fals, eqte, eqte, _fals, _absn},
/*VOID */ {eq_b_sx, eq_b_sx, _fals, eq_b_ss, eq_b_ss, _fals, _fals, eqte, eqte, _fals, _absn},
/*STRING */ {eq_b_sx, eq_b_sx, _fals, eq_b_ss, eq_b_ss, _fals, _fals, eqte, eqte, _fals, _absn},
/*ARRAY */ {_fals, _fals, _fals, _fals, _fals, eq_b_aa, _fals, eqte, eqte, _fals, _absn},
/*MAP */ {_fals, _fals, _fals, _fals, _fals, _fals, eq_b_mm, eqte, eqte, _fals, _absn},
/*FUNC */ {eqte, eqte, eqte, eqte, eqte, eqte, eqte, eqte, eqte, eqte, eqte},
/*ERROR */ {eqte, eqte, eqte, eqte, eqte, eqte, eqte, eqte, eqte, eqte, eqte},
/*NULL */ {_fals, _fals, _fals, _fals, _fals, _fals, _fals, eqte, eqte, _true, _absn},
/*ABSENT */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, eqte, eqte, _absn, _absn},
}
}
func nete(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("!=", input1, input2)
}
var ne_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {ne_b_ii, ne_b_if, _true, ne_b_xs, ne_b_xs, _true, _true, _erro, _erro, _true, _absn},
/*FLOAT */ {ne_b_fi, ne_b_ff, _true, ne_b_xs, ne_b_xs, _true, _true, _erro, _erro, _true, _absn},
/*BOOL */ {_true, _true, ne_b_bb, _true, _true, _true, _true, _erro, _erro, _true, _absn},
/*VOID */ {ne_b_sx, ne_b_sx, _true, ne_b_ss, ne_b_ss, _true, _true, _erro, _erro, _true, _absn},
/*STRING */ {ne_b_sx, ne_b_sx, _true, ne_b_ss, ne_b_ss, _true, _true, _erro, _erro, _true, _absn},
/*ARRAY */ {_true, _true, _true, _true, _true, ne_b_aa, _true, _erro, _erro, _true, _absn},
/*MAP */ {_true, _true, _true, _true, _true, _true, ne_b_mm, _erro, _erro, _true, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*NULL */ {_true, _true, _true, _true, _true, _true, _true, _erro, _erro, _fals, _absn},
/*ABSENT */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _erro, _absn, _absn},
/*INT */ {ne_b_ii, ne_b_if, _true, ne_b_xs, ne_b_xs, _true, _true, nete, nete, _true, _absn},
/*FLOAT */ {ne_b_fi, ne_b_ff, _true, ne_b_xs, ne_b_xs, _true, _true, nete, nete, _true, _absn},
/*BOOL */ {_true, _true, ne_b_bb, _true, _true, _true, _true, nete, nete, _true, _absn},
/*VOID */ {ne_b_sx, ne_b_sx, _true, ne_b_ss, ne_b_ss, _true, _true, nete, nete, _true, _absn},
/*STRING */ {ne_b_sx, ne_b_sx, _true, ne_b_ss, ne_b_ss, _true, _true, nete, nete, _true, _absn},
/*ARRAY */ {_true, _true, _true, _true, _true, ne_b_aa, _true, nete, nete, _true, _absn},
/*MAP */ {_true, _true, _true, _true, _true, _true, ne_b_mm, nete, nete, _true, _absn},
/*FUNC */ {nete, nete, nete, nete, nete, nete, nete, nete, nete, nete, nete},
/*ERROR */ {nete, nete, nete, nete, nete, nete, nete, nete, nete, nete, nete},
/*NULL */ {_true, _true, _true, _true, _true, _true, _true, nete, nete, _fals, _absn},
/*ABSENT */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, nete, nete, _absn, _absn},
}
func gtte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary(">", input1, input2)
}
var gt_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {gt_b_ii, gt_b_if, _fals, gt_b_xs, gt_b_xs, _fals, _fals, _erro, _erro, _fals, _absn},
/*FLOAT */ {gt_b_fi, gt_b_ff, _fals, gt_b_xs, gt_b_xs, _fals, _fals, _erro, _erro, _fals, _absn},
/*BOOL */ {_fals, _fals, gt_b_bb, _fals, _fals, _fals, _fals, _erro, _erro, _fals, _absn},
/*VOID */ {gt_b_sx, gt_b_sx, _fals, gt_b_ss, gt_b_ss, _fals, _fals, _erro, _erro, _fals, _absn},
/*STRING */ {gt_b_sx, gt_b_sx, _fals, gt_b_ss, gt_b_ss, _fals, _fals, _erro, _erro, _fals, _absn},
/*ARRAY */ {_fals, _fals, _fals, _fals, _fals, _erro, _fals, _erro, _erro, _fals, _absn},
/*MAP */ {_fals, _fals, _fals, _fals, _fals, _fals, _erro, _erro, _erro, _fals, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _fals, _erro},
/*NULL */ {_true, _true, _true, _true, _true, _absn, _absn, _erro, _true, _fals, _fals},
/*ABSENT */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _erro, _true, _absn},
/*INT */ {gt_b_ii, gt_b_if, _fals, gt_b_xs, gt_b_xs, _fals, _fals, gtte, gtte, _fals, _absn},
/*FLOAT */ {gt_b_fi, gt_b_ff, _fals, gt_b_xs, gt_b_xs, _fals, _fals, gtte, gtte, _fals, _absn},
/*BOOL */ {_fals, _fals, gt_b_bb, _fals, _fals, _fals, _fals, gtte, gtte, _fals, _absn},
/*VOID */ {gt_b_sx, gt_b_sx, _fals, gt_b_ss, gt_b_ss, _fals, _fals, gtte, gtte, _fals, _absn},
/*STRING */ {gt_b_sx, gt_b_sx, _fals, gt_b_ss, gt_b_ss, _fals, _fals, gtte, gtte, _fals, _absn},
/*ARRAY */ {_fals, _fals, _fals, _fals, _fals, gtte, _fals, gtte, gtte, _fals, _absn},
/*MAP */ {_fals, _fals, _fals, _fals, _fals, _fals, gtte, gtte, gtte, _fals, _absn},
/*FUNC */ {gtte, gtte, gtte, gtte, gtte, gtte, gtte, gtte, gtte, gtte, gtte},
/*ERROR */ {gtte, gtte, gtte, gtte, gtte, gtte, gtte, gtte, gtte, _fals, gtte},
/*NULL */ {_true, _true, _true, _true, _true, _absn, _absn, gtte, _true, _fals, _fals},
/*ABSENT */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, gtte, gtte, _true, _absn},
}
func gete(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary(">=", input1, input2)
}
var ge_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {ge_b_ii, ge_b_if, _fals, ge_b_xs, ge_b_xs, _fals, _fals, _erro, _erro, _fals, _absn},
/*FLOAT */ {ge_b_fi, ge_b_ff, _fals, ge_b_xs, ge_b_xs, _fals, _fals, _erro, _erro, _fals, _absn},
/*BOOL */ {_fals, _fals, ge_b_bb, _fals, _fals, _fals, _fals, _erro, _erro, _fals, _absn},
/*VOID */ {ge_b_sx, ge_b_sx, _fals, ge_b_ss, ge_b_ss, _fals, _fals, _erro, _erro, _fals, _absn},
/*STRING */ {ge_b_sx, ge_b_sx, _fals, ge_b_ss, ge_b_ss, _fals, _fals, _erro, _erro, _fals, _absn},
/*ARRAY */ {_fals, _fals, _fals, _fals, _fals, _erro, _fals, _erro, _erro, _fals, _absn},
/*MAP */ {_fals, _fals, _fals, _fals, _fals, _fals, _erro, _erro, _erro, _fals, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _fals, _erro},
/*NULL */ {_true, _true, _true, _true, _true, _absn, _absn, _erro, _true, _true, _fals},
/*ABSENT */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _erro, _true, _absn},
/*INT */ {ge_b_ii, ge_b_if, _fals, ge_b_xs, ge_b_xs, _fals, _fals, gete, gete, _fals, _absn},
/*FLOAT */ {ge_b_fi, ge_b_ff, _fals, ge_b_xs, ge_b_xs, _fals, _fals, gete, gete, _fals, _absn},
/*BOOL */ {_fals, _fals, ge_b_bb, _fals, _fals, _fals, _fals, gete, gete, _fals, _absn},
/*VOID */ {ge_b_sx, ge_b_sx, _fals, ge_b_ss, ge_b_ss, _fals, _fals, gete, gete, _fals, _absn},
/*STRING */ {ge_b_sx, ge_b_sx, _fals, ge_b_ss, ge_b_ss, _fals, _fals, gete, gete, _fals, _absn},
/*ARRAY */ {_fals, _fals, _fals, _fals, _fals, gete, _fals, gete, gete, _fals, _absn},
/*MAP */ {_fals, _fals, _fals, _fals, _fals, _fals, gete, gete, gete, _fals, _absn},
/*FUNC */ {gete, gete, gete, gete, gete, gete, gete, gete, gete, gete, gete},
/*ERROR */ {gete, gete, gete, gete, gete, gete, gete, gete, gete, _fals, gete},
/*NULL */ {_true, _true, _true, _true, _true, _absn, _absn, gete, _true, _true, _fals},
/*ABSENT */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, gete, gete, _true, _absn},
}
func ltte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("<", input1, input2)
}
var lt_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {lt_b_ii, lt_b_if, _fals, lt_b_xs, lt_b_xs, _fals, _fals, _erro, _erro, _true, _absn},
/*FLOAT */ {lt_b_fi, lt_b_ff, _fals, lt_b_xs, lt_b_xs, _fals, _fals, _erro, _erro, _true, _absn},
/*BOOL */ {_fals, _fals, lt_b_bb, _fals, _fals, _fals, _fals, _erro, _erro, _true, _absn},
/*VOID */ {lt_b_sx, lt_b_sx, _fals, lt_b_ss, lt_b_ss, _fals, _fals, _erro, _erro, _true, _absn},
/*STRING */ {lt_b_sx, lt_b_sx, _fals, lt_b_ss, lt_b_ss, _fals, _fals, _erro, _erro, _true, _absn},
/*ARRAY */ {_fals, _fals, _fals, _fals, _fals, _erro, _fals, _erro, _erro, _absn, _absn},
/*MAP */ {_fals, _fals, _fals, _fals, _fals, _fals, _erro, _erro, _erro, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _true, _erro},
/*NULL */ {_fals, _fals, _fals, _fals, _fals, _absn, _absn, _erro, _fals, _fals, _true},
/*ABSENT */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _erro, _fals, _absn},
/*INT */ {lt_b_ii, lt_b_if, _fals, lt_b_xs, lt_b_xs, _fals, _fals, ltte, ltte, _true, _absn},
/*FLOAT */ {lt_b_fi, lt_b_ff, _fals, lt_b_xs, lt_b_xs, _fals, _fals, ltte, ltte, _true, _absn},
/*BOOL */ {_fals, _fals, lt_b_bb, _fals, _fals, _fals, _fals, ltte, ltte, _true, _absn},
/*VOID */ {lt_b_sx, lt_b_sx, _fals, lt_b_ss, lt_b_ss, _fals, _fals, ltte, ltte, _true, _absn},
/*STRING */ {lt_b_sx, lt_b_sx, _fals, lt_b_ss, lt_b_ss, _fals, _fals, ltte, ltte, _true, _absn},
/*ARRAY */ {_fals, _fals, _fals, _fals, _fals, ltte, _fals, ltte, ltte, _absn, _absn},
/*MAP */ {_fals, _fals, _fals, _fals, _fals, _fals, ltte, ltte, ltte, _absn, _absn},
/*FUNC */ {ltte, ltte, ltte, ltte, ltte, ltte, ltte, ltte, ltte, ltte, ltte},
/*ERROR */ {ltte, ltte, ltte, ltte, ltte, ltte, ltte, ltte, ltte, _true, ltte},
/*NULL */ {_fals, _fals, _fals, _fals, _fals, _absn, _absn, ltte, _fals, _fals, _true},
/*ABSENT */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, ltte, ltte, _fals, _absn},
}
func lete(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("<=", input1, input2)
}
var le_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {le_b_ii, le_b_if, _fals, le_b_xs, le_b_xs, _fals, _fals, _erro, _erro, _true, _absn},
/*FLOAT */ {le_b_fi, le_b_ff, _fals, le_b_xs, le_b_xs, _fals, _fals, _erro, _erro, _true, _absn},
/*BOOL */ {_fals, _fals, le_b_bb, _fals, _fals, _fals, _fals, _erro, _erro, _true, _absn},
/*VOID */ {le_b_sx, le_b_sx, _fals, le_b_ss, le_b_ss, _fals, _fals, _erro, _erro, _true, _absn},
/*STRING */ {le_b_sx, le_b_sx, _fals, le_b_ss, le_b_ss, _fals, _fals, _erro, _erro, _true, _absn},
/*ARRAY */ {_fals, _fals, _fals, _fals, _fals, _erro, _fals, _erro, _erro, _absn, _absn},
/*MAP */ {_fals, _fals, _fals, _fals, _fals, _fals, _erro, _erro, _erro, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _true, _erro},
/*NULL */ {_fals, _fals, _fals, _fals, _fals, _absn, _absn, _erro, _fals, _true, _true},
/*ABSENT */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _erro, _fals, _absn},
/*INT */ {le_b_ii, le_b_if, _fals, le_b_xs, le_b_xs, _fals, _fals, lete, lete, _true, _absn},
/*FLOAT */ {le_b_fi, le_b_ff, _fals, le_b_xs, le_b_xs, _fals, _fals, lete, lete, _true, _absn},
/*BOOL */ {_fals, _fals, le_b_bb, _fals, _fals, _fals, _fals, lete, lete, _true, _absn},
/*VOID */ {le_b_sx, le_b_sx, _fals, le_b_ss, le_b_ss, _fals, _fals, lete, lete, _true, _absn},
/*STRING */ {le_b_sx, le_b_sx, _fals, le_b_ss, le_b_ss, _fals, _fals, lete, lete, _true, _absn},
/*ARRAY */ {_fals, _fals, _fals, _fals, _fals, lete, _fals, lete, lete, _absn, _absn},
/*MAP */ {_fals, _fals, _fals, _fals, _fals, _fals, lete, lete, lete, _absn, _absn},
/*FUNC */ {lete, lete, lete, lete, lete, lete, lete, lete, lete, lete, lete},
/*ERROR */ {lete, lete, lete, lete, lete, lete, lete, lete, lete, _true, lete},
/*NULL */ {_fals, _fals, _fals, _fals, _fals, _absn, _absn, lete, _fals, _true, _true},
/*ABSENT */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, lete, lete, _fals, _absn},
}
func cmpte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("<=>", input1, input2)
}
var cmp_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {cmp_b_ii, cmp_b_if, _less, cmp_b_xs, cmp_b_xs, _less, _less, _erro, _erro, _true, _absn},
/*FLOAT */ {cmp_b_fi, cmp_b_ff, _less, cmp_b_xs, cmp_b_xs, _less, _less, _erro, _erro, _true, _absn},
/*BOOL */ {_more, _more, cmp_b_bb, _less, _less, _less, _less, _erro, _erro, _true, _absn},
/*VOID */ {cmp_b_sx, cmp_b_sx, _more, cmp_b_ss, cmp_b_ss, _less, _less, _erro, _erro, _true, _absn},
/*STRING */ {cmp_b_sx, cmp_b_sx, _more, cmp_b_ss, cmp_b_ss, _less, _less, _erro, _erro, _true, _absn},
/*ARRAY */ {_more, _more, _more, _more, _more, _erro, _less, _erro, _erro, _absn, _absn},
/*MAP */ {_more, _more, _more, _more, _more, _more, _erro, _erro, _erro, _absn, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _true, _erro},
/*NULL */ {_more, _more, _more, _more, _more, _absn, _absn, _erro, _more, _same, _true},
/*ABSENT */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _erro, _more, _absn},
/*INT */ {cmp_b_ii, cmp_b_if, _less, cmp_b_xs, cmp_b_xs, _less, _less, cmpte, cmpte, _true, _absn},
/*FLOAT */ {cmp_b_fi, cmp_b_ff, _less, cmp_b_xs, cmp_b_xs, _less, _less, cmpte, cmpte, _true, _absn},
/*BOOL */ {_more, _more, cmp_b_bb, _less, _less, _less, _less, cmpte, cmpte, _true, _absn},
/*VOID */ {cmp_b_sx, cmp_b_sx, _more, cmp_b_ss, cmp_b_ss, _less, _less, cmpte, cmpte, _true, _absn},
/*STRING */ {cmp_b_sx, cmp_b_sx, _more, cmp_b_ss, cmp_b_ss, _less, _less, cmpte, cmpte, _true, _absn},
/*ARRAY */ {_more, _more, _more, _more, _more, cmpte, _less, cmpte, cmpte, _absn, _absn},
/*MAP */ {_more, _more, _more, _more, _more, _more, cmpte, cmpte, cmpte, _absn, _absn},
/*FUNC */ {cmpte, cmpte, cmpte, cmpte, cmpte, cmpte, cmpte, cmpte, cmpte, cmpte, cmpte},
/*ERROR */ {cmpte, cmpte, cmpte, cmpte, cmpte, cmpte, cmpte, cmpte, cmpte, _true, cmpte},
/*NULL */ {_more, _more, _more, _more, _more, _absn, _absn, cmpte, _more, _same, _true},
/*ABSENT */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, cmpte, cmpte, _more, _absn},
}
func BIF_equals(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {

View file

@ -65,6 +65,10 @@ func depth_from_scalar(input1 *mlrval.Mlrval) *mlrval.Mlrval {
// if this is defined statically. So, we use a "package init" function.
var depth_dispositions = [mlrval.MT_DIM]UnaryFunc{}
func depth_te(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorUnary("depth", input1)
}
func init() {
depth_dispositions = [mlrval.MT_DIM]UnaryFunc{
/*INT */ depth_from_scalar,
@ -74,8 +78,8 @@ func init() {
/*STRING */ depth_from_scalar,
/*ARRAY */ depth_from_array,
/*MAP */ depth_from_map,
/*FUNC */ _erro1,
/*ERROR */ _erro1,
/*FUNC */ depth_te,
/*ERROR */ depth_te,
/*NULL */ _zero1,
/*ABSENT */ _absn1,
}
@ -134,6 +138,10 @@ func leafcount_from_scalar(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromInt(1)
}
func leafcount_te(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorUnary("leafcount", input1)
}
var leafcount_dispositions = [mlrval.MT_DIM]UnaryFunc{
/*INT */ leafcount_from_scalar,
/*FLOAT */ leafcount_from_scalar,
@ -142,8 +150,8 @@ var leafcount_dispositions = [mlrval.MT_DIM]UnaryFunc{
/*STRING */ leafcount_from_scalar,
/*ARRAY */ leafcount_from_array,
/*MAP */ leafcount_from_map,
/*FUNC */ _erro1,
/*ERROR */ _erro1,
/*FUNC */ leafcount_te,
/*ERROR */ leafcount_te,
/*NULL */ _zero1,
/*ABSENT */ _absn1,
}
@ -158,7 +166,7 @@ func has_key_in_array(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FALSE
}
if !input2.IsInt() {
return mlrval.ERROR
return mlrval.FromNotIntError("haskey", input2)
}
arrayval := input1.AcquireArrayValue()
_, ok := unaliasArrayIndex(&arrayval, int(input2.AcquireIntValue()))
@ -169,7 +177,7 @@ func has_key_in_map(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if input2.IsString() || input2.IsInt() {
return mlrval.FromBool(input1.AcquireMapValue().Has(input2.String()))
} else {
return mlrval.ERROR
return mlrval.FromNotNamedTypeError("haskey", input2, "string or int")
}
}
@ -179,7 +187,7 @@ func BIF_haskey(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
} else if input1.IsMap() {
return has_key_in_map(input1, input2)
} else {
return mlrval.ERROR
return mlrval.FromNotCollectionError("haskey", input1)
}
}
@ -204,10 +212,10 @@ func BIF_concat(mlrvals []*mlrval.Mlrval) *mlrval.Mlrval {
// ================================================================
func BIF_mapselect(mlrvals []*mlrval.Mlrval) *mlrval.Mlrval {
if len(mlrvals) < 1 {
return mlrval.ERROR
return mlrval.FromErrorString("mapselect: received a zero-length array as input")
}
if !mlrvals[0].IsMap() {
return mlrval.ERROR
return mlrval.FromNotMapError("mapselect", mlrvals[0])
}
oldmap := mlrvals[0].AcquireMapValue()
newMap := mlrval.NewMlrmap()
@ -223,11 +231,11 @@ func BIF_mapselect(mlrvals []*mlrval.Mlrval) *mlrval.Mlrval {
if element.IsString() {
newKeys[element.AcquireStringValue()] = true
} else {
return mlrval.ERROR
return mlrval.FromNotStringError("mapselect", element)
}
}
} else {
return mlrval.ERROR
return mlrval.FromNotNamedTypeError("mapselect", selectArg, "string, int, or array")
}
}
@ -245,10 +253,10 @@ func BIF_mapselect(mlrvals []*mlrval.Mlrval) *mlrval.Mlrval {
// ----------------------------------------------------------------
func BIF_mapexcept(mlrvals []*mlrval.Mlrval) *mlrval.Mlrval {
if len(mlrvals) < 1 {
return mlrval.ERROR
return mlrval.FromErrorString("mapexcept: received a zero-length array as input")
}
if !mlrvals[0].IsMap() {
return mlrval.ERROR
return mlrval.FromNotMapError("mapexcept", mlrvals[0])
}
newMap := mlrvals[0].AcquireMapValue().Copy()
@ -262,11 +270,11 @@ func BIF_mapexcept(mlrvals []*mlrval.Mlrval) *mlrval.Mlrval {
if element.IsString() {
newMap.Remove(element.AcquireStringValue())
} else {
return mlrval.ERROR
return mlrval.FromNotStringError("mapselect", element)
}
}
} else {
return mlrval.ERROR
return mlrval.FromNotNamedTypeError("mapexcept", exceptArg, "string, int, or array")
}
}
@ -282,13 +290,13 @@ func BIF_mapsum(mlrvals []*mlrval.Mlrval) *mlrval.Mlrval {
return mlrvals[0]
}
if mlrvals[0].Type() != mlrval.MT_MAP {
return mlrval.ERROR
return mlrval.FromNotMapError("mapsum", mlrvals[0])
}
newMap := mlrvals[0].AcquireMapValue().Copy()
for _, otherMapArg := range mlrvals[1:] {
if otherMapArg.Type() != mlrval.MT_MAP {
return mlrval.ERROR
return mlrval.FromNotMapError("mapsum", otherMapArg)
}
for pe := otherMapArg.AcquireMapValue().Head; pe != nil; pe = pe.Next {
@ -308,13 +316,13 @@ func BIF_mapdiff(mlrvals []*mlrval.Mlrval) *mlrval.Mlrval {
return mlrvals[0]
}
if !mlrvals[0].IsMap() {
return mlrval.ERROR
return mlrval.FromNotMapError("mapdiff", mlrvals[0])
}
newMap := mlrvals[0].AcquireMapValue().Copy()
for _, otherMapArg := range mlrvals[1:] {
if !otherMapArg.IsMap() {
return mlrval.ERROR
return mlrval.FromNotMapError("mapdiff", otherMapArg)
}
for pe := otherMapArg.AcquireMapValue().Head; pe != nil; pe = pe.Next {
@ -330,7 +338,7 @@ func BIF_mapdiff(mlrvals []*mlrval.Mlrval) *mlrval.Mlrval {
// joink({"a":3,"b":4,"c":5}, ",") -> "a,b,c"
func BIF_joink(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("joink", input2)
}
fieldSeparator := input2.AcquireStringValue()
if input1.IsMap() {
@ -357,7 +365,7 @@ func BIF_joink(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromString(buffer.String())
} else {
return mlrval.ERROR
return mlrval.FromNotCollectionError("joink", input1)
}
}
@ -366,7 +374,7 @@ func BIF_joink(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
// joinv({"a":3,"b":4,"c":5}, ",") -> "3,4,5"
func BIF_joinv(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("joinv", input2)
}
fieldSeparator := input2.AcquireStringValue()
@ -393,7 +401,7 @@ func BIF_joinv(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromString(buffer.String())
} else {
return mlrval.ERROR
return mlrval.FromNotCollectionError("joinv", input1)
}
}
@ -402,11 +410,11 @@ func BIF_joinv(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
// joinkv({"a":3,"b":4,"c":5}, "=", ",") -> "a=3,b=4,c=5"
func BIF_joinkv(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("joinkv", input2)
}
pairSeparator := input2.AcquireStringValue()
if !input3.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("joinkv", input3)
}
fieldSeparator := input3.AcquireStringValue()
@ -438,7 +446,7 @@ func BIF_joinkv(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromString(buffer.String())
} else {
return mlrval.ERROR
return mlrval.FromNotCollectionError("joinkv", input1)
}
}
@ -446,14 +454,14 @@ func BIF_joinkv(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
// splitkv("a=3,b=4,c=5", "=", ",") -> {"a":3,"b":4,"c":5}
func BIF_splitkv(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("splitkv", input1)
}
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("splitkv", input2)
}
pairSeparator := input2.AcquireStringValue()
if !input3.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("splitkv", input3)
}
fieldSeparator := input3.AcquireStringValue()
@ -481,14 +489,14 @@ func BIF_splitkv(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
// splitkvx("a=3,b=4,c=5", "=", ",") -> {"a":"3","b":"4","c":"5"}
func BIF_splitkvx(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("splitkvx", input1)
}
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("splitkvx", input2)
}
pairSeparator := input2.AcquireStringValue()
if !input3.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("splitkvx", input3)
}
fieldSeparator := input3.AcquireStringValue()
@ -517,10 +525,10 @@ func BIF_splitkvx(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
// splitnv("a,b,c", ",") -> {"1":"a","2":"b","3":"c"}
func BIF_splitnv(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("splitnv", input1)
}
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("splitnv", input2)
}
output := mlrval.FromMap(mlrval.NewMlrmap())
@ -539,10 +547,10 @@ func BIF_splitnv(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
// splitnvx("3,4,5", ",") -> {"1":"3","2":"4","3":"5"}
func BIF_splitnvx(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("splitnvx", input1)
}
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("splitnvx", input2)
}
output := mlrval.FromMap(mlrval.NewMlrmap())
@ -561,10 +569,10 @@ func BIF_splitnvx(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
// splita("3,4,5", ",") -> [3,4,5]
func BIF_splita(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("splita", input1)
}
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("splita", input2)
}
fieldSeparator := input2.AcquireStringValue()
@ -585,10 +593,10 @@ func BIF_splita(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
// e.g. splitax("3,4,5", ",") -> ["3","4","5"]
func BIF_splitax(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("splitax", input1)
}
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("splitax", input2)
}
input := input1.AcquireStringValue()
fieldSeparator := input2.AcquireStringValue()
@ -632,7 +640,7 @@ func BIF_get_keys(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromArray(arrayval)
} else {
return mlrval.ERROR
return mlrval.FromNotCollectionError("get_keys", input1)
}
}
@ -657,14 +665,14 @@ func BIF_get_values(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromArray(arrayval)
} else {
return mlrval.ERROR
return mlrval.FromNotCollectionError("get_values", input1)
}
}
// ----------------------------------------------------------------
func BIF_append(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsArray() {
return mlrval.ERROR
return mlrval.FromNotArrayError("append", input1)
}
output := input1.Copy()
@ -681,11 +689,11 @@ func BIF_append(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
func BIF_flatten(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
if input3.IsMap() || input3.IsArray() {
if !input1.IsString() && input1.Type() != mlrval.MT_VOID {
return mlrval.ERROR
return mlrval.FromNotStringError("flatten", input1)
}
prefix := input1.AcquireStringValue()
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("flatten", input2)
}
delimiter := input2.AcquireStringValue()
@ -707,7 +715,7 @@ func BIF_flatten_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
// unflatten({"a.b.c", ".") is {"a": { "b": { "c": 4}}}.
func BIF_unflatten(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("unflatten", input2)
}
if input1.Type() != mlrval.MT_MAP {
return input1
@ -770,12 +778,12 @@ func BIF_json_parse(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if input1.IsVoid() {
return input1
} else if !input1.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("json_parse", input1)
} else {
output := mlrval.FromPending()
err := output.UnmarshalJSON([]byte(input1.AcquireStringValue()))
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
return output
}
@ -784,7 +792,7 @@ func BIF_json_parse(input1 *mlrval.Mlrval) *mlrval.Mlrval {
func BIF_json_stringify_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
outputBytes, err := input1.MarshalJSON(mlrval.JSON_SINGLE_LINE, false)
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
} else {
return mlrval.FromString(string(outputBytes))
}
@ -794,7 +802,7 @@ func BIF_json_stringify_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
var jsonFormatting mlrval.TJSONFormatting = mlrval.JSON_SINGLE_LINE
useMultiline, ok := input2.GetBoolValue()
if !ok {
return mlrval.ERROR
return mlrval.FromNotBooleanError("json_stringify", input2)
}
if useMultiline {
jsonFormatting = mlrval.JSON_MULTILINE
@ -802,7 +810,7 @@ func BIF_json_stringify_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
outputBytes, err := input1.MarshalJSON(jsonFormatting, false)
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
} else {
return mlrval.FromString(string(outputBytes))
}
@ -902,7 +910,8 @@ func MillerSliceAccess(
if lowerIndexMlrval.IsVoid() {
lowerIndex = 1
} else {
return false, mlrval.ERROR, 0, 0
e := mlrval.FromNotNamedTypeError("array/map/slice lower index", lowerIndexMlrval, "int or empty")
return false, e, 0, 0
}
}
upperIndex, ok := upperIndexMlrval.GetIntValue()
@ -910,7 +919,8 @@ func MillerSliceAccess(
if upperIndexMlrval.IsVoid() {
upperIndex = int64(n)
} else {
return false, mlrval.ERROR, 0, 0
e := mlrval.FromNotNamedTypeError("array/map/slice upper index", upperIndexMlrval, "int or empty")
return false, e, 0, 0
}
}

View file

@ -62,22 +62,22 @@ func BIF_sec2gmt_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
}
func BIF_nsec2gmt_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
intValue, ok := input1.GetIntValue()
if !ok {
return mlrval.ERROR
intValue, errValue := input1.GetIntValueOrError("nsec2gmt")
if errValue != nil {
return errValue
}
numDecimalPlaces := 0
return mlrval.FromString(lib.Nsec2GMT(intValue, numDecimalPlaces))
}
func BIF_sec2gmt_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
floatValue, isNumeric := input1.GetNumericToFloatValue()
if !isNumeric {
return input1
floatValue, errValue := input1.GetNumericToFloatValueOrError("sec2gmt")
if errValue != nil {
return errValue
}
numDecimalPlaces, isInt := input2.GetIntValue()
if !isInt {
return mlrval.ERROR
numDecimalPlaces, errValue := input2.GetIntValueOrError("sec2gmt")
if errValue != nil {
return errValue
}
return mlrval.FromString(lib.Sec2GMT(floatValue, int(numDecimalPlaces)))
}
@ -87,9 +87,9 @@ func BIF_nsec2gmt_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !ok {
return input1
}
numDecimalPlaces, isInt := input2.GetIntValue()
if !isInt {
return mlrval.ERROR
numDecimalPlaces, errValue := input2.GetIntValueOrError("nsec2gmt")
if errValue != nil {
return errValue
}
return mlrval.FromString(lib.Nsec2GMT(intValue, int(numDecimalPlaces)))
}
@ -117,9 +117,9 @@ func BIF_sec2localtime_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !isNumeric {
return input1
}
numDecimalPlaces, isInt := input2.GetIntValue()
if !isInt {
return mlrval.ERROR
numDecimalPlaces, errValue := input2.GetIntValueOrError("sec2localtime")
if errValue != nil {
return errValue
}
return mlrval.FromString(lib.Sec2LocalTime(floatValue, int(numDecimalPlaces)))
}
@ -129,9 +129,9 @@ func BIF_nsec2localtime_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !ok {
return input1
}
numDecimalPlaces, isInt := input2.GetIntValue()
if !isInt {
return mlrval.ERROR
numDecimalPlaces, errValue := input2.GetIntValueOrError("nsec2localtime")
if errValue != nil {
return errValue
}
return mlrval.FromString(lib.Nsec2LocalTime(intValue, int(numDecimalPlaces)))
}
@ -141,17 +141,17 @@ func BIF_sec2localtime_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.Ml
if !isNumeric {
return input1
}
numDecimalPlaces, isInt := input2.GetIntValue()
if !isInt {
return mlrval.ERROR
numDecimalPlaces, errValue := input2.GetIntValueOrError("sec2localtime")
if errValue != nil {
return errValue
}
locationString, isString := input3.GetStringValue()
if !isString {
return mlrval.ERROR
locationString, errValue := input3.GetStringValueOrError("sec2localtime")
if errValue != nil {
return errValue
}
location, err := time.LoadLocation(locationString)
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
return mlrval.FromString(lib.Sec2LocationTime(floatValue, int(numDecimalPlaces), location))
}
@ -161,17 +161,17 @@ func BIF_nsec2localtime_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.M
if !isNumeric {
return input1
}
numDecimalPlaces, isInt := input2.GetIntValue()
if !isInt {
return mlrval.ERROR
numDecimalPlaces, errValue := input2.GetIntValueOrError("nsec2localtime")
if errValue != nil {
return errValue
}
locationString, isString := input3.GetStringValue()
if !isString {
return mlrval.ERROR
locationString, errValue := input3.GetStringValueOrError("nsec2localtime")
if errValue != nil {
return errValue
}
location, err := time.LoadLocation(locationString)
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
return mlrval.FromString(lib.Nsec2LocationTime(intValue, int(numDecimalPlaces), location))
}
@ -221,28 +221,28 @@ func BIF_nsec2localdate_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
// ----------------------------------------------------------------
func BIF_localtime2gmt_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("localtime2gmt", input1)
}
return BIF_nsec2gmt_unary(BIF_localtime2nsec_unary(input1))
}
func BIF_localtime2gmt_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("localtime2gmt", input1)
}
return BIF_nsec2gmt_unary(BIF_localtime2nsec_binary(input1, input2))
}
func BIF_gmt2localtime_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("gmt2localtime2", input1)
}
return BIF_nsec2localtime_unary(BIF_gmt2nsec(input1))
}
func BIF_gmt2localtime_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("gmt2localtime2", input1)
}
return BIF_nsec2localtime_ternary(BIF_gmt2nsec(input1), mlrval.FromInt(0), input2)
}
@ -254,57 +254,62 @@ func BIF_gmt2localtime_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
var extensionRegex = regexp.MustCompile("([1-9])S")
func BIF_strftime(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return strftimeHelper(input1, input2, false, nil)
return strftimeHelper(input1, input2, false, nil, "strftime")
}
func BIF_strfntime(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return strfntimeHelper(input1, input2, false, nil)
return strfntimeHelper(input1, input2, false, nil, "strfntime")
}
func BIF_strftime_local_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return strftimeHelper(input1, input2, true, nil)
return strftimeHelper(input1, input2, true, nil, "strftime_local")
}
func BIF_strfntime_local_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return strfntimeHelper(input1, input2, true, nil)
return strfntimeHelper(input1, input2, true, nil, "strfntime_local")
}
func BIF_strftime_local_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
locationString, isString := input3.GetStringValue()
if !isString {
return mlrval.ERROR
locationString, errValue := input3.GetStringValueOrError("strftime")
if errValue != nil {
return errValue
}
location, err := time.LoadLocation(locationString)
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
return strftimeHelper(input1, input2, true, location)
return strftimeHelper(input1, input2, true, location, "strftime_local")
}
func BIF_strfntime_local_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
locationString, isString := input3.GetStringValue()
if !isString {
return mlrval.ERROR
locationString, errValue := input3.GetStringValueOrError("strfntime")
if errValue != nil {
return errValue
}
location, err := time.LoadLocation(locationString)
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
return strfntimeHelper(input1, input2, true, location)
return strfntimeHelper(input1, input2, true, location, "strfntime_local")
}
func strftimeHelper(input1, input2 *mlrval.Mlrval, doLocal bool, location *time.Location) *mlrval.Mlrval {
func strftimeHelper(
input1, input2 *mlrval.Mlrval,
doLocal bool,
location *time.Location,
funcname string,
) *mlrval.Mlrval {
if input1.IsVoid() {
return input1
}
epochSeconds, ok := input1.GetNumericToFloatValue()
if !ok {
return mlrval.ERROR
epochSeconds, errValue := input1.GetNumericToFloatValueOrError(funcname)
if errValue != nil {
return errValue
}
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError(funcname, input2)
}
// Convert argument1 from float seconds since the epoch to a Go time.
@ -329,7 +334,7 @@ func strftimeHelper(input1, input2 *mlrval.Mlrval, doLocal bool, location *time.
formatter, err := strftime.New(formatString, strftimeExtensions)
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
outputString := formatter.FormatString(inputTime)
@ -337,16 +342,21 @@ func strftimeHelper(input1, input2 *mlrval.Mlrval, doLocal bool, location *time.
return mlrval.FromString(outputString)
}
func strfntimeHelper(input1, input2 *mlrval.Mlrval, doLocal bool, location *time.Location) *mlrval.Mlrval {
func strfntimeHelper(
input1, input2 *mlrval.Mlrval,
doLocal bool,
location *time.Location,
funcname string,
) *mlrval.Mlrval {
if input1.IsVoid() {
return input1
}
epochNanoseconds, ok := input1.GetIntValue()
if !ok {
return mlrval.ERROR
epochNanoseconds, errValue := input1.GetIntValueOrError(funcname)
if errValue != nil {
return errValue
}
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError(funcname, input2)
}
// Convert argument1 from float seconds since the epoch to a Go time.
@ -371,7 +381,7 @@ func strfntimeHelper(input1, input2 *mlrval.Mlrval, doLocal bool, location *time
formatter, err := strftime.New(formatString, strftimeExtensions)
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
outputString := formatter.FormatString(inputTime)
@ -473,10 +483,10 @@ func BIF_strpntime(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
func bif_strptime_unary_aux(input1, input2 *mlrval.Mlrval, doLocal, produceNanoseconds bool) *mlrval.Mlrval {
if !input1.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("strptime", input1)
}
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("strptime", input2)
}
timeString := input1.AcquireStringValue()
formatString := input2.AcquireStringValue()
@ -489,7 +499,7 @@ func bif_strptime_unary_aux(input1, input2 *mlrval.Mlrval, doLocal, produceNanos
t, err = strptime.Parse(timeString, formatString)
}
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
if produceNanoseconds {
@ -529,10 +539,10 @@ func BIF_strpntime_local_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
func bif_strptime_binary_aux(input1, input2 *mlrval.Mlrval, doLocal, produceNanoseconds bool) *mlrval.Mlrval {
if !input1.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("strptime", input1)
}
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("strptime", input2)
}
timeString := input1.AcquireStringValue()
formatString := input2.AcquireStringValue()
@ -545,7 +555,7 @@ func bif_strptime_binary_aux(input1, input2 *mlrval.Mlrval, doLocal, produceNano
t, err = strptime.Parse(timeString, formatString)
}
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
if produceNanoseconds {
@ -575,13 +585,13 @@ func BIF_localtime2nsec_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
func bif_strptime_local_ternary_aux(input1, input2, input3 *mlrval.Mlrval, produceNanoseconds bool) *mlrval.Mlrval {
if !input1.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("strptime_local", input1)
}
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("strptime_local", input2)
}
if !input3.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("strptime_local", input3)
}
timeString := input1.AcquireStringValue()
@ -590,12 +600,12 @@ func bif_strptime_local_ternary_aux(input1, input2, input3 *mlrval.Mlrval, produ
location, err := time.LoadLocation(locationString)
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
t, err := strptime.ParseLocation(timeString, formatString, location)
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
if produceNanoseconds {

View file

@ -12,7 +12,7 @@ import (
func BIF_md5(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("md5", input1)
} else {
return mlrval.FromString(
fmt.Sprintf(
@ -25,7 +25,7 @@ func BIF_md5(input1 *mlrval.Mlrval) *mlrval.Mlrval {
func BIF_sha1(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("sha1", input1)
} else {
return mlrval.FromString(
fmt.Sprintf(
@ -38,7 +38,7 @@ func BIF_sha1(input1 *mlrval.Mlrval) *mlrval.Mlrval {
func BIF_sha256(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("sha256", input1)
} else {
return mlrval.FromString(
fmt.Sprintf(
@ -51,7 +51,7 @@ func BIF_sha256(input1 *mlrval.Mlrval) *mlrval.Mlrval {
func BIF_sha512(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("sha512", input1)
} else {
return mlrval.FromString(
fmt.Sprintf(

View file

@ -13,33 +13,33 @@ import (
// ----------------------------------------------------------------
// Return error (unary math-library func)
func _math_unary_erro1(input1 *mlrval.Mlrval, f mathLibUnaryFunc) *mlrval.Mlrval {
return mlrval.ERROR
func _math_unary_erro1(input1 *mlrval.Mlrval, f mathLibUnaryFunc, fname string) *mlrval.Mlrval {
return mlrval.FromTypeErrorUnary(fname, input1)
}
// Return absent (unary math-library func)
func _math_unary_absn1(input1 *mlrval.Mlrval, f mathLibUnaryFunc) *mlrval.Mlrval {
func _math_unary_absn1(input1 *mlrval.Mlrval, f mathLibUnaryFunc, fname string) *mlrval.Mlrval {
return mlrval.ABSENT
}
// Return null (unary math-library func)
func _math_unary_null1(input1 *mlrval.Mlrval, f mathLibUnaryFunc) *mlrval.Mlrval {
func _math_unary_null1(input1 *mlrval.Mlrval, f mathLibUnaryFunc, fname string) *mlrval.Mlrval {
return mlrval.NULL
}
// Return void (unary math-library func)
func _math_unary_void1(input1 *mlrval.Mlrval, f mathLibUnaryFunc) *mlrval.Mlrval {
func _math_unary_void1(input1 *mlrval.Mlrval, f mathLibUnaryFunc, fname string) *mlrval.Mlrval {
return mlrval.VOID
}
// ----------------------------------------------------------------
func math_unary_f_i(input1 *mlrval.Mlrval, f mathLibUnaryFunc) *mlrval.Mlrval {
func math_unary_f_i(input1 *mlrval.Mlrval, f mathLibUnaryFunc, fname string) *mlrval.Mlrval {
return mlrval.FromFloat(f(float64(input1.AcquireIntValue())))
}
func math_unary_i_i(input1 *mlrval.Mlrval, f mathLibUnaryFunc) *mlrval.Mlrval {
func math_unary_i_i(input1 *mlrval.Mlrval, f mathLibUnaryFunc, fname string) *mlrval.Mlrval {
return mlrval.FromInt(int64(f(float64(input1.AcquireIntValue()))))
}
func math_unary_f_f(input1 *mlrval.Mlrval, f mathLibUnaryFunc) *mlrval.Mlrval {
func math_unary_f_f(input1 *mlrval.Mlrval, f mathLibUnaryFunc, fname string) *mlrval.Mlrval {
return mlrval.FromFloat(f(input1.AcquireFloatValue()))
}
@ -58,45 +58,75 @@ var mudispo = [mlrval.MT_DIM]mathLibUnaryFuncWrapper{
/*ABSENT */ _math_unary_absn1,
}
func BIF_acos(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mudispo[input1.Type()](input1, math.Acos) }
func BIF_acos(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Acos, "acos")
}
func BIF_acosh(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Acosh)
return mudispo[input1.Type()](input1, math.Acosh, "acosh")
}
func BIF_asin(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Asin, "asin")
}
func BIF_asin(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mudispo[input1.Type()](input1, math.Asin) }
func BIF_asinh(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Asinh)
return mudispo[input1.Type()](input1, math.Asinh, "asinh")
}
func BIF_atan(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Atan, "atan")
}
func BIF_atan(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mudispo[input1.Type()](input1, math.Atan) }
func BIF_atanh(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Atanh)
return mudispo[input1.Type()](input1, math.Atanh, "atanh")
}
func BIF_cbrt(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Cbrt, "atan")
}
func BIF_cos(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Cos, "cos")
}
func BIF_cosh(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Cosh, "cosh")
}
func BIF_erf(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Erf, "erf")
}
func BIF_erfc(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Erfc, "erfc")
}
func BIF_exp(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Exp, "exp")
}
func BIF_cbrt(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mudispo[input1.Type()](input1, math.Cbrt) }
func BIF_cos(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mudispo[input1.Type()](input1, math.Cos) }
func BIF_cosh(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mudispo[input1.Type()](input1, math.Cosh) }
func BIF_erf(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mudispo[input1.Type()](input1, math.Erf) }
func BIF_erfc(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mudispo[input1.Type()](input1, math.Erfc) }
func BIF_exp(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mudispo[input1.Type()](input1, math.Exp) }
func BIF_expm1(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Expm1)
return mudispo[input1.Type()](input1, math.Expm1, "expm1")
}
func BIF_invqnorm(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, lib.Invqnorm)
return mudispo[input1.Type()](input1, lib.Invqnorm, "invqnorm")
}
func BIF_log(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Log, "log")
}
func BIF_log(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mudispo[input1.Type()](input1, math.Log) }
func BIF_log10(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Log10)
return mudispo[input1.Type()](input1, math.Log10, "log10")
}
func BIF_log1p(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Log1p)
return mudispo[input1.Type()](input1, math.Log1p, "log1p")
}
func BIF_qnorm(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, lib.Qnorm)
return mudispo[input1.Type()](input1, lib.Qnorm, "qnorm")
}
func BIF_sin(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Sin, "sin")
}
func BIF_sinh(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Sinh, "sinh")
}
func BIF_sqrt(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Sqrt, "sqrt")
}
func BIF_tan(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Tan, "tan")
}
func BIF_tanh(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mudispo[input1.Type()](input1, math.Tanh, "tanh")
}
func BIF_sin(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mudispo[input1.Type()](input1, math.Sin) }
func BIF_sinh(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mudispo[input1.Type()](input1, math.Sinh) }
func BIF_sqrt(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mudispo[input1.Type()](input1, math.Sqrt) }
func BIF_tan(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mudispo[input1.Type()](input1, math.Tan) }
func BIF_tanh(input1 *mlrval.Mlrval) *mlrval.Mlrval { return mudispo[input1.Type()](input1, math.Tanh) }
// Disposition vector for unary mathlib functions which are int-preserving
var imudispo = [mlrval.MT_DIM]mathLibUnaryFuncWrapper{
@ -114,17 +144,21 @@ var imudispo = [mlrval.MT_DIM]mathLibUnaryFuncWrapper{
}
// Int-preserving
func BIF_abs(input1 *mlrval.Mlrval) *mlrval.Mlrval { return imudispo[input1.Type()](input1, math.Abs) } // xxx
func BIF_abs(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return imudispo[input1.Type()](input1, math.Abs, "abs")
} // xxx
func BIF_ceil(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return imudispo[input1.Type()](input1, math.Ceil)
return imudispo[input1.Type()](input1, math.Ceil, "ceil")
} // xxx
func BIF_floor(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return imudispo[input1.Type()](input1, math.Floor)
return imudispo[input1.Type()](input1, math.Floor, "floor")
} // xxx
func BIF_round(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return imudispo[input1.Type()](input1, math.Round)
} // xxx
func BIF_sgn(input1 *mlrval.Mlrval) *mlrval.Mlrval { return imudispo[input1.Type()](input1, lib.Sgn) } // xxx
return imudispo[input1.Type()](input1, math.Round, "round")
} // xxx
func BIF_sgn(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return imudispo[input1.Type()](input1, lib.Sgn, "sgn")
} // xxx
// ================================================================
// Exponentiation: DSL operator '**'. See also
@ -150,19 +184,23 @@ func pow_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromFloat(math.Pow(input1.AcquireFloatValue(), input2.AcquireFloatValue()))
}
func powte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("**", input1, input2)
}
var pow_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {pow_f_ii, pow_f_if, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*FLOAT */ {pow_f_fi, pow_f_ff, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _erro, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _erro, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _absn},
/*ABSENT */ {_i0__, _f0__, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {pow_f_ii, pow_f_if, powte, _void, powte, powte, powte, powte, powte, powte, _1___},
/*FLOAT */ {pow_f_fi, pow_f_ff, powte, _void, powte, powte, powte, powte, powte, powte, _1___},
/*BOOL */ {powte, powte, powte, powte, powte, powte, powte, powte, powte, powte, _absn},
/*VOID */ {_void, _void, powte, _void, powte, powte, powte, powte, powte, powte, _absn},
/*STRING */ {powte, powte, powte, powte, powte, powte, powte, powte, powte, powte, _absn},
/*ARRAY */ {powte, powte, powte, powte, powte, powte, powte, powte, powte, powte, _absn},
/*MAP */ {powte, powte, powte, powte, powte, powte, powte, powte, powte, powte, _absn},
/*FUNC */ {powte, powte, powte, powte, powte, powte, powte, powte, powte, powte, _absn},
/*ERROR */ {powte, powte, powte, powte, powte, powte, powte, powte, powte, powte, _absn},
/*NULL */ {powte, powte, powte, powte, powte, powte, powte, powte, powte, powte, _absn},
/*ABSENT */ {_i0__, _f0__, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn},
}
func BIF_pow(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -183,19 +221,23 @@ func atan2_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromFloat(math.Atan2(input1.AcquireFloatValue(), input2.AcquireFloatValue()))
}
func atan2te(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("atan2", input1, input2)
}
var atan2_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {atan2_f_ii, atan2_f_if, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*FLOAT */ {atan2_f_fi, atan2_f_ff, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _erro, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _erro, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _absn},
/*ABSENT */ {_i0__, _f0__, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {atan2_f_ii, atan2_f_if, atan2te, _void, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, _1___},
/*FLOAT */ {atan2_f_fi, atan2_f_ff, atan2te, _void, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, _1___},
/*BOOL */ {atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, _absn},
/*VOID */ {_void, _void, atan2te, _void, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, _absn},
/*STRING */ {atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, _absn},
/*ARRAY */ {atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, _absn},
/*MAP */ {atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, _absn},
/*FUNC */ {atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, _absn},
/*ERROR */ {atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, _absn},
/*NULL */ {atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, atan2te, _absn},
/*ABSENT */ {_i0__, _f0__, atan2te, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn},
}
func BIF_atan2(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -220,19 +262,23 @@ func roundm_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromFloat(mlr_roundm(input1.AcquireFloatValue(), input2.AcquireFloatValue()))
}
func rdmte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("roundm", input1, input2)
}
var roundm_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {roundm_f_ii, roundm_f_if, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*FLOAT */ {roundm_f_fi, roundm_f_ff, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _1___},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*VOID */ {_void, _void, _erro, _void, _erro, _absn, _absn, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _erro, _absn},
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, _erro, _absn, _erro, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _absn},
/*ABSENT */ {_i0__, _f0__, _erro, _absn, _erro, _absn, _absn, _erro, _erro, _absn, _absn},
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {roundm_f_ii, roundm_f_if, rdmte, _void, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, _1___},
/*FLOAT */ {roundm_f_fi, roundm_f_ff, rdmte, _void, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, _1___},
/*BOOL */ {rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, _absn},
/*VOID */ {_void, _void, rdmte, _void, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, _absn},
/*STRING */ {rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, _absn},
/*ARRAY */ {rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, _absn},
/*MAP */ {rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, _absn},
/*FUNC */ {rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, _absn},
/*ERROR */ {rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, _absn},
/*NULL */ {rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, rdmte, _absn},
/*ABSENT */ {_i0__, _f0__, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn, _absn},
}
func BIF_roundm(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -240,6 +286,10 @@ func BIF_roundm(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
}
// ================================================================
func logifit_te(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("logifit", input1, input2)
}
func BIF_logifit(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsLegit() {
return input1
@ -254,15 +304,15 @@ func BIF_logifit(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
// int/float OK; rest not
x, xok := input1.GetNumericToFloatValue()
if !xok {
return mlrval.ERROR
return logifit_te(input1, input2)
}
m, mok := input2.GetNumericToFloatValue()
if !mok {
return mlrval.ERROR
return logifit_te(input1, input2)
}
b, bok := input3.GetNumericToFloatValue()
if !bok {
return mlrval.ERROR
return logifit_te(input1, input2)
}
return mlrval.FromFloat(1.0 / (1.0 + math.Exp(-m*x-b)))

View file

@ -30,10 +30,10 @@ func BIF_urandint(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return input2
}
if !input1.IsInt() {
return mlrval.ERROR
return mlrval.FromNotIntError("urandint", input1)
}
if !input2.IsInt() {
return mlrval.ERROR
return mlrval.FromNotIntError("urandint", input2)
}
a := input1.AcquireIntValue()
@ -62,10 +62,10 @@ func BIF_urandrange(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
a, aok := input1.GetNumericToFloatValue()
b, bok := input2.GetNumericToFloatValue()
if !aok {
return mlrval.ERROR
return mlrval.FromNotNumericError("urandrange", input1)
}
if !bok {
return mlrval.ERROR
return mlrval.FromNotNumericError("urandrange", input2)
}
return mlrval.FromFloat(
a + (b-a)*lib.RandFloat64(),
@ -75,10 +75,10 @@ func BIF_urandrange(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
func BIF_urandelement(input1 *mlrval.Mlrval) *mlrval.Mlrval {
arrayval := input1.GetArray()
if arrayval == nil { // not an array
return mlrval.ERROR
return mlrval.FromNotArrayError("urandelement", input1)
}
if len(arrayval) == 0 {
return mlrval.ERROR
return mlrval.FromErrorString("urandelement: received a zero-length array as input")
}
// lo is inclusive, hi is exclusive

View file

@ -10,17 +10,17 @@ import (
// BIF_ssub implements the ssub function -- no-frills string-replace, no
// regexes, no escape sequences.
func BIF_ssub(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
return bif_ssub_gssub(input1, input2, input3, false)
return bif_ssub_gssub(input1, input2, input3, false, "ssub")
}
// BIF_gssub implements the gssub function -- no-frills string-replace, no
// regexes, no escape sequences.
func BIF_gssub(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
return bif_ssub_gssub(input1, input2, input3, true)
return bif_ssub_gssub(input1, input2, input3, true, "gssub")
}
// bif_ssub_gssub is shared code for BIF_ssub and BIF_gssub.
func bif_ssub_gssub(input1, input2, input3 *mlrval.Mlrval, doAll bool) *mlrval.Mlrval {
func bif_ssub_gssub(input1, input2, input3 *mlrval.Mlrval, doAll bool, funcname string) *mlrval.Mlrval {
if input1.IsErrorOrAbsent() {
return input1
}
@ -31,13 +31,13 @@ func bif_ssub_gssub(input1, input2, input3 *mlrval.Mlrval, doAll bool) *mlrval.M
return input3
}
if !input1.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError(funcname, input1)
}
if !input2.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError(funcname, input2)
}
if !input3.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError(funcname, input3)
}
if doAll {
return mlrval.FromString(
@ -68,13 +68,13 @@ func BIF_sub(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
return input3
}
if !input1.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("sub", input1)
}
if !input2.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("sub", input2)
}
if !input3.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("sub", input3)
}
input := input1.AcquireStringValue()
@ -98,13 +98,13 @@ func BIF_gsub(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
return input3
}
if !input1.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("gsub", input1)
}
if !input2.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("gsub", input2)
}
if !input3.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("gsub", input3)
}
input := input1.AcquireStringValue()
@ -126,7 +126,7 @@ func BIF_string_matches_regexp(input1, input2 *mlrval.Mlrval) (retval *mlrval.Ml
}
input1string := input1.String()
if !input2.IsStringOrVoid() {
return mlrval.ERROR, nil
return mlrval.FromNotStringError("=~", input2), nil
}
boolOutput, captures := lib.RegexMatches(input1string, input2.AcquireStringValue())
@ -146,10 +146,10 @@ func BIF_string_does_not_match_regexp(input1, input2 *mlrval.Mlrval) (retval *ml
func BIF_regextract(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("!=~", input1)
}
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("!=~", input2)
}
regex := lib.CompileMillerRegexOrDie(input2.AcquireStringValue())
match := regex.FindStringIndex(input1.AcquireStringValue())
@ -162,10 +162,10 @@ func BIF_regextract(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
func BIF_regextract_or_else(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("regextract_or_else", input1)
}
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("regextract_or_else", input2)
}
regex := lib.CompileMillerRegexOrDie(input2.AcquireStringValue())
match := regex.FindStringIndex(input1.AcquireStringValue())

View file

@ -10,12 +10,12 @@ import (
func BIF_dhms2sec(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("dhms2sec", input1)
}
input := input1.String()
if input == "" {
return mlrval.ERROR
return mlrval.FromNotStringError("dhms2sec", input1)
}
negate := false
@ -36,10 +36,10 @@ func BIF_dhms2sec(input1 *mlrval.Mlrval) *mlrval.Mlrval {
_, err := fmt.Sscanf(remainingInput, "%d%s", &n, &rest)
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
if len(rest) < 1 {
return mlrval.ERROR
return mlrval.FromErrorString("dhms2sec: input too short")
}
unitPart := rest[0]
remainingInput = rest[1:]
@ -54,7 +54,13 @@ func BIF_dhms2sec(input1 *mlrval.Mlrval) *mlrval.Mlrval {
case 's':
seconds += n
default:
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf(
"dhms2sec(\"%s\"): unrecognized unit '%c'",
input1.OriginalString(),
unitPart,
),
)
}
}
if negate {
@ -66,12 +72,12 @@ func BIF_dhms2sec(input1 *mlrval.Mlrval) *mlrval.Mlrval {
func BIF_dhms2fsec(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("dhms2fsec", input1)
}
input := input1.String()
if input == "" {
return mlrval.ERROR
return mlrval.FromNotStringError("dhms2fsec", input1)
}
negate := false
@ -92,10 +98,10 @@ func BIF_dhms2fsec(input1 *mlrval.Mlrval) *mlrval.Mlrval {
_, err := fmt.Sscanf(remainingInput, "%f%s", &f, &rest)
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
if len(rest) < 1 {
return mlrval.ERROR
return mlrval.FromErrorString("dhms2fsec: input too short")
}
unitPart := rest[0]
remainingInput = rest[1:]
@ -110,7 +116,13 @@ func BIF_dhms2fsec(input1 *mlrval.Mlrval) *mlrval.Mlrval {
case 's':
seconds += f
default:
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf(
"dhms2fsec(\"%s\"): unrecognized unit '%c'",
input1.OriginalString(),
unitPart,
),
)
}
}
if negate {
@ -122,10 +134,10 @@ func BIF_dhms2fsec(input1 *mlrval.Mlrval) *mlrval.Mlrval {
func BIF_hms2sec(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("hms2sec", input1)
}
if input1.AcquireStringValue() == "" {
return mlrval.ERROR
return mlrval.FromNotStringError("hms2sec", input1)
}
var h, m, s int64
@ -141,12 +153,14 @@ func BIF_hms2sec(input1 *mlrval.Mlrval) *mlrval.Mlrval {
}
}
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf("hsm2sec: could not parse input \"%s\"", input1.OriginalString()),
)
}
func BIF_hms2fsec(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsString() {
return mlrval.ERROR
return mlrval.FromNotStringError("hms2fsec", input1)
}
var h, m int
@ -164,13 +178,15 @@ func BIF_hms2fsec(input1 *mlrval.Mlrval) *mlrval.Mlrval {
}
}
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf("hsm2fsec: could not parse input \"%s\"", input1.OriginalString()),
)
}
func BIF_sec2dhms(input1 *mlrval.Mlrval) *mlrval.Mlrval {
isec, ok := input1.GetIntValue()
if !ok {
return mlrval.ERROR
return mlrval.FromNotIntError("sec2dhms", input1)
}
var d, h, m, s int64
@ -198,7 +214,7 @@ func BIF_sec2dhms(input1 *mlrval.Mlrval) *mlrval.Mlrval {
func BIF_sec2hms(input1 *mlrval.Mlrval) *mlrval.Mlrval {
isec, ok := input1.GetIntValue()
if !ok {
return mlrval.ERROR
return mlrval.FromNotIntError("sec2hms", input1)
}
sign := ""
if isec < 0 {
@ -219,7 +235,7 @@ func BIF_sec2hms(input1 *mlrval.Mlrval) *mlrval.Mlrval {
func BIF_fsec2dhms(input1 *mlrval.Mlrval) *mlrval.Mlrval {
fsec, ok := input1.GetNumericToFloatValue()
if !ok {
return mlrval.ERROR
return mlrval.FromNotIntError("fsec2dhms", input1)
}
sign := int64(1)
@ -269,7 +285,7 @@ func BIF_fsec2dhms(input1 *mlrval.Mlrval) *mlrval.Mlrval {
func BIF_fsec2hms(input1 *mlrval.Mlrval) *mlrval.Mlrval {
fsec, ok := input1.GetNumericToFloatValue()
if !ok {
return mlrval.ERROR
return mlrval.FromNotIntError("fsec2hms", input1)
}
sign := ""

View file

@ -156,7 +156,7 @@ func BIF_finalize_kurtosis(mn, msum, msum2, msum3, msum4 *mlrval.Mlrval) *mlrval
// This is a helper function for BIFs which operate only on array or map.
// It shorthands what values to return for non-collection inputs.
func check_collection(c *mlrval.Mlrval) (bool, *mlrval.Mlrval) {
func check_collection(c *mlrval.Mlrval, funcname string) (bool, *mlrval.Mlrval) {
vtype := c.Type()
switch vtype {
case mlrval.MT_ARRAY:
@ -165,8 +165,10 @@ func check_collection(c *mlrval.Mlrval) (bool, *mlrval.Mlrval) {
return true, c
case mlrval.MT_ABSENT:
return false, mlrval.ABSENT
case mlrval.MT_ERROR:
return false, c
default:
return false, mlrval.ERROR
return false, mlrval.FromNotCollectionError(funcname, c)
}
}
@ -186,7 +188,7 @@ func collection_sum_of_function(
}
func BIF_count(collection *mlrval.Mlrval) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, "count")
if !ok {
return value_if_not
}
@ -200,7 +202,7 @@ func BIF_count(collection *mlrval.Mlrval) *mlrval.Mlrval {
}
func BIF_null_count(collection *mlrval.Mlrval) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, "null_count")
if !ok {
return value_if_not
}
@ -221,7 +223,7 @@ func BIF_null_count(collection *mlrval.Mlrval) *mlrval.Mlrval {
}
func BIF_distinct_count(collection *mlrval.Mlrval) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, "distinct_count")
if !ok {
return value_if_not
}
@ -243,18 +245,19 @@ func BIF_distinct_count(collection *mlrval.Mlrval) *mlrval.Mlrval {
}
func BIF_mode(collection *mlrval.Mlrval) *mlrval.Mlrval {
return bif_mode_or_antimode(collection, func(a, b int) bool { return a > b })
return bif_mode_or_antimode(collection, "mode", func(a, b int) bool { return a > b })
}
func BIF_antimode(collection *mlrval.Mlrval) *mlrval.Mlrval {
return bif_mode_or_antimode(collection, func(a, b int) bool { return a < b })
return bif_mode_or_antimode(collection, "antimode", func(a, b int) bool { return a < b })
}
func bif_mode_or_antimode(
collection *mlrval.Mlrval,
funcname string,
cmp func(int, int) bool,
) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, funcname)
if !ok {
return value_if_not
}
@ -316,7 +319,7 @@ func bif_mode_or_antimode(
}
func BIF_sum(collection *mlrval.Mlrval) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, "sum")
if !ok {
return value_if_not
}
@ -329,7 +332,7 @@ func BIF_sum(collection *mlrval.Mlrval) *mlrval.Mlrval {
}
func BIF_sum2(collection *mlrval.Mlrval) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, "sum2")
if !ok {
return value_if_not
}
@ -340,7 +343,7 @@ func BIF_sum2(collection *mlrval.Mlrval) *mlrval.Mlrval {
}
func BIF_sum3(collection *mlrval.Mlrval) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, "sum3")
if !ok {
return value_if_not
}
@ -351,7 +354,7 @@ func BIF_sum3(collection *mlrval.Mlrval) *mlrval.Mlrval {
}
func BIF_sum4(collection *mlrval.Mlrval) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, "sum4")
if !ok {
return value_if_not
}
@ -363,7 +366,7 @@ func BIF_sum4(collection *mlrval.Mlrval) *mlrval.Mlrval {
}
func BIF_mean(collection *mlrval.Mlrval) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, "mean")
if !ok {
return value_if_not
}
@ -376,7 +379,7 @@ func BIF_mean(collection *mlrval.Mlrval) *mlrval.Mlrval {
}
func BIF_meaneb(collection *mlrval.Mlrval) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, "meaneb")
if !ok {
return value_if_not
}
@ -387,7 +390,7 @@ func BIF_meaneb(collection *mlrval.Mlrval) *mlrval.Mlrval {
}
func BIF_variance(collection *mlrval.Mlrval) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, "variance")
if !ok {
return value_if_not
}
@ -398,7 +401,7 @@ func BIF_variance(collection *mlrval.Mlrval) *mlrval.Mlrval {
}
func BIF_stddev(collection *mlrval.Mlrval) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, "stddev")
if !ok {
return value_if_not
}
@ -409,7 +412,7 @@ func BIF_stddev(collection *mlrval.Mlrval) *mlrval.Mlrval {
}
func BIF_skewness(collection *mlrval.Mlrval) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, "skewness")
if !ok {
return value_if_not
}
@ -421,7 +424,7 @@ func BIF_skewness(collection *mlrval.Mlrval) *mlrval.Mlrval {
}
func BIF_kurtosis(collection *mlrval.Mlrval) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, "kurtosis")
if !ok {
return value_if_not
}
@ -434,7 +437,7 @@ func BIF_kurtosis(collection *mlrval.Mlrval) *mlrval.Mlrval {
}
func BIF_minlen(collection *mlrval.Mlrval) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, "minlen")
if !ok {
return value_if_not
}
@ -446,7 +449,7 @@ func BIF_minlen(collection *mlrval.Mlrval) *mlrval.Mlrval {
}
func BIF_maxlen(collection *mlrval.Mlrval) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, "maxlen")
if !ok {
return value_if_not
}
@ -458,7 +461,7 @@ func BIF_maxlen(collection *mlrval.Mlrval) *mlrval.Mlrval {
}
func BIF_sort_collection(collection *mlrval.Mlrval) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
ok, value_if_not := check_collection(collection, "sort_collection")
if !ok {
return value_if_not
}
@ -492,21 +495,21 @@ func BIF_sort_collection(collection *mlrval.Mlrval) *mlrval.Mlrval {
func BIF_median(
collection *mlrval.Mlrval,
) *mlrval.Mlrval {
return BIF_percentile(collection, mlrval.FromFloat(50.0))
return bif_percentile_with_options_aux(collection, mlrval.FromFloat(50.0), nil, "median")
}
func BIF_median_with_options(
collection *mlrval.Mlrval,
options *mlrval.Mlrval,
) *mlrval.Mlrval {
return BIF_percentile_with_options(collection, mlrval.FromFloat(50.0), options)
return bif_percentile_with_options_aux(collection, mlrval.FromFloat(50.0), options, "median")
}
func BIF_percentile(
collection *mlrval.Mlrval,
percentile *mlrval.Mlrval,
) *mlrval.Mlrval {
return BIF_percentile_with_options(collection, percentile, nil)
return bif_percentile_with_options_aux(collection, percentile, nil, "percentile")
}
func BIF_percentile_with_options(
@ -514,16 +517,14 @@ func BIF_percentile_with_options(
percentile *mlrval.Mlrval,
options *mlrval.Mlrval,
) *mlrval.Mlrval {
percentiles := mlrval.FromSingletonArray(percentile)
outputs := BIF_percentiles_with_options(collection, percentiles, options)
return outputs.AcquireMapValue().Head.Value
return bif_percentile_with_options_aux(collection, percentile, options, "percentile")
}
func BIF_percentiles(
collection *mlrval.Mlrval,
percentiles *mlrval.Mlrval,
) *mlrval.Mlrval {
return BIF_percentiles_with_options(collection, percentiles, nil)
return bif_percentiles_with_options_aux(collection, percentiles, nil, "percentiles")
}
func BIF_percentiles_with_options(
@ -531,7 +532,34 @@ func BIF_percentiles_with_options(
percentiles *mlrval.Mlrval,
options *mlrval.Mlrval,
) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection)
return bif_percentiles_with_options_aux(collection, percentiles, options, "percentiles")
}
func bif_percentile_with_options_aux(
collection *mlrval.Mlrval,
percentile *mlrval.Mlrval,
options *mlrval.Mlrval,
funcname string,
) *mlrval.Mlrval {
percentiles := mlrval.FromSingletonArray(percentile)
outputs := bif_percentiles_with_options_aux(collection, percentiles, options, funcname)
// Check for error/absent returns from the main impl body
ok, value_if_not := check_collection(outputs, funcname)
if !ok {
return value_if_not
}
return outputs.AcquireMapValue().Head.Value
}
func bif_percentiles_with_options_aux(
collection *mlrval.Mlrval,
percentiles *mlrval.Mlrval,
options *mlrval.Mlrval,
funcname string,
) *mlrval.Mlrval {
ok, value_if_not := check_collection(collection, funcname)
if !ok {
return value_if_not
}
@ -543,7 +571,7 @@ func BIF_percentiles_with_options(
if options != nil {
om := options.GetMap()
if om == nil { // not a map
return mlrval.ERROR
return type_error_named_argument(funcname, "map", "options", options)
}
for pe := om.Head; pe != nil; pe = pe.Next {
if pe.Key == "array_is_sorted" || pe.Key == "ais" {
@ -552,7 +580,7 @@ func BIF_percentiles_with_options(
} else if mlrval.Equals(pe.Value, mlrval.FALSE) {
array_is_sorted = false
} else {
return mlrval.ERROR
return type_error_named_argument(funcname, "boolean", pe.Key, pe.Value)
}
} else if pe.Key == "interpolate_linearly" || pe.Key == "il" {
if mlrval.Equals(pe.Value, mlrval.TRUE) {
@ -560,7 +588,7 @@ func BIF_percentiles_with_options(
} else if mlrval.Equals(pe.Value, mlrval.FALSE) {
interpolate_linearly = false
} else {
return mlrval.ERROR
return type_error_named_argument(funcname, "boolean", pe.Key, pe.Value)
}
} else if pe.Key == "output_array_not_map" || pe.Key == "oa" {
if mlrval.Equals(pe.Value, mlrval.TRUE) {
@ -568,7 +596,7 @@ func BIF_percentiles_with_options(
} else if mlrval.Equals(pe.Value, mlrval.FALSE) {
output_array_not_map = false
} else {
return mlrval.ERROR
return type_error_named_argument(funcname, "boolean", pe.Key, pe.Value)
}
}
}
@ -577,31 +605,33 @@ func BIF_percentiles_with_options(
var sorted_array *mlrval.Mlrval
if array_is_sorted {
if !collection.IsArray() {
return mlrval.ERROR
return mlrval.FromNotArrayError(funcname+" collection", collection)
}
sorted_array = collection
} else {
sorted_array = BIF_sort_collection(collection)
}
return bif_percentiles(
return bif_percentiles_impl(
sorted_array.AcquireArrayValue(),
percentiles,
interpolate_linearly,
output_array_not_map,
funcname,
)
}
func bif_percentiles(
func bif_percentiles_impl(
sorted_array []*mlrval.Mlrval,
percentiles *mlrval.Mlrval,
interpolate_linearly bool,
output_array_not_map bool,
funcname string,
) *mlrval.Mlrval {
ps := percentiles.GetArray()
if ps == nil { // not an array
return mlrval.ERROR
return mlrval.FromNotArrayError(funcname+" percentiles", percentiles)
}
outputs := make([]*mlrval.Mlrval, len(ps))
@ -609,7 +639,7 @@ func bif_percentiles(
for i, _ := range ps {
p, ok := ps[i].GetNumericToFloatValue()
if !ok {
outputs[i] = mlrval.ERROR.Copy()
outputs[i] = type_error_named_argument(funcname, "numeric", "percentile", ps[i])
} else if len(sorted_array) == 0 {
outputs[i] = mlrval.VOID
} else {

View file

@ -72,7 +72,7 @@ func TestBIF_null_count(t *testing.T) {
mlrval.FromInt(1),
mlrval.FromString("two"),
mlrval.FromString(""), // this counts
mlrval.ERROR,
mlrval.FromAnonymousError(),
mlrval.ABSENT,
mlrval.NULL, // this counts
})

View file

@ -2,6 +2,7 @@ package bifs
import (
"bytes"
"fmt"
"regexp"
"strconv"
"strings"
@ -13,7 +14,7 @@ import (
// ================================================================
func BIF_strlen(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("strlen", input1)
} else {
return mlrval.FromInt(lib.UTF8Strlen(input1.AcquireStringValue()))
}
@ -42,19 +43,23 @@ func dot_s_xx(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromString(input1.String() + input2.String())
}
func dot_te(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary(".", input1, input2)
}
var dot_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {dot_s_xx, dot_s_xx, dot_s_xx, _s1__, dot_s_xx, _erro, _erro, _erro, _erro, _1___, _s1__},
/*FLOAT */ {dot_s_xx, dot_s_xx, dot_s_xx, _s1__, dot_s_xx, _erro, _erro, _erro, _erro, _1___, _s1__},
/*BOOL */ {dot_s_xx, dot_s_xx, dot_s_xx, _s1__, dot_s_xx, _erro, _erro, _erro, _erro, _1___, _s1__},
/*VOID */ {_s2__, _s2__, _s2__, _void, _2___, _absn, _absn, _erro, _erro, _void, _void},
/*STRING */ {dot_s_xx, dot_s_xx, dot_s_xx, _1___, dot_s_xx, _erro, _erro, _erro, _erro, _1___, _1___},
/*ARRAY */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*MAP */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _absn, _absn, _erro, _erro, _erro, _erro},
/*NULL */ {_s2__, _s2__, _s2__, _void, _2___, _absn, _absn, _erro, _erro, _null, _null},
/*ABSENT */ {_s2__, _s2__, _s2__, _void, _2___, _absn, _absn, _erro, _erro, _null, _absn},
/*INT */ {dot_s_xx, dot_s_xx, dot_s_xx, _s1__, dot_s_xx, dot_te, dot_te, dot_te, dot_te, _1___, _s1__},
/*FLOAT */ {dot_s_xx, dot_s_xx, dot_s_xx, _s1__, dot_s_xx, dot_te, dot_te, dot_te, dot_te, _1___, _s1__},
/*BOOL */ {dot_s_xx, dot_s_xx, dot_s_xx, _s1__, dot_s_xx, dot_te, dot_te, dot_te, dot_te, _1___, _s1__},
/*VOID */ {_s2__, _s2__, _s2__, _void, _2___, _absn, _absn, dot_te, dot_te, _void, _void},
/*STRING */ {dot_s_xx, dot_s_xx, dot_s_xx, _1___, dot_s_xx, dot_te, dot_te, dot_te, dot_te, _1___, _1___},
/*ARRAY */ {dot_te, dot_te, dot_te, dot_te, dot_te, dot_te, dot_te, dot_te, dot_te, dot_te, dot_te},
/*MAP */ {dot_te, dot_te, dot_te, dot_te, dot_te, dot_te, dot_te, dot_te, dot_te, dot_te, dot_te},
/*FUNC */ {dot_te, dot_te, dot_te, dot_te, dot_te, dot_te, dot_te, dot_te, dot_te, dot_te, dot_te},
/*ERROR */ {dot_te, dot_te, dot_te, dot_te, dot_te, _absn, _absn, dot_te, dot_te, dot_te, dot_te},
/*NULL */ {_s2__, _s2__, _s2__, _void, _2___, _absn, _absn, dot_te, dot_te, _null, _null},
/*ABSENT */ {_s2__, _s2__, _s2__, _void, _2___, _absn, _absn, dot_te, dot_te, _null, _absn},
}
func BIF_dot(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -70,7 +75,7 @@ func BIF_substr_1_up(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.ABSENT
}
if input1.IsError() {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("substr1", input1)
}
sinput := input1.String()
@ -102,7 +107,7 @@ func BIF_substr_0_up(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.ABSENT
}
if input1.IsError() {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("substr0", input1)
}
sinput := input1.String()
@ -134,7 +139,7 @@ func BIF_index(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.ABSENT
}
if input1.IsError() {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("index", input1)
}
sinput1 := input1.String()
sinput2 := input2.String()
@ -157,7 +162,7 @@ func BIF_contains(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.ABSENT
}
if input1.IsError() {
return mlrval.ERROR
return input1
}
return mlrval.FromBool(strings.Contains(input1.String(), input2.String()))
@ -172,13 +177,13 @@ func BIF_truncate(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return input2
}
if !input1.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("truncate", input1)
}
if !input2.IsInt() {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("truncate", input2)
}
if input2.AcquireIntValue() < 0 {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("truncate", input2)
}
// Handle UTF-8 correctly: len(input1.AcquireStringValue()) will count bytes, not runes.
@ -205,7 +210,7 @@ func BIF_leftpad(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
}
if !input2.IsInt() {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("leftpad", input2)
}
inputString := input1.String()
@ -238,7 +243,7 @@ func BIF_rightpad(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
}
if !input2.IsInt() {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("rightpad", input2)
}
inputString := input1.String()
@ -353,7 +358,7 @@ func BIF_format(mlrvals []*mlrval.Mlrval) *mlrval.Mlrval {
}
formatString, ok := mlrvals[0].GetStringValue()
if !ok { // not a string
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("format", mlrvals[0])
}
pieces := lib.SplitString(formatString, "{}")
@ -405,11 +410,11 @@ func BIF_unformatx(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
func bif_unformat_aux(input1, input2 *mlrval.Mlrval, inferTypes bool) *mlrval.Mlrval {
template, ok1 := input1.GetStringValue()
if !ok1 {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("unformat", input1)
}
input, ok2 := input2.GetStringValue()
if !ok2 {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("unformat", input2)
}
templatePieces := strings.Split(template, "{}")
@ -422,7 +427,15 @@ func bif_unformat_aux(input1, input2 *mlrval.Mlrval, inferTypes bool) *mlrval.Ml
remaining := input
if !strings.HasPrefix(remaining, templatePieces[0]) {
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf(
"unformat(\"%s\", \"%s\"): component \"%s\" lacks prefix \"%s\"",
input1.OriginalString(),
input2.OriginalString(),
remaining,
templatePieces[0],
),
)
}
remaining = remaining[len(templatePieces[0]):]
templatePieces = templatePieces[1:]
@ -438,7 +451,15 @@ func bif_unformat_aux(input1, input2 *mlrval.Mlrval, inferTypes bool) *mlrval.Ml
} else {
index = strings.Index(remaining, templatePiece)
if index < 0 {
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf(
"unformat(\"%s\", \"%s\"): component \"%s\" lacks prefix \"%s\"",
input1.OriginalString(),
input2.OriginalString(),
remaining,
templatePiece,
),
)
}
}
@ -466,12 +487,12 @@ func BIF_hexfmt(input1 *mlrval.Mlrval) *mlrval.Mlrval {
// ----------------------------------------------------------------
func fmtnum_is(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("fmtnum", input2)
}
formatString := input2.AcquireStringValue()
formatter, err := mlrval.GetFormatter(formatString)
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
return formatter.Format(input1)
@ -479,12 +500,12 @@ func fmtnum_is(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
func fmtnum_fs(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("fmtnum", input2)
}
formatString := input2.AcquireStringValue()
formatter, err := mlrval.GetFormatter(formatString)
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
return formatter.Format(input1)
@ -492,12 +513,12 @@ func fmtnum_fs(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
func fmtnum_bs(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input2.IsString() {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("fmtnum", input2)
}
formatString := input2.AcquireStringValue()
formatter, err := mlrval.GetFormatter(formatString)
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
intMv := mlrval.FromInt(lib.BoolToInt(input1.AcquireBoolValue()))
@ -505,19 +526,23 @@ func fmtnum_bs(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return formatter.Format(intMv)
}
func fmtnum_te(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("fmtnum", input1, input2)
}
var fmtnum_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
/*INT */ {_erro, _erro, _erro, _erro, fmtnum_is, _erro, _erro, _erro, _erro, _erro, _absn},
/*FLOAT */ {_erro, _erro, _erro, _erro, fmtnum_fs, _erro, _erro, _erro, _erro, _erro, _absn},
/*BOOL */ {_erro, _erro, _erro, _erro, fmtnum_bs, _erro, _erro, _erro, _erro, _erro, _absn},
/*VOID */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _absn},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _absn},
/*ARRAY */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _absn},
/*MAP */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _absn},
/*FUNC */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*NULL */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _erro, _absn},
/*ABSENT */ {_absn, _absn, _erro, _absn, _absn, _erro, _erro, _erro, _erro, _absn, _absn},
/*INT */ {fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_is, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, _absn},
/*FLOAT */ {fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_fs, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, _absn},
/*BOOL */ {fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_bs, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, _absn},
/*VOID */ {fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, _absn},
/*STRING */ {fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, _absn},
/*ARRAY */ {fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, _absn},
/*MAP */ {fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, _absn},
/*FUNC */ {fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te},
/*ERROR */ {fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te},
/*NULL */ {fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, _absn},
/*ABSENT */ {_absn, _absn, fmtnum_te, _absn, _absn, fmtnum_te, fmtnum_te, fmtnum_te, fmtnum_te, _absn, _absn},
}
func BIF_fmtnum(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
@ -549,7 +574,7 @@ func BIF_latin1_to_utf8(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if err != nil {
// Somewhat arbitrary design decision
// return input1
return mlrval.ERROR
return mlrval.FromError(err)
} else {
return mlrval.FromString(output)
}
@ -566,7 +591,7 @@ func BIF_utf8_to_latin1(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if err != nil {
// Somewhat arbitrary design decision
// return input1
return mlrval.ERROR
return mlrval.FromError(err)
} else {
return mlrval.FromString(output)
}

View file

@ -22,7 +22,7 @@ func BIF_os() *mlrval.Mlrval {
func BIF_hostname() *mlrval.Mlrval {
hostname, err := os.Hostname()
if err != nil {
return mlrval.ERROR
return mlrval.FromErrorString("could not retrieve system hostname")
} else {
return mlrval.FromString(hostname)
}
@ -30,7 +30,7 @@ func BIF_hostname() *mlrval.Mlrval {
func BIF_system(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsStringOrVoid() {
return mlrval.ERROR
return mlrval.FromNotStringError("system", input1)
}
commandString := input1.AcquireStringValue()
@ -38,7 +38,7 @@ func BIF_system(input1 *mlrval.Mlrval) *mlrval.Mlrval {
outputBytes, err := exec.Command(shellRunArray[0], shellRunArray[1:]...).Output()
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
outputString := strings.TrimRight(string(outputBytes), "\n")
@ -48,7 +48,7 @@ func BIF_system(input1 *mlrval.Mlrval) *mlrval.Mlrval {
func BIF_exec(mlrvals []*mlrval.Mlrval) *mlrval.Mlrval {
if len(mlrvals) == 0 {
return mlrval.ERROR
return mlrval.FromErrorString("exec: zero-length input given")
}
cmd := exec.Command(mlrvals[0].String())
@ -96,7 +96,7 @@ func BIF_exec(mlrvals []*mlrval.Mlrval) *mlrval.Mlrval {
}
if err != nil {
return mlrval.ERROR
return mlrval.FromError(err)
}
outputString := strings.TrimRight(string(outputBytes), "\n")

View file

@ -21,7 +21,14 @@ func string_to_int(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if ok {
return mlrval.FromInt(i)
} else {
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf(
"%s: unacceptable value %s with type %s",
"int",
input1.StringMaybeQuoted(),
input1.GetTypeName(),
),
)
}
}
@ -37,16 +44,20 @@ func bool_to_int(input1 *mlrval.Mlrval) *mlrval.Mlrval {
}
}
func to_int_te(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorUnary("int", input1)
}
var to_int_dispositions = [mlrval.MT_DIM]UnaryFunc{
/*INT */ _1u___,
/*FLOAT */ float_to_int,
/*BOOL */ bool_to_int,
/*VOID */ _void1,
/*STRING */ string_to_int,
/*ARRAY */ _erro1,
/*MAP */ _erro1,
/*FUNC */ _erro1,
/*ERROR */ _erro1,
/*ARRAY */ to_int_te,
/*MAP */ to_int_te,
/*FUNC */ to_int_te,
/*ERROR */ to_int_te,
/*NULL */ _null1,
/*ABSENT */ _absn1,
}
@ -61,7 +72,14 @@ func string_to_int_with_base(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if ok {
return mlrval.FromInt(i)
} else {
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf(
"%s: unacceptable value %s with type %s",
"int",
input1.StringMaybeQuoted(),
input1.GetTypeName(),
),
)
}
}
@ -81,23 +99,27 @@ func bool_to_int_with_base(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
}
}
func to_int_with_base_te(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorBinary("int", input1, input2)
}
var to_int_with_base_dispositions = [mlrval.MT_DIM]BinaryFunc{
/*INT */ int_to_int_with_base,
/*FLOAT */ float_to_int_with_base,
/*BOOL */ bool_to_int_with_base,
/*VOID */ _void,
/*STRING */ string_to_int_with_base,
/*ARRAY */ _erro,
/*MAP */ _erro,
/*FUNC */ _erro,
/*ERROR */ _erro,
/*ARRAY */ to_int_with_base_te,
/*MAP */ to_int_with_base_te,
/*FUNC */ to_int_with_base_te,
/*ERROR */ to_int_with_base_te,
/*NULL */ _null,
/*ABSENT */ _absn,
}
func BIF_int_with_base(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input2.IsInt() {
return mlrval.ERROR
return mlrval.FromTypeErrorBinary("int", input1, input2)
}
return to_int_with_base_dispositions[input1.Type()](input1, input2)
}
@ -108,7 +130,14 @@ func string_to_float(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if ok {
return mlrval.FromFloat(f)
} else {
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf(
"%s: unacceptable value %s with type %s",
"float",
input1.StringMaybeQuoted(),
input1.GetTypeName(),
),
)
}
}
@ -124,16 +153,20 @@ func bool_to_float(input1 *mlrval.Mlrval) *mlrval.Mlrval {
}
}
func to_float_te(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorUnary("float", input1)
}
var to_float_dispositions = [mlrval.MT_DIM]UnaryFunc{
/*INT */ int_to_float,
/*FLOAT */ _1u___,
/*BOOL */ bool_to_float,
/*VOID */ _void1,
/*STRING */ string_to_float,
/*ARRAY */ _erro1,
/*MAP */ _erro1,
/*FUNC */ _erro1,
/*ERROR */ _erro1,
/*ARRAY */ to_float_te,
/*MAP */ to_float_te,
/*FUNC */ to_float_te,
/*ERROR */ to_float_te,
/*NULL */ _null1,
/*ABSENT */ _absn1,
}
@ -148,7 +181,14 @@ func string_to_boolean(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if ok {
return mlrval.FromBool(b)
} else {
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf(
"%s: unacceptable value %s with type %s",
"boolean",
input1.StringMaybeQuoted(),
input1.GetTypeName(),
),
)
}
}
@ -160,16 +200,20 @@ func float_to_bool(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromBool(input1.AcquireFloatValue() != 0.0)
}
func to_boolean_te(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromTypeErrorUnary("boolean", input1)
}
var to_boolean_dispositions = [mlrval.MT_DIM]UnaryFunc{
/*INT */ int_to_bool,
/*FLOAT */ float_to_bool,
/*BOOL */ _1u___,
/*VOID */ _void1,
/*STRING */ string_to_boolean,
/*ARRAY */ _erro1,
/*MAP */ _erro1,
/*FUNC */ _erro1,
/*ERROR */ _erro1,
/*ARRAY */ to_boolean_te,
/*MAP */ to_boolean_te,
/*FUNC */ to_boolean_te,
/*ERROR */ to_boolean_te,
/*NULL */ _null1,
/*ABSENT */ _absn1,
}

View file

@ -2711,6 +2711,15 @@ var MiscFlagSection = FlagSection{
infoPrinter: MiscPrintInfo,
flags: []Flag{
{
name: "-x",
help: "If any record has an error value in it, report it and stop the process. The default is to print the field value as `(error)` and continue.",
parser: func(args []string, argc int, pargi *int, options *TOptions) {
options.WriterOptions.FailOnDataError = true
*pargi += 1
},
},
{
name: "-n",
help: "Process no input files, nor standard input either. Useful for `mlr put` with `begin`/`end` statements only. (Same as `--from /dev/null`.) Also useful in `mlr -n put -v '...'` for analyzing abstract syntax trees (if that's your thing).",

View file

@ -135,6 +135,9 @@ type TWriterOptions struct {
// For floating-point numbers: "" means use the Go default.
FPOFMT string
// Fatal the process when error data in a given record is about to be output.
FailOnDataError bool
}
// ----------------------------------------------------------------

View file

@ -261,6 +261,10 @@ func parseCommandLinePassTwo(
options.WriterOptions.FPOFMT = mlr_ofmt
}
if os.Getenv("MLR_FAIL_ON_DATA_ERROR") != "" {
options.WriterOptions.FailOnDataError = true
}
recordTransformers = make([]transformers.IRecordTransformer, 0)
err = nil
ignoresInput := false

View file

@ -752,7 +752,7 @@ func (node *LogicalANDOperatorNode) Evaluate(
aout := node.a.Evaluate(state)
atype := aout.Type()
if !(atype == mlrval.MT_ABSENT || atype == mlrval.MT_BOOL) {
return mlrval.ERROR
return mlrval.FromNotNamedTypeError("&&", aout, "absent or boolean")
}
if atype == mlrval.MT_ABSENT {
return mlrval.ABSENT
@ -768,7 +768,7 @@ func (node *LogicalANDOperatorNode) Evaluate(
bout := node.b.Evaluate(state)
btype := bout.Type()
if !(btype == mlrval.MT_ABSENT || btype == mlrval.MT_BOOL) {
return mlrval.ERROR
return mlrval.FromNotNamedTypeError("&&", bout, "absent or boolean")
}
if btype == mlrval.MT_ABSENT {
return mlrval.ABSENT
@ -800,7 +800,7 @@ func (node *LogicalOROperatorNode) Evaluate(
aout := node.a.Evaluate(state)
atype := aout.Type()
if !(atype == mlrval.MT_ABSENT || atype == mlrval.MT_BOOL) {
return mlrval.ERROR
return mlrval.FromNotNamedTypeError("||", aout, "absent or boolean")
}
if atype == mlrval.MT_ABSENT {
return mlrval.ABSENT
@ -816,7 +816,7 @@ func (node *LogicalOROperatorNode) Evaluate(
bout := node.b.Evaluate(state)
btype := bout.Type()
if !(btype == mlrval.MT_ABSENT || btype == mlrval.MT_BOOL) {
return mlrval.ERROR
return mlrval.FromNotNamedTypeError("||", bout, "absent or boolean")
}
if btype == mlrval.MT_ABSENT {
return mlrval.ABSENT
@ -884,7 +884,7 @@ func (node *StandardTernaryOperatorNode) Evaluate(
boolValue, isBool := aout.GetBoolValue()
if !isBool {
return mlrval.ERROR
return mlrval.FromNotBooleanError("?:", aout)
}
// Short-circuit: defer evaluation unless needed
@ -908,10 +908,10 @@ func (node *StandardTernaryOperatorNode) Evaluate(
func BinaryShortCircuitPlaceholder(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
lib.InternalCodingErrorPanic("Short-circuting was not correctly implemented")
return mlrval.ERROR // not reached
return nil // not reached
}
func TernaryShortCircuitPlaceholder(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
lib.InternalCodingErrorPanic("Short-circuting was not correctly implemented")
return mlrval.ERROR // not reached
return nil // not reached
}

View file

@ -6,6 +6,8 @@
package cst
import (
"fmt"
"github.com/johnkerl/miller/internal/pkg/bifs"
"github.com/johnkerl/miller/internal/pkg/dsl"
"github.com/johnkerl/miller/internal/pkg/lib"
@ -97,14 +99,28 @@ func (node *ArrayOrMapIndexAccessNode) Evaluate(
} else if baseMlrval.IsStringOrVoid() {
mindex, isInt := indexMlrval.GetIntValue()
if !isInt {
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf(
"unacceptable non-int index value %s of type %s on base value %s",
indexMlrval.StringMaybeQuoted(),
indexMlrval.GetTypeName(),
baseMlrval.StringMaybeQuoted(),
),
)
}
// Handle UTF-8 correctly: len(input1.printrep) will count bytes, not runes.
runes := []rune(baseMlrval.String())
// Miller uses 1-up, and negatively aliased, indexing for strings and arrays.
zindex, inBounds := mlrval.UnaliasArrayLengthIndex(len(runes), int(mindex))
if !inBounds {
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf(
"cannot index base string %s of length %d with out-of-bounds index %d",
baseMlrval.StringMaybeQuoted(),
len(runes),
int(mindex),
),
)
}
return mlrval.FromString(string(runes[zindex]))
@ -112,7 +128,13 @@ func (node *ArrayOrMapIndexAccessNode) Evaluate(
// For strict mode, absence should be detected on the baseMlrval and indexMlrval evaluators.
return mlrval.ABSENT
} else {
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf(
"cannot index base value %s of type %s, which is not array, map, or string",
baseMlrval.StringMaybeQuoted(),
baseMlrval.GetTypeName(),
),
)
}
}
@ -171,7 +193,13 @@ func (node *ArraySliceAccessNode) Evaluate(
}
array := baseMlrval.GetArray()
if array == nil {
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf(
"cannot slice base value %s with non-array type %s",
baseMlrval.StringMaybeQuoted(),
baseMlrval.GetTypeName(),
),
)
}
n := len(array)
@ -236,7 +264,7 @@ func (node *PositionalFieldNameNode) Evaluate(
index, ok := indexMlrval.GetIntValue()
if !ok {
return mlrval.ERROR
return mlrval.FromNotIntError("$[[...]]", indexMlrval)
}
name, ok := state.Inrec.GetNameAtPositionalIndex(index)
@ -282,7 +310,7 @@ func (node *PositionalFieldValueNode) Evaluate(
index, ok := indexMlrval.GetIntValue()
if !ok {
return mlrval.ERROR
return mlrval.FromNotIntError("$[[...]]", indexMlrval)
}
retval := state.Inrec.GetWithPositionalIndex(index)
@ -338,7 +366,7 @@ func (node *ArrayOrMapPositionalNameAccessNode) Evaluate(
index, ok := indexMlrval.GetIntValue()
if !ok {
return mlrval.ERROR
return mlrval.FromNotIntError("$[[...]]", indexMlrval)
}
if baseMlrval.IsArray() {
@ -363,7 +391,13 @@ func (node *ArrayOrMapPositionalNameAccessNode) Evaluate(
return mlrval.ABSENT
} else {
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf(
"cannot index base value %s of type %s, which is not array, map, or string",
baseMlrval.StringMaybeQuoted(),
baseMlrval.GetTypeName(),
),
)
}
}
@ -412,7 +446,7 @@ func (node *ArrayOrMapPositionalValueAccessNode) Evaluate(
index, ok := indexMlrval.GetIntValue()
if !ok {
return mlrval.ERROR
return mlrval.FromNotIntError("$[[...]]", indexMlrval)
}
if baseMlrval.IsArray() {
@ -434,7 +468,13 @@ func (node *ArrayOrMapPositionalValueAccessNode) Evaluate(
return mlrval.ABSENT
} else {
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf(
"cannot index base value %s of type %s, which is not array, map, or string",
baseMlrval.StringMaybeQuoted(),
baseMlrval.GetTypeName(),
),
)
}
}

View file

@ -41,7 +41,7 @@ func (node *EnvironmentVariableNode) Evaluate(
return mlrval.ABSENT.StrictModeCheck(state.StrictMode, "ENV[(absent)]")
}
if !name.IsString() {
return mlrval.ERROR
return mlrval.FromTypeErrorUnary("ENV[]", name)
}
return mlrval.FromString(os.Getenv(name.String()))

View file

@ -207,7 +207,7 @@ func SelectHOF(
} else if input1.IsMap() {
return selectMap(input1, input2, state)
} else {
return mlrval.ERROR
return mlrval.FromNotCollectionError("select", input1)
}
}
@ -216,9 +216,9 @@ func selectArray(
input2 *mlrval.Mlrval,
state *runtime.State,
) *mlrval.Mlrval {
inputArray := input1.GetArray()
inputArray, errVal := input1.GetArrayValueOrError("select")
if inputArray == nil { // not an array
return mlrval.ERROR
return errVal
}
isFunctionOrDie(input2, "select")
@ -252,9 +252,9 @@ func selectMap(
input2 *mlrval.Mlrval,
state *runtime.State,
) *mlrval.Mlrval {
inputMap := input1.GetMap()
inputMap, errVal := input1.GetMapValueOrError("select")
if inputMap == nil { // not a map
return mlrval.ERROR
return errVal
}
isFunctionOrDie(input2, "select")
@ -298,7 +298,7 @@ func ApplyHOF(
} else if input1.IsMap() {
return applyMap(input1, input2, state)
} else {
return mlrval.ERROR
return mlrval.FromNotCollectionError("apply", input1)
}
}
@ -307,9 +307,9 @@ func applyArray(
input2 *mlrval.Mlrval,
state *runtime.State,
) *mlrval.Mlrval {
inputArray := input1.GetArray()
if inputArray == nil { // not an array
return mlrval.ERROR
inputArray, errVal := input1.GetArrayValueOrError("apply")
if inputArray == nil {
return errVal
}
isFunctionOrDie(input2, "apply")
@ -334,9 +334,9 @@ func applyMap(
input2 *mlrval.Mlrval,
state *runtime.State,
) *mlrval.Mlrval {
inputMap := input1.GetMap()
inputMap, errVal := input1.GetMapValueOrError("apply")
if inputMap == nil { // not a map
return mlrval.ERROR
return errVal
}
isFunctionOrDie(input2, "apply")
@ -369,7 +369,7 @@ func ReduceHOF(
} else if input1.IsMap() {
return reduceMap(input1, input2, state)
} else {
return mlrval.ERROR
return mlrval.FromNotCollectionError("reduce", input1)
}
}
@ -378,9 +378,9 @@ func reduceArray(
input2 *mlrval.Mlrval,
state *runtime.State,
) *mlrval.Mlrval {
inputArray := input1.GetArray()
if inputArray == nil { // not an array
return mlrval.ERROR
inputArray, errVal := input1.GetArrayValueOrError("reduce")
if inputArray == nil {
return errVal
}
isFunctionOrDie(input2, "reduce")
@ -408,9 +408,9 @@ func reduceMap(
input2 *mlrval.Mlrval,
state *runtime.State,
) *mlrval.Mlrval {
inputMap := input1.GetMap()
inputMap, errVal := input1.GetMapValueOrError("reduce")
if inputMap == nil { // not a map
return mlrval.ERROR
return errVal
}
isFunctionOrDie(input2, "reduce")
@ -449,7 +449,7 @@ func FoldHOF(
} else if input1.IsMap() {
return foldMap(input1, input2, input3, state)
} else {
return mlrval.ERROR
return mlrval.FromNotCollectionError("fold", input1)
}
}
@ -459,9 +459,9 @@ func foldArray(
input3 *mlrval.Mlrval,
state *runtime.State,
) *mlrval.Mlrval {
inputArray := input1.GetArray()
if inputArray == nil { // not an array
return mlrval.ERROR
inputArray, errVal := input1.GetArrayValueOrError("fold")
if inputArray == nil {
return errVal
}
isFunctionOrDie(input2, "fold")
@ -486,9 +486,9 @@ func foldMap(
input3 *mlrval.Mlrval,
state *runtime.State,
) *mlrval.Mlrval {
inputMap := input1.GetMap()
inputMap, errVal := input1.GetMapValueOrError("fold")
if inputMap == nil { // not a map
return mlrval.ERROR
return errVal
}
isFunctionOrDie(input2, "fold")
@ -528,7 +528,7 @@ func SortHOF(
} else if inputs[0].IsMap() {
return sortM(inputs[0], "")
} else {
return mlrval.ERROR
return mlrval.FromNotCollectionError("sort", inputs[0])
}
} else if inputs[1].IsStringOrVoid() {
@ -537,7 +537,7 @@ func SortHOF(
} else if inputs[0].IsMap() {
return sortM(inputs[0], inputs[1].String())
} else {
return mlrval.ERROR
return mlrval.FromNotCollectionError("sort", inputs[0])
}
} else if inputs[1].IsFunction() {
@ -546,7 +546,7 @@ func SortHOF(
} else if inputs[0].IsMap() {
return sortMF(inputs[0], inputs[1], state)
} else {
return mlrval.ERROR
return mlrval.FromNotCollectionError("sort", inputs[0])
}
} else {
@ -555,7 +555,9 @@ func SortHOF(
)
os.Exit(1)
}
return mlrval.ERROR
// Not reached
lib.InternalCodingErrorIf(true)
return nil
}
// ----------------------------------------------------------------
@ -600,10 +602,10 @@ func sortA(
input1 *mlrval.Mlrval,
flags string,
) *mlrval.Mlrval {
if input1.GetArray() == nil { // not an array
return mlrval.ERROR
temp, errVal := input1.GetArrayValueOrError("sort")
if temp == nil { // not an array
return errVal
}
output := input1.Copy()
// byMapValue is ignored for sorting arrays
@ -677,19 +679,19 @@ func sortM(
input1 *mlrval.Mlrval,
flags string,
) *mlrval.Mlrval {
inmap := input1.GetMap()
if inmap == nil { // not a map
return mlrval.ERROR
inputMap, errVal := input1.GetMapValueOrError("sort")
if inputMap == nil { // not a map
return errVal
}
// Get sort-flags, if provided
sortType, reverse, byMapValue := decodeSortFlags(flags)
// Copy the entries to an array for sorting.
n := inmap.FieldCount
n := inputMap.FieldCount
entries := make([]mlrval.MlrmapEntryForArray, n)
i := 0
for pe := inmap.Head; pe != nil; pe = pe.Next {
for pe := inputMap.Head; pe != nil; pe = pe.Next {
entries[i].Key = pe.Key
entries[i].Value = pe.Value // pointer alias for now until new map at end of this function
i++
@ -838,13 +840,11 @@ func sortAF(
input2 *mlrval.Mlrval,
state *runtime.State,
) *mlrval.Mlrval {
inputArray := input1.GetArray()
inputArray, errVal := input1.GetArrayValueOrError("select")
if inputArray == nil { // not an array
return mlrval.ERROR
}
if !input2.IsFunction() {
return mlrval.ERROR
return errVal
}
isFunctionOrDie(input2, "sort")
hofSpace := getHOFSpace(input2, 2, "sort", "array")
udfCallsite := hofSpace.udfCallsite
@ -881,13 +881,11 @@ func sortMF(
input2 *mlrval.Mlrval,
state *runtime.State,
) *mlrval.Mlrval {
inputMap := input1.GetMap()
inputMap, errVal := input1.GetMapValueOrError("sort")
if inputMap == nil { // not a map
return mlrval.ERROR
}
if !input2.IsFunction() {
return mlrval.ERROR
return errVal
}
isFunctionOrDie(input2, "sort")
pairsArray := inputMap.ToPairsArray()
@ -936,7 +934,7 @@ func AnyHOF(
} else if input1.IsMap() {
return anyMap(input1, input2, state)
} else {
return mlrval.ERROR
return mlrval.FromNotCollectionError("any", input1)
}
}
@ -945,9 +943,9 @@ func anyArray(
input2 *mlrval.Mlrval,
state *runtime.State,
) *mlrval.Mlrval {
inputArray := input1.GetArray()
inputArray, errVal := input1.GetArrayValueOrError("any")
if inputArray == nil { // not an array
return mlrval.ERROR
return errVal
}
isFunctionOrDie(input2, "any")
@ -981,9 +979,9 @@ func anyMap(
input2 *mlrval.Mlrval,
state *runtime.State,
) *mlrval.Mlrval {
inputMap := input1.GetMap()
inputMap, errVal := input1.GetMapValueOrError("any")
if inputMap == nil { // not a map
return mlrval.ERROR
return errVal
}
isFunctionOrDie(input2, "any")
@ -1028,7 +1026,7 @@ func EveryHOF(
} else if input1.IsMap() {
return everyMap(input1, input2, state)
} else {
return mlrval.ERROR
return mlrval.FromNotCollectionError("every", input1)
}
}
@ -1037,9 +1035,9 @@ func everyArray(
input2 *mlrval.Mlrval,
state *runtime.State,
) *mlrval.Mlrval {
inputArray := input1.GetArray()
inputArray, errVal := input1.GetArrayValueOrError("every")
if inputArray == nil { // not an array
return mlrval.ERROR
return errVal
}
isFunctionOrDie(input2, "every")
@ -1073,9 +1071,9 @@ func everyMap(
input2 *mlrval.Mlrval,
state *runtime.State,
) *mlrval.Mlrval {
inputMap := input1.GetMap()
inputMap, errVal := input1.GetMapValueOrError("every")
if inputMap == nil { // not a map
return mlrval.ERROR
return errVal
}
isFunctionOrDie(input2, "every")

View file

@ -250,12 +250,12 @@ func (site *UDFCallsite) EvaluateWithArguments(
// 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 {
err = udf.signature.typeGatedReturnValue.Check(mlrval.ERROR)
if err != nil {
fmt.Fprint(os.Stderr, err)
err2 := udf.signature.typeGatedReturnValue.Check(mlrval.FromError(err))
if err2 != nil {
fmt.Fprint(os.Stderr, err2)
os.Exit(1)
}
return mlrval.ERROR
return mlrval.FromError(err)
}
// Fell off end of function with no return

View file

@ -31,9 +31,11 @@ func InternalCodingErrorIf(condition bool) {
"(unknown)",
)
}
// Uncomment this and re-run if you want to get a stack trace to get the
// Use this and re-run if you want to get a stack trace to get the
// call-tree that led to the indicated file/line:
// panic("eek")
if os.Getenv("MLR_PANIC_ON_INTERNAL_ERROR") != "" {
panic("Here is the stack trace")
}
os.Exit(1)
}
@ -61,9 +63,11 @@ func InternalCodingErrorWithMessageIf(condition bool, message string) {
message,
)
}
// Uncomment this and re-run if you want to get a stack trace to get the
// use this and re-run if you want to get a stack trace to get the
// call-tree that led to the indicated file/line:
// panic("eek")
if os.Getenv("MLR_PANIC_ON_INTERNAL_ERROR") != "" {
panic("Here is the stack trace")
}
os.Exit(1)
}

View file

@ -153,7 +153,7 @@ func (entry *MlrmapEntry) JSONStringifyInPlace(
) {
outputBytes, err := entry.Value.MarshalJSON(jsonFormatting, false)
if err != nil {
entry.Value = ERROR
entry.Value = FromError(err)
} else {
entry.Value = FromString(string(outputBytes))
}
@ -165,7 +165,7 @@ func (entry *MlrmapEntry) JSONParseInPlace() {
input := entry.Value.String()
err := entry.Value.UnmarshalJSON([]byte(input))
if err != nil {
entry.Value = ERROR
entry.Value = FromError(err)
}
}

View file

@ -34,7 +34,7 @@ var orderedMlrvals = []*Mlrval{
// FromMap(NewMlrmap()),
// TODO:
ERROR,
FromErrorString("error text goes here"),
NULL,
ABSENT,
}

View file

@ -81,10 +81,10 @@ import (
// TODO: copy-reduction refactor
func (mv *Mlrval) ArrayGet(mindex *Mlrval) Mlrval {
if !mv.IsArray() {
return *ERROR
return *FromNotArrayError("array [] base", mv)
}
if !mindex.IsInt() {
return *ERROR
return *FromNotIntError("array [] index", mindex)
}
arrayval := mv.intf.([]*Mlrval)
value := arrayGetAliased(&arrayval, int(mindex.intf.(int64)))
@ -223,12 +223,12 @@ func (mv *Mlrval) ArrayAppend(value *Mlrval) {
// ================================================================
func (mv *Mlrval) MapGet(key *Mlrval) Mlrval {
if !mv.IsMap() {
return *ERROR
return *FromNotMapError("map[]", mv)
}
mval, err := mv.intf.(*Mlrmap).GetWithMlrvalIndex(key)
if err != nil { // xxx maybe error-return in the API
return *ERROR
if err != nil {
return *FromError(err)
}
if mval == nil {
return *ABSENT

View file

@ -41,12 +41,6 @@ var VOID = &Mlrval{
printrepValid: true,
}
var ERROR = &Mlrval{
mvtype: MT_ERROR,
printrep: ERROR_PRINTREP,
printrepValid: true,
}
var NULL = &Mlrval{
mvtype: MT_NULL,
printrep: "null",

View file

@ -23,6 +23,14 @@ func (mv *Mlrval) GetStringValue() (stringValue string, isString bool) {
}
}
func (mv *Mlrval) GetStringValueOrError(funcname string) (stringValue string, errValue *Mlrval) {
if mv.Type() == MT_STRING || mv.Type() == MT_VOID {
return mv.printrep, nil
} else {
return "", FromNotStringError(funcname, mv)
}
}
func (mv *Mlrval) GetIntValue() (intValue int64, isInt bool) {
if mv.Type() == MT_INT {
return mv.intf.(int64), true
@ -31,6 +39,14 @@ func (mv *Mlrval) GetIntValue() (intValue int64, isInt bool) {
}
}
func (mv *Mlrval) GetIntValueOrError(funcname string) (intValue int64, errValue *Mlrval) {
if mv.Type() == MT_INT {
return mv.intf.(int64), nil
} else {
return -999, FromNotIntError(funcname, mv)
}
}
func (mv *Mlrval) GetFloatValue() (floatValue float64, isFloat bool) {
if mv.Type() == MT_FLOAT {
return mv.intf.(float64), true
@ -49,6 +65,16 @@ func (mv *Mlrval) GetNumericToFloatValue() (floatValue float64, isFloat bool) {
}
}
func (mv *Mlrval) GetNumericToFloatValueOrError(funcname string) (floatValue float64, errValue *Mlrval) {
if mv.Type() == MT_FLOAT {
return mv.intf.(float64), nil
} else if mv.Type() == MT_INT {
return float64(mv.intf.(int64)), nil
} else {
return -888.0, FromNotNumericError(funcname, mv)
}
}
func (mv *Mlrval) GetNumericNegativeorDie() bool {
floatValue, ok := mv.GetNumericToFloatValue()
lib.InternalCodingErrorIf(!ok)
@ -71,6 +97,14 @@ func (mv *Mlrval) GetArray() []*Mlrval {
}
}
func (mv *Mlrval) GetArrayValueOrError(funcname string) (ok []*Mlrval, errValue *Mlrval) {
if mv.IsArray() {
return mv.intf.([]*Mlrval), nil
} else {
return nil, FromNotArrayError(funcname, mv)
}
}
func (mv *Mlrval) GetMap() *Mlrmap {
if mv.IsMap() {
return mv.intf.(*Mlrmap)
@ -79,6 +113,14 @@ func (mv *Mlrval) GetMap() *Mlrmap {
}
}
func (mv *Mlrval) GetMapValueOrError(funcname string) (ok *Mlrmap, errValue *Mlrval) {
if mv.IsMap() {
return mv.intf.(*Mlrmap), nil
} else {
return nil, FromNotMapError(funcname, mv)
}
}
func (mv *Mlrval) GetFunction() interface{} {
if mv.Type() == MT_FUNC {
return mv.intf

View file

@ -23,6 +23,14 @@ func (mv *Mlrval) IsError() bool {
return mv.Type() == MT_ERROR
}
func (mv *Mlrval) GetError() (bool, error) {
if mv.Type() == MT_ERROR {
return true, mv.err
} else {
return false, nil
}
}
// TODO: comment no JIT-infer here -- absent is non-inferrable and we needn't take the expense of JIT.
func (mv *Mlrval) IsAbsent() bool {
return mv.mvtype == MT_ABSENT

View file

@ -11,7 +11,7 @@ import (
)
func TestIsLegit(t *testing.T) {
assert.False(t, ERROR.IsLegit())
assert.False(t, FromErrorString("foo").IsLegit())
assert.False(t, ABSENT.IsLegit())
assert.False(t, NULL.IsLegit())
assert.True(t, FromString("").IsLegit())
@ -24,35 +24,35 @@ func TestIsLegit(t *testing.T) {
}
func TestIsErrorOrAbsent(t *testing.T) {
assert.True(t, ERROR.IsErrorOrAbsent())
assert.True(t, FromErrorString("foo").IsErrorOrAbsent())
assert.True(t, ABSENT.IsErrorOrAbsent())
assert.False(t, NULL.IsErrorOrAbsent())
assert.False(t, FromString("").IsErrorOrAbsent())
}
func TestIsError(t *testing.T) {
assert.True(t, ERROR.IsError())
assert.True(t, FromErrorString("foo").IsError())
assert.False(t, ABSENT.IsError())
assert.False(t, NULL.IsError())
assert.False(t, FromString("").IsError())
}
func TestIsAbsent(t *testing.T) {
assert.False(t, ERROR.IsAbsent())
assert.False(t, FromErrorString("foo").IsAbsent())
assert.True(t, ABSENT.IsAbsent())
assert.False(t, NULL.IsAbsent())
assert.False(t, FromString("").IsAbsent())
}
func TestIsNull(t *testing.T) {
assert.False(t, ERROR.IsNull())
assert.False(t, FromErrorString("foo").IsNull())
assert.False(t, ABSENT.IsNull())
assert.True(t, NULL.IsNull())
assert.False(t, FromString("").IsNull())
}
func TestIsVoid(t *testing.T) {
assert.False(t, ERROR.IsVoid())
assert.False(t, FromErrorString("foo").IsVoid())
assert.False(t, ABSENT.IsVoid())
assert.False(t, NULL.IsVoid())
assert.True(t, FromString("").IsVoid())
@ -63,7 +63,7 @@ func TestIsVoid(t *testing.T) {
}
func TestIsEmptyString(t *testing.T) {
assert.False(t, ERROR.IsEmptyString())
assert.False(t, FromErrorString("foo").IsEmptyString())
assert.False(t, ABSENT.IsEmptyString())
assert.False(t, NULL.IsEmptyString())
assert.True(t, FromString("").IsEmptyString())
@ -74,7 +74,7 @@ func TestIsEmptyString(t *testing.T) {
}
func TestIsString(t *testing.T) {
assert.False(t, ERROR.IsString())
assert.False(t, FromErrorString("foo").IsString())
assert.False(t, ABSENT.IsString())
assert.False(t, NULL.IsString())
assert.False(t, FromString("").IsString())
@ -89,7 +89,7 @@ func TestIsString(t *testing.T) {
}
func TestIsStringOrVoid(t *testing.T) {
assert.False(t, ERROR.IsStringOrVoid())
assert.False(t, FromErrorString("foo").IsStringOrVoid())
assert.False(t, ABSENT.IsStringOrVoid())
assert.False(t, NULL.IsStringOrVoid())
assert.True(t, FromString("").IsStringOrVoid())

View file

@ -5,7 +5,8 @@
package mlrval
import (
//"errors"
"errors"
"fmt"
"github.com/johnkerl/miller/internal/pkg/lib"
)
@ -31,6 +32,115 @@ func FromDeferredType(input string) *Mlrval {
}
}
func FromError(err error) *Mlrval {
return &Mlrval{
mvtype: MT_ERROR,
err: err,
printrep: ERROR_PRINTREP,
printrepValid: true,
}
}
func FromErrorString(err string) *Mlrval {
return &Mlrval{
mvtype: MT_ERROR,
err: errors.New(err),
printrep: ERROR_PRINTREP,
printrepValid: true,
}
}
func FromAnonymousError() *Mlrval {
return &Mlrval{
mvtype: MT_ERROR,
printrep: ERROR_PRINTREP,
printrepValid: true,
}
}
func FromTypeErrorUnary(funcname string, v *Mlrval) *Mlrval {
return FromError(
fmt.Errorf(
"%s: unacceptable type %s with value %s",
funcname,
v.GetTypeName(),
v.StringMaybeQuoted(),
),
)
}
func FromTypeErrorBinary(funcname string, v, input2 *Mlrval) *Mlrval {
return FromError(
fmt.Errorf(
"%s: unacceptable types %s, %s with values %s, %s",
funcname,
v.GetTypeName(),
input2.GetTypeName(),
v.StringMaybeQuoted(),
input2.StringMaybeQuoted(),
),
)
}
func FromTypeErrorTernary(funcname string, v, input2, input3 *Mlrval) *Mlrval {
return FromError(
fmt.Errorf(
"%s: unacceptable types %s, %s, %s with values %s, %s, %s",
funcname,
v.GetTypeName(),
input2.GetTypeName(),
input3.GetTypeName(),
v.StringMaybeQuoted(),
input2.StringMaybeQuoted(),
input3.StringMaybeQuoted(),
),
)
}
func FromNotStringError(funcname string, v *Mlrval) *Mlrval {
return FromNotNamedTypeError(funcname, v, "string")
}
func FromNotBooleanError(funcname string, v *Mlrval) *Mlrval {
return FromNotNamedTypeError(funcname, v, "boolean")
}
func FromNotIntError(funcname string, v *Mlrval) *Mlrval {
return FromNotNamedTypeError(funcname, v, "int")
}
func FromNotNumericError(funcname string, v *Mlrval) *Mlrval {
return FromNotNamedTypeError(funcname, v, "int or float")
}
func FromNotArrayError(funcname string, v *Mlrval) *Mlrval {
return FromNotNamedTypeError(funcname, v, "array")
}
func FromNotMapError(funcname string, v *Mlrval) *Mlrval {
return FromNotNamedTypeError(funcname, v, "map")
}
func FromNotCollectionError(funcname string, v *Mlrval) *Mlrval {
return FromNotNamedTypeError(funcname, v, "array or map")
}
func FromNotFunctionError(funcname string, v *Mlrval) *Mlrval {
return FromNotNamedTypeError(funcname, v, "function")
}
func FromNotNamedTypeError(funcname string, v *Mlrval, expected_type_name string) *Mlrval {
return FromError(
fmt.Errorf(
"%s: unacceptable non-array value %s with type %s; needed type %s",
funcname,
v.StringMaybeQuoted(),
v.GetTypeName(),
expected_type_name,
),
)
}
// TODO: comment non-JIT context like mlr put -s.
// TODO: comment re inferBool.
func FromInferredType(input string) *Mlrval {

View file

@ -44,6 +44,16 @@ func (mv *Mlrval) OriginalString() string {
}
}
// StringMaybeQuoted Returns strings double-quoted; all else not.
func (mv *Mlrval) StringMaybeQuoted() string {
output := mv.String()
if mv.mvtype == MT_VOID || mv.mvtype == MT_STRING {
return `"` + output + `"`
} else {
return output
}
}
// See mlrval.go for more about JIT-formatting of string backings
func (mv *Mlrval) setPrintRep() {
if !mv.printrepValid {

View file

@ -37,7 +37,7 @@ func TestComparators(t *testing.T) {
assert.Equal(t, 0, LexicalAscendingComparator(bfalse, bfalse))
assert.Equal(t, -1, LexicalAscendingComparator(bfalse, btrue))
assert.Equal(t, -1, LexicalAscendingComparator(sabc, sdef))
assert.Equal(t, 0, LexicalAscendingComparator(ERROR, ERROR))
assert.Equal(t, 0, LexicalAscendingComparator(FromErrorString("foo"), FromErrorString("foo")))
assert.Equal(t, 0, LexicalAscendingComparator(ABSENT, ABSENT))
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -48,30 +48,30 @@ func TestComparators(t *testing.T) {
assert.Equal(t, 1, NumericAscendingComparator(btrue, bfalse))
assert.Equal(t, 0, NumericAscendingComparator(ERROR, ERROR))
assert.Equal(t, 0, NumericAscendingComparator(FromErrorString("foo"), FromErrorString("foo")))
assert.Equal(t, 0, NumericAscendingComparator(ABSENT, ABSENT))
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Across-type lexical comparisons
assert.Equal(t, -1, LexicalAscendingComparator(i10, btrue)) // "10" < "true"
assert.Equal(t, -1, LexicalAscendingComparator(i10, sabc)) // "10" < "abc"
assert.Equal(t, 1, LexicalAscendingComparator(i10, ERROR)) // "10" > "(error)"
assert.Equal(t, -1, LexicalAscendingComparator(i10, btrue)) // "10" < "true"
assert.Equal(t, -1, LexicalAscendingComparator(i10, sabc)) // "10" < "abc"
assert.Equal(t, 1, LexicalAscendingComparator(i10, FromErrorString("foo"))) // "10" > "(error)"
assert.Equal(t, 1, LexicalAscendingComparator(bfalse, sabc)) // "false" > "abc"
assert.Equal(t, 1, LexicalAscendingComparator(bfalse, ERROR)) // "false" > "(error)"
assert.Equal(t, 1, LexicalAscendingComparator(bfalse, sabc)) // "false" > "abc"
assert.Equal(t, 1, LexicalAscendingComparator(bfalse, FromErrorString("foo"))) // "false" > "(error)"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Across-type numeric comparisons
assert.Equal(t, -1, NumericAscendingComparator(i10, btrue))
assert.Equal(t, -1, NumericAscendingComparator(i10, sabc))
assert.Equal(t, -1, NumericAscendingComparator(i10, ERROR))
assert.Equal(t, -1, NumericAscendingComparator(i10, FromErrorString("foo")))
assert.Equal(t, -1, NumericAscendingComparator(i10, ABSENT))
assert.Equal(t, -1, NumericAscendingComparator(bfalse, sabc))
assert.Equal(t, -1, NumericAscendingComparator(bfalse, ERROR))
assert.Equal(t, -1, NumericAscendingComparator(bfalse, FromErrorString("foo")))
assert.Equal(t, -1, NumericAscendingComparator(bfalse, ABSENT))
assert.Equal(t, -1, NumericAscendingComparator(ERROR, ABSENT))
assert.Equal(t, -1, NumericAscendingComparator(FromErrorString("foo"), ABSENT))
}

View file

@ -56,6 +56,7 @@ package mlrval
type Mlrval struct {
printrep string
intf interface{}
err error // Payload for MT_ERROR types
printrepValid bool
// Enumeration for string / int / float / boolean / etc.
// I would call this "type" not "mvtype" but "type" is a keyword in Go.

View file

@ -3,6 +3,8 @@ package output
import (
"bufio"
"container/list"
"fmt"
"os"
"github.com/johnkerl/miller/internal/pkg/cli"
"github.com/johnkerl/miller/internal/pkg/types"
@ -13,19 +15,26 @@ func ChannelWriter(
recordWriter IRecordWriter,
writerOptions *cli.TWriterOptions,
doneChannel chan<- bool,
dataProcessingErrorChannel chan<- bool,
bufferedOutputStream *bufio.Writer,
outputIsStdout bool,
) {
for {
recordsAndContexts := <-writerChannel
done := channelWriterHandleBatch(
done, errored := channelWriterHandleBatch(
recordsAndContexts,
recordWriter,
writerOptions,
dataProcessingErrorChannel,
bufferedOutputStream,
outputIsStdout,
)
if errored {
dataProcessingErrorChannel <- true
doneChannel <- true
break
}
if done {
doneChannel <- true
break
@ -39,9 +48,10 @@ func channelWriterHandleBatch(
recordsAndContexts *list.List,
recordWriter IRecordWriter,
writerOptions *cli.TWriterOptions,
dataProcessingErrorChannel chan<- bool,
bufferedOutputStream *bufio.Writer,
outputIsStdout bool,
) bool {
) (done bool, errored bool) {
for e := recordsAndContexts.Front(); e != nil; e = e.Next() {
recordAndContext := e.Value.(*types.RecordAndContext)
@ -56,6 +66,33 @@ func channelWriterHandleBatch(
if !recordAndContext.EndOfStream {
record := recordAndContext.Record
// XXX more
// XXX also make sure this results in exit 1 & goroutine cleanup
if writerOptions.FailOnDataError {
ok := true
for pe := record.Head; pe != nil; pe = pe.Next {
if pe.Value.IsError() {
context := recordAndContext.Context
fmt.Fprintf(os.Stderr, "mlr: data error at NR=%d FNR=%d FILENAME=%s\n",
context.NR, context.FNR, context.FILENAME,
)
is, err := pe.Value.GetError()
if is {
if err != nil {
fmt.Fprintf(os.Stderr, "mlr: field %s: %v\n", pe.Key, err)
} else {
fmt.Fprintf(os.Stderr, "mlr: field %s\n", pe.Key)
}
ok = false
}
}
}
if !ok {
return true, true
}
}
if record != nil {
recordWriter.Write(record, bufferedOutputStream, outputIsStdout)
}
@ -75,8 +112,8 @@ func channelWriterHandleBatch(
// records before printing any, since it needs to compute max width
// down columns.
recordWriter.Write(nil, bufferedOutputStream, outputIsStdout)
return true
return true, false
}
}
return false
return false, false
}

View file

@ -15,6 +15,7 @@ package output
import (
"bufio"
"container/list"
"errors"
"fmt"
"io"
"os"
@ -213,10 +214,11 @@ type FileOutputHandler struct {
// lazily created on WriteRecord. The record-writer / channel parts are
// called only by WriteRecrod which is called by emit and tee variants;
// print and dump variants call WriteString.
recordWriterOptions *cli.TWriterOptions
recordWriter IRecordWriter
recordOutputChannel chan *list.List // list of *types.RecordAndContext
recordDoneChannel chan bool
recordWriterOptions *cli.TWriterOptions
recordWriter IRecordWriter
recordOutputChannel chan *list.List // list of *types.RecordAndContext
recordDoneChannel chan bool
recordErroredChannel chan bool
}
func newOutputHandlerCommon(
@ -231,10 +233,11 @@ func newOutputHandlerCommon(
bufferedOutputStream: bufio.NewWriter(handle),
closeable: closeable,
recordWriterOptions: recordWriterOptions,
recordWriter: nil,
recordOutputChannel: nil,
recordDoneChannel: nil,
recordWriterOptions: recordWriterOptions,
recordWriter: nil,
recordOutputChannel: nil,
recordDoneChannel: nil,
recordErroredChannel: nil,
}
}
@ -368,12 +371,14 @@ func (handler *FileOutputHandler) setUpRecordWriter() error {
handler.recordOutputChannel = make(chan *list.List, 1) // list of *types.RecordAndContext
handler.recordDoneChannel = make(chan bool, 1)
handler.recordErroredChannel = make(chan bool, 1)
go ChannelWriter(
handler.recordOutputChannel,
handler.recordWriter,
handler.recordWriterOptions,
handler.recordDoneChannel,
handler.recordErroredChannel,
handler.bufferedOutputStream,
false, // outputIsStdout
)
@ -382,7 +387,9 @@ func (handler *FileOutputHandler) setUpRecordWriter() error {
}
// ----------------------------------------------------------------
func (handler *FileOutputHandler) Close() error {
func (handler *FileOutputHandler) Close() (retval error) {
retval = nil
if handler.recordOutputChannel != nil {
// TODO: see if we need a real context
emptyContext := types.Context{}
@ -392,6 +399,10 @@ func (handler *FileOutputHandler) Close() error {
done := false
for !done {
select {
case _ = <-handler.recordErroredChannel:
done = true
retval = errors.New("exiting due to data error") // details already printed
break
case _ = <-handler.recordDoneChannel:
done = true
break
@ -399,10 +410,14 @@ func (handler *FileOutputHandler) Close() error {
}
}
if retval != nil {
return retval
}
handler.bufferedOutputStream.Flush()
if handler.closeable {
return handler.handle.Close()
} else {
} else { // e.g. stdout
return nil
}
}

View file

@ -3,6 +3,7 @@ package stream
import (
"bufio"
"container/list"
"errors"
"io"
"github.com/johnkerl/miller/internal/pkg/cli"
@ -67,8 +68,9 @@ func Stream(
// We're done when a fatal error is registered on input (file not found,
// etc) or when the record-writer has written all its output. We use
// channels to communicate both of these conditions.
errorChannel := make(chan error, 1)
inputErrorChannel := make(chan error, 1)
doneWritingChannel := make(chan bool, 1)
dataProcessingErrorChannel := make(chan bool, 1)
// For mlr head, so a transformer can communicate it will disregard all
// further input. It writes this back upstream, and that is passed back to
@ -81,17 +83,22 @@ func Stream(
// error or end-of-processing happens.
bufferedOutputStream := bufio.NewWriter(outputStream)
go recordReader.Read(fileNames, *initialContext, readerChannel, errorChannel, readerDownstreamDoneChannel)
go recordReader.Read(fileNames, *initialContext, readerChannel, inputErrorChannel, readerDownstreamDoneChannel)
go transformers.ChainTransformer(readerChannel, readerDownstreamDoneChannel, recordTransformers,
writerChannel, options)
go output.ChannelWriter(writerChannel, recordWriter, &options.WriterOptions, doneWritingChannel,
bufferedOutputStream, outputIsStdout)
dataProcessingErrorChannel, bufferedOutputStream, outputIsStdout)
var retval error
done := false
for !done {
select {
case err := <-errorChannel:
return err
case ierr := <-inputErrorChannel:
retval = ierr
break
case _ = <-dataProcessingErrorChannel:
retval = errors.New("exiting due to data error") // details already printed
break
case _ = <-doneWritingChannel:
done = true
break
@ -100,5 +107,5 @@ func Stream(
bufferedOutputStream.Flush()
return nil
return retval
}

View file

@ -488,7 +488,7 @@ func helpTypeArithmeticInfo() {
mlrval.FromFloat(2.5),
mlrval.VOID,
mlrval.ABSENT,
mlrval.ERROR,
mlrval.FromAnonymousError(),
}
n := len(mlrvals)

View file

@ -89,6 +89,13 @@ func (repl *Repl) handleDSLStringAux(
filterExpression := repl.runtimeState.FilterExpression
if filterExpression.IsNull() {
// nothing to print
} else if filterExpression.IsError() {
_, err := filterExpression.GetError()
if err == nil { // No supporting information
fmt.Printf("\"%s\"\n", filterExpression.String())
} else {
fmt.Printf("%v\n", err)
}
} else if filterExpression.IsStringOrVoid() {
fmt.Printf("\"%s\"\n", filterExpression.String())
} else {

View file

@ -2,6 +2,7 @@ package transformers
import (
"container/list"
"errors"
"fmt"
"os"
"strings"
@ -269,7 +270,11 @@ func (tr *TransformerFraction) Transform(
outputValue = bifs.BIF_divide(numerator, denominator)
outputValue = bifs.BIF_times(outputValue, tr.multiplier)
} else {
outputValue = mlrval.ERROR
outputValue = mlrval.FromError(
errors.New(
"mlr fraction: division by zero",
),
)
}
outrec.PutCopy(

View file

@ -106,7 +106,7 @@ func (tr *TransformerLatin1ToUTF8) Transform(
if err == nil {
pe.Value = mlrval.FromString(output)
} else {
pe.Value = mlrval.ERROR
pe.Value = mlrval.FromError(err)
}
}
}

View file

@ -106,7 +106,7 @@ func (tr *TransformerUTF8ToLatin1) Transform(
if err == nil {
pe.Value = mlrval.FromString(output)
} else {
pe.Value = mlrval.ERROR
pe.Value = mlrval.FromError(err)
}
}
}

View file

@ -149,7 +149,9 @@ func (keeper *PercentileKeeper) EmitNamed(name string) *mlrval.Mlrval {
}
} else {
return mlrval.ERROR
return mlrval.FromError(
fmt.Errorf(`stats1: unrecognized percentilename "%s"`, name),
)
}
}

View file

@ -582,6 +582,9 @@ MILLER(1) MILLER(1)
-s {file name} Take command-line flags from file name. For more
information please see
https://miller.readthedocs.io/en/latest/scripting/.
-x If any record has an error value in it, report it and
stop the process. The default is to print the field
value as `(error)` and continue.
1mOUTPUT-COLORIZATION FLAGS0m
Miller uses colors to highlight outputs. You can specify color preferences.

View file

@ -701,6 +701,9 @@ These are flags which don't fit into any other category.
-s {file name} Take command-line flags from file name. For more
information please see
https://miller.readthedocs.io/en/latest/scripting/.
-x If any record has an error value in it, report it and
stop the process. The default is to print the field
value as `(error)` and continue.
.fi
.if n \{\
.RE

View file

@ -21,6 +21,6 @@ n,sec,gmt
20,2000000000.99900007,2033-05-18T03:33:20.9Z
21,2000000000.99999905,2033-05-18T03:33:20.9Z
22,2000000001.00000000,2033-05-18T03:33:21.0Z
23,,
24,x,x
25,123x,123x
23,,(error)
24,x,(error)
25,123x,(error)

View file

@ -21,6 +21,6 @@ n,sec,gmt
20,2000000000.99900007,2033-05-18T03:33:20.999Z
21,2000000000.99999905,2033-05-18T03:33:20.999Z
22,2000000001.00000000,2033-05-18T03:33:21.000Z
23,,
24,x,x
25,123x,123x
23,,(error)
24,x,(error)
25,123x,(error)

View file

@ -21,6 +21,6 @@ n,sec,gmt
20,2000000000.99900007,2033-05-18T03:33:20.999000Z
21,2000000000.99999905,2033-05-18T03:33:20.999999Z
22,2000000001.00000000,2033-05-18T03:33:21.000000Z
23,,
24,x,x
25,123x,123x
23,,(error)
24,x,(error)
25,123x,(error)

View file

@ -1 +1 @@
mlr --itsv --ojson cat ${CASEDIR}/single-column-with-blank.json
mlr --itsv --ojson cat ${CASEDIR}/single-column-with-blank.tsv

View file

@ -1,2 +1,2 @@
mlr: mlr: TSV header/data length mismatch 1 != 0 at filename test/cases/io-spec-tsv/0004/single-column-with-blank.json line 4.
mlr: mlr: TSV header/data length mismatch 1 != 0 at filename test/cases/io-spec-tsv/0004/single-column-with-blank.tsv line 4.
.

View file

@ -0,0 +1,8 @@
[
{
"a": 1
},
{
"a": 2
}
]

70
xtodo.txt Normal file
View file

@ -0,0 +1,70 @@
----------------------------------------------------------------
* look at: mr -vvv test/cases/io-spec-tsv/0004/cmd
----------------------------------------------------------------
func (keeper *PercentileKeeper) EmitNamed(name string) *mlrval.Mlrval {
if name == "min" {
return keeper.EmitNonInterpolated(0.0)
} else if name == "p25" {
return keeper.EmitNonInterpolated(25.0)
} else if name == "median" {
return keeper.EmitNonInterpolated(50.0)
} else if name == "p75" {
return keeper.EmitNonInterpolated(75.0)
} else if name == "max" {
return keeper.EmitNonInterpolated(100.0)
} else if name == "iqr" {
p25 := keeper.EmitNonInterpolated(25.0)
p75 := keeper.EmitNonInterpolated(75.0)
if p25.IsNumeric() && p75.IsNumeric() {
return bifs.BIF_minus_binary(p75, p25)
} else {
return mlrval.VOID
}
} else if name == "lof" {
p25 := keeper.EmitNonInterpolated(25.0)
iqr := keeper.EmitNamed("iqr")
if p25.IsNumeric() && iqr.IsNumeric() {
return bifs.BIF_minus_binary(p25, bifs.BIF_times(fenceOuterK, iqr))
} else {
return mlrval.VOID
}
} else if name == "lif" {
p25 := keeper.EmitNonInterpolated(25.0)
iqr := keeper.EmitNamed("iqr")
if p25.IsNumeric() && iqr.IsNumeric() {
return bifs.BIF_minus_binary(p25, bifs.BIF_times(fenceInnerK, iqr))
} else {
return mlrval.VOID
}
} else if name == "uif" {
p75 := keeper.EmitNonInterpolated(75.0)
iqr := keeper.EmitNamed("iqr")
if p75.IsNumeric() && iqr.IsNumeric() {
return bifs.BIF_plus_binary(p75, bifs.BIF_times(fenceInnerK, iqr))
} else {
return mlrval.VOID
}
} else if name == "uof" {
p75 := keeper.EmitNonInterpolated(75.0)
iqr := keeper.EmitNamed("iqr")
if p75.IsNumeric() && iqr.IsNumeric() {
return bifs.BIF_plus_binary(p75, bifs.BIF_times(fenceOuterK, iqr))
} else {
return mlrval.VOID
}
} else {
return mlrval.FromError(
errors.New(
"stats1: unrecognized
),
)
}
}