mlrval/interpreter iterate

This commit is contained in:
John Kerl 2020-08-31 09:13:02 -04:00
parent 3a0654899c
commit 52255a070f
13 changed files with 1559 additions and 1094 deletions

View file

@ -1091,7 +1091,7 @@ static mv_t minus_n_ii(mv_t* pa, mv_t* pb) {
}
if (overflowed) {
return mv_from_float((double)a + (double)b);
return mv_from_float((double)a - (double)b);
} else {
return mv_from_int(c);
}
@ -1193,7 +1193,7 @@ static mv_t divide_f_if(mv_t* pa, mv_t* pb) {
double b = pb->u.fltv;
return mv_from_float(a / b);
}
static mv_t divide_i_ii(mv_t* pa, mv_t* pb) {
static mv_t divide_n_ii(mv_t* pa, mv_t* pb) {
long long a = pa->u.intv;
long long b = pb->u.intv;
if (b == 0LL) { // Compute inf/nan as with floats rather than fatal runtime FPE on integer divide by zero
@ -1214,7 +1214,7 @@ static mv_binary_func_t* divide_dispositions[MT_DIM][MT_DIM] = {
/*ABSENT*/ {_err, _a, _a, _err, _i0, _f0, _err},
/*EMPTY*/ {_err, _a, _emt, _err, _emt, _emt, _err},
/*STRING*/ {_err, _err, _err, _err, _err, _err, _err},
/*INT*/ {_err, _1, _emt, _err, divide_i_ii, divide_f_if, _err},
/*INT*/ {_err, _1, _emt, _err, divide_n_ii, divide_f_if, _err},
/*FLOAT*/ {_err, _1, _emt, _err, divide_f_fi, divide_f_ff, _err},
/*BOOL*/ {_err, _err, _err, _err, _err, _err, _err},
};

View file

@ -2422,7 +2422,7 @@ SEE ALSO
2020-08-25 MILLER(1)
2020-08-31 MILLER(1)
</pre>
</div>
<p/>

View file

@ -2348,4 +2348,4 @@ SEE ALSO
2020-08-25 MILLER(1)
2020-08-31 MILLER(1)

View file

@ -2,12 +2,12 @@
.\" Title: mlr
.\" Author: [see the "AUTHOR" section]
.\" Generator: ./mkman.rb
.\" Date: 2020-08-25
.\" Date: 2020-08-31
.\" Manual: \ \&
.\" Source: \ \&
.\" Language: English
.\"
.TH "MILLER" "1" "2020-08-25" "\ \&" "\ \&"
.TH "MILLER" "1" "2020-08-31" "\ \&" "\ \&"
.\" -----------------------------------------------------------------
.\" * Portability definitions
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -8,9 +8,10 @@ import (
type TNodeType string
const (
NodeTypeStringLiteral TNodeType = "StringLiteral"
NodeTypeNumberLiteral = "NumberLiteral"
NodeTypeBooleanLiteral = "BooleanLiteral"
NodeTypeStringLiteral TNodeType = "StringLiteral"
NodeTypeIntLiteral = "IntLiteral"
NodeTypeFloatLiteral = "FloatLiteral"
NodeTypeBoolLiteral = "BoolLiteral"
NodeTypeDirectFieldName = "DirectFieldName"
NodeTypeIndirectFieldName = "IndirectFieldName"

View file

@ -2,16 +2,16 @@ package dsl
import (
"errors"
"strconv"
"miller/containers"
"miller/lib"
"miller/runtime"
)
// ----------------------------------------------------------------
// Just a very temporary CST-free, AST-only interpreter to get me executing
// some DSL code with a minimum of keystroking, while I work out other issues
// including mlrval-valued lrecs.
// including mlrval-valued lrecs, and port of mvfuncs from C to Go.
type Interpreter struct {
}
@ -19,6 +19,7 @@ func NewInterpreter() *Interpreter {
return &Interpreter{}
}
// ----------------------------------------------------------------
func (this *Interpreter) InterpretOnInputRecord(
inrec *containers.Lrec,
context *runtime.Context,
@ -51,19 +52,21 @@ func (this *Interpreter) InterpretOnInputRecord(
rhsNode := child.Children[1]
fieldName := string(lhsNode.Token.Lit)[1:] // strip off leading '$'
value, defined, err := this.evaluateNode(rhsNode, inrec, context)
mvalue, err := this.evaluateNode(rhsNode, inrec, context)
if err != nil {
return nil, err
}
if defined {
inrec.Put(&fieldName, &value)
} else {
// xxx temp -- srec values are going to be mlrvals all the way through
svalue := mvalue.String()
inrec.Put(&fieldName, &svalue)
}
}
return inrec, nil
}
// xxx make into ASTNode method
// ----------------------------------------------------------------
// xxx make into ASTNode method?
func (this *Interpreter) checkArity(
node *ASTNode,
arity int,
@ -75,12 +78,12 @@ func (this *Interpreter) checkArity(
}
}
// xxx needs null/undefined/string/error. then, string->mlrval.
// ----------------------------------------------------------------
func (this *Interpreter) evaluateNode(
node *ASTNode,
inrec *containers.Lrec,
context *runtime.Context,
) (string, bool, error) {
) (lib.Mlrval, error) {
var sval = ""
if node.Token != nil {
sval = string(node.Token.Lit)
@ -89,31 +92,33 @@ func (this *Interpreter) evaluateNode(
switch node.NodeType {
case NodeTypeStringLiteral:
// xxx temp -- fix this in the grammar or ast-insert?
return sval[1 : len(sval)-1], true, nil
case NodeTypeNumberLiteral:
return sval, true, nil // xxx temp -- to mlrval
case NodeTypeBooleanLiteral:
return sval, true, nil // xxx temp -- to mlrval
// xxx temp "..." strip -- fix this in the grammar or ast-insert
return lib.MlrvalFromString(sval[1 : len(sval)-1]), nil
case NodeTypeIntLiteral:
return lib.MlrvalFromInt64String(sval), nil
case NodeTypeFloatLiteral:
return lib.MlrvalFromFloat64String(sval), nil
case NodeTypeBoolLiteral:
return lib.MlrvalFromBoolString(sval), nil
case NodeTypeDirectFieldName:
fieldName := sval[1:] // xxx temp -- fix this in the grammar or ast-insert?
fieldValue := inrec.Get(&fieldName)
if fieldValue == nil {
return "", false, nil
return lib.MlrvalFromAbsent(), nil
} else {
return *fieldValue, true, nil
return lib.MlrvalFromInferredType(*fieldValue), nil
}
break
case NodeTypeIndirectFieldName:
return "", true, errors.New("unhandled")
return lib.MlrvalFromError(), errors.New("unhandled1")
break
case NodeTypeStatementBlock:
return "", true, errors.New("unhandled")
return lib.MlrvalFromError(), errors.New("unhandled2")
break
case NodeTypeAssignment:
return "", true, errors.New("unhandled")
return lib.MlrvalFromError(), errors.New("unhandled3")
break
case NodeTypeOperator:
this.checkArity(node, 2) // xxx temp -- binary-only for now
@ -125,54 +130,57 @@ func (this *Interpreter) evaluateNode(
break
}
return "", true, errors.New("unhandled")
return lib.MlrvalFromError(), errors.New("unhandled4")
}
func (this *Interpreter) evaluateContextVariableNode(
node *ASTNode,
context *runtime.Context,
) (string, bool, error) {
) (lib.Mlrval, error) {
if node.Token == nil {
return "", true, errors.New("internal coding error") // xxx libify
return lib.MlrvalFromError(), errors.New("internal coding error") // xxx libify
}
sval := string(node.Token.Lit)
switch sval {
case "FILENAME":
return context.FILENAME, true, nil
return lib.MlrvalFromString(context.FILENAME), nil
break
case "FILENUM":
return strconv.FormatInt(context.FILENUM, 10), true, nil
return lib.MlrvalFromInt64(context.FILENUM), nil
break
case "NF":
return strconv.FormatInt(context.NF, 10), true, nil
return lib.MlrvalFromInt64(context.NF), nil
break
case "NR":
return strconv.FormatInt(context.NR, 10), true, nil
return lib.MlrvalFromInt64(context.NR), nil
break
case "FNR":
return strconv.FormatInt(context.FNR, 10), true, nil
return lib.MlrvalFromInt64(context.FNR), nil
break
case "IPS":
return context.IPS, true, nil
return lib.MlrvalFromString(context.IPS), nil
break
case "IFS":
return context.IFS, true, nil
return lib.MlrvalFromString(context.IFS), nil
break
case "IRS":
return context.IRS, true, nil
return lib.MlrvalFromString(context.IRS), nil
break
case "OPS":
return context.OPS, true, nil
return lib.MlrvalFromString(context.OPS), nil
break
case "OFS":
return context.OFS, true, nil
return lib.MlrvalFromString(context.OFS), nil
break
case "ORS":
return context.ORS, true, nil
return lib.MlrvalFromString(context.ORS), nil
break
break
}
return "", true, errors.New("internal coding error") // xxx libify
return lib.MlrvalFromError(), errors.New("internal coding error") // xxx libify
}
func (this *Interpreter) evaluateBinaryOperatorNode(
@ -181,81 +189,36 @@ func (this *Interpreter) evaluateBinaryOperatorNode(
rightChild *ASTNode,
inrec *containers.Lrec,
context *runtime.Context,
) (string, bool, error) {
sval := string(node.Token.Lit)
) (lib.Mlrval, error) {
sop := string(node.Token.Lit)
leftValue, leftDefined, leftErr := this.evaluateNode(leftChild, inrec, context)
leftValue, leftErr := this.evaluateNode(leftChild, inrec, context)
if leftErr != nil {
return "", true, leftErr
return lib.MlrvalFromError(), leftErr
}
if !leftDefined {
return "", false, nil
}
rightValue, rightDefined, rightErr := this.evaluateNode(rightChild, inrec, context)
rightValue, rightErr := this.evaluateNode(rightChild, inrec, context)
if rightErr != nil {
return "", true, rightErr
}
if !rightDefined {
return "", false, nil
return lib.MlrvalFromError(), rightErr
}
switch sval {
case ".":
return leftValue + rightValue, true, nil
break
}
switch sval {
switch sop {
case "+":
// xxx make a lib method -- Itoa64
//return lib.Itoa64(leftInt + rightInt), true, nil
a := lib.MlrvalFromInt64String(leftValue)
b := lib.MlrvalFromInt64String(rightValue)
c := lib.MlrvalPlus(&a, &b)
return c.String(), true, nil
return lib.MlrvalPlus(&leftValue, &rightValue), nil
break
}
// make a helper method for int-pairings
leftInt, lerr := strconv.ParseInt(leftValue, 10, 0)
if lerr != nil {
// to do: consider error-propagation through the AST evaluator, with
// null/undefined/error in the binop matrices etc.
//
// need to separate internal coding errors, from data-dependent ones
//
//return "", true, lerr
return "(error)", true, nil
}
rightInt, rerr := strconv.ParseInt(rightValue, 10, 0)
if rerr != nil {
//return "", true, rerr
return "(error)", true, nil
}
switch sval {
case "-":
return lib.Itoa64(leftInt - rightInt), true, nil
return lib.MlrvalMinus(&leftValue, &rightValue), nil
break
case "*":
return lib.Itoa64(leftInt * rightInt), true, nil
return lib.MlrvalTimes(&leftValue, &rightValue), nil
break
case "/":
return lib.Itoa64(leftInt / rightInt), true, nil
break
case "^":
return lib.Itoa64(leftInt ^ rightInt), true, nil
break
case "&":
return lib.Itoa64(leftInt & rightInt), true, nil
break
case "|":
return lib.Itoa64(leftInt | rightInt), true, nil
return lib.MlrvalDivide(&leftValue, &rightValue), nil
break
case "//":
return "", true, errors.New("unhandled")
return lib.MlrvalIntDivide(&leftValue, &rightValue), nil
break
// xxx continue ...
}
return "", true, errors.New("internal coding error") // xxx libify
return lib.MlrvalFromError(), errors.New("internal coding error") // xxx libify
}

View file

@ -2,82 +2,59 @@ package lib
import (
"fmt"
"math"
"os"
"strconv"
)
// Two kinds of null: absent (key not present in a record) and void (key
// present with empty value). Note void is an acceptable string (empty string)
// but not an acceptable number. (In Javascript, similarly, there are null and
// undefined.) Void-valued mlrvals have u.strv = "".
// #define MT_ERROR 0 // E.g. error encountered in one eval & it propagates up the AST.
// --> JS undefined -- rename this -- or maybe MT_ABSENT ok ...
// #define MT_ABSENT 1 // No such key, e.g. $z in 'x=,y=2'
// --> JS null -- rename this -- or maybe MT_VOID
// xxx note it seralizes to "" ... which is kinda whack ...
// #define MT_EMPTY 2 // Empty value, e.g. $x in 'x=,y=2'
// #define MT_STRING 3
// #define MT_INT 4
// #define MT_FLOAT 5
// #define MT_BOOL 6
// #define MT_DIM 7
// typedef struct _mv_t {
// union {
// char* strv; // MT_STRING and MT_EMPTY
// long long intv; // MT_INT, and == 0 for MT_ABSENT and MT_ERROR
// double fltv; // MT_FLOAT
// int boolv; // MT_BOOL
// } u;
// unsigned char type;
// } mv_t;
// Requirements:
// ================================================================
// Requirements for mlrvals:
//
// * Keep original string-formatting even if parseable/parsed as int
// o E.g. if 005 (octal), pass through as 005 unless math is done on it
// o Likewise with number of decimal places -- 7.4 not 7.400 or (worse) 7.399999999
// * Invalidate the string-formatting as the output of a computational result
// * Have number-to-string formatting methods in the API/DSL which stick the string format
// * Final to-string method
//
// Also:
// * split current C mvfuncs into mlrval-private (dispo matrices etc) and new
// * Split current C mvfuncs into mlrval-private (dispo matrices etc) and new
// mvfuncs.go where the latter don't need access to private members
// ================================================================
// Question:
// * What to do with disposition matrices from the C impl?
// Example:
//static mv_binary_func_t* plus_dispositions[MT_DIM][MT_DIM] = {
// // ERROR ABSENT EMPTY STRING INT FLOAT BOOL
// /*ERROR*/ {_err, _err, _err, _err, _err, _err, _err},
// /*ABSENT*/ {_err, _a, _a, _err, _2___, _2___, _err},
// /*EMPTY*/ {_err, _a, _emt, _err, _emt, _emt, _err},
// /*STRING*/ {_err, _err, _err, _err, _err, _err, _err},
// /*INT*/ {_err, _1___, _emt, _err, plus_n_ii, plus_f_if, _err},
// /*FLOAT*/ {_err, _1___, _emt, _err, plus_f_fi, plus_f_ff, _err},
// /*BOOL*/ {_err, _err, _err, _err, _err, _err, _err},
//};
// ================================================================
// There are two kinds of null: ABSENT (key not present in a record) and VOID
// (key present with empty value). Note void is an acceptable string (empty
// string) but not an acceptable number. (In Javascript, similarly, there are
// undefined and null, respectively.)
// ================================================================
// ----------------------------------------------------------------
// ================================================================
type MVType int
const (
// E.g. error encountered in one eval & it propagates up the AST at evaluation time:
MT_ERROR MVType = 0
// Key not present in input record, e.g. 'foo = $nosuchkey'
MT_ABSENT = 1
// Key present in input record with empty value, e.g. input data '$x=,$y=2'
MT_VOID = 2
MT_STRING = 3
MT_INT = 4
MT_FLOAT = 5
MT_BOOL = 6
// Not a type -- this is a dimension for disposition matrices
MT_DIM = 7
)
// ----------------------------------------------------------------
// ================================================================
type Mlrval struct {
mvtype MVType
printrep string
@ -87,7 +64,7 @@ type Mlrval struct {
boolval bool
}
// ----------------------------------------------------------------
// ================================================================
func MlrvalFromError() Mlrval {
return Mlrval{
MT_ERROR,
@ -115,6 +92,7 @@ func MlrvalFromVoid() Mlrval {
}
}
// ----------------------------------------------------------------
func MlrvalFromString(input string) Mlrval {
return Mlrval{
MT_STRING,
@ -124,17 +102,16 @@ func MlrvalFromString(input string) Mlrval {
}
}
// ----------------------------------------------------------------
// xxx comment why two -- one for from parsed user data; other for from math ops
func MlrvalFromInt64String(input string) Mlrval {
// xxx handle octal, hex, ......
ival, err := strconv.ParseInt(input, 10, 64)
ival, ok := tryInt64FromString(input)
// xxx comment assummption is input-string already deemed parseable so no error return
if err != nil {
if !ok {
// xxx get file/line info here .......
fmt.Fprintf(os.Stderr, "Internal coding error detected\n")
os.Exit(1)
}
return Mlrval{
MT_INT,
input,
@ -148,7 +125,7 @@ func MlrvalFromInt64String(input string) Mlrval {
func MlrvalFromInt64(input int64) Mlrval {
return Mlrval{
MT_INT,
"(uninit)",
"(bug-if-you-see-this)",
false,
input,
0.0,
@ -156,13 +133,25 @@ func MlrvalFromInt64(input int64) Mlrval {
}
}
func tryInt64FromString(input string) (int64, bool) {
// xxx need to handle octal, hex, ......
ival, err := strconv.ParseInt(input, 10, 64)
if err == nil {
return ival, true
} else {
return 0, false
}
}
// ----------------------------------------------------------------
// xxx comment why two -- one for from parsed user data; other for from math ops
// xxx comment assummption is input-string already deemed parseable so no error return
func MlrvalFromFloat64String(input string) Mlrval {
fval, err := strconv.ParseFloat(input, 64)
fval, ok := tryFloat64FromString(input)
// xxx comment assummption is input-string already deemed parseable so no error return
if err != nil {
// xxx panic ?
if !ok {
// xxx get file/line info here .......
fmt.Fprintf(os.Stderr, "Internal coding error detected\n")
os.Exit(1)
}
@ -179,7 +168,7 @@ func MlrvalFromFloat64String(input string) Mlrval {
func MlrvalFromFloat64(input float64) Mlrval {
return Mlrval{
MT_FLOAT,
"(uninit)",
"(bug-if-you-see-this)",
false,
0,
input,
@ -187,6 +176,16 @@ func MlrvalFromFloat64(input float64) Mlrval {
}
}
func tryFloat64FromString(input string) (float64, bool) {
ival, err := strconv.ParseFloat(input, 64)
if err == nil {
return ival, true
} else {
return 0, false
}
}
// ----------------------------------------------------------------
func MlrvalFromTrue() Mlrval {
return Mlrval{
MT_BOOL,
@ -209,15 +208,50 @@ func MlrvalFromFalse() Mlrval {
}
}
func MlrvalFromBoolean(input bool) Mlrval {
if input == true {
func MlrvalFromBoolString(input string) Mlrval {
if input == "true" {
return MlrvalFromTrue()
} else {
return MlrvalFromFalse()
}
// else panic
}
func tryBoolFromBoolString(input string) (bool, bool) {
if input == "true" {
return true, true
} else if input == "false" {
return false, true
} else {
return false, false
}
}
// ----------------------------------------------------------------
func MlrvalFromInferredType(input string) Mlrval {
// xxx the parsing has happened so stash it ...
// xxx emphasize the invariant that a non-invalid printrep always
// matches the nval ...
_, iok := tryInt64FromString(input)
if iok {
return MlrvalFromInt64String(input)
}
_, fok := tryFloat64FromString(input)
if fok {
return MlrvalFromFloat64String(input)
}
_, bok := tryBoolFromBoolString(input)
if bok {
return MlrvalFromBoolString(input)
}
return MlrvalFromString(input)
}
// ================================================================
// xxx comment about JIT-parsing of string backings
func (this *Mlrval) setPrintRep() {
if !this.printrepValid {
// xxx do it -- disposition vector
@ -230,7 +264,7 @@ func (this *Mlrval) setPrintRep() {
// Callsites should be using absence to do non-assigns, so flag
// this clearly visually if it should (buggily) slip through to
// user-level visibility.
this.printrep = "(absent)" // xxx constdef at top of file
this.printrep = "(bug-if-you-see-this)" // xxx constdef at top of file
break
case MT_VOID:
this.printrep = "" // xxx constdef at top of file
@ -278,8 +312,86 @@ func _1___(val1, val2 *Mlrval) Mlrval {
func _2___(val1, val2 *Mlrval) Mlrval {
return *val2
}
func _i0__(val1, val2 *Mlrval) Mlrval {
return MlrvalFromInt64(0)
}
func _f0__(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(0.0)
}
// xxx comment
type dyadicFunc func(*Mlrval, *Mlrval) Mlrval
// ================================================================
//static mv_t dot_strings(char* string1, char* string2) {
// int len1 = strlen(string1);
// int len2 = strlen(string2);
// int len3 = len1 + len2 + 1; // for the null-terminator byte
// char* string3 = mlr_malloc_or_die(len3);
// strcpy(&string3[0], string1);
// strcpy(&string3[len1], string2);
// return mv_from_string_with_free(string3);
//}
//
//mv_t dot_s_ss(mv_t* pval1, mv_t* pval2) {
// mv_t rv = dot_strings(pval1->u.strv, pval2->u.strv);
// mv_free(pval1);
// mv_free(pval2);
// return rv;
//}
//
//mv_t dot_s_xs(mv_t* pval1, mv_t* pval2) {
// mv_t sval1 = s_x_string_func(pval1);
// mv_free(pval1);
// mv_t rv = dot_strings(sval1.u.strv, pval2->u.strv);
// mv_free(&sval1);
// mv_free(pval2);
// return rv;
//}
//
//mv_t dot_s_sx(mv_t* pval1, mv_t* pval2) {
// mv_t sval2 = s_x_string_func(pval2);
// mv_free(pval2);
// mv_t rv = dot_strings(pval1->u.strv, sval2.u.strv);
// mv_free(pval1);
// mv_free(&sval2);
// return rv;
//}
//
//mv_t dot_s_xx(mv_t* pval1, mv_t* pval2) {
// mv_t sval1 = s_x_string_func(pval1);
// mv_t sval2 = s_x_string_func(pval2);
// mv_t rv = dot_strings(sval1.u.strv, sval2.u.strv);
// mv_free(&sval1);
// mv_free(&sval2);
// return rv;
//}
//
//static mv_binary_func_t* dot_dispositions[MT_DIM][MT_DIM] = {
// // ERROR ABSENT EMPTY STRING INT FLOAT BOOL
// /*ERROR*/ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
// /*ABSENT*/ {_erro, _a, _void, _2, _s2, _s2, _s2},
// /*EMPTY*/ {_erro, _void, _void, _2, _s2, _s2, _s2},
// /*STRING*/ {_erro, _1, _1, dot_s_ss, dot_s_sx, dot_s_sx, dot_s_sx},
// /*INT*/ {_erro, _s1, _s1, dot_s_xs, dot_s_xx, dot_s_xx, dot_s_xx},
// /*FLOAT*/ {_erro, _s1, _s1, dot_s_xs, dot_s_xx, dot_s_xx, dot_s_xx},
// /*BOOL*/ {_erro, _s1, _s1, dot_s_xs, dot_s_xx, dot_s_xx, dot_s_xx},
//};
//
//mv_t s_xx_dot_func(mv_t* pval1, mv_t* pval2) { return (dot_dispositions[pval1->type][pval2->type])(pval1,pval2); }
// ================================================================
func plus_f_fi(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(val1.floatval + float64(val2.intval))
}
func plus_f_if(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(float64(val1.intval) + val2.floatval)
}
func plus_f_ff(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(val1.floatval + val2.floatval)
}
// ----------------------------------------------------------------
// Auto-overflows up to float. Additions & subtractions overflow by at most
// one bit so it suffices to check sign-changes.
func plus_n_ii(val1, val2 *Mlrval) Mlrval {
@ -305,19 +417,6 @@ func plus_n_ii(val1, val2 *Mlrval) Mlrval {
}
}
func plus_f_fi(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(val1.floatval + float64(val2.intval))
}
func plus_f_if(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(float64(val1.intval) + val2.floatval)
}
func plus_f_ff(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(val1.floatval + val2.floatval)
}
// // var pfunc func(*Mlrval, *Mlrval) Mlrval
type dyadicFunc func(*Mlrval, *Mlrval) Mlrval
var plusDispositions = [MT_DIM][MT_DIM]dyadicFunc{
// ERROR ABSENT EMPTY STRING INT FLOAT BOOL
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
@ -333,18 +432,419 @@ func MlrvalPlus(val1, val2 *Mlrval) Mlrval {
return plusDispositions[val1.mvtype][val2.mvtype](val1, val2)
}
// ----------------------------------------------------------------
//static mv_binary_func_t* plus_dispositions[MT_DIM][MT_DIM] = {
// // ERROR ABSENT EMPTY STRING INT FLOAT BOOL
// /*ERROR*/ {_err, _err, _err, _err, _err, _err, _err},
// /*ABSENT*/ {_err, _a, _a, _err, _2___, _2___, _err},
// /*EMPTY*/ {_err, _a, _emt, _err, _emt, _emt, _err},
// /*STRING*/ {_err, _err, _err, _err, _err, _err, _err},
// /*INT*/ {_err, _1___, _emt, _err, plus_n_ii, plus_f_if, _err},
// /*FLOAT*/ {_err, _1___, _emt, _err, plus_f_fi, plus_f_ff, _err},
// /*BOOL*/ {_err, _err, _err, _err, _err, _err, _err},
// ================================================================
func minus_f_ff(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(val1.floatval - val2.floatval)
}
func minus_f_fi(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(val1.floatval - float64(val2.intval))
}
func minus_f_if(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(float64(val1.intval) - val2.floatval)
}
// Adds & subtracts overflow by at most one bit so it suffices to check
// sign-changes.
func minus_n_ii(val1, val2 *Mlrval) Mlrval {
a := val1.intval
b := val2.intval
c := a - b
overflowed := false
if a > 0 {
if b < 0 && c < 0 {
overflowed = true
}
} else if a < 0 {
if b > 0 && c > 0 {
overflowed = true
}
}
if overflowed {
return MlrvalFromFloat64(float64(a) - float64(b))
} else {
return MlrvalFromInt64(c)
}
}
var minusDispositions = [MT_DIM][MT_DIM]dyadicFunc{
// ERROR ABSENT EMPTY STRING INT FLOAT BOOL
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ABSENT */ {_erro, _absn, _absn, _erro, _2___, _2___, _erro},
/*EMPTY */ {_erro, _absn, _void, _erro, _void, _void, _erro},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*INT */ {_erro, _1___, _void, _erro, minus_n_ii, minus_f_if, _erro},
/*FLOAT */ {_erro, _1___, _void, _erro, minus_f_fi, minus_f_ff, _erro},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
}
func MlrvalMinus(val1, val2 *Mlrval) Mlrval {
return minusDispositions[val1.mvtype][val2.mvtype](val1, val2)
}
// ================================================================
func times_f_fi(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(val1.floatval * float64(val2.intval))
}
func times_f_if(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(float64(val1.intval) * val2.floatval)
}
func times_f_ff(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(val1.floatval * val2.floatval)
}
// Auto-overflows up to float.
//
// Unlike adds & subtracts which overflow by at most one bit, multiplies can
// overflow by a word size. Thus detecting sign-changes does not suffice to
// detect overflow. Instead we test whether the floating-point product exceeds
// the representable integer range. Now 64-bit integers have 64-bit precision
// while IEEE-doubles have only 52-bit mantissas -- so, 53 bits including
// implicit leading one.
//
// The following experiment explicitly demonstrates the resolution at this range:
//
// 64-bit integer 64-bit integer Casted to double Back to 64-bit
// in hex in decimal integer
// 0x7ffffffffffff9ff 9223372036854774271 9223372036854773760.000000 0x7ffffffffffff800
// 0x7ffffffffffffa00 9223372036854774272 9223372036854773760.000000 0x7ffffffffffff800
// 0x7ffffffffffffbff 9223372036854774783 9223372036854774784.000000 0x7ffffffffffffc00
// 0x7ffffffffffffc00 9223372036854774784 9223372036854774784.000000 0x7ffffffffffffc00
// 0x7ffffffffffffdff 9223372036854775295 9223372036854774784.000000 0x7ffffffffffffc00
// 0x7ffffffffffffe00 9223372036854775296 9223372036854775808.000000 0x8000000000000000
// 0x7ffffffffffffffe 9223372036854775806 9223372036854775808.000000 0x8000000000000000
// 0x7fffffffffffffff 9223372036854775807 9223372036854775808.000000 0x8000000000000000
//
// That is, we cannot check an integer product to see if it is greater than
// 2**63-1 (or is less than -2**63) using integer arithmetic (it may have
// already overflowed) *or* using double-precision (granularity). Instead we
// check if the absolute value of the product exceeds the largest representable
// double less than 2**63. (An alterative would be to do all integer multiplies
// using handcrafted multi-word 128-bit arithmetic).
func times_n_ii(val1, val2 *Mlrval) Mlrval {
a := val1.intval
b := val2.intval
c := float64(a) * float64(b)
if math.Abs(c) > 9223372036854774784.0 {
return MlrvalFromFloat64(c)
} else {
return MlrvalFromInt64(a * b)
}
}
var timesDispositions = [MT_DIM][MT_DIM]dyadicFunc{
// ERROR ABSENT EMPTY STRING INT FLOAT BOOL
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ABSENT */ {_erro, _absn, _absn, _erro, _2___, _2___, _erro},
/*EMPTY */ {_erro, _absn, _void, _erro, _void, _void, _erro},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*INT */ {_erro, _1___, _void, _erro, times_n_ii, times_f_if, _erro},
/*FLOAT */ {_erro, _1___, _void, _erro, times_f_fi, times_f_ff, _erro},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
}
func MlrvalTimes(val1, val2 *Mlrval) Mlrval {
return timesDispositions[val1.mvtype][val2.mvtype](val1, val2)
}
// ================================================================
func divide_f_fi(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(val1.floatval / float64(val2.intval))
}
func divide_f_if(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(float64(val1.intval) / val2.floatval)
}
func divide_f_ff(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(val1.floatval / val2.floatval)
}
func divide_n_ii(val1, val2 *Mlrval) Mlrval {
a := val1.intval
b := val2.intval
if b == 0 {
// Compute inf/nan as with floats rather than fatal runtime FPE on integer divide by zero
return MlrvalFromFloat64(float64(a) / float64(b))
}
// Pythonic division, not C division.
if a%b == 0 {
return MlrvalFromInt64(a / b)
} else {
return MlrvalFromFloat64(float64(a) / float64(b))
}
c := float64(a) * float64(b)
if math.Abs(c) > 9223372036854774784.0 {
return MlrvalFromFloat64(c)
} else {
return MlrvalFromInt64(a * b)
}
}
var divideDispositions = [MT_DIM][MT_DIM]dyadicFunc{
// ERROR ABSENT EMPTY STRING INT FLOAT BOOL
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ABSENT */ {_erro, _absn, _absn, _erro, _i0__, _f0__, _erro},
/*EMPTY */ {_erro, _absn, _void, _erro, _void, _void, _erro},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*INT */ {_erro, _1___, _void, _erro, divide_n_ii, divide_f_if, _erro},
/*FLOAT */ {_erro, _1___, _void, _erro, divide_f_fi, divide_f_ff, _erro},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
}
func MlrvalDivide(val1, val2 *Mlrval) Mlrval {
return divideDispositions[val1.mvtype][val2.mvtype](val1, val2)
}
// ================================================================
func int_divide_f_fi(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(math.Floor(val1.floatval / float64(val2.intval)))
}
func int_divide_f_if(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(math.Floor(float64(val1.intval) / val2.floatval))
}
func int_divide_f_ff(val1, val2 *Mlrval) Mlrval {
return MlrvalFromFloat64(math.Floor(val1.floatval / val2.floatval))
}
func int_divide_n_ii(val1, val2 *Mlrval) Mlrval {
a := val1.intval
b := val2.intval
if b == 0 {
// Compute inf/nan as with floats rather than fatal runtime FPE on integer divide by zero
return MlrvalFromFloat64(float64(a) / float64(b))
}
// Pythonic division, not C division.
q := a / b
r := a % b
if a < 0 {
if b > 0 {
if r != 0 {
q--
}
}
} else {
if b < 0 {
if r != 0 {
q--
}
}
}
return MlrvalFromInt64(q)
}
var int_divideDispositions = [MT_DIM][MT_DIM]dyadicFunc{
// ERROR ABSENT EMPTY STRING INT FLOAT BOOL
/*ERROR */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*ABSENT */ {_erro, _absn, _absn, _erro, _i0__, _f0__, _erro},
/*EMPTY */ {_erro, _absn, _void, _erro, _void, _void, _erro},
/*STRING */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
/*INT */ {_erro, _1___, _void, _erro, int_divide_n_ii, int_divide_f_if, _erro},
/*FLOAT */ {_erro, _1___, _void, _erro, int_divide_f_fi, int_divide_f_ff, _erro},
/*BOOL */ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
}
func MlrvalIntDivide(val1, val2 *Mlrval) Mlrval {
return int_divideDispositions[val1.mvtype][val2.mvtype](val1, val2)
}
//// ================================================================
//static mv_t oplus_f_ff(mv_t* pa, mv_t* pb) {
// double a = pa->u.fltv;
// double b = pb->u.fltv;
// return mv_from_float(a + b);
//}
//static mv_t oplus_f_fi(mv_t* pa, mv_t* pb) {
// double a = pa->u.fltv;
// double b = (double)pb->u.intv;
// return mv_from_float(a + b);
//}
//static mv_t oplus_f_if(mv_t* pa, mv_t* pb) {
// double a = (double)pa->u.intv;
// double b = pb->u.fltv;
// return mv_from_float(a + b);
//}
//static mv_t oplus_n_ii(mv_t* pa, mv_t* pb) {
// long long a = pa->u.intv;
// long long b = pb->u.intv;
// long long c = a + b;
// return mv_from_int(c);
//}
//
//static mv_binary_func_t* oplus_dispositions[MT_DIM][MT_DIM] = {
// // ERROR ABSENT EMPTY STRING INT FLOAT BOOL
// /*ERROR*/ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
// /*ABSENT*/ {_erro, _a, _a, _erro, _2, _2, _erro},
// /*EMPTY*/ {_erro, _a, _void, _erro, _void, _void, _erro},
// /*STRING*/ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
// /*INT*/ {_erro, _1, _void, _erro, oplus_n_ii, oplus_f_if, _erro},
// /*FLOAT*/ {_erro, _1, _void, _erro, oplus_f_fi, oplus_f_ff, _erro},
// /*BOOL*/ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
//};
// mv_t x_xx_plus_func(mv_t* pval1, mv_t* pval2) { return (plus_dispositions[pval1->type][pval2->type])(pval1,pval2); }
// func MvPlus(val1, val2 *Mlrval) Mlrval {
// return plusDispositions[val1.mvtype][val2.mvtype]
// }
//
//mv_t x_xx_oplus_func(mv_t* pval1, mv_t* pval2) { return (oplus_dispositions[pval1->type][pval2->type])(pval1,pval2); }
//
//// ----------------------------------------------------------------
//static mv_t ominus_f_ff(mv_t* pa, mv_t* pb) {
// double a = pa->u.fltv;
// double b = pb->u.fltv;
// return mv_from_float(a - b);
//}
//static mv_t ominus_f_fi(mv_t* pa, mv_t* pb) {
// double a = pa->u.fltv;
// double b = (double)pb->u.intv;
// return mv_from_float(a - b);
//}
//static mv_t ominus_f_if(mv_t* pa, mv_t* pb) {
// double a = (double)pa->u.intv;
// double b = pb->u.fltv;
// return mv_from_float(a - b);
//}
//static mv_t ominus_n_ii(mv_t* pa, mv_t* pb) {
// long long a = pa->u.intv;
// long long b = pb->u.intv;
// long long c = a - b;
// return mv_from_int(c);
//}
//
//static mv_binary_func_t* ominus_dispositions[MT_DIM][MT_DIM] = {
// // ERROR ABSENT EMPTY STRING INT FLOAT BOOL
// /*ERROR*/ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
// /*ABSENT*/ {_erro, _a, _a, _erro, _2, _2, _erro},
// /*EMPTY*/ {_erro, _a, _void, _erro, _void, _void, _erro},
// /*STRING*/ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
// /*INT*/ {_erro, _1, _void, _erro, ominus_n_ii, ominus_f_if, _erro},
// /*FLOAT*/ {_erro, _1, _void, _erro, ominus_f_fi, ominus_f_ff, _erro},
// /*BOOL*/ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
//};
//
//mv_t x_xx_ominus_func(mv_t* pval1, mv_t* pval2) { return (ominus_dispositions[pval1->type][pval2->type])(pval1,pval2); }
//
//// ----------------------------------------------------------------
//static mv_t otimes_f_ff(mv_t* pa, mv_t* pb) {
// double a = pa->u.fltv;
// double b = pb->u.fltv;
// return mv_from_float(a * b);
//}
//static mv_t otimes_f_fi(mv_t* pa, mv_t* pb) {
// double a = pa->u.fltv;
// double b = (double)pb->u.intv;
// return mv_from_float(a * b);
//}
//static mv_t otimes_f_if(mv_t* pa, mv_t* pb) {
// double a = (double)pa->u.intv;
// double b = pb->u.fltv;
// return mv_from_float(a * b);
//}
//static mv_t otimes_n_ii(mv_t* pa, mv_t* pb) {
// long long a = pa->u.intv;
// long long b = pb->u.intv;
// return mv_from_int(a * b);
//}
//
//static mv_binary_func_t* otimes_dispositions[MT_DIM][MT_DIM] = {
// // ERROR ABSENT EMPTY STRING INT FLOAT BOOL
// /*ERROR*/ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
// /*ABSENT*/ {_erro, _a, _a, _erro, _2, _2, _erro},
// /*EMPTY*/ {_erro, _a, _void, _erro, _void, _void, _erro},
// /*STRING*/ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
// /*INT*/ {_erro, _1, _void, _erro, otimes_n_ii, otimes_f_if, _erro},
// /*FLOAT*/ {_erro, _1, _void, _erro, otimes_f_fi, otimes_f_ff, _erro},
// /*BOOL*/ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
//};
//
//mv_t x_xx_otimes_func(mv_t* pval1, mv_t* pval2) { return (otimes_dispositions[pval1->type][pval2->type])(pval1,pval2); }
//
//// ----------------------------------------------------------------
//static mv_t odivide_f_ff(mv_t* pa, mv_t* pb) {
// double a = pa->u.fltv;
// double b = pb->u.fltv;
// return mv_from_float(a / b);
//}
//static mv_t odivide_f_fi(mv_t* pa, mv_t* pb) {
// double a = pa->u.fltv;
// double b = (double)pb->u.intv;
// return mv_from_float(a / b);
//}
//static mv_t odivide_f_if(mv_t* pa, mv_t* pb) {
// double a = (double)pa->u.intv;
// double b = pb->u.fltv;
// return mv_from_float(a / b);
//}
//static mv_t odivide_i_ii(mv_t* pa, mv_t* pb) {
// long long a = pa->u.intv;
// long long b = pb->u.intv;
// return mv_from_int(a / b);
//}
//
//static mv_binary_func_t* odivide_dispositions[MT_DIM][MT_DIM] = {
// // ERROR ABSENT EMPTY STRING INT FLOAT BOOL
// /*ERROR*/ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
// /*ABSENT*/ {_erro, _a, _a, _erro, _i0, _f0, _erro},
// /*EMPTY*/ {_erro, _a, _void, _erro, _void, _void, _erro},
// /*STRING*/ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
// /*INT*/ {_erro, _1, _void, _erro, odivide_i_ii, odivide_f_if, _erro},
// /*FLOAT*/ {_erro, _1, _void, _erro, odivide_f_fi, odivide_f_ff, _erro},
// /*BOOL*/ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
//};
//
//mv_t x_xx_odivide_func(mv_t* pval1, mv_t* pval2) { return (odivide_dispositions[pval1->type][pval2->type])(pval1,pval2); }
//
//// ----------------------------------------------------------------
//static mv_t oidiv_f_ff(mv_t* pa, mv_t* pb) {
// double a = pa->u.fltv;
// double b = pb->u.fltv;
// return mv_from_float(floor(a / b));
//}
//static mv_t oidiv_f_fi(mv_t* pa, mv_t* pb) {
// double a = pa->u.fltv;
// double b = (double)pb->u.intv;
// return mv_from_float(floor(a / b));
//}
//static mv_t oidiv_f_if(mv_t* pa, mv_t* pb) {
// double a = (double)pa->u.intv;
// double b = pb->u.fltv;
// return mv_from_float(floor(a / b));
//}
//static mv_t oidiv_i_ii(mv_t* pa, mv_t* pb) {
// long long a = pa->u.intv;
// long long b = pb->u.intv;
//
// // Pythonic division, not C division.
// long long q = a / b;
// long long r = a % b;
// if (a < 0) {
// if (b > 0) {
// if (r != 0)
// q--;
// }
// } else {
// if (b < 0) {
// if (r != 0)
// q--;
// }
// }
// return mv_from_int(q);
//}
//
//static mv_binary_func_t* oidiv_dispositions[MT_DIM][MT_DIM] = {
// // ERROR ABSENT EMPTY STRING INT FLOAT BOOL
// /*ERROR*/ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
// /*ABSENT*/ {_erro, _a, _a, _erro, _i0, _f0, _erro},
// /*EMPTY*/ {_erro, _a, _void, _erro, _void, _void, _erro},
// /*STRING*/ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
// /*INT*/ {_erro, _1, _void, _erro, oidiv_i_ii, oidiv_f_if, _erro},
// /*FLOAT*/ {_erro, _1, _void, _erro, oidiv_f_fi, oidiv_f_ff, _erro},
// /*BOOL*/ {_erro, _erro, _erro, _erro, _erro, _erro, _erro},
//};
//
//mv_t x_xx_int_odivide_func(mv_t* pval1, mv_t* pval2) {
// return (oidiv_dispositions[pval1->type][pval2->type])(pval1,pval2);
//}

View file

@ -77,11 +77,11 @@ var ActTab = ActionTable{
Ignore: "",
},
ActionRow{ // S14
Accept: 58,
Accept: 59,
Ignore: "",
},
ActionRow{ // S15
Accept: 58,
Accept: 59,
Ignore: "",
},
ActionRow{ // S16
@ -157,7 +157,7 @@ var ActTab = ActionTable{
Ignore: "",
},
ActionRow{ // S34
Accept: 60,
Accept: 58,
Ignore: "",
},
ActionRow{ // S35
@ -237,7 +237,7 @@ var ActTab = ActionTable{
Ignore: "",
},
ActionRow{ // S54
Accept: 59,
Accept: 60,
Ignore: "",
},
ActionRow{ // S55
@ -361,7 +361,7 @@ var ActTab = ActionTable{
Ignore: "",
},
ActionRow{ // S85
Accept: 59,
Accept: 60,
Ignore: "",
},
ActionRow{ // S86
@ -373,11 +373,11 @@ var ActTab = ActionTable{
Ignore: "",
},
ActionRow{ // S88
Accept: 59,
Accept: 60,
Ignore: "",
},
ActionRow{ // S89
Accept: 58,
Accept: 59,
Ignore: "",
},
ActionRow{ // S90
@ -441,7 +441,7 @@ var ActTab = ActionTable{
Ignore: "",
},
ActionRow{ // S105
Accept: 59,
Accept: 60,
Ignore: "",
},
ActionRow{ // S106
@ -453,11 +453,11 @@ var ActTab = ActionTable{
Ignore: "",
},
ActionRow{ // S108
Accept: 59,
Accept: 60,
Ignore: "",
},
ActionRow{ // S109
Accept: 59,
Accept: 60,
Ignore: "",
},
ActionRow{ // S110
@ -473,7 +473,7 @@ var ActTab = ActionTable{
Ignore: "",
},
ActionRow{ // S113
Accept: 59,
Accept: 60,
Ignore: "",
},
ActionRow{ // S114
@ -481,11 +481,11 @@ var ActTab = ActionTable{
Ignore: "",
},
ActionRow{ // S115
Accept: 59,
Accept: 60,
Ignore: "",
},
ActionRow{ // S116
Accept: 59,
Accept: 60,
Ignore: "",
},
ActionRow{ // S117
@ -497,7 +497,7 @@ var ActTab = ActionTable{
Ignore: "",
},
ActionRow{ // S119
Accept: 59,
Accept: 60,
Ignore: "",
},
ActionRow{ // S120

View file

@ -2637,10 +2637,10 @@ IndirectFieldName
// to the lrecs, with mlrvals there! :)
AtomOrFunction
: md_token_int_literal << dsl.NewASTNode($0, dsl.NodeTypeNumberLiteral) >>
| md_token_float_literal << dsl.NewASTNode($0, dsl.NodeTypeNumberLiteral) >>
| md_token_string_literal << dsl.NewASTNode($0, dsl.NodeTypeStringLiteral) >>
| md_token_boolean_literal << dsl.NewASTNode($0, dsl.NodeTypeBooleanLiteral) >>
: md_token_string_literal << dsl.NewASTNode($0, dsl.NodeTypeStringLiteral) >>
| md_token_int_literal << dsl.NewASTNode($0, dsl.NodeTypeIntLiteral) >>
| md_token_float_literal << dsl.NewASTNode($0, dsl.NodeTypeFloatLiteral) >>
| md_token_boolean_literal << dsl.NewASTNode($0, dsl.NodeTypeBoolLiteral) >>
;
//AtomOrFunction(A) ::= md_regexi(B). {

File diff suppressed because it is too large Load diff

View file

@ -830,44 +830,44 @@ var productionsTable = ProdTab{
return dsl.NewASTNodeUnary(X[0], X[1], dsl.NodeTypeIndirectFieldName)
},
},
ProdTabEntry{
String: `AtomOrFunction : md_token_int_literal << dsl.NewASTNode(X[0], dsl.NodeTypeNumberLiteral) >>`,
Id: "AtomOrFunction",
NTType: 21,
Index: 81,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return dsl.NewASTNode(X[0], dsl.NodeTypeNumberLiteral)
},
},
ProdTabEntry{
String: `AtomOrFunction : md_token_float_literal << dsl.NewASTNode(X[0], dsl.NodeTypeNumberLiteral) >>`,
Id: "AtomOrFunction",
NTType: 21,
Index: 82,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return dsl.NewASTNode(X[0], dsl.NodeTypeNumberLiteral)
},
},
ProdTabEntry{
String: `AtomOrFunction : md_token_string_literal << dsl.NewASTNode(X[0], dsl.NodeTypeStringLiteral) >>`,
Id: "AtomOrFunction",
NTType: 21,
Index: 83,
Index: 81,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return dsl.NewASTNode(X[0], dsl.NodeTypeStringLiteral)
},
},
ProdTabEntry{
String: `AtomOrFunction : md_token_boolean_literal << dsl.NewASTNode(X[0], dsl.NodeTypeBooleanLiteral) >>`,
String: `AtomOrFunction : md_token_int_literal << dsl.NewASTNode(X[0], dsl.NodeTypeIntLiteral) >>`,
Id: "AtomOrFunction",
NTType: 21,
Index: 82,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return dsl.NewASTNode(X[0], dsl.NodeTypeIntLiteral)
},
},
ProdTabEntry{
String: `AtomOrFunction : md_token_float_literal << dsl.NewASTNode(X[0], dsl.NodeTypeFloatLiteral) >>`,
Id: "AtomOrFunction",
NTType: 21,
Index: 83,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return dsl.NewASTNode(X[0], dsl.NodeTypeFloatLiteral)
},
},
ProdTabEntry{
String: `AtomOrFunction : md_token_boolean_literal << dsl.NewASTNode(X[0], dsl.NodeTypeBoolLiteral) >>`,
Id: "AtomOrFunction",
NTType: 21,
Index: 84,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return dsl.NewASTNode(X[0], dsl.NodeTypeBooleanLiteral)
return dsl.NewASTNode(X[0], dsl.NodeTypeBoolLiteral)
},
},
ProdTabEntry{

View file

@ -177,9 +177,9 @@ var TokMap = TokenMap{
"md_token_field_name",
"$[",
"]",
"md_token_string_literal",
"md_token_int_literal",
"md_token_float_literal",
"md_token_string_literal",
"md_token_boolean_literal",
"md_token_IPS",
"md_token_IFS",
@ -253,9 +253,9 @@ var TokMap = TokenMap{
"md_token_field_name": 55,
"$[": 56,
"]": 57,
"md_token_int_literal": 58,
"md_token_float_literal": 59,
"md_token_string_literal": 60,
"md_token_string_literal": 58,
"md_token_int_literal": 59,
"md_token_float_literal": 60,
"md_token_boolean_literal": 61,
"md_token_IPS": 62,
"md_token_IFS": 63,

View file

@ -44,6 +44,7 @@ func NewContext() *Context {
func (this *Context) UpdateForStartOfFile(filename string) {
this.FILENAME = filename
this.FILENUM++
this.FNR = 0
}
func (this *Context) UpdateForInputRecord(inrec *containers.Lrec) {