define and call forge code
This commit is contained in:
parent
c724ad89bd
commit
8d8e13d8ed
3 changed files with 36 additions and 10 deletions
|
@ -6,7 +6,7 @@ type FE = forge.FE
|
||||||
type XT = forge.XT
|
type XT = forge.XT
|
||||||
|
|
||||||
type builtins struct {
|
type builtins struct {
|
||||||
Add, Lit XT
|
Add, Dup, Lit, Mult XT
|
||||||
}
|
}
|
||||||
|
|
||||||
func Get(f FE) *builtins {
|
func Get(f FE) *builtins {
|
||||||
|
@ -25,6 +25,8 @@ func setup(f FE) *builtins {
|
||||||
}
|
}
|
||||||
return &builtins{
|
return &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)) }),
|
||||||
|
Dup: r("dup", func(f FE, _ XT) { f.Push(f.Peek(0)) }),
|
||||||
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)) }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,10 +92,6 @@ func (it *xitem) Name() string {
|
||||||
|
|
||||||
// forgeEnv methods
|
// forgeEnv methods
|
||||||
|
|
||||||
func (f *forgeEnv) Voc() *fvoc {
|
|
||||||
return f.voc
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *forgeEnv) Code(items ...fitem) fptr {
|
func (f *forgeEnv) Code(items ...fitem) fptr {
|
||||||
code := newPtr(items...)
|
code := newPtr(items...)
|
||||||
// ... pre-process (compile) code ...
|
// ... pre-process (compile) code ...
|
||||||
|
@ -112,6 +108,24 @@ func (f *forgeEnv) Call(code fptr) {
|
||||||
f.ip = f.rs.Pop().(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) {
|
func (f *forgeEnv) Push(it fitem) {
|
||||||
f.ds.Push(it)
|
f.ds.Push(it)
|
||||||
}
|
}
|
||||||
|
@ -120,6 +134,12 @@ func (f *forgeEnv) Pop() fitem {
|
||||||
return f.ds.Pop()
|
return f.ds.Pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *forgeEnv) Literal() {
|
func (f *forgeEnv) Peek(d int) fitem {
|
||||||
f.Push(f.ip.Next().Value())
|
return f.ds.Peek(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
// basic functions for executable items
|
||||||
|
|
||||||
|
func callDef(f *forgeEnv, xt XT) {
|
||||||
|
f.Call(xt.Body().Value().(fptr))
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,10 @@ func TestForge(tb *tbase.T) {
|
||||||
func ExecTest(t *testing.T) {
|
func ExecTest(t *testing.T) {
|
||||||
fe := forge.NewFE()
|
fe := forge.NewFE()
|
||||||
b := builtins.Get(fe)
|
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)
|
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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue