diff --git a/forge/builtins/builtins.go b/forge/builtins/builtins.go index 3a29e46..308fb51 100644 --- a/forge/builtins/builtins.go +++ b/forge/builtins/builtins.go @@ -9,8 +9,9 @@ type XT = forge.XT type FPtr = forge.FPtr type builtins struct { - Add, Body, Code, Comp, Dup, Get, Lit, Mult, New1, Put, Reg, Swap XT - Var1 XT + Add, Body, Code, Comp, Drop, Dup, Get, If, IfElse, Leave, Lit, Mult, + New1, Put, Reg, Repeat, Swap, + Var1 XT } func Get(f FE) *builtins { @@ -33,16 +34,19 @@ func setup(f FE) *builtins { item := f.Pop() f.Peek(0).(FPtr).Append(item) }),*/ - 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()) }), - 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.PopI() * f.PopI()) }), - New1: r("new1", func(f FE, _ XT) { f.Push(f.NewVar()) }), - Put: r("!", func(f FE, _ XT) { f.Pop().(FPtr).Set(f.Pop()) }), - Reg: r("reg", func(f FE, _ XT) { reg(f) }), + 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()) }), + Leave: r("leave", func(f FE, _ XT) { f.RPop() }), + Lit: r("lit", func(f FE, _ XT) { f.Push(f.Literal()) }), + Mult: r("*", func(f FE, _ XT) { f.Push(f.PopI() * f.PopI()) }), + New1: r("new1", func(f FE, _ XT) { f.Push(f.NewVar()) }), + Put: r("!", func(f FE, _ XT) { f.Pop().(FPtr).Set(f.Pop()) }), + Reg: r("reg", func(f FE, _ XT) { reg(f) }), + Repeat: r("repeat", func(f FE, _ XT) { f.Reset() }), Swap: r("swap", func(f FE, _ XT) { a := f.Pop() b := f.Pop() @@ -57,6 +61,23 @@ func setup(f FE) *builtins { return &b } +func doif(f FE) { + ifBranch := f.Literal().(FPtr) + if f.Pop().(bool) { + f.Call(ifBranch) + } +} + +func doifelse(f FE) { + ifBranch := f.Literal().(FPtr) + elseBranch := f.Literal().(FPtr) + if f.Pop().(bool) { + f.Call(ifBranch) + } else { + f.Call(elseBranch) + } +} + func reg(f FE) { f.Register(forge.FCode(f.Pop().(string), f.Pop().(FPtr))) } diff --git a/forge/forge.go b/forge/forge.go index be7a169..5900f43 100644 --- a/forge/forge.go +++ b/forge/forge.go @@ -68,7 +68,7 @@ func (f *forgeEnv) Call(code fptr) *forgeEnv { f.Push(value) } } - f.ip = f.rs.Pop().(fptr) + f.ip = f.RPop() return f } @@ -104,6 +104,14 @@ func (f *forgeEnv) Peek(d int) fitem { return f.ds.Peek(d) } +func (f *forgeEnv) RPop() fptr { + return f.rs.Pop().(fptr) +} + +func (f *forgeEnv) Reset() fptr { + return f.ip.Reset() +} + func (f *forgeEnv) LatestXT() XT { return f.latestxt }