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", func(f FE, _ XT) { reg(f) }), Var: r("var", func(f FE, _ XT) { f.Register(forge.FCode(f.Pop().(string), f.Code(f.NewVar()))) }), } // b.Var1 = forge.Register(voc, forge.FCode("var1", //f.Code(f.Code(b.New1), b.Swap, b.Reg))) return &b } func reg(f FE) { f.Register(forge.FCode(f.Pop().(string), f.Pop().(FPtr))) } func create(f FE, _ XT) { name := f.Pop().(string) does := forge.AnonCode(f.Pop().(FPtr)) f.Register(forge.GoFunc(name, func(f FE, _ XT) { f.Register(forge.FCode(f.Pop().(string), f.Code(f.NewVar(), does))) })) }