add more common math and fix my comparison checks

This commit is contained in:
David 2021-02-20 18:03:02 -05:00
parent 06ad13dd28
commit a75db93581
2 changed files with 63 additions and 21 deletions

View File

@ -7,6 +7,9 @@ import (
"os" "os"
) )
var FALSE = 0
var TRUE = -1
// Builtins is a handy holder for our various default words // Builtins is a handy holder for our various default words
type Builtins struct{} type Builtins struct{}
@ -61,10 +64,10 @@ func (b *Builtins) Eq(s *Stack) func() error {
return err return err
} }
if tos == nos { if tos == nos {
s.Push(-1) s.Push(TRUE)
return nil return nil
} }
s.Push(0) s.Push(FALSE)
return nil return nil
} }
} }
@ -81,10 +84,10 @@ func (b *Builtins) NEq(s *Stack) func() error {
return err return err
} }
if tos != nos { if tos != nos {
s.Push(-1) s.Push(TRUE)
return nil return nil
} }
s.Push(0) s.Push(FALSE)
return nil return nil
} }
} }
@ -100,11 +103,11 @@ func (b *Builtins) Lt(s *Stack) func() error {
if err != nil { if err != nil {
return err return err
} }
if tos < nos { if nos < tos {
s.Push(-1) s.Push(TRUE)
return nil return nil
} }
s.Push(0) s.Push(FALSE)
return nil return nil
} }
} }
@ -120,11 +123,11 @@ func (b *Builtins) Gt(s *Stack) func() error {
if err != nil { if err != nil {
return err return err
} }
if tos > nos { if nos > tos {
s.Push(-1) s.Push(TRUE)
return nil return nil
} }
s.Push(0) s.Push(FALSE)
return nil return nil
} }
} }
@ -140,11 +143,11 @@ func (b *Builtins) LtEq(s *Stack) func() error {
if err != nil { if err != nil {
return err return err
} }
if tos <= nos { if nos <= tos {
s.Push(-1) s.Push(TRUE)
return nil return nil
} }
s.Push(0) s.Push(FALSE)
return nil return nil
} }
} }
@ -160,11 +163,11 @@ func (b *Builtins) GtEq(s *Stack) func() error {
if err != nil { if err != nil {
return err return err
} }
if tos >= nos { if nos >= tos {
s.Push(-1) s.Push(TRUE)
return nil return nil
} }
s.Push(0) s.Push(FALSE)
return nil return nil
} }
} }
@ -233,6 +236,39 @@ func (b *Builtins) Div(s *Stack) func() error {
} }
} }
// Mod performs NOS%TOS and pushes the (integer!) modulo result
func (b *Builtins) Mod(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
}
s.Push(nos % tos)
return nil
}
}
// DivMod performs NOS/TOS & NOS%TOS and pushes the (integer!) results: TOS as quotient, NOS as remainder
func (b *Builtins) DivMod(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
}
s.Push(nos % tos)
s.Push(nos / tos)
return nil
}
}
// Print pops the stack and outputs it to the writer with a trailing space (defaults to stdout) // Print pops the stack and outputs it to the writer with a trailing space (defaults to stdout)
func (b *Builtins) Print(out io.Writer, s *Stack) func() error { func (b *Builtins) Print(out io.Writer, s *Stack) func() error {
if out == nil { if out == nil {
@ -418,13 +454,13 @@ func (b *Builtins) If(s *Stack, i *Stack) func() error {
if err != nil { if err != nil {
return err return err
} }
// TOS was 0, don't execute this branch // TOS was FALSE, don't execute this branch
if tos == 0 { if tos == FALSE {
i.Push(0) i.Push(0)
} else { return nil
}
// TOS wasn't 0, execute until we see ELSE/THEN // TOS wasn't 0, execute until we see ELSE/THEN
i.Push(1) i.Push(1)
}
return nil return nil
} }
} }

View File

@ -39,6 +39,11 @@ func main() {
dict.AddWord("-", Word{Name: "-", Impl: b.Sub(&stack)}) dict.AddWord("-", Word{Name: "-", Impl: b.Sub(&stack)})
dict.AddWord("*", Word{Name: "*", Impl: b.Mul(&stack)}) dict.AddWord("*", Word{Name: "*", Impl: b.Mul(&stack)})
dict.AddWord("/", Word{Name: "/", Impl: b.Div(&stack)}) dict.AddWord("/", Word{Name: "/", Impl: b.Div(&stack)})
dict.AddWord("MOD", Word{Name: "MOD", Impl: b.Mod(&stack)})
dict.AddWord("/MOD", Word{Name: "/MOD", Impl: b.DivMod(&stack)})
dict.AddWord("+1", Word{Name: "+1", Source: []string{"1", "+"}})
dict.AddWord("-1", Word{Name: "-1", Source: []string{"1", "-"}})
dict.AddWord("ABS", Word{Name: "ABS", Source: []string{"DUP 0< IF DUP DUP - SWAP - THEN"}})
// output // output
dict.AddWord(".", Word{Name: ".", Impl: b.Print(os.Stdout, &stack)}) dict.AddWord(".", Word{Name: ".", Impl: b.Print(os.Stdout, &stack)})
dict.AddWord("EMIT", Word{Name: "EMIT", Impl: b.Emit(os.Stdout, &stack)}) dict.AddWord("EMIT", Word{Name: "EMIT", Impl: b.Emit(os.Stdout, &stack)})
@ -47,6 +52,7 @@ func main() {
dict.AddWord("=", Word{Name: "=", Impl: b.Eq(&stack)}) dict.AddWord("=", Word{Name: "=", Impl: b.Eq(&stack)})
dict.AddWord("0=", Word{Name: "0=", Source: []string{"0", "="}}) dict.AddWord("0=", Word{Name: "0=", Source: []string{"0", "="}})
dict.AddWord("<>", Word{Name: "<>", Impl: b.NEq(&stack)}) dict.AddWord("<>", Word{Name: "<>", Impl: b.NEq(&stack)})
dict.AddWord("0<>", Word{Name: "0<>", Source: []string{"0=", "0="}})
dict.AddWord(">", Word{Name: ">", Impl: b.Gt(&stack)}) dict.AddWord(">", Word{Name: ">", Impl: b.Gt(&stack)})
dict.AddWord("<", Word{Name: "<", Impl: b.Lt(&stack)}) dict.AddWord("<", Word{Name: "<", Impl: b.Lt(&stack)})
dict.AddWord(">=", Word{Name: ">=", Impl: b.GtEq(&stack)}) dict.AddWord(">=", Word{Name: ">=", Impl: b.GtEq(&stack)})