/
5.50.tex
122 lines (98 loc) · 2.68 KB
/
5.50.tex
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
111
112
113
114
115
116
117
118
119
120
121
122
\documentclass[a4paper,12pt]{article}
\usepackage{listings}
\lstset{language=Lisp}
\newcommand{\subpar}[1]{\medskip \noindent #1.}
\begin{document}
We try to compile the meta-circular evaluator defined in the file
meta.scm by wrapping it inside a \lstinline!begin! statement. First
of all, booleans should be recognized as self-evaluating expressions
so the compiler won't choke:
\begin{lstlisting}
(define (self-evaluating? exp)
(cond ((number? exp) #t)
((string? exp) #t)
((boolean? exp) #t)
(else #f)))
\end{lstlisting}
High order functions also pose problems since we have our own
procedure implementation. Hence, we can't use function such as
\lstinline!map! as primitive procedure. We decide to implement them
as a library that we load with the expression we wish to execute in
\lstinline!compile-and-go!.
\begin{lstlisting}
(define library
'((define (map fn lst)
(if (null? lst)
'()
(cons (fn (car lst))
(map fn (cdr lst)))))
(define (filter pred? lst)
(cond ((null? lst) '())
((pred? (car lst))
(cons (car lst)
(filter pred? (cdr lst))))
(else
(filter pred? (cdr lst)))))
(define (foldl fn init lst)
(if (null? lst)
init
(foldl fn
(fn (car lst) init)
(cdr lst))))
(define (for-each fn lst)
(if (null? lst)
'done
(begin
(fn (car lst))
(for-each fn (cdr lst)))))))
(define (compile-and-go expression)
(let ((instructions
(assemble (statements
(compile* `(begin
,@library
,expression)
'val
'return
the-empty-comp-time-env))
eceval)))
(set! the-global-environment (setup-environment))
(set-register-contents! eceval 'val instructions)
(set-register-contents! eceval 'flag #t)
(start eceval)))
\end{lstlisting}
Here's a simulation of the compiled version of the meta-circular
evaluator wrapped inside a \lstinline!begin!:
\begin{lstlisting}
> (compile-and-go
'(begin
<meta-circular evaluator body>))
(total-pushes = 2973 maximum-depth = 174)
;;; EC-EVAL value:
ok
;;; EC-EVAL input:
(driver-loop)
;;; M-Eval input:
1
;;; M-Eval value:
1
;;; M-Eval input:
#t
;;; M-Eval value:
#t
;;; M-Eval input:
(define (fact n)
(if (= n 1)
1
(* n (fact (- n 1)))))
;;; M-Eval value:
ok
;;; M-Eval input:
(fact 2)
;;; M-Eval value:
2
;;; M-Eval input:
(fact 4)
;;; M-Eval value:
24
\end{lstlisting}
\end{document}