-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterpreter.lpy
113 lines (99 loc) · 2.86 KB
/
interpreter.lpy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
; metacircular lispy interpreter written in lispy with a repl
(define eval-expr [node env]
(cond
(nil? node) ()
(int? node) node
(float? node) node
; variable
(symbol? node) (get env node)
; list forms
(list? node)
(switch (car node)
('quote node)
('if
(if (eval-expr (cadr node) env)
(eval-expr (car (cddr node)) env)
(eval-expr (cadr (cddr node)) env))
)
('define (add-env (cadr node) (eval-expr (car (cddr node)) env)))
('fn
(do
(define params (cadr node))
(define body (car (cddr node)))
; return a function which will be the operator when apply is called
(fn [& args]
(do
;set-new-env env parameters arguments
(set-new-env env (cadr (car node)) (car args))
;(println env)
; eval-expr body env
(eval-expr (car (cddr (car node))) env)
)
)
)
)
; evaluate function call
((car node)
(do
(define operator (eval-expr (car node) env))
(define operands (cdr node))
(if (= (caar node) 'fn)
(operator operands)
(apply operator (apply-compound env operands))
)
)
)
)
)
)
(define apply-compound [env args]
(if (nil? args)
()
(cons (eval-expr (car args) env) (apply-compound env (cdr args)))
)
)
(define add-env [env key val]
(do
(swap env (add env key val))
val
)
)
;parameters are named variables passed to the functions, arguments are actual valus
(define set-new-env [env params args]
(if (nil? params)
()
(do
(set-new-env env (cdr params) (cdr args))
(add-env env (car params) (car args))
)
)
)
(define env
(hash-map
'+ +
'- -
'/ /
'* *
'= =
)
)
(define eval [source]
(eval-expr source env)
)
(define repl-loop [line]
(do
(println "lispy> ")
; readstring parses into an ast
(define source (readstring (readline)))
(println (eval source))
;uncomment for debugging to see env (println new-env)
(repl-loop source)
)
)
(repl-loop "")
;(eval '(define a 5))
;(eval '(+ a 10))
;(eval '(* 1 2))
;(eval '5)
;(eval '6.0)
;(eval '(if (false) 5 6))