prosper/main.go

103 lines
2.8 KiB
Go
Raw Normal View History

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-14 02:09:56 +00:00
dict := Dictionary{}
2021-02-15 20:35:40 +00:00
c := Context{
Dictionary: dict,
Stack: &stack,
RStack: &rstack,
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
dict.AddWord(":", b.Colon(&c), nil, false)
2021-02-15 20:35:40 +00:00
dict.AddWord(";", b.Semicolon(&c), nil, true)
// comments
dict.AddWord("(", b.OpenComment(&c), nil, true)
dict.AddWord(")", b.CloseComment(&c), nil, true)
2021-02-15 20:35:40 +00:00
// math
2021-02-15 01:26:30 +00:00
dict.AddWord("+", b.Add(&stack), nil, false)
dict.AddWord("-", b.Sub(&stack), nil, false)
dict.AddWord("*", b.Mul(&stack), nil, false)
dict.AddWord("/", b.Div(&stack), nil, false)
2021-02-15 20:35:40 +00:00
// output
dict.AddWord(".", b.Print(os.Stdout, &stack), nil, false)
dict.AddWord("EMIT", b.Emit(os.Stdout, &stack), nil, false)
dict.AddWord("CR", nil, []string{"10", "EMIT"}, false) // emit a newline
2021-02-15 20:35:40 +00:00
// logic
2021-02-15 01:26:30 +00:00
dict.AddWord("=", b.Eq(&stack), nil, false)
dict.AddWord("0=", nil, []string{"0", "="}, false)
dict.AddWord("<>", b.NEq(&stack), nil, false)
dict.AddWord(">", b.Gt(&stack), nil, false)
dict.AddWord("<", b.Lt(&stack), nil, false)
dict.AddWord(">=", b.GtEq(&stack), nil, false)
dict.AddWord("<=", b.LtEq(&stack), nil, false)
dict.AddWord("0<", nil, []string{"0", "<"}, false)
dict.AddWord("0>", nil, []string{"0", ">"}, false)
2021-02-15 20:35:40 +00:00
// stack manipulation
2021-02-15 01:26:30 +00:00
dict.AddWord("DUP", b.Dup(&stack), nil, false)
dict.AddWord("SWAP", b.Swap(&stack), nil, false)
dict.AddWord("OVER", b.Over(&stack), nil, false)
dict.AddWord("DROP", b.Drop(&stack), nil, false)
dict.AddWord("ROT", b.Rot(&stack), nil, false)
2021-02-15 20:35:40 +00:00
// debugging
2021-02-15 01:26:30 +00:00
dict.AddWord("WORDS", b.Words(dict), nil, false)
dict.AddWord("FLAGS", b.Flags(c), nil, false)
2021-02-15 01:26:30 +00:00
dict.AddWord(".S", b.Debug(&stack), nil, false)
dict.AddWord(".R", b.Debug(&rstack), nil, false)
dict.AddWord("R>", b.RFrom(&stack, &rstack), nil, false)
dict.AddWord(">R", b.ToR(&stack, &rstack), nil, false)
dict.AddWord("R@", b.RFetch(&stack, &rstack), nil, false)
2021-02-15 20:35:40 +00:00
// branching
2021-02-15 01:26:30 +00:00
dict.AddWord("DO", b.Do(&stack, &rstack), nil, false)
dict.AddWord("LOOP", b.Loop(&stack, &rstack), nil, false)
dict.AddWord("I", b.I(&stack, &rstack), nil, false)
2021-02-15 20:35:40 +00:00
// exit
dict.AddWord("BYE", b.Quit(), nil, false)
2021-02-14 02:09:56 +00:00
reader := bufio.NewReader(os.Stdin)
fmt.Print("prosper\n")
2021-02-14 02:09:56 +00:00
// read loop
for {
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 {
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
}
}
}