This commit is contained in:
David 2021-02-25 21:04:35 -05:00
parent 762b6c870c
commit e428c883db
3 changed files with 37 additions and 3 deletions

View File

@ -54,7 +54,7 @@ ok
55 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 > VARIABLE FOO
ok ok
@ -64,6 +64,10 @@ ok
ok ok
> . > .
10 ok 10 ok
> 100 CONSTANT HUNDRED
ok
> HUNDRED HUNDRED * .
10000 ok
``` ```
And, of course, it knows how to quit: And, of course, it knows how to quit:
@ -75,6 +79,5 @@ bye
## Future Plans ## Future Plans
* Implement `CONSTANT`
* Implement loading libraries of pre-written functions both from the command-line and at run-time * 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...) * Add much better readline behaviors in the interactive console (up-arrow for history, cursor movement...)

View File

@ -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 // Store places a value in memory
func (b *Builtins) Store(c *Context) func(string) error { func (b *Builtins) Store(c *Context) func(string) error {
return func(_ string) error { return func(_ string) error {

View File

@ -82,8 +82,9 @@ func main() {
dict.AddWord("2DROP", Word{Name: "2DROP", Source: []string{"DROP", "DROP"}}) dict.AddWord("2DROP", Word{Name: "2DROP", Source: []string{"DROP", "DROP"}})
dict.AddWord("2DUP", Word{Name: "2DUP", Source: []string{"OVER", "OVER"}}) dict.AddWord("2DUP", Word{Name: "2DUP", Source: []string{"OVER", "OVER"}})
dict.AddWord("2OVER", Word{Name: "2OVER", Source: []string{"3", "PICK", "3", "PICK"}}) 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("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.Store(&c)})
dict.AddWord("@", Word{Name: "@", Impl: b.Fetch(&c)}) dict.AddWord("@", Word{Name: "@", Impl: b.Fetch(&c)})
// debugging // debugging