From c724ad89bd4813e872b58c5ccf81432c031ecd5a Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Sun, 23 Jul 2023 10:20:25 +0200 Subject: [PATCH] forge: execute simple forge code --- forge/builtins/builtins.go | 19 +++++++++---- forge/forge.go | 58 ++++++++++++++++++++++---------------- tests/forge_test.go | 8 ++---- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/forge/builtins/builtins.go b/forge/builtins/builtins.go index 70e7bc6..adfa172 100644 --- a/forge/builtins/builtins.go +++ b/forge/builtins/builtins.go @@ -9,15 +9,22 @@ type builtins struct { Add, Lit XT } -func Setup(f FE) *builtins { +func Get(f FE) *builtins { + m := f.Voc().Lookup("builtins") + if m.IsNothing() { + b := setup(f) + f.Voc().Register("builtins", b) + return b + } + return m.Value().(*builtins) +} + +func setup(f FE) *builtins { r := func(name string, fct forge.Callable) XT { return forge.Register(f.Voc(), name, fct) } return &builtins{ - Lit: r("literal", literal), + Add: r("+", func(f FE, _ XT) { f.Push(f.Pop().(int) + f.Pop().(int)) }), + Lit: r("literal", func(f FE, _ XT) { f.Literal() }), } } - -func literal(f FE, it XT) { - f.Push(f.IP().Next().Value()) -} diff --git a/forge/forge.go b/forge/forge.go index 730dba2..9be7085 100644 --- a/forge/forge.go +++ b/forge/forge.go @@ -14,19 +14,10 @@ type fitem interface{} type fptr = ptr.Ptr[fitem] type fstack = stack.Stack[fitem] -type fvoc = voc.Vocabulary[XT] +type fvoc = voc.Vocabulary[fitem] type Callable func(*forgeEnv, XT) -type xitem struct { - name string - immediate bool - fct Callable - body fptr -} - -type XT = *xitem - type forgeEnv struct { ds, rs fstack cp, ip, dp fptr @@ -38,16 +29,12 @@ type forgeEnv struct { type FE = *forgeEnv -func NewVoc(parent *fvoc) *fvoc { - return voc.NewVoc[XT](parent) -} - func NewFE() *forgeEnv { - return newFE(NewVoc(nil)) + return newFE(newVoc(nil)) } func (f *forgeEnv) ChildFE() *forgeEnv { - return newFE(NewVoc(f.voc)) + return newFE(newVoc(f.voc)) } func newFE(voc *fvoc) *forgeEnv { @@ -60,7 +47,20 @@ func newFE(voc *fvoc) *forgeEnv { } } -// basic functions and methods +var newVoc = voc.NewVoc[fitem] + +var newPtr = ptr.NewSlice[fitem] + +// xitem (executable item) / XT (execution token) + +type xitem struct { + name string + immediate bool + fct Callable + body fptr +} + +type XT = *xitem func Register(voc *fvoc, name string, fct Callable) *xitem { it := xitem{ @@ -81,7 +81,7 @@ func (it *xitem) Immediate() { func (it *xitem) Body() fptr { if it.body == nil { - it.body = ptr.NewSlice[fitem]() + it.body = newPtr() } return it.body } @@ -90,22 +90,26 @@ func (it *xitem) Name() string { return it.name } -// ForgeEnv methods +// forgeEnv methods func (f *forgeEnv) Voc() *fvoc { return f.voc } -func (f *forgeEnv) IP() fptr { - return f.ip +func (f *forgeEnv) Code(items ...fitem) fptr { + code := newPtr(items...) + // ... pre-process (compile) code ... + return code } -func (f *forgeEnv) Exec(items ...fitem) { - f.ip = ptr.NewSlice[fitem](items...) +func (f *forgeEnv) Call(code fptr) { + f.rs.Push(f.ip) + f.ip = code.Clone() for f.ip.Next() != nil { - it := f.ip.Value().(XT) - it.fct(f, it) + xt := f.ip.Value().(XT) + xt.fct(f, xt) } + f.ip = f.rs.Pop().(fptr) } func (f *forgeEnv) Push(it fitem) { @@ -115,3 +119,7 @@ func (f *forgeEnv) Push(it fitem) { func (f *forgeEnv) Pop() fitem { return f.ds.Pop() } + +func (f *forgeEnv) Literal() { + f.Push(f.ip.Next().Value()) +} diff --git a/tests/forge_test.go b/tests/forge_test.go index d3996fe..4522758 100644 --- a/tests/forge_test.go +++ b/tests/forge_test.go @@ -15,9 +15,7 @@ func TestForge(tb *tbase.T) { func ExecTest(t *testing.T) { fe := forge.NewFE() - b := builtins.Setup(fe) - fe.Exec(b.Lit, 4) - t.AssertEqual(fe.Pop(), 4) - // fe.Execute(forge.Code{b.Lit, 3, b.Lit, 2, b.Add}) - // t.AssertEqual(fe.Pop(), 5) + b := builtins.Get(fe) + fe.Call(fe.Code(b.Lit, 4, b.Lit, 2, b.Add)) + t.AssertEqual(fe.Pop(), 6) }