From 75b82db25064fdd6ac0ffadedf437238712f82f0 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Tue, 12 Sep 2023 11:59:51 +0200 Subject: [PATCH] forge, work in progress: factorial, using if, leave, repeat --- forge/builtins/builtins.go | 38 ++++++++++++++++++++++++-------------- tests/forge_test.go | 9 +++++++++ 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/forge/builtins/builtins.go b/forge/builtins/builtins.go index 308fb51..81e0242 100644 --- a/forge/builtins/builtins.go +++ b/forge/builtins/builtins.go @@ -9,8 +9,8 @@ type XT = forge.XT type FPtr = forge.FPtr type builtins struct { - Add, Body, Code, Comp, Drop, Dup, Get, If, IfElse, Leave, Lit, Mult, - New1, Put, Reg, Repeat, Swap, + Add, Body, Code, Comp, Drop, Dup, Get, If, IfElse, Leave, LT, Lit, + Mult, New1, Over, Put, Reg, Repeat, Sub, Swap, Var1 XT } @@ -29,30 +29,33 @@ func setup(f FE) *builtins { return forge.Register(voc, forge.GoFunc(name, fct)) } b := builtins{ - Add: r("+", func(f FE, _ XT) { f.Push(f.PopI() + f.PopI()) }), - /*Append: r("append", func(f FE, _ XT) { - item := f.Pop() - f.Peek(0).(FPtr).Append(item) - }),*/ + Add: r("+", func(f FE, _ XT) { f.Push(f.PopI() + f.PopI()) }), 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()) }), 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()) }), + If: r("if", func(f FE, _ XT) { doif(f) }), + IfElse: r("if-else", func(f FE, _ XT) { doifelse(f) }), Leave: r("leave", func(f FE, _ XT) { f.RPop() }), Lit: r("lit", func(f FE, _ XT) { f.Push(f.Literal()) }), + LT: r("<", func(f FE, _ XT) { f.Push(f.PopI() > f.PopI()) }), Mult: r("*", func(f FE, _ XT) { f.Push(f.PopI() * f.PopI()) }), New1: r("new1", func(f FE, _ XT) { f.Push(f.NewVar()) }), + Over: r("over", func(f FE, _ XT) { f.Push(f.Peek(1)) }), Put: r("!", func(f FE, _ XT) { f.Pop().(FPtr).Set(f.Pop()) }), - Reg: r("reg", func(f FE, _ XT) { reg(f) }), + Reg: r("reg", func(f FE, _ XT) { doreg(f) }), Repeat: r("repeat", func(f FE, _ XT) { f.Reset() }), - Swap: r("swap", func(f FE, _ XT) { - a := f.Pop() - b := f.Pop() - f.Push(a) - f.Push(b) + Sub: r("-", func(f FE, _ XT) { + a := f.PopI() + f.Push(f.PopI() - a) }), + Swap: r("swap", func(f FE, _ XT) { doswap(f) }), + /*Append: r("append", func(f FE, _ XT) { + item := f.Pop() + f.Peek(0).(FPtr).Append(item) + }),*/ } rf := func(name string, code ...forge.FItem) XT { return forge.Register(voc, forge.FCode(name, f.Code(code...))) @@ -78,7 +81,14 @@ func doifelse(f FE) { } } -func reg(f FE) { +func doswap(f FE) { + a := f.Pop() + b := f.Pop() + f.Push(a) + f.Push(b) +} + +func doreg(f FE) { f.Register(forge.FCode(f.Pop().(string), f.Pop().(FPtr))) } diff --git a/tests/forge_test.go b/tests/forge_test.go index 65f6c91..fe316a9 100644 --- a/tests/forge_test.go +++ b/tests/forge_test.go @@ -21,6 +21,7 @@ func TestForge(tb *tbase.T) { t := testing.SetUp(tb) t.Run("exec", ExecTest) t.Run("core", CoreTest) + t.Run("control", ControlTest) t.Run("rep", RepTest) t.Run("json", JsonTest) } @@ -45,6 +46,14 @@ func CoreTest(t *testing.T) { } func ControlTest(t *testing.T) { + fac := fe.Exec(fe.Code( + b.Dup, 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)), + "fac", b.Reg).LatestXT() + fe.Exec(2, fac) + //t.AssertEqual(fe.Pop(), 12) } func RepTest(t *testing.T) {