diff --git a/forge/forge.go b/forge/forge.go index 06fd00f..5492d68 100644 --- a/forge/forge.go +++ b/forge/forge.go @@ -8,6 +8,7 @@ import ( ) type fitem interface{} +type FItem = fitem type fptr = ptr.Ptr[fitem] type FPtr = fptr diff --git a/forge/rep/rep.go b/forge/rep/rep.go new file mode 100644 index 0000000..4773ba5 --- /dev/null +++ b/forge/rep/rep.go @@ -0,0 +1,45 @@ +package rep + +import ( + "git.sr.ht/~cco/go-scopes/common/funky" + "git.sr.ht/~cco/go-scopes/forge" +) + +// maybe: code, defs, string, int, float +type citem interface{} + +// code, represented by a slice + +type code []citem + +func Code(items ...citem) code { + return code(items) +} + +func (ci code) Compile(f forge.FE) forge.FPtr { + c := f.Code() + for _, item := range ci { + switch i := item.(type) { + case int: + c.Append(i) + case string: + m := compStr(f, i) + if !m.IsNothing() { + c.Append(m.Value()) + } + } + } + return c.Reset() +} + +func compStr(f forge.FE, s string) funky.Maybe[forge.FItem] { + mxt := f.Voc().Lookup(s) + if mxt.IsNothing() { + return funky.Nothing[forge.FItem]() + } + return funky.Just(forge.FItem(mxt.Value())) +} + +// defs - definitions, represented by a map + +type defs map[string]citem diff --git a/tests/forge_test.go b/tests/forge_test.go index 5d5b008..50929cd 100644 --- a/tests/forge_test.go +++ b/tests/forge_test.go @@ -6,6 +6,7 @@ import ( "git.sr.ht/~cco/go-scopes/common/testing" "git.sr.ht/~cco/go-scopes/forge" "git.sr.ht/~cco/go-scopes/forge/builtins" + "git.sr.ht/~cco/go-scopes/forge/rep" ) var fe = forge.NewFE() @@ -15,6 +16,7 @@ func TestForge(tb *tbase.T) { t := testing.SetUp(tb) t.Run("exec", ExecTest) t.Run("core", CoreTest) + t.Run("rep", RepTest) } func ExecTest(t *testing.T) { @@ -35,3 +37,10 @@ func CoreTest(t *testing.T) { fe.Exec(9, b.Lit, seven, b.Body, b.Put) t.AssertEqual(fe.Exec(seven).Pop(), 9) } + +func RepTest(t *testing.T) { + src := rep.Code(4, 2, "+") + c := src.Compile(fe) + fe.Call(c) + t.AssertEqual(fe.Pop(), 6) +}