diff --git a/forge/builtins/builtins.go b/forge/builtins/builtins.go index 81e0242..d462015 100644 --- a/forge/builtins/builtins.go +++ b/forge/builtins/builtins.go @@ -1,6 +1,8 @@ package builtins import ( + "fmt" + "git.sr.ht/~cco/go-scopes/forge" ) @@ -9,7 +11,7 @@ type XT = forge.XT type FPtr = forge.FPtr type builtins struct { - Add, Body, Code, Comp, Drop, Dup, Get, If, IfElse, Leave, LT, Lit, + Add, Body, Code, Comp, Do, Dot, Drop, Dup, Get, If, IfElse, Leave, LT, Lit, Mult, New1, Over, Put, Reg, Repeat, Sub, Swap, Var1 XT } @@ -33,6 +35,8 @@ func setup(f FE) *builtins { Body: r("body", func(f FE, _ XT) { f.Push(f.Pop().(XT).Code().New().Next()) }), Code: r("code", func(f FE, _ XT) { f.Push(f.Code()) }), Comp: r("comp", func(f FE, _ XT) { f.LatestXT().Code().Append(f.Pop()) }), + Do: r("do", func(f FE, _ XT) { f.Call(f.Literal().(FPtr)) }), + Dot: r(".", func(f FE, _ XT) { fmt.Println(f.Peek(0)) }), Drop: r("drop", func(f FE, _ XT) { f.Pop() }), Dup: r("dup", func(f FE, _ XT) { f.Push(f.Peek(0)) }), Get: r("@", func(f FE, _ XT) { f.Push(f.Pop().(FPtr).Value()) }), diff --git a/forge/forge.go b/forge/forge.go index 5900f43..fc2283e 100644 --- a/forge/forge.go +++ b/forge/forge.go @@ -105,7 +105,10 @@ func (f *forgeEnv) Peek(d int) fitem { } func (f *forgeEnv) RPop() fptr { - return f.rs.Pop().(fptr) + if f.rs.Depth() > 0 { + return f.rs.Pop().(fptr) + } + return f.Code() } func (f *forgeEnv) Reset() fptr { diff --git a/tests/forge_test.go b/tests/forge_test.go index fe316a9..848ad2a 100644 --- a/tests/forge_test.go +++ b/tests/forge_test.go @@ -47,13 +47,15 @@ func CoreTest(t *testing.T) { func ControlTest(t *testing.T) { fac := fe.Exec(fe.Code( - b.Dup, fe.Code( + b.Dup, b.Do, fe.Code( b.Dup, 3, b.LT, b.If, fe.Code( b.Drop, b.Leave), - b.Swap, b.Over, b.Mult, b.Swap, 1, b.Sub, b.Repeat)), + 1, b.Sub, b.Swap, b.Over, b.Mult, b.Swap, b.Repeat)), "fac", b.Reg).LatestXT() - fe.Exec(2, fac) - //t.AssertEqual(fe.Pop(), 12) + t.AssertEqual(fe.Exec(1, fac).Pop(), 1) + t.AssertEqual(fe.Exec(2, fac).Pop(), 2) + t.AssertEqual(fe.Exec(3, fac).Pop(), 6) + t.AssertEqual(fe.Exec(4, fac).Pop(), 24) } func RepTest(t *testing.T) {