2021-02-14 02:09:56 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
2021-02-14 02:37:56 +00:00
|
|
|
"errors"
|
2021-02-14 02:09:56 +00:00
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
stack := Stack{values: []int{}}
|
2021-02-14 16:58:43 +00:00
|
|
|
rstack := Stack{values: []int{}}
|
2021-02-20 20:52:27 +00:00
|
|
|
ifstack := Stack{values: []int{}}
|
2021-02-14 02:09:56 +00:00
|
|
|
|
|
|
|
dict := Dictionary{}
|
2021-02-15 20:35:40 +00:00
|
|
|
|
|
|
|
c := Context{
|
|
|
|
Dictionary: dict,
|
|
|
|
Stack: &stack,
|
|
|
|
RStack: &rstack,
|
2021-02-20 20:52:27 +00:00
|
|
|
IfStack: &ifstack,
|
2021-02-16 00:24:04 +00:00
|
|
|
Flags: Flags{
|
|
|
|
"Immediate": true,
|
|
|
|
"Comment": false,
|
|
|
|
},
|
|
|
|
Words: []string{},
|
2021-02-15 20:35:40 +00:00
|
|
|
}
|
|
|
|
|
2021-02-14 02:09:56 +00:00
|
|
|
b := &Builtins{}
|
2021-02-15 20:35:40 +00:00
|
|
|
// word definitions
|
2021-02-20 20:52:27 +00:00
|
|
|
dict.AddWord(":", Word{Name: ":", Impl: b.Colon(&c)})
|
|
|
|
dict.AddWord(";", Word{Name: ";", Impl: b.Semicolon(&c), Immediate: true})
|
2021-02-16 00:24:04 +00:00
|
|
|
// comments
|
2021-02-20 20:52:27 +00:00
|
|
|
dict.AddWord("(", Word{Name: "(", Impl: b.OpenComment(&c), Immediate: true})
|
|
|
|
dict.AddWord(")", Word{Name: ")", Impl: b.CloseComment(&c), Immediate: true})
|
2021-02-15 20:35:40 +00:00
|
|
|
// math
|
2021-02-20 20:52:27 +00:00
|
|
|
dict.AddWord("+", Word{Name: "+", Impl: b.Add(&stack)})
|
|
|
|
dict.AddWord("-", Word{Name: "-", Impl: b.Sub(&stack)})
|
|
|
|
dict.AddWord("*", Word{Name: "*", Impl: b.Mul(&stack)})
|
|
|
|
dict.AddWord("/", Word{Name: "/", Impl: b.Div(&stack)})
|
2021-02-15 20:35:40 +00:00
|
|
|
// output
|
2021-02-20 20:52:27 +00:00
|
|
|
dict.AddWord(".", Word{Name: ".", Impl: b.Print(os.Stdout, &stack)})
|
|
|
|
dict.AddWord("EMIT", Word{Name: "EMIT", Impl: b.Emit(os.Stdout, &stack)})
|
|
|
|
dict.AddWord("CR", Word{Name: "CR", Source: []string{"10", "EMIT"}}) // emit a newline
|
2021-02-15 20:35:40 +00:00
|
|
|
// logic
|
2021-02-20 20:52:27 +00:00
|
|
|
dict.AddWord("=", Word{Name: "=", Impl: b.Eq(&stack)})
|
|
|
|
dict.AddWord("0=", Word{Name: "0=", Source: []string{"0", "="}})
|
|
|
|
dict.AddWord("<>", Word{Name: "<>", Impl: b.NEq(&stack)})
|
|
|
|
dict.AddWord(">", Word{Name: ">", Impl: b.Gt(&stack)})
|
|
|
|
dict.AddWord("<", Word{Name: "<", Impl: b.Lt(&stack)})
|
|
|
|
dict.AddWord(">=", Word{Name: ">=", Impl: b.GtEq(&stack)})
|
|
|
|
dict.AddWord("<=", Word{Name: "<=", Impl: b.LtEq(&stack)})
|
|
|
|
dict.AddWord("0<", Word{Name: "0<", Source: []string{"0", "<"}})
|
|
|
|
dict.AddWord("0>", Word{Name: "0>", Source: []string{"0", ">"}})
|
2021-02-15 20:35:40 +00:00
|
|
|
// stack manipulation
|
2021-02-20 20:52:27 +00:00
|
|
|
dict.AddWord("DUP", Word{Name: "DUP", Impl: b.Dup(&stack)})
|
|
|
|
dict.AddWord("SWAP", Word{Name: "SWAP", Impl: b.Swap(&stack)})
|
|
|
|
dict.AddWord("OVER", Word{Name: "OVER", Impl: b.Over(&stack)})
|
|
|
|
dict.AddWord("DROP", Word{Name: "DROP", Impl: b.Drop(&stack)})
|
|
|
|
dict.AddWord("ROT", Word{Name: "ROT", Impl: b.Rot(&stack)})
|
2021-02-15 20:35:40 +00:00
|
|
|
// debugging
|
2021-02-20 20:52:27 +00:00
|
|
|
dict.AddWord("WORDS", Word{Name: "WORDS", Impl: b.Words(dict)})
|
|
|
|
dict.AddWord("FLAGS", Word{Name: "FLAGS", Impl: b.Flags(c)})
|
|
|
|
dict.AddWord(".S", Word{Name: ".S", Impl: b.Debug(&stack)})
|
|
|
|
dict.AddWord(".R", Word{Name: ".R", Impl: b.Debug(&rstack)})
|
|
|
|
dict.AddWord(".I", Word{Name: ".I", Impl: b.Debug(&ifstack)})
|
|
|
|
dict.AddWord("R>", Word{Name: "R>", Impl: b.RFrom(&stack, &rstack)})
|
|
|
|
dict.AddWord(">R", Word{Name: ">R", Impl: b.ToR(&stack, &rstack)})
|
|
|
|
dict.AddWord("R@", Word{Name: "R@", Impl: b.RFetch(&stack, &rstack)})
|
2021-02-15 20:35:40 +00:00
|
|
|
// branching
|
2021-02-20 20:52:27 +00:00
|
|
|
dict.AddWord("IF", Word{Name: "IF", Impl: b.If(&stack, &ifstack), BranchCheck: true})
|
|
|
|
dict.AddWord("ELSE", Word{Name: "ELSE", Impl: b.Else(&ifstack), BranchCheck: true})
|
|
|
|
dict.AddWord("THEN", Word{Name: "THEN", Impl: b.Then(&ifstack), BranchCheck: true})
|
|
|
|
dict.AddWord("DO", Word{Name: "DO", Impl: b.Do(&stack, &rstack)})
|
|
|
|
dict.AddWord("LOOP", Word{Name: "LOOP", Impl: b.Loop(&stack, &rstack)})
|
|
|
|
dict.AddWord("I", Word{Name: "I", Impl: b.I(&stack, &rstack)})
|
2021-02-15 20:35:40 +00:00
|
|
|
// exit
|
2021-02-20 20:52:27 +00:00
|
|
|
dict.AddWord("BYE", Word{Name: "BYE", Impl: b.Quit()})
|
2021-02-14 02:09:56 +00:00
|
|
|
|
|
|
|
reader := bufio.NewReader(os.Stdin)
|
2021-02-16 00:24:04 +00:00
|
|
|
fmt.Print("prosper\n")
|
2021-02-14 02:09:56 +00:00
|
|
|
|
|
|
|
// read loop
|
|
|
|
for {
|
2021-02-16 00:24:04 +00:00
|
|
|
if c.Flags["Immediate"] {
|
|
|
|
fmt.Print("> ")
|
|
|
|
} else {
|
|
|
|
fmt.Print(" ")
|
|
|
|
}
|
2021-02-14 02:09:56 +00:00
|
|
|
|
|
|
|
line, err := reader.ReadString('\n')
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err.Error())
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
line = strings.TrimSpace(line)
|
|
|
|
err = c.Eval(line + " ") // append a space to make sure we always close out our parse loop
|
2021-02-14 02:37:56 +00:00
|
|
|
if errors.Is(err, ErrExit) {
|
|
|
|
fmt.Printf("bye\n")
|
|
|
|
os.Exit(0)
|
|
|
|
} else if err != nil {
|
2021-02-16 00:24:04 +00:00
|
|
|
fmt.Printf("error in evaluation: %v\n", err)
|
|
|
|
} else if c.Flags["Immediate"] {
|
|
|
|
fmt.Print("ok\n")
|
2021-02-14 02:09:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|