forge/rep: first level of parsing and compiling an JSON array OK
This commit is contained in:
parent
434fba79d8
commit
cea36b0320
3 changed files with 62 additions and 3 deletions
35
forge/rep/json.go
Normal file
35
forge/rep/json.go
Normal 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
|
||||||
|
}
|
|
@ -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
|
package rep
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"git.sr.ht/~cco/go-scopes/common/voc"
|
||||||
"git.sr.ht/~cco/go-scopes/forge"
|
"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 citem interface{}
|
||||||
|
|
||||||
|
type coderep interface {
|
||||||
|
Compile(forge.FE) forge.FPtr
|
||||||
|
}
|
||||||
|
|
||||||
// code, represented by a slice
|
// code, represented by a slice
|
||||||
|
|
||||||
type code []citem
|
type code []citem
|
||||||
|
@ -24,6 +32,8 @@ func (ci code) Compile(f forge.FE) forge.FPtr {
|
||||||
switch i := item.(type) {
|
switch i := item.(type) {
|
||||||
case int:
|
case int:
|
||||||
c.Append(i)
|
c.Append(i)
|
||||||
|
case float64:
|
||||||
|
c.Append(int(i))
|
||||||
case string:
|
case string:
|
||||||
if v, err := compStr(f, i); err == nil {
|
if v, err := compStr(f, i); err == nil {
|
||||||
c.Append(v)
|
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)
|
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)
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ func TestForge(tb *tbase.T) {
|
||||||
t.Run("exec", ExecTest)
|
t.Run("exec", ExecTest)
|
||||||
t.Run("core", CoreTest)
|
t.Run("core", CoreTest)
|
||||||
t.Run("rep", RepTest)
|
t.Run("rep", RepTest)
|
||||||
|
t.Run("json", JsonTest)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExecTest(t *testing.T) {
|
func ExecTest(t *testing.T) {
|
||||||
|
@ -48,3 +49,11 @@ func RepTest(t *testing.T) {
|
||||||
fe.Call(rep.Code(3, "cube").Compile(fe))
|
fe.Call(rep.Code(3, "cube").Compile(fe))
|
||||||
t.AssertEqual(fe.Pop(), 27)
|
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)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue