mimic Def and Const using core definitions

This commit is contained in:
Helmut Merz 2023-07-29 14:15:03 +02:00
parent 08b9391559
commit 1f27700334
3 changed files with 53 additions and 15 deletions

View file

@ -6,7 +6,7 @@ type FE = forge.FE
type XT = forge.XT type XT = forge.XT
type builtins struct { type builtins struct {
Add, Dup, Get, Lit, Mult, Put XT Add, Comp, Dup, Get, Here, Lit, Mult, New, Put, Reg XT
} }
func Get(f FE) *builtins { func Get(f FE) *builtins {
@ -24,12 +24,20 @@ func setup(f FE) *builtins {
r := func(name string, fct forge.Callable) XT { r := func(name string, fct forge.Callable) XT {
return forge.Register(voc, forge.GoFunc(name, fct)) return forge.Register(voc, forge.GoFunc(name, fct))
} }
return &builtins{ b := builtins{
Add: r("+", func(f FE, _ XT) { f.Push(f.Pop().(int) + f.Pop().(int)) }), Add: r("+", func(f FE, _ XT) { f.Push(f.Pop().(int) + f.Pop().(int)) }),
Comp: r("comp", func(f FE, _ XT) { f.Compile(f.Pop()) }),
Dup: r("dup", func(f FE, _ XT) { f.Push(f.Peek(0)) }), Dup: r("dup", func(f FE, _ XT) { f.Push(f.Peek(0)) }),
Get: r("@", func(f FE, _ XT) { f.Push(f.Pop().(forge.FPtr).Value()) }), Get: r("@", func(f FE, _ XT) { f.Push(f.Pop().(forge.FPtr).Value()) }),
Here: r("here", func(f FE, _ XT) { f.Push(f.Here()) }),
Lit: r("literal", func(f FE, _ XT) { f.Literal() }), Lit: r("literal", func(f FE, _ XT) { f.Literal() }),
Mult: r("*", func(f FE, _ XT) { f.Push(f.Pop().(int) * f.Pop().(int)) }), Mult: r("*", func(f FE, _ XT) { f.Push(f.Pop().(int) * f.Pop().(int)) }),
New: r("new", func(f FE, _ XT) { f.New() }),
Put: r("!", func(f FE, _ XT) { f.Pop().(forge.FPtr).Set(f.Pop()) }), Put: r("!", func(f FE, _ XT) { f.Pop().(forge.FPtr).Set(f.Pop()) }),
Reg: r("reg", func(f FE, _ XT) {
f.Push(forge.Register(voc,
forge.FCode(f.Pop().(string), f.Pop().(forge.FPtr))))
}),
} }
return &b
} }

View file

@ -62,6 +62,11 @@ func (n name) Name() string {
return string(n) return string(n)
} }
func Register(voc *fvoc, it XT) XT {
voc.Register(it.Name(), it)
return it
}
// gofunc: XT consisting only of a function written in Go // gofunc: XT consisting only of a function written in Go
type gofunc struct { type gofunc struct {
@ -97,7 +102,7 @@ func FCode(n string, c fptr) XT {
} }
func (it *fcode) Fct() Callable { func (it *fcode) Fct() Callable {
return doDef return doFCode
} }
func (it *fcode) Code() fptr { func (it *fcode) Code() fptr {
@ -132,12 +137,6 @@ func (it *data) Data() fptr {
return it.data return it.data
} }
// func Register(voc *fvoc, n string, fct Callable) *xitem {
func Register(voc *fvoc, it XT) XT {
voc.Register(it.Name(), it)
return it
}
// forgeEnv methods // forgeEnv methods
func (f *forgeEnv) Code(items ...fitem) fptr { func (f *forgeEnv) Code(items ...fitem) fptr {
@ -160,6 +159,12 @@ func (f *forgeEnv) Exec(items ...fitem) {
f.Call(f.Code(items...)) f.Call(f.Code(items...))
} }
func (f *forgeEnv) Literal() {
f.Push(f.ip.Next().Value())
}
// definition methods, may become obsolete
func (f *forgeEnv) Def(name string, items ...fitem) XT { func (f *forgeEnv) Def(name string, items ...fitem) XT {
code := f.Code(items...) code := f.Code(items...)
return Register(f.voc, FCode(name, code)) return Register(f.voc, FCode(name, code))
@ -167,11 +172,22 @@ func (f *forgeEnv) Def(name string, items ...fitem) XT {
func (f *forgeEnv) Create(name string, value fitem, code fptr) XT { func (f *forgeEnv) Create(name string, value fitem, code fptr) XT {
data := newScalar().Set(value) data := newScalar().Set(value)
//return Register(f.voc, FCode(name, f.Code(b.Lit, data, code))
return Register(f.voc, Data(name, data, code)) return Register(f.voc, Data(name, data, code))
} }
func (f *forgeEnv) Literal() { // core methods
f.Push(f.ip.Next().Value())
func (f *forgeEnv) New() {
f.cp = newPtr()
}
func (f *forgeEnv) Compile(it fitem) {
f.cp.Append(it)
}
func (f *forgeEnv) Here() fptr {
return f.cp.Clone()
} }
func (f *forgeEnv) Voc() *fvoc { func (f *forgeEnv) Voc() *fvoc {
@ -192,8 +208,8 @@ func (f *forgeEnv) Peek(d int) fitem {
// basic functions for executable items // basic functions for executable items
func doDef(f *forgeEnv, xt XT) { func doFCode(f *forgeEnv, xt XT) {
f.Call(xt.Code().(fptr)) f.Call(xt.Code())
} }
func doData(f *forgeEnv, xt XT) { func doData(f *forgeEnv, xt XT) {

View file

@ -8,14 +8,16 @@ import (
"git.sr.ht/~cco/go-scopes/forge/builtins" "git.sr.ht/~cco/go-scopes/forge/builtins"
) )
var fe = forge.NewFE()
var b = builtins.Get(fe)
func TestForge(tb *tbase.T) { func TestForge(tb *tbase.T) {
t := testing.SetUp(tb) t := testing.SetUp(tb)
t.Run("exec", ExecTest) t.Run("exec", ExecTest)
t.Run("core", CoreTest)
} }
func ExecTest(t *testing.T) { func ExecTest(t *testing.T) {
fe := forge.NewFE()
b := builtins.Get(fe)
c1 := fe.Code(b.Lit, 4, b.Lit, 2, b.Add) c1 := fe.Code(b.Lit, 4, b.Lit, 2, b.Add)
fe.Call(c1) fe.Call(c1)
t.AssertEqual(fe.Pop(), 6) t.AssertEqual(fe.Pop(), 6)
@ -27,3 +29,15 @@ func ExecTest(t *testing.T) {
fe.Exec(b.Lit, 3, seven, sq, b.Add) fe.Exec(b.Lit, 3, seven, sq, b.Add)
t.AssertEqual(fe.Pop(), 52) t.AssertEqual(fe.Pop(), 52)
} }
func CoreTest(t *testing.T) {
//sq := fe.Def("square", b.Dup, b.Mult)
fe.Exec(b.New, b.Here)
fe.Exec(b.Lit, b.Dup, b.Comp, b.Lit, b.Mult, b.Comp, b.Lit, "square", b.Reg)
sq := fe.Pop()
fe.Exec(b.New, b.Here)
fe.Exec(b.Lit, b.Lit, b.Comp, b.Lit, 7, b.Comp, b.Lit, "x", b.Reg)
seven := fe.Pop()
fe.Exec(b.Lit, 3, seven, sq, b.Add)
t.AssertEqual(fe.Pop(), 52)
}