-
Notifications
You must be signed in to change notification settings - Fork 0
/
README
152 lines (106 loc) · 4.09 KB
/
README
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
Babby's first toy lisp (scheme) interpreter
===========================================
Based on the examples given in the SICP videos
(http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/)
and also on the SICP text's examples
(http://mitpress.mit.edu/sicp/)
Currently supported Scheme procedures and special forms are:
<, <=, =, >, >=, -, *, +, and, append, apply, begin, car, cdr, caar,
cdar, ..., caaaaar, cond, cons, cons-stream, define, delay, display,
eq?, even?, filter, fold-right, force, if, lambda, length, let, list,
list-ref, list-tail, map, newline, not, null?, number?, odd?, or, pair?,
remainder, reverse, set!, stream-car, stream-cdr, stream-null?, symbol?,
the-empty-stream.
(Some more obscure variations of some special forms may not yet be supported)
Features include: tail-recursion optimization, noobish mark-sweep garbage
collection, support for quotation (but not yet quasiquotation), ...
To build the code, do:
$ make
To run interactive REPL mode, do:
$ ./lisp -i
To run a code file, do:
$ ./lisp <test.txt
The file `TODO' lists features that I might eventually add.
Example code files, available in the directory `test', are:
test.txt, closure.txt, tco-test.txt, pattern-matcher.txt, var-args.txt,
perfect.txt.
-----------------------------------
Memory usage benchmarks (as of Aug 8, 2013)
===========================================
These tests were made using valgrind --tool=massif
They show the approximate peak heap memory usage
Test program WL WL w/o ST ts
------------- -- --------- --
pattern-matcher.txt 1.009 MB 0.986 MB 361.7 KB
test.txt 1.356 MB 1.333 MB 361.2 KB
Legend
------
WL "wannabe-lisp" (i.e. this interpreter)
WL w/o ST "wannabe-lisp" compiled without
the debug tracer (DISABLE_STACKTRACER flag)
ts "tinyscheme" interpreter
This footprint could be (further) reduced by using smaller buffers in
various places, and especially perhaps by implementing a more
sophisticated garbage collector.
-----------------------------------
Some notes on special features
==============================
I. Special functions
- (leval quoted-exp) de-quotes and evaluates quoted-exp in the local scope.
For example, (leval '(+ 1 2 3)) => 6.
- (max-space exp) evaluates exp in the local scope, returning a number
indicating the peak number of stack frames used in the evaluation.
See tco-test.txt for example code. TCO'd iterative processes will
return a constant space count; recursive ones will return a growing
space count. max-space cannot be used recursively.
- (save-to 'file-name.txt) logs to a file.
- (load 'file.txt) loads code from a file.
~~~~~~~~
II. Parenthesis autocomplete:
you type a big expression in the REPL, then hit return with
an empty line and the missing parentheses will be automatically
added
]=> (define (bob x)
... (cond ((= x 0) 123
... ((= x 1) 456
...
... ))))
~~~~~~~~
III. Auto-indent
The REPL auto-indents
~~~~~~~~
IV. Debugging facilities
When user code crashes, it is possible to be presented, upon request,
with a useful printout showing a trace of recently evaluated list
structures as well as the values of the symbols involved in these.
The trace printout grows downwards from outermost, least-recently-evaluated
list, up until the list structure that caused the error.
[ The constant BUFLEN (by default 5) in stacktrace.c sets the maximum number of
evaluation steps memorized by the debug-tracer, and the constant SYMLEN,
by default 8, sets the maximum number of symbols memorized. ]
Below is an example session.
]=> (define (derp l n)
... (if (= n 0)
... (cadr l)
... (derp l (- n 1))))
#<CLOSURE:0x109e630>
]=> (derp 123 10)
Error: `cdr' expects a linked-list
A debug log has been prepared. Type (debuglog) to see it.
]=> (debuglog)
===== DEBUGGING INFO =====
Evaluation trace:
(if (= n 0) (cadr l) (derp l (- n 1)))
(= n 0)
(cadr l)
(car (cdr x))
(cdr x)
Symbols:
derp: #<CLOSURE:0x109e630>
n: 0
=: (PRIM-OP =)
l: 123
-: (PRIM-OP -)
cadr: #<CLOSURE:0x109e630>
x: 123
===========================