From 8d8e13d8ed54aea351edc29df817b94e80716f2b Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Sun, 23 Jul 2023 12:35:18 +0200 Subject: [PATCH] define and call forge code --- forge/builtins/builtins.go | 8 +++++--- forge/forge.go | 32 ++++++++++++++++++++++++++------ tests/forge_test.go | 6 +++++- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/forge/builtins/builtins.go b/forge/builtins/builtins.go index adfa172..454f033 100644 --- a/forge/builtins/builtins.go +++ b/forge/builtins/builtins.go @@ -6,7 +6,7 @@ type FE = forge.FE type XT = forge.XT type builtins struct { - Add, Lit XT + Add, Dup, Lit, Mult XT } func Get(f FE) *builtins { @@ -24,7 +24,9 @@ func setup(f FE) *builtins { return forge.Register(f.Voc(), name, fct) } return &builtins{ - Add: r("+", func(f FE, _ XT) { f.Push(f.Pop().(int) + f.Pop().(int)) }), - Lit: r("literal", func(f FE, _ XT) { f.Literal() }), + Add: r("+", func(f FE, _ XT) { f.Push(f.Pop().(int) + f.Pop().(int)) }), + Dup: r("dup", func(f FE, _ XT) { f.Push(f.Peek(0)) }), + Lit: r("literal", func(f FE, _ XT) { f.Literal() }), + Mult: r("*", func(f FE, _ XT) { f.Push(f.Pop().(int) * f.Pop().(int)) }), } } diff --git a/forge/forge.go b/forge/forge.go index 9be7085..435ee68 100644 --- a/forge/forge.go +++ b/forge/forge.go @@ -92,10 +92,6 @@ func (it *xitem) Name() string { // forgeEnv methods -func (f *forgeEnv) Voc() *fvoc { - return f.voc -} - func (f *forgeEnv) Code(items ...fitem) fptr { code := newPtr(items...) // ... pre-process (compile) code ... @@ -112,6 +108,24 @@ func (f *forgeEnv) Call(code fptr) { f.ip = f.rs.Pop().(fptr) } +func (f *forgeEnv) Exec(items ...fitem) { + f.Call(f.Code(items...)) +} + +func (f *forgeEnv) Def(name string, items ...fitem) XT { + xt := Register(f.voc, name, callDef) + xt.Body().Append(f.Code(items...)) + return xt +} + +func (f *forgeEnv) Literal() { + f.Push(f.ip.Next().Value()) +} + +func (f *forgeEnv) Voc() *fvoc { + return f.voc +} + func (f *forgeEnv) Push(it fitem) { f.ds.Push(it) } @@ -120,6 +134,12 @@ func (f *forgeEnv) Pop() fitem { return f.ds.Pop() } -func (f *forgeEnv) Literal() { - f.Push(f.ip.Next().Value()) +func (f *forgeEnv) Peek(d int) fitem { + return f.ds.Peek(d) +} + +// basic functions for executable items + +func callDef(f *forgeEnv, xt XT) { + f.Call(xt.Body().Value().(fptr)) } diff --git a/tests/forge_test.go b/tests/forge_test.go index 4522758..c70d854 100644 --- a/tests/forge_test.go +++ b/tests/forge_test.go @@ -16,6 +16,10 @@ func TestForge(tb *tbase.T) { func ExecTest(t *testing.T) { fe := forge.NewFE() b := builtins.Get(fe) - fe.Call(fe.Code(b.Lit, 4, b.Lit, 2, b.Add)) + c1 := fe.Code(b.Lit, 4, b.Lit, 2, b.Add) + fe.Call(c1) t.AssertEqual(fe.Pop(), 6) + sq := fe.Def("square", b.Dup, b.Mult) + fe.Exec(b.Lit, 3, sq, b.Lit, 2, b.Add) + t.AssertEqual(fe.Pop(), 11) }