Compare commits
5 Commits
0e55f83d56
...
cca3b76baa
Author | SHA1 | Date | |
---|---|---|---|
cca3b76baa | |||
24e31997fc | |||
646710e180 | |||
b38327b841 | |||
fd912b2eb1 |
@ -8,6 +8,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -188,6 +189,30 @@ func fractFunc(ctx ExprContext, name string, args map[string]any) (result any, e
|
|||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
func evalFunc(ctx ExprContext, name string, args map[string]any) (result any, err error) {
|
||||||
|
if source, ok := args[ParamSource].(string); ok {
|
||||||
|
var expr Expr
|
||||||
|
|
||||||
|
parser := NewParser()
|
||||||
|
if ctx == nil {
|
||||||
|
ctx = NewSimpleStore()
|
||||||
|
}
|
||||||
|
|
||||||
|
r := strings.NewReader(source)
|
||||||
|
scanner := NewScanner(r, DefaultTranslations())
|
||||||
|
|
||||||
|
if expr, err = parser.Parse(scanner); err == nil {
|
||||||
|
CtrlEnable(ctx, control_export_all)
|
||||||
|
result, err = expr.Eval(ctx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = ErrWrongParamType(name, ParamSource, TypeString, args[ParamSource])
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//// import
|
||||||
|
|
||||||
func ImportBuiltinsFuncs(ctx ExprContext) {
|
func ImportBuiltinsFuncs(ctx ExprContext) {
|
||||||
anyParams := []ExprFuncParam{
|
anyParams := []ExprFuncParam{
|
||||||
NewFuncParam(ParamValue),
|
NewFuncParam(ParamValue),
|
||||||
@ -211,6 +236,10 @@ func ImportBuiltinsFuncs(ctx ExprContext) {
|
|||||||
NewFuncParam(ParamValue),
|
NewFuncParam(ParamValue),
|
||||||
NewFuncParamFlagDef(ParamDenominator, PfDefault, int64(1)),
|
NewFuncParamFlagDef(ParamDenominator, PfDefault, int64(1)),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ctx.RegisterFunc("eval", NewGolangFunctor(evalFunc), TypeAny, []ExprFuncParam{
|
||||||
|
NewFuncParam(ParamSource),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -55,8 +55,25 @@ func ErrInvalidParameterValue(funcName, paramName string, paramValue any) error
|
|||||||
return fmt.Errorf("%s(): invalid value %s (%v) for parameter %q", funcName, TypeName(paramValue), paramValue, paramName)
|
return fmt.Errorf("%s(): invalid value %s (%v) for parameter %q", funcName, TypeName(paramValue), paramValue, paramName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func undefArticle(s string) (article string) {
|
||||||
|
if len(s) > 0 && strings.Contains("aeiou", s[0:1]) {
|
||||||
|
article = "an"
|
||||||
|
} else {
|
||||||
|
article = "a"
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func prependUndefArticle(s string) (result string) {
|
||||||
|
return undefArticle(s) + " " + s
|
||||||
|
}
|
||||||
|
|
||||||
func ErrWrongParamType(funcName, paramName, paramType string, paramValue any) error {
|
func ErrWrongParamType(funcName, paramName, paramType string, paramValue any) error {
|
||||||
return fmt.Errorf("%s(): the %q parameter must be a %s, got a %s (%v)", funcName, paramName, paramType, TypeName(paramValue), paramValue)
|
var artWantType, artGotType string
|
||||||
|
gotType := TypeName(paramValue)
|
||||||
|
artGotType = prependUndefArticle(gotType)
|
||||||
|
artWantType = prependUndefArticle(paramType)
|
||||||
|
return fmt.Errorf("%s(): the %q parameter must be %s, got %s (%v)", funcName, paramName, artWantType, artGotType, paramValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrUnknownParam(funcName, paramName string) error {
|
func ErrUnknownParam(funcName, paramName string) error {
|
||||||
|
@ -29,7 +29,7 @@ func exportObjects(destCtx, sourceCtx ExprContext) {
|
|||||||
exportAll := CtrlIsEnabled(sourceCtx, control_export_all)
|
exportAll := CtrlIsEnabled(sourceCtx, control_export_all)
|
||||||
// fmt.Printf("Exporting from sourceCtx [%p] to destCtx [%p] -- exportAll=%t\n", sourceCtx, destCtx, exportAll)
|
// fmt.Printf("Exporting from sourceCtx [%p] to destCtx [%p] -- exportAll=%t\n", sourceCtx, destCtx, exportAll)
|
||||||
// Export variables
|
// Export variables
|
||||||
for _, refName := range sourceCtx.EnumVars(func(name string) bool { return exportAll || name[0] == '@' }) {
|
for _, refName := range sourceCtx.EnumVars(func(name string) bool { return (exportAll || name[0] == '@') && !(name[0] == '_') }) {
|
||||||
// fmt.Printf("\tExporting %q\n", refName)
|
// fmt.Printf("\tExporting %q\n", refName)
|
||||||
refValue, _ := sourceCtx.GetVar(refName)
|
refValue, _ := sourceCtx.GetVar(refName)
|
||||||
exportVar(destCtx, refName, refValue)
|
exportVar(destCtx, refName, refValue)
|
||||||
|
@ -126,34 +126,36 @@ func (f *FractionType) ToString(opt FmtOpt) string {
|
|||||||
if opt&MultiLine == 0 {
|
if opt&MultiLine == 0 {
|
||||||
sb.WriteString(fmt.Sprintf("%d:%d", f.num, f.den))
|
sb.WriteString(fmt.Sprintf("%d:%d", f.num, f.den))
|
||||||
} else {
|
} else {
|
||||||
var s, num string
|
var sign, num string
|
||||||
if f.num < 0 && opt&TTY == 0 {
|
if f.num < 0 && opt&TTY == 0 {
|
||||||
num = strconv.FormatInt(-f.num, 10)
|
num = strconv.FormatInt(-f.num, 10)
|
||||||
s = "-"
|
sign = "-"
|
||||||
} else {
|
} else {
|
||||||
num = strconv.FormatInt(f.num, 10)
|
num = strconv.FormatInt(f.num, 10)
|
||||||
}
|
}
|
||||||
den := strconv.FormatInt(f.den, 10)
|
den := strconv.FormatInt(f.den, 10)
|
||||||
size := max(len(num), len(den))
|
size := max(len(num), len(den))
|
||||||
if opt&TTY != 0 {
|
if opt&TTY != 0 {
|
||||||
sb.WriteString(fmt.Sprintf("\x1b[4m%[1]*s\x1b[0m\n", -size, fmt.Sprintf("%[1]*s", (size+len(num))/2, s+num)))
|
sNum := fmt.Sprintf("\x1b[4m%[1]*s\x1b[0m\n", -size, fmt.Sprintf("%[1]*s", (size+len(num))/2, sign+num))
|
||||||
|
sb.WriteString(sNum)
|
||||||
} else {
|
} else {
|
||||||
if len(s) > 0 {
|
if len(sign) > 0 {
|
||||||
sb.WriteString(" ")
|
sb.WriteString(" ")
|
||||||
}
|
}
|
||||||
sb.WriteString(fmt.Sprintf("%[1]*s", -size, fmt.Sprintf("%[1]*s", (size+len(num))/2, num)))
|
sb.WriteString(fmt.Sprintf("%[1]*s", -size, fmt.Sprintf("%[1]*s", (size+len(num))/2, num)))
|
||||||
sb.WriteByte('\n')
|
sb.WriteByte('\n')
|
||||||
if len(s) > 0 {
|
if len(sign) > 0 {
|
||||||
sb.WriteString(s)
|
sb.WriteString(sign)
|
||||||
sb.WriteByte(' ')
|
sb.WriteByte(' ')
|
||||||
}
|
}
|
||||||
sb.WriteString(strings.Repeat("-", size))
|
sb.WriteString(strings.Repeat("-", size))
|
||||||
sb.WriteByte('\n')
|
sb.WriteByte('\n')
|
||||||
if len(s) > 0 {
|
if len(sign) > 0 {
|
||||||
sb.WriteString(" ")
|
sb.WriteString(" ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sb.WriteString(fmt.Sprintf("%[1]*s", -size, fmt.Sprintf("%[1]*s", (size+len(den))/2, den)))
|
sDen := fmt.Sprintf("%[1]*s", size, fmt.Sprintf("%[1]*s", (size+len(den))/2, den))
|
||||||
|
sb.WriteString(sDen)
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.String()
|
return sb.String()
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
package expr
|
package expr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
// "errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -43,6 +43,6 @@ func errNoOperation(name string) error {
|
|||||||
return fmt.Errorf("no %s() function defined in the data-source", name)
|
return fmt.Errorf("no %s() function defined in the data-source", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func errInvalidDataSource() error {
|
// func errInvalidDataSource() error {
|
||||||
return errors.New("invalid data-source")
|
// return errors.New("invalid data-source")
|
||||||
}
|
// }
|
||||||
|
@ -20,7 +20,7 @@ func evalContextValue(ctx ExprContext, opTerm *term) (v any, err error) {
|
|||||||
var childValue any
|
var childValue any
|
||||||
|
|
||||||
var sourceCtx ExprContext
|
var sourceCtx ExprContext
|
||||||
if opTerm.children == nil || len(opTerm.children) == 0 {
|
if len(opTerm.children) == 0 {
|
||||||
sourceCtx = ctx
|
sourceCtx = ctx
|
||||||
} else if opTerm.children[0].symbol() == SymVariable && opTerm.children[0].source() == "global" {
|
} else if opTerm.children[0].symbol() == SymVariable && opTerm.children[0].source() == "global" {
|
||||||
sourceCtx = globalCtx
|
sourceCtx = globalCtx
|
||||||
|
@ -460,7 +460,7 @@ func (scanner *scanner) parseNumber(firstCh byte) (tk *Token) {
|
|||||||
tk = scanner.makeErrorToken(err)
|
tk = scanner.makeErrorToken(err)
|
||||||
} else {
|
} else {
|
||||||
var value any
|
var value any
|
||||||
err = scanner.sync(err) // TODO: Check this function
|
_ = scanner.sync(err) // TODO: Check this function
|
||||||
txt := sb.String()
|
txt := sb.String()
|
||||||
if sym == SymFloat {
|
if sym == SymFloat {
|
||||||
value, err = strconv.ParseFloat(txt, 64)
|
value, err = strconv.ParseFloat(txt, 64)
|
||||||
|
@ -56,11 +56,12 @@ func TestFuncBase(t *testing.T) {
|
|||||||
/* 42 */ {`dec(false)`, float64(0), nil},
|
/* 42 */ {`dec(false)`, float64(0), nil},
|
||||||
/* 43 */ {`dec(1:2)`, float64(0.5), nil},
|
/* 43 */ {`dec(1:2)`, float64(0.5), nil},
|
||||||
/* 44 */ {`dec([1])`, nil, `dec(): can't convert list to float`},
|
/* 44 */ {`dec([1])`, nil, `dec(): can't convert list to float`},
|
||||||
|
/* 45 */ {`eval("a=3"); a`, int64(3), nil},
|
||||||
// /* 45 */ {`string([1])`, nil, `string(): can't convert list to string`},
|
// /* 45 */ {`string([1])`, nil, `string(): can't convert list to string`},
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Setenv("EXPR_PATH", ".")
|
t.Setenv("EXPR_PATH", ".")
|
||||||
|
|
||||||
// runTestSuiteSpec(t, section, inputs, 30)
|
// runTestSuiteSpec(t, section, inputs, 45)
|
||||||
runTestSuite(t, section, inputs)
|
runTestSuite(t, section, inputs)
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ func TestFuncString(t *testing.T) {
|
|||||||
/* 1 */ {`builtin "string"; strJoin("-", "one", "two", "three")`, "one-two-three", nil},
|
/* 1 */ {`builtin "string"; strJoin("-", "one", "two", "three")`, "one-two-three", nil},
|
||||||
/* 2 */ {`builtin "string"; strJoin("-", ["one", "two", "three"])`, "one-two-three", nil},
|
/* 2 */ {`builtin "string"; strJoin("-", ["one", "two", "three"])`, "one-two-three", nil},
|
||||||
/* 3 */ {`builtin "string"; ls= ["one", "two", "three"]; strJoin("-", ls)`, "one-two-three", nil},
|
/* 3 */ {`builtin "string"; ls= ["one", "two", "three"]; strJoin("-", ls)`, "one-two-three", nil},
|
||||||
/* 4 */ {`builtin "string"; ls= ["one", "two", "three"]; strJoin(1, ls)`, nil, `strJoin(): the "separator" parameter must be a string, got a integer (1)`},
|
/* 4 */ {`builtin "string"; ls= ["one", "two", "three"]; strJoin(1, ls)`, nil, `strJoin(): the "separator" parameter must be a string, got an integer (1)`},
|
||||||
/* 5 */ {`builtin "string"; ls= ["one", 2, "three"]; strJoin("-", ls)`, nil, `strJoin(): expected string, got integer (2)`},
|
/* 5 */ {`builtin "string"; ls= ["one", 2, "three"]; strJoin("-", ls)`, nil, `strJoin(): expected string, got integer (2)`},
|
||||||
/* 6 */ {`builtin "string"; "<"+strTrim(" bye bye ")+">"`, "<bye bye>", nil},
|
/* 6 */ {`builtin "string"; "<"+strTrim(" bye bye ")+">"`, "<bye bye>", nil},
|
||||||
/* 7 */ {`builtin "string"; strSub("0123456789", 1,2)`, "12", nil},
|
/* 7 */ {`builtin "string"; strSub("0123456789", 1,2)`, "12", nil},
|
||||||
|
@ -59,10 +59,9 @@ func TestFractionToStringMultiline(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Check this test: the output string ends with a space
|
func TestToStringMultilineTty(t *testing.T) {
|
||||||
func _TestToStringMultilineTty(t *testing.T) {
|
|
||||||
source := newFraction(-1, 2)
|
source := newFraction(-1, 2)
|
||||||
want := "\x1b[4m-1\x1b[0m\n2"
|
want := "\x1b[4m-1\x1b[0m\n 2"
|
||||||
got := source.ToString(MultiLine | TTY)
|
got := source.ToString(MultiLine | TTY)
|
||||||
if got != want {
|
if got != want {
|
||||||
t.Errorf(`(1,2) -> result = %#v [%T], want = %#v [%T]`, got, got, want, want)
|
t.Errorf(`(1,2) -> result = %#v [%T], want = %#v [%T]`, got, got, want, want)
|
||||||
|
@ -8,18 +8,18 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func _TestImportPlugin(t *testing.T) {
|
// func TestImportPlugin(t *testing.T) {
|
||||||
t.Setenv("PLUGINS", "${HOME}/go/src/git.portale-stac.it/go")
|
// t.Setenv("PLUGINS", "${HOME}/go/src/git.portale-stac.it/go")
|
||||||
t.Setenv("EXPR_PLUGIN_PATH","${PLUGINS}/expr-json-plugin:${PLUGINS}/expr-csv-plugin")
|
// t.Setenv("EXPR_PLUGIN_PATH","${PLUGINS}/expr-json-plugin:${PLUGINS}/expr-csv-plugin")
|
||||||
|
|
||||||
gotCount, gotErr := importPluginFromSearchPath("json")
|
// gotCount, gotErr := importPluginFromSearchPath("json")
|
||||||
if gotCount != 1 {
|
// if gotCount != 1 {
|
||||||
t.Errorf("Import count: got=%d, want=1", gotCount)
|
// t.Errorf("Import count: got=%d, want=1", gotCount)
|
||||||
}
|
// }
|
||||||
if gotErr != nil {
|
// if gotErr != nil {
|
||||||
t.Errorf("importPlugin() failed: %v", gotErr)
|
// t.Errorf("importPlugin() failed: %v", gotErr)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
func TestPluginExists(t *testing.T) {
|
func TestPluginExists(t *testing.T) {
|
||||||
name := "json"
|
name := "json"
|
||||||
|
Loading…
Reference in New Issue
Block a user