Compare commits
No commits in common. "199203e73f222c8196e1b4d56fbe5fd3318e3cbb" and "bce7e3df4e35a9665af9bbc2ac49893b4f276ee4" have entirely different histories.
199203e73f
...
bce7e3df4e
225
builtins.go
225
builtins.go
@ -8,138 +8,18 @@ type Builtins struct{}
|
|||||||
// ErrExit is a special sentinel value to cease computation and quit
|
// ErrExit is a special sentinel value to cease computation and quit
|
||||||
var ErrExit = fmt.Errorf("exit requested")
|
var ErrExit = fmt.Errorf("exit requested")
|
||||||
|
|
||||||
// Eq compares TOS and NOS and puts -1 on the stack if they're equal, 0 otherwise.
|
|
||||||
func (b *Builtins) Eq(s *Stack) func() error {
|
|
||||||
return func() error {
|
|
||||||
tos, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
nos, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if tos == nos {
|
|
||||||
s.Push(-1)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
s.Push(0)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NEq compares TOS and NOS and puts -1 on the stack if they're not equal, 0 otherwise.
|
|
||||||
func (b *Builtins) NEq(s *Stack) func() error {
|
|
||||||
return func() error {
|
|
||||||
tos, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
nos, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if tos != nos {
|
|
||||||
s.Push(-1)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
s.Push(0)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lt compares TOS and NOS and puts -1 on the stack if TOS is less than NOS, 0 otherwise.
|
|
||||||
func (b *Builtins) Lt(s *Stack) func() error {
|
|
||||||
return func() error {
|
|
||||||
tos, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
nos, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if tos < nos {
|
|
||||||
s.Push(-1)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
s.Push(0)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gt compares TOS and NOS and puts -1 on the stack if TOS is greater than NOS, 0 otherwise.
|
|
||||||
func (b *Builtins) Gt(s *Stack) func() error {
|
|
||||||
return func() error {
|
|
||||||
tos, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
nos, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if tos > nos {
|
|
||||||
s.Push(-1)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
s.Push(0)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LtEq compares TOS and NOS and puts -1 on the stack if TOS is less than or equal to NOS, 0 otherwise.
|
|
||||||
func (b *Builtins) LtEq(s *Stack) func() error {
|
|
||||||
return func() error {
|
|
||||||
tos, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
nos, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if tos <= nos {
|
|
||||||
s.Push(-1)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
s.Push(0)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GtEq compares TOS and NOS and puts -1 on the stack if TOS is greater than or equal to NOS, 0 otherwise.
|
|
||||||
func (b *Builtins) GtEq(s *Stack) func() error {
|
|
||||||
return func() error {
|
|
||||||
tos, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
nos, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if tos >= nos {
|
|
||||||
s.Push(-1)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
s.Push(0)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add sums the top two numbers on the stack and pushes the result
|
// Add sums the top two numbers on the stack and pushes the result
|
||||||
func (b *Builtins) Add(s *Stack) func() error {
|
func (b *Builtins) Add(s *Stack) func() error {
|
||||||
return func() error {
|
return func() error {
|
||||||
tos, err := s.Pop()
|
r1, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
nos, err := s.Pop()
|
r2, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.Push(tos + nos)
|
s.Push(r1 + r2)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,15 +27,15 @@ func (b *Builtins) Add(s *Stack) func() error {
|
|||||||
// Sub performs NOS - TOS and pushes the result
|
// Sub performs NOS - TOS and pushes the result
|
||||||
func (b *Builtins) Sub(s *Stack) func() error {
|
func (b *Builtins) Sub(s *Stack) func() error {
|
||||||
return func() error {
|
return func() error {
|
||||||
tos, err := s.Pop()
|
r1, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
nos, err := s.Pop()
|
r2, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.Push(nos - tos)
|
s.Push(r2 - r1)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,15 +43,15 @@ func (b *Builtins) Sub(s *Stack) func() error {
|
|||||||
// Mul multiplies the two numbers on the top of the stack and pushes the result
|
// Mul multiplies the two numbers on the top of the stack and pushes the result
|
||||||
func (b *Builtins) Mul(s *Stack) func() error {
|
func (b *Builtins) Mul(s *Stack) func() error {
|
||||||
return func() error {
|
return func() error {
|
||||||
tos, err := s.Pop()
|
r1, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
nos, err := s.Pop()
|
r2, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.Push(nos * tos)
|
s.Push(r2 * r1)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,15 +59,15 @@ func (b *Builtins) Mul(s *Stack) func() error {
|
|||||||
// Div performs NOS/TOS and pushes the (integer!) result
|
// Div performs NOS/TOS and pushes the (integer!) result
|
||||||
func (b *Builtins) Div(s *Stack) func() error {
|
func (b *Builtins) Div(s *Stack) func() error {
|
||||||
return func() error {
|
return func() error {
|
||||||
tos, err := s.Pop()
|
r1, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
nos, err := s.Pop()
|
r2, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.Push(nos / tos)
|
s.Push(r2 / r1)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -195,11 +75,11 @@ func (b *Builtins) Div(s *Stack) func() error {
|
|||||||
// Print pops the stack and outputs it to stdout
|
// Print pops the stack and outputs it to stdout
|
||||||
func (b *Builtins) Print(s *Stack) func() error {
|
func (b *Builtins) Print(s *Stack) func() error {
|
||||||
return func() error {
|
return func() error {
|
||||||
tos, err := s.Pop()
|
r1, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Print(tos, " ")
|
fmt.Print(r1, " ")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -207,12 +87,12 @@ func (b *Builtins) Print(s *Stack) func() error {
|
|||||||
// Dup pops the stack, then pushes two copies onto the stack
|
// Dup pops the stack, then pushes two copies onto the stack
|
||||||
func (b *Builtins) Dup(s *Stack) func() error {
|
func (b *Builtins) Dup(s *Stack) func() error {
|
||||||
return func() error {
|
return func() error {
|
||||||
tos, err := s.Pop()
|
r1, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.Push(tos)
|
s.Push(r1)
|
||||||
s.Push(tos)
|
s.Push(r1)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,16 +100,16 @@ func (b *Builtins) Dup(s *Stack) func() error {
|
|||||||
// Swap inverts the order of TOS and NOS
|
// Swap inverts the order of TOS and NOS
|
||||||
func (b *Builtins) Swap(s *Stack) func() error {
|
func (b *Builtins) Swap(s *Stack) func() error {
|
||||||
return func() error {
|
return func() error {
|
||||||
tos, err := s.Pop()
|
r1, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
nos, err := s.Pop()
|
r2, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.Push(tos)
|
s.Push(r1)
|
||||||
s.Push(nos)
|
s.Push(r2)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,17 +117,17 @@ func (b *Builtins) Swap(s *Stack) func() error {
|
|||||||
// Over duplicates NOS to TOS, resulting in NOS TOS NOS
|
// Over duplicates NOS to TOS, resulting in NOS TOS NOS
|
||||||
func (b *Builtins) Over(s *Stack) func() error {
|
func (b *Builtins) Over(s *Stack) func() error {
|
||||||
return func() error {
|
return func() error {
|
||||||
tos, err := s.Pop()
|
r1, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
nos, err := s.Pop()
|
r2, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.Push(nos)
|
s.Push(r2)
|
||||||
s.Push(tos)
|
s.Push(r1)
|
||||||
s.Push(nos)
|
s.Push(r2)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,21 +143,21 @@ func (b *Builtins) Drop(s *Stack) func() error {
|
|||||||
// Rot cycles the first three items on the stack: TOS 1 2 3 -> TOS 3 1 2
|
// Rot cycles the first three items on the stack: TOS 1 2 3 -> TOS 3 1 2
|
||||||
func (b *Builtins) Rot(s *Stack) func() error {
|
func (b *Builtins) Rot(s *Stack) func() error {
|
||||||
return func() error {
|
return func() error {
|
||||||
tos, err := s.Pop()
|
r1, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
nos, err := s.Pop()
|
r2, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p3, err := s.Pop()
|
r3, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.Push(nos)
|
s.Push(r2)
|
||||||
s.Push(tos)
|
s.Push(r1)
|
||||||
s.Push(p3)
|
s.Push(r3)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -295,48 +175,11 @@ func (b *Builtins) Words(d Dictionary) func() error {
|
|||||||
// Emit outputs the UTF-8 rune for the int on the top of the stack
|
// Emit outputs the UTF-8 rune for the int on the top of the stack
|
||||||
func (b *Builtins) Emit(s *Stack) func() error {
|
func (b *Builtins) Emit(s *Stack) func() error {
|
||||||
return func() error {
|
return func() error {
|
||||||
tos, err := s.Pop()
|
i, err := s.Pop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Print(string(rune(tos)) + " ")
|
fmt.Print(string(rune(i)) + " ")
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToR pops from the stack to the return stack
|
|
||||||
func (b *Builtins) ToR(s *Stack, r *Stack) func() error {
|
|
||||||
return func() error {
|
|
||||||
tos, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
r.Push(tos)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RFrom pops from the return stack to the stack
|
|
||||||
func (b *Builtins) RFrom(s *Stack, r *Stack) func() error {
|
|
||||||
return func() error {
|
|
||||||
tors, err := r.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
s.Push(tors)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RFetch copies from the return stack to the stack
|
|
||||||
func (b *Builtins) RFetch(s *Stack, r *Stack) func() error {
|
|
||||||
return func() error {
|
|
||||||
tors, err := r.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
r.Push(tors)
|
|
||||||
s.Push(tors)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
eval.go
1
eval.go
@ -10,7 +10,6 @@ import (
|
|||||||
type Context struct {
|
type Context struct {
|
||||||
Dictionary Dictionary
|
Dictionary Dictionary
|
||||||
Stack *Stack
|
Stack *Stack
|
||||||
RStack *Stack
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Eval evaulates a given line, recursively descending into given words as needed
|
// Eval evaulates a given line, recursively descending into given words as needed
|
||||||
|
12
main.go
12
main.go
@ -10,7 +10,6 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
stack := Stack{values: []int{}}
|
stack := Stack{values: []int{}}
|
||||||
rstack := Stack{values: []int{}}
|
|
||||||
|
|
||||||
dict := Dictionary{}
|
dict := Dictionary{}
|
||||||
b := &Builtins{}
|
b := &Builtins{}
|
||||||
@ -19,13 +18,6 @@ func main() {
|
|||||||
dict.AddWord("*", b.Mul(&stack), "")
|
dict.AddWord("*", b.Mul(&stack), "")
|
||||||
dict.AddWord("/", b.Div(&stack), "")
|
dict.AddWord("/", b.Div(&stack), "")
|
||||||
dict.AddWord(".", b.Print(&stack), "")
|
dict.AddWord(".", b.Print(&stack), "")
|
||||||
dict.AddWord("=", b.Eq(&stack), "")
|
|
||||||
dict.AddWord("0=", nil, "0 = ")
|
|
||||||
dict.AddWord("<>", b.NEq(&stack), "")
|
|
||||||
dict.AddWord(">", b.Gt(&stack), "")
|
|
||||||
dict.AddWord("<", b.Lt(&stack), "")
|
|
||||||
dict.AddWord(">=", b.GtEq(&stack), "")
|
|
||||||
dict.AddWord("<=", b.LtEq(&stack), "")
|
|
||||||
dict.AddWord("DUP", b.Dup(&stack), "")
|
dict.AddWord("DUP", b.Dup(&stack), "")
|
||||||
dict.AddWord("SWAP", b.Swap(&stack), "")
|
dict.AddWord("SWAP", b.Swap(&stack), "")
|
||||||
dict.AddWord("OVER", b.Over(&stack), "")
|
dict.AddWord("OVER", b.Over(&stack), "")
|
||||||
@ -34,16 +26,12 @@ func main() {
|
|||||||
dict.AddWord("WORDS", b.Words(dict), "")
|
dict.AddWord("WORDS", b.Words(dict), "")
|
||||||
dict.AddWord(".S", b.Debug(&stack), "")
|
dict.AddWord(".S", b.Debug(&stack), "")
|
||||||
dict.AddWord("EMIT", b.Emit(&stack), "")
|
dict.AddWord("EMIT", b.Emit(&stack), "")
|
||||||
dict.AddWord("R>", b.RFrom(&stack, &rstack), "")
|
|
||||||
dict.AddWord(">R", b.ToR(&stack, &rstack), "")
|
|
||||||
dict.AddWord("R@", b.RFetch(&stack, &rstack), "")
|
|
||||||
dict.AddWord("CR", b.CR(), "")
|
dict.AddWord("CR", b.CR(), "")
|
||||||
dict.AddWord("QUIT", b.Quit(), "")
|
dict.AddWord("QUIT", b.Quit(), "")
|
||||||
|
|
||||||
c := Context{
|
c := Context{
|
||||||
Dictionary: dict,
|
Dictionary: dict,
|
||||||
Stack: &stack,
|
Stack: &stack,
|
||||||
RStack: &rstack,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reader := bufio.NewReader(os.Stdin)
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
Loading…
Reference in New Issue
Block a user