go-scopes/forge/builtins/builtins.go

65 lines
1.6 KiB
Go

package builtins
import "git.sr.ht/~cco/go-scopes/forge"
type FE = forge.FE
type XT = forge.XT
type FPtr = forge.FPtr
type builtins struct {
Add, Body, Create, Dup, Get, Lit, Mult, Put, Reg, Var XT
}
func Get(f FE) *builtins {
if v, ok := f.Voc().Lookup("builtins"); ok {
return v.(*builtins)
}
b := setup(f)
f.Voc().Register("builtins", b)
return b
}
func setup(f FE) *builtins {
voc := f.Voc()
r := func(name string, fct forge.Callable) XT {
return forge.Register(voc, forge.GoFunc(name, fct))
}
b := builtins{
Add: r("+", func(f FE, _ XT) {
f.Push(f.Pop().(int) + f.Pop().(int))
}),
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)) }),
Get: r("@", func(f FE, _ XT) { f.Push(f.Pop().(FPtr).Value()) }),
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))
}),
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,
forge.FCode(f.Pop().(string), f.Code(f.NewVar()))))
}),
}
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))))
})))
}