From e428c883db7be0aa19caeecb8eb011a7864f5196 Mon Sep 17 00:00:00 2001 From: David Ashby Date: Thu, 25 Feb 2021 21:04:35 -0500 Subject: [PATCH] CONSTANT --- README.md | 7 +++++-- builtins.go | 30 ++++++++++++++++++++++++++++++ main.go | 3 ++- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ca30dbe..72d3e5a 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ ok 55 ok ``` -Propser also has a basic off-stack memory model using variables and pointers: +Propser also has a basic off-stack memory model using variables, constants, and pointers: ``` > VARIABLE FOO ok @@ -64,6 +64,10 @@ ok ok > . 10 ok +> 100 CONSTANT HUNDRED +ok +> HUNDRED HUNDRED * . +10000 ok ``` And, of course, it knows how to quit: @@ -75,6 +79,5 @@ bye ## Future Plans -* Implement `CONSTANT` * Implement loading libraries of pre-written functions both from the command-line and at run-time * Add much better readline behaviors in the interactive console (up-arrow for history, cursor movement...) diff --git a/builtins.go b/builtins.go index cde8e66..d310aa1 100644 --- a/builtins.go +++ b/builtins.go @@ -689,6 +689,36 @@ func (b *Builtins) Variable(c *Context) func(string) error { } } +// Constant adds a new word to the dictionary that puts a value on the stack +func (b *Builtins) Constant(c *Context) func(string) error { + return func(next string) error { + w := []byte{} + for i := 1; i < len(next); i = i + 1 { + switch next[i] { + case ' ': + v, err := c.Stack.Pop() + if err != nil { + return err + } + c.Dictionary.AddWord(string(w), Word{ + Name: string(w), + Impl: func(_ string) error { + c.Stack.Push(v) + return nil + }, + }) + j, _ := c.RStack.Pop() + c.RStack.Push(j + i - 1) // push the end-point onto the stack + return nil + default: + w = append(w, next[i]) + continue + } + } + return nil + } +} + // Store places a value in memory func (b *Builtins) Store(c *Context) func(string) error { return func(_ string) error { diff --git a/main.go b/main.go index 2f375e6..2ff5808 100644 --- a/main.go +++ b/main.go @@ -82,8 +82,9 @@ func main() { dict.AddWord("2DROP", Word{Name: "2DROP", Source: []string{"DROP", "DROP"}}) dict.AddWord("2DUP", Word{Name: "2DUP", Source: []string{"OVER", "OVER"}}) dict.AddWord("2OVER", Word{Name: "2OVER", Source: []string{"3", "PICK", "3", "PICK"}}) - // memory access with variables + // memory access with variables and constants dict.AddWord("VARIABLE", Word{Name: "VARIABLE", Impl: b.Variable(&c)}) + dict.AddWord("CONSTANT", Word{Name: "CONSTANT", Impl: b.Constant(&c)}) dict.AddWord("!", Word{Name: "!", Impl: b.Store(&c)}) dict.AddWord("@", Word{Name: "@", Impl: b.Fetch(&c)}) // debugging