forge: create: allocate variable with optional 'does' code
This commit is contained in:
parent
fa2aa23e87
commit
b88ef658ee
2 changed files with 38 additions and 12 deletions
|
@ -4,9 +4,10 @@ import "git.sr.ht/~cco/go-scopes/forge"
|
||||||
|
|
||||||
type FE = forge.FE
|
type FE = forge.FE
|
||||||
type XT = forge.XT
|
type XT = forge.XT
|
||||||
|
type FPtr = forge.FPtr
|
||||||
|
|
||||||
type builtins struct {
|
type builtins struct {
|
||||||
Add, Body, Dup, Get, Lit, Mult, Put, Reg XT
|
Add, Body, Create, Dup, Get, Lit, Mult, Put, Reg, Var XT
|
||||||
}
|
}
|
||||||
|
|
||||||
func Get(f FE) *builtins {
|
func Get(f FE) *builtins {
|
||||||
|
@ -24,19 +25,41 @@ func setup(f FE) *builtins {
|
||||||
return forge.Register(voc, forge.GoFunc(name, fct))
|
return forge.Register(voc, forge.GoFunc(name, fct))
|
||||||
}
|
}
|
||||||
b := builtins{
|
b := builtins{
|
||||||
Add: r("+", func(f FE, _ XT) { f.Push(f.Pop().(int) + f.Pop().(int)) }),
|
Add: r("+", func(f FE, _ XT) {
|
||||||
Body: r("body", func(f FE, _ XT) {
|
f.Push(f.Pop().(int) + f.Pop().(int))
|
||||||
f.Push(f.Pop().(forge.XT).Code().New().Next())
|
|
||||||
}),
|
}),
|
||||||
|
Body: r("body", func(f FE, _ XT) {
|
||||||
|
f.Push(f.Pop().(XT).Code().New().Next())
|
||||||
|
}),
|
||||||
|
Create: r("create", create),
|
||||||
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().(FPtr).Value()) }),
|
||||||
Lit: r("lit", func(f FE, _ XT) { f.Push(f.Literal()) }),
|
Lit: r("lit", func(f FE, _ XT) { f.Push(f.Literal()) }),
|
||||||
Mult: r("*", func(f FE, _ XT) { f.Push(f.Pop().(int) * f.Pop().(int)) }),
|
Mult: r("*", func(f FE, _ XT) {
|
||||||
Put: r("!", func(f FE, _ XT) { f.Pop().(forge.FPtr).Set(f.Pop()) }),
|
f.Push(f.Pop().(int) * f.Pop().(int))
|
||||||
Reg: r("reg", func(f FE, _ XT) {
|
}),
|
||||||
|
Put: r("!", func(f FE, _ XT) { f.Pop().(FPtr).Set(f.Pop()) }),
|
||||||
|
Reg: r("reg", reg),
|
||||||
|
Var: r("var", func(f FE, _ XT) {
|
||||||
f.Push(forge.Register(voc,
|
f.Push(forge.Register(voc,
|
||||||
forge.FCode(f.Pop().(string), f.Pop().(forge.FPtr))))
|
forge.FCode(f.Pop().(string), f.Code(f.NewVar()))))
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
return &b
|
return &b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func reg(f FE, _ XT) {
|
||||||
|
f.Push(forge.Register(f.Voc(),
|
||||||
|
forge.FCode(f.Pop().(string), f.Pop().(FPtr))))
|
||||||
|
}
|
||||||
|
|
||||||
|
func create(f FE, xt XT) {
|
||||||
|
name := f.Pop().(string)
|
||||||
|
does := forge.FCode("", f.Pop().(FPtr))
|
||||||
|
f.Push(forge.Register(f.Voc(),
|
||||||
|
forge.GoFunc(name, func(f FE, xt XT) {
|
||||||
|
f.Push(forge.Register(f.Voc(),
|
||||||
|
forge.FCode(f.Pop().(string),
|
||||||
|
f.Code(f.NewVar(), does))))
|
||||||
|
})))
|
||||||
|
}
|
||||||
|
|
|
@ -31,7 +31,10 @@ func CoreTest(t *testing.T) {
|
||||||
seven := fe.Exec(fe.Code(7), "seven", b.Reg).Pop()
|
seven := fe.Exec(fe.Code(7), "seven", b.Reg).Pop()
|
||||||
fe.Exec(3, seven, sq, b.Add)
|
fe.Exec(3, seven, sq, b.Add)
|
||||||
t.AssertEqual(fe.Pop(), 52)
|
t.AssertEqual(fe.Pop(), 52)
|
||||||
myvar := fe.Exec(fe.Code(fe.NewVar()), "myvar", b.Reg).Pop()
|
//myvar := fe.Exec(fe.Code(fe.NewVar()), "myvar", b.Reg).Pop()
|
||||||
|
dvar := fe.Exec(fe.Code(), "var", b.Create).Pop()
|
||||||
|
myvar := fe.Exec("myvar", dvar).Pop()
|
||||||
|
//myvar := fe.Exec("myvar", b.Var).Pop()
|
||||||
fe.Exec(5, myvar, b.Put)
|
fe.Exec(5, myvar, b.Put)
|
||||||
fe.Exec(seven, myvar, b.Get, b.Mult)
|
fe.Exec(seven, myvar, b.Get, b.Mult)
|
||||||
t.AssertEqual(fe.Pop(), 35)
|
t.AssertEqual(fe.Pop(), 35)
|
||||||
|
|
Loading…
Add table
Reference in a new issue