diff --git a/simple-func-store.go b/simple-func-store.go index cfc9373..2ce81f3 100644 --- a/simple-func-store.go +++ b/simple-func-store.go @@ -4,7 +4,10 @@ // simple-func-store.go package expr -import "fmt" +import ( + "fmt" + "strings" +) type SimpleFuncStore struct { SimpleVarStore @@ -18,6 +21,29 @@ type funcInfo struct { functor Functor } +func (info *funcInfo) ToString(opt FmtOpt) string { + var sb strings.Builder + var i int + sb.WriteString("func(") + for i = 0; i < info.minArgs; i++ { + if i > 0 { + sb.WriteString(", ") + } + sb.WriteString(fmt.Sprintf("arg%d", i+1)) + } + for ; i < info.maxArgs; i++ { + sb.WriteString(fmt.Sprintf("arg%d", i+1)) + } + if info.maxArgs < 0 { + if info.minArgs > 0 { + sb.WriteString(", ") + } + sb.WriteString("...") + } + sb.WriteString(") {...}") + return sb.String() +} + func (info *funcInfo) Name() string { return info.name } @@ -52,6 +78,36 @@ func (ctx *SimpleFuncStore) Clone() ExprContext { } } +func funcsCtxToBuilder(sb *strings.Builder, ctx ExprContext, indent int) { + sb.WriteString("funcs: {\n") + first := true + for _, name := range ctx.EnumFuncs(func(name string) bool { return true }) { + if first { + first = false + } else { + sb.WriteByte(',') + sb.WriteByte('\n') + } + value, _ := ctx.GetFuncInfo(name) + sb.WriteString(strings.Repeat("\t", indent+1)) + sb.WriteString(name) + sb.WriteString("=") + if formatter, ok := value.(Formatter); ok { + sb.WriteString(formatter.ToString(0)) + } else { + sb.WriteString(fmt.Sprintf("%v", value)) + } + } + sb.WriteString("\n}\n") +} + +func (ctx *SimpleFuncStore) ToString(opt FmtOpt) string { + var sb strings.Builder + sb.WriteString(ctx.SimpleVarStore.ToString(opt)) + funcsCtxToBuilder(&sb, ctx, 0) + return sb.String() +} + func (ctx *SimpleFuncStore) GetFuncInfo(name string) (info ExprFunc, exists bool) { info, exists = ctx.funcStore[name] return diff --git a/simple-var-store.go b/simple-var-store.go index 1702147..ae5e3a9 100644 --- a/simple-var-store.go +++ b/simple-var-store.go @@ -79,34 +79,43 @@ func (ctx *SimpleVarStore) EnumFuncs(acceptor func(name string) (accept bool)) ( return } -func CtxToBuilder(sb *strings.Builder, ctx ExprContext, indent int) { - sb.WriteString("{\n") +func varsCtxToBuilder(sb *strings.Builder, ctx ExprContext, indent int) { + sb.WriteString("vars: {\n") first := true for _, name := range ctx.EnumVars(func(name string) bool { return name[0] != '_' }) { + if first { + first = false + } else { + sb.WriteByte(',') + sb.WriteByte('\n') + } + value, _ := ctx.GetVar(name) sb.WriteString(strings.Repeat("\t", indent+1)) sb.WriteString(name) - sb.WriteString("=") - if _, ok := value.(Functor); ok { - sb.WriteString(": func(){}") + sb.WriteString(": ") + if f, ok := value.(Formatter); ok { + sb.WriteString(f.ToString(0)) + } else if _, ok = value.(Functor); ok { + sb.WriteString("func(){}") } else if _, ok = value.(map[any]any); ok { sb.WriteString("dict{}") } else { sb.WriteString(fmt.Sprintf("%v", value)) } - if first { - first = false - } else { - sb.WriteByte(',') - } - sb.WriteByte('\n') } sb.WriteString(strings.Repeat("\t", indent)) - sb.WriteString("}\n") + sb.WriteString("\n}\n") } -func CtxToString(ctx ExprContext, indent int) string { +func varsCtxToString(ctx ExprContext, indent int) string { var sb strings.Builder - CtxToBuilder(&sb, ctx, indent) + varsCtxToBuilder(&sb, ctx, indent) + return sb.String() +} + +func (ctx *SimpleVarStore) ToString(opt FmtOpt) string { + var sb strings.Builder + varsCtxToBuilder(&sb, ctx, 0) return sb.String() }