|
|
|
@ -663,3 +663,56 @@ func (b *Builtins) Depth(s *Stack) func(string) error { |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Variable adds a new word to the dictionary that returns a pointer to memory
|
|
|
|
|
func (b *Builtins) Variable(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 ' ': |
|
|
|
|
next := c.Memory.NextFreeAddress() |
|
|
|
|
if next == 0 { |
|
|
|
|
// don't use the 0 cell, since we can't distinguish that from the uninitialized field
|
|
|
|
|
next = 1 |
|
|
|
|
} |
|
|
|
|
c.Dictionary.AddWord(string(w), Word{Name: string(w), Variable: next}) |
|
|
|
|
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 { |
|
|
|
|
addr, err := c.Stack.Pop() |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
val, err := c.Stack.Pop() |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
return c.Memory.Write(addr, []int{val}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Fetch returns a value from memory and puts it on the stack
|
|
|
|
|
func (b *Builtins) Fetch(c *Context) func(string) error { |
|
|
|
|
return func(_ string) error { |
|
|
|
|
addr, err := c.Stack.Pop() |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
res := c.Memory.Read(addr, 1) |
|
|
|
|
c.Stack.Push(res[0]) |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|