diff --git a/kern/dict-type.go b/kern/dict-type.go index dd2bb5f..a1d87b8 100644 --- a/kern/dict-type.go +++ b/kern/dict-type.go @@ -76,9 +76,11 @@ func (dict *DictType) toMultiLine(sb *strings.Builder, opt FmtOpt) { sb.WriteString(nest) if key, ok := name.(string); ok { - sb.WriteString(string('"') + key + string('"')) + sb.WriteByte('"') + sb.WriteString(key) + sb.WriteByte('"') } else { - sb.WriteString(fmt.Sprintf("%v", name)) + fmt.Fprintf(sb, "%v", name) } sb.WriteString(": ") if f, ok := value.(Formatter); ok { @@ -86,7 +88,7 @@ func (dict *DictType) toMultiLine(sb *strings.Builder, opt FmtOpt) { } else if _, ok = value.(Functor); ok { sb.WriteString("func(){}") } else { - sb.WriteString(fmt.Sprintf("%v", value)) + fmt.Fprintf(sb, "%v", value) } } sb.WriteByte('\n') @@ -110,9 +112,11 @@ func (dict *DictType) ToString(opt FmtOpt) string { sb.WriteString(", ") } if s, ok := key.(string); ok { - sb.WriteString(string('"') + s + string('"')) + sb.WriteByte('"') + sb.WriteString(s) + sb.WriteByte('"') } else { - sb.WriteString(fmt.Sprintf("%v", key)) + fmt.Fprintf(&sb, "%v", key) } sb.WriteString(": ") if formatter, ok := value.(Formatter); ok { @@ -120,7 +124,7 @@ func (dict *DictType) ToString(opt FmtOpt) string { } else if t, ok := value.(Term); ok { sb.WriteString(t.String()) } else { - sb.WriteString(fmt.Sprintf("%#v", value)) + fmt.Fprintf(&sb, "%#v", value) } } sb.WriteByte('}') diff --git a/kern/expr-context.go b/kern/expr-context.go index a5d7f95..88e8f21 100644 --- a/kern/expr-context.go +++ b/kern/expr-context.go @@ -28,4 +28,36 @@ type ExprContext interface { Call(name string, args map[string]any) (result any, err error) RegisterFuncInfo(info ExprFunc) RegisterFunc(name string, f Functor, returnType string, param []ExprFuncParam) (funcInfo ExprFunc, err error) + + ToDict() (dict *DictType) + ToString(opt FmtOpt) string +} + +func ContextToDict(ctx ExprContext) (dict *DictType) { + var keys []string + // Variables + keys = ctx.EnumVars(nil) + vars := MakeDict() + for _, key := range keys { + value, _ := ctx.GetVar(key) + vars.SetItem(key, value) + } + + // Functions + keys = ctx.EnumFuncs(func(name string) bool { return true }) + funcs := MakeDict() + for _, key := range keys { + funcInfo, _ := ctx.GetFuncInfo(key) + funcs.SetItem(key, funcInfo) + } + + dict = MakeDict() + dict.SetItem("vars", vars) + dict.SetItem("funcs", funcs) + return +} + +func ContextToString(ctx ExprContext, opt FmtOpt) string { + dict := ctx.ToDict() + return dict.ToString(opt) } diff --git a/operator-context.go b/operator-context.go index 6b26eed..14037b7 100644 --- a/operator-context.go +++ b/operator-context.go @@ -40,7 +40,7 @@ func evalContextValue(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error } if sourceCtx != nil { - v = contextToDict(sourceCtx) + v = sourceCtx.ToDict() } else if childValue != nil { it, ok := childValue.(kern.Iterator) if !ok { @@ -63,28 +63,6 @@ func evalContextValue(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error return } -func contextToDict(ctx kern.ExprContext) (dict *kern.DictType) { - // Variables - keys := ctx.EnumVars(nil) - vars := kern.MakeDict() - for _, key := range keys { - value, _ := ctx.GetVar(key) - vars.SetItem(key, value) - } - // Functions - keys = ctx.EnumFuncs(func(name string) bool { return true }) - funcs := kern.MakeDict() - for _, key := range keys { - funcInfo, _ := ctx.GetFuncInfo(key) - funcs.SetItem(key, funcInfo) - } - - dict = kern.MakeDict() - dict.SetItem("vars", vars) - dict.SetItem("funcs", funcs) - return -} - // init func init() { scan.RegisterTermConstructor(scan.SymDoubleDollar, newContextTerm) diff --git a/simple-store.go b/simple-store.go index 0e24374..3f16d16 100644 --- a/simple-store.go +++ b/simple-store.go @@ -6,7 +6,6 @@ package expr import ( "fmt" - "slices" "git.portale-stac.it/go-pkg/expr/kern" "git.portale-stac.it/go-pkg/expr/util" @@ -77,48 +76,56 @@ func (ctx *SimpleStore) Clone() kern.ExprContext { // } // } -func (ctx *SimpleStore) ToString(opt kern.FmtOpt) string { - dict := ctx.ToDict() - return dict.ToString(opt) -} - -func (ctx *SimpleStore) varsToDict(dict *kern.DictType) *kern.DictType { - names := ctx.EnumVars(nil) - slices.Sort(names) - for _, name := range ctx.EnumVars(nil) { - value, _ := ctx.GetVar(name) - if f, ok := value.(kern.Formatter); ok { - (*dict)[name] = f.ToString(0) - } else if _, ok = value.(kern.Functor); ok { - (*dict)[name] = "func(){}" - } else { - (*dict)[name] = fmt.Sprintf("%v", value) - } - } - return dict -} - -func (ctx *SimpleStore) funcsToDict(dict *kern.DictType) *kern.DictType { - names := ctx.EnumFuncs(func(name string) bool { return true }) - slices.Sort(names) - for _, name := range names { - value, _ := ctx.GetFuncInfo(name) - if formatter, ok := value.(kern.Formatter); ok { - (*dict)[name] = formatter.ToString(0) - } else { - (*dict)[name] = fmt.Sprintf("%v", value) - } - } - return dict -} - func (ctx *SimpleStore) ToDict() (dict *kern.DictType) { - dict = kern.MakeDict() - (*dict)["variables"] = ctx.varsToDict(kern.MakeDict()) - (*dict)["functions"] = ctx.funcsToDict(kern.MakeDict()) - return + return kern.ContextToDict(ctx) } +func (ctx *SimpleStore) ToString(opt kern.FmtOpt) string { + return kern.ContextToString(ctx, opt) +} + +// func (ctx *SimpleStore) ToString(opt kern.FmtOpt) string { +// dict := ctx.ToDict() +// return dict.ToString(opt) +// } + +// func (ctx *SimpleStore) varsToDict(dict *kern.DictType) *kern.DictType { +// names := ctx.EnumVars(nil) +// slices.Sort(names) +// for _, name := range ctx.EnumVars(nil) { +// value, _ := ctx.GetVar(name) +// if f, ok := value.(kern.Formatter); ok { +// (*dict)[name] = f.ToString(0) +// } else if _, ok = value.(kern.Functor); ok { +// (*dict)[name] = "func(){}" +// } else { +// (*dict)[name] = fmt.Sprintf("%v", value) +// } +// } +// return dict +// } + +// func (ctx *SimpleStore) funcsToDict(dict *kern.DictType) *kern.DictType { +// names := ctx.EnumFuncs(func(name string) bool { return true }) +// slices.Sort(names) +// for _, name := range names { +// value, _ := ctx.GetFuncInfo(name) +// if formatter, ok := value.(kern.Formatter); ok { +// (*dict)[name] = formatter.ToString(0) +// } else { +// (*dict)[name] = fmt.Sprintf("%v", value) +// } +// } +// return dict +// } + +// func (ctx *SimpleStore) ToDict() (dict *kern.DictType) { +// dict = kern.MakeDict() +// (*dict)["variables"] = ctx.varsToDict(kern.MakeDict()) +// (*dict)["functions"] = ctx.funcsToDict(kern.MakeDict()) +// return +// } + func (ctx *SimpleStore) GetVar(varName string) (value any, exists bool) { if value, exists = ctx.varStore[varName]; !exists && ctx.global != nil { value, exists = ctx.global.GetVar(varName) diff --git a/t_context_test.go b/t_context_test.go index 9bb6beb..4295fc3 100644 --- a/t_context_test.go +++ b/t_context_test.go @@ -74,7 +74,6 @@ func TestCtrlEnable(t *testing.T) { if !CtrlDisable(ctx, varName) { t.Errorf(`%s -- CtrlEnable(ctx, %q) should have returned 'true', got 'false'`, section, varName) - // t.Errorf(`%s -- CtrlEnable(ctx, %q) should have returned 'false', got 'true'`, section, varName) } } @@ -88,7 +87,7 @@ func TestList(t *testing.T) { /* 3 */ {`string(($$global).funcs.bool)`, `bool(value):boolean{}`, nil}, } - runTestSuiteSpec(t, section, inputs, 3) - // runTestSuite(t, section, inputs) + // runTestSuiteSpec(t, section, inputs, 3) + runTestSuite(t, section, inputs) }