forge/rep: first level of parsing and compiling an JSON array OK

This commit is contained in:
Helmut Merz 2023-08-02 09:09:48 +02:00
parent 434fba79d8
commit cea36b0320
3 changed files with 62 additions and 3 deletions

35
forge/rep/json.go Normal file
View file

@ -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
}

View file

@ -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)
}

View file

@ -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)
}