forge: execute simple forge code
This commit is contained in:
parent
96a1bdb39f
commit
c724ad89bd
3 changed files with 49 additions and 36 deletions
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue