define and call forge code

This commit is contained in:
Helmut Merz 2023-07-23 12:35:18 +02:00
parent c724ad89bd
commit 8d8e13d8ed
3 changed files with 36 additions and 10 deletions

View file

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

View file

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

View file

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