4 (require "readline.rkt" "types.rkt" "reader.rkt" "printer.rkt"
13 (and (_sequential? x) (> (_count x) 0)))
15 (define (quasiquote ast)
20 [(equal? 'unquote (_nth ast 0))
23 [(and (is-pair (_nth ast 0))
24 (equal? 'splice-unquote (_nth (_nth ast 0) 0)))
25 (list 'concat (_nth (_nth ast 0) 1) (quasiquote (_rest ast)))]
28 (list 'cons (quasiquote (_nth ast 0)) (quasiquote (_rest ast)))]))
30 (define (macro? ast env)
33 (not (equal? null (send env find (first ast))))
34 (let ([fn (send env get (first ast))])
35 (and (malfunc? fn) (malfunc-macro? fn)))))
37 (define (macroexpand ast env)
39 (let ([mac (malfunc-fn (send env get (first ast)))])
40 (macroexpand (apply mac (rest ast)) env))
43 (define (eval-ast ast env)
45 [(symbol? ast) (send env get ast)]
46 [(_sequential? ast) (_map (lambda (x) (EVAL x env)) ast)]
47 [(hash? ast) (make-hash
48 (dict-map ast (lambda (k v) (cons k (EVAL v env)))))]
51 (define (EVAL ast env)
52 ;(printf "~a~n" (pr_str ast true))
56 (let ([ast (macroexpand ast env)])
59 (let ([a0 (_nth ast 0)])
62 (send env set (_nth ast 1) (EVAL (_nth ast 2) env))]
64 (let ([let-env (new Env% [outer env] [binds null] [exprs null])])
66 (send let-env set (_first b_e)
67 (EVAL (_nth b_e 1) let-env)))
68 (_partition 2 (_to_list (_nth ast 1))))
69 (EVAL (_nth ast 2) let-env))]
73 (EVAL (quasiquote (_nth ast 1)) env)]
75 (let* ([func (EVAL (_nth ast 2) env)]
76 [mac (struct-copy malfunc func [macro? #t])])
77 (send env set (_nth ast 1) mac))]
78 [(eq? 'macroexpand a0)
79 (macroexpand (_nth ast 1) env)]
81 (if (eq? 'catch* (_nth (_nth ast 2) 0))
82 (let ([efn (lambda (exc)
83 (EVAL (_nth (_nth ast 2) 2)
86 [binds (list (_nth (_nth ast 2) 1))]
87 [exprs (list exc)])))])
89 ([mal-exn? (lambda (exc) (efn (mal-exn-val exc)))]
90 [string? (lambda (exc) (efn exc))]
91 [exn:fail? (lambda (exc) (efn (format "~a" exc)))])
92 (EVAL (_nth ast 1) env)))
95 (eval-ast (drop (drop-right ast 1) 1) env)
96 (EVAL (last ast) env)]
98 (let ([cnd (EVAL (_nth ast 1) env)])
99 (if (or (eq? cnd nil) (eq? cnd #f))
100 (if (> (length ast) 3)
101 (EVAL (_nth ast 3) env)
103 (EVAL (_nth ast 2) env)))]
106 (lambda args (EVAL (_nth ast 2)
107 (new Env% [outer env]
110 (_nth ast 2) env (_nth ast 1) #f nil)]
111 [else (let* ([el (eval-ast ast env)]
115 (EVAL (malfunc-ast f)
117 [outer (malfunc-env f)]
118 [binds (malfunc-params f)]
120 (apply f args)))]))))))
128 (new Env% [outer null] [binds null] [exprs null]))
130 (PRINT (EVAL (READ str) repl-env)))
132 (for () ;; ignore return values
134 ;; core.rkt: defined using Racket
135 (hash-for-each core_ns (lambda (k v) (send repl-env set k v)))
136 (send repl-env set 'eval (lambda [ast] (EVAL ast repl-env)))
137 (send repl-env set '*ARGV* (list))
139 ;; core.mal: defined using the language itself
140 (rep "(def! *host-language* \"racket\")")
141 (rep "(def! not (fn* (a) (if a false true)))")
142 (rep "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))")
143 (rep "(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)))))))")
144 (rep "(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))))))))")
149 (let ([line (readline "user> ")])
150 (when (not (eq? nil line))
152 ([string? (lambda (exc) (printf "Error: ~a~n" exc))]
153 [mal-exn? (lambda (exc) (printf "Error: ~a~n"
154 (pr_str (mal-exn-val exc) true)))]
155 [blank-exn? (lambda (exc) null)])
156 (printf "~a~n" (rep line)))
158 (let ([args (current-command-line-arguments)])
159 (if (> (vector-length args) 0)
160 (for () (rep (string-append "(load-file \"" (vector-ref args 0) "\")")))
162 (rep "(println (str \"Mal [\" *host-language* \"]\"))")