diff --git a/forge/builtins/builtins.go b/forge/builtins/builtins.go index dde6d6a..1c6bad4 100644 --- a/forge/builtins/builtins.go +++ b/forge/builtins/builtins.go @@ -4,9 +4,10 @@ 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, Dup, Get, Lit, Mult, Put, Reg XT + Add, Body, Create, Dup, Get, Lit, Mult, Put, Reg, Var XT } func Get(f FE) *builtins { @@ -24,19 +25,41 @@ func setup(f FE) *builtins { 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().(forge.XT).Code().New().Next()) + 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)) }), - Get: r("@", func(f FE, _ XT) { f.Push(f.Pop().(forge.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().(forge.FPtr).Set(f.Pop()) }), - Reg: r("reg", func(f FE, _ XT) { + 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.Pop().(forge.FPtr)))) + 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)))) + }))) +} diff --git a/tests/forge_test.go b/tests/forge_test.go index 43f5c5f..fc72a52 100644 --- a/tests/forge_test.go +++ b/tests/forge_test.go @@ -31,7 +31,10 @@ func CoreTest(t *testing.T) { seven := fe.Exec(fe.Code(7), "seven", b.Reg).Pop() fe.Exec(3, seven, sq, b.Add) 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(seven, myvar, b.Get, b.Mult) t.AssertEqual(fe.Pop(), 35)