func main() { // core.go: defined using go for k, v := range core.NS { repl_env.Set(Symbol{k}, Func{v.(func([]PlumType) (PlumType, error)), nil}) } repl_env.Set(Symbol{"eval"}, Func{func(a []PlumType) (PlumType, error) { return EVAL(a[0], repl_env) }, nil}) repl_env.Set(Symbol{"*ARGV*"}, List{}) // core.Plum: defined using the language itself repl("(define not (fn* (a) (if a false true)))") repl("(define load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))") repl("(defmacro cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))") repl("(defmacro or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))") repl("(define not1 (fn* (a) (if a false true)))") repl(`(load-file "lib/base.p")`) // called with Plum script to load and eval if len(os.Args) > 1 { args := make([]PlumType, 0, len(os.Args)-2) for _, a := range os.Args[2:] { args = append(args, a) } repl_env.Set(Symbol{"*ARGV*"}, List{args, nil}) if _, e := repl("(load-file \"" + os.Args[1] + "\")"); e != nil { fmt.Printf("Error: %v\n", e) os.Exit(1) } os.Exit(0) } // repl loop for { text, err := readline.Readline("user> ") text = strings.TrimRight(text, "\n") // fmt.Println(text) if err != nil { return } var out PlumType var e error if out, e = repl(text); e != nil { if e.Error() == "<empty line>" { continue } fmt.Printf("Error: %v\n", e) continue } fmt.Printf("%v\n", out) } }
} }, "keyword?": func(a []PlumType) (PlumType, error) { return Keyword_Q(a[0]), nil }, "pr-str": func(a []PlumType) (PlumType, error) { return pr_str(a) }, "str": func(a []PlumType) (PlumType, error) { return str(a) }, "prn": func(a []PlumType) (PlumType, error) { return prn(a) }, "println": func(a []PlumType) (PlumType, error) { return println(a) }, "read-string": func(a []PlumType) (PlumType, error) { return reader.Read_str(a[0].(string)) }, "slurp": slurp, "readline": func(a []PlumType) (PlumType, error) { return readline.Readline(a[0].(string)) }, "<": func(a []PlumType) (PlumType, error) { return a[0].(int) < a[1].(int), nil }, "<=": func(a []PlumType) (PlumType, error) { return a[0].(int) <= a[1].(int), nil }, ">": func(a []PlumType) (PlumType, error) { return a[0].(int) > a[1].(int), nil }, ">=": func(a []PlumType) (PlumType, error) { return a[0].(int) >= a[1].(int), nil }, "+": func(a []PlumType) (PlumType, error) {