From cea36b032075f869445f13c71b8f62de9bab6e12 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Wed, 2 Aug 2023 09:09:48 +0200 Subject: [PATCH] forge/rep: first level of parsing and compiling an JSON array OK --- forge/rep/json.go | 35 +++++++++++++++++++++++++++++++++++ forge/rep/rep.go | 21 ++++++++++++++++++--- tests/forge_test.go | 9 +++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 forge/rep/json.go diff --git a/forge/rep/json.go b/forge/rep/json.go new file mode 100644 index 0000000..2437a92 --- /dev/null +++ b/forge/rep/json.go @@ -0,0 +1,35 @@ +package rep + +import ( + "encoding/json" + "fmt" +) + +func ParseJson(inp string) coderep { + var raw interface{} + err := json.Unmarshal([]byte(inp), &raw) + if err != nil { + fmt.Println(err) + return nil + } + rep := prepare(raw) + return rep +} + +func prepare(raw interface{}) coderep { + switch ri := raw.(type) { + case []interface{}: + c := code{} + for _, it := range ri { + c = append(c, it) + } + return c + case map[string]interface{}: + m := module{} + for k, v := range ri { + m[k] = v + } + return m + } + return nil +} diff --git a/forge/rep/rep.go b/forge/rep/rep.go index f9618b9..6b2da0b 100644 --- a/forge/rep/rep.go +++ b/forge/rep/rep.go @@ -1,15 +1,23 @@ +// Package rep implements representations of Forge code - internal ones +// as slices and maps and corresponding external ones using serialization +// formats like JSON and YAML. package rep import ( "fmt" "strings" + "git.sr.ht/~cco/go-scopes/common/voc" "git.sr.ht/~cco/go-scopes/forge" ) -// may be: code, defs, string, int, float +// may be: code, module, string, int, float type citem interface{} +type coderep interface { + Compile(forge.FE) forge.FPtr +} + // code, represented by a slice type code []citem @@ -24,6 +32,8 @@ func (ci code) Compile(f forge.FE) forge.FPtr { switch i := item.(type) { case int: c.Append(i) + case float64: + c.Append(int(i)) case string: if v, err := compStr(f, i); err == nil { c.Append(v) @@ -47,6 +57,11 @@ func compStr(f forge.FE, s string) (forge.FItem, error) { return nil, fmt.Errorf("not found: %s", s) } -// defs - definitions, represented by a map +// module - code definitions, represented by a map -type defs map[string]citem +type module map[string]citem + +func (m module) Compile(f forge.FE) forge.FPtr { + v := voc.NewVoc(f.Voc()) + return f.Code(v) +} diff --git a/tests/forge_test.go b/tests/forge_test.go index 7230598..43f5c5f 100644 --- a/tests/forge_test.go +++ b/tests/forge_test.go @@ -17,6 +17,7 @@ func TestForge(tb *tbase.T) { t.Run("exec", ExecTest) t.Run("core", CoreTest) t.Run("rep", RepTest) + t.Run("json", JsonTest) } func ExecTest(t *testing.T) { @@ -48,3 +49,11 @@ func RepTest(t *testing.T) { fe.Call(rep.Code(3, "cube").Compile(fe)) t.AssertEqual(fe.Pop(), 27) } + +func JsonTest(t *testing.T) { + j := `[4, 2, "+"]` + src := rep.ParseJson(j) + c := src.Compile(fe) + fe.Call(c) + t.AssertEqual(fe.Pop(), 6) +}