Skip to content

Commit cd14903

Browse files
authored
Merge pull request #3 from NJdevPro/extend
Extend
2 parents cf196d9 + e66fa67 commit cd14903

8 files changed

Lines changed: 226 additions & 297 deletions

File tree

README.md

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,18 @@ CTRL-Z SUSPEND PROCESS
7878
```
7979

8080
The REPL also saves the history of commands in the file history.txt
81+
<<<<<<< HEAD
82+
=======
83+
84+
Known bugs:
85+
* Operators "and" and "or" do not work like their typical Lisp counterpart
86+
because they evaluate all their operands at the same time instead of one
87+
by one.
88+
89+
90+
Original README
91+
=======
92+
>>>>>>> 0822c20 (Update README)
8193
This file is loaded at startup, so one can recall previous commands.
8294

8395
Future improvements:
@@ -260,22 +272,23 @@ exhaustion error.
260272

261273
`(progn expr expr ...)` executes several expressions in sequence.
262274

263-
(progn (print "I own ")
264-
(defun add(x y)(+ x y))
265-
(println (add 3 7) " cents")) ; -> prints "I own 10 cents"
275+
( progn (print "I own ")
276+
(defun add(x y)(+ x y))
277+
(println (add 3 7) " cents") ) ; -> prints "I own 10 cents"
266278

267279
### Equivalence test operators
268280

269281
`eq` takes two arguments and returns `t` if the objects are the same. What `eq`
270282
really does is a pointer comparison, so two objects happened to have the same
271283
contents but actually different are considered to not be the same by `eq`.
284+
`eq` can also compare two strings.
272285

273286
### String functions
274287

275-
`string=` compares two strings.
288+
`eq` compares two strings.
276289

277-
(string= "Hello" "Hello") ; -> t
278-
(string= "Hello" "World") ; -> ()
290+
(eq "Hello" "Hello") ; -> t
291+
(eq "Hello" "hello") ; -> ()
279292

280293
`string-concat` concatenates strings.
281294

examples/hanoi.lisp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(defun list (x . y) (cons x y))
1+
(load "examples/library.lisp")
22

33
(defun hanoi-print (disk from to)
44
(println (string-concat "Move disk " disk
@@ -16,4 +16,4 @@
1616
(defun hanoi (n)
1717
(hanoi-move n 'L 'M 'R))
1818

19-
(hanoi 5)
19+
(hanoi 5)

examples/library.lisp

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
;;
2+
;; Simple library of useful functions and macros
3+
;;
4+
5+
(defun list (x . y)
6+
(cons x y))
7+
8+
9+
;; (and e1 e2 ...)
10+
;; => (if e1 (and e2 ...))
11+
;; (and e1)
12+
;; => e1
13+
(defmacro and (expr . rest)
14+
(if rest
15+
(list 'if expr (cons 'and rest))
16+
expr))
17+
18+
;; (or e1 e2 ...)
19+
;; => (let <tmp> e1
20+
;; (if <tmp> <tmp> (or e2 ...)))
21+
;; (or e1)
22+
;; => e1
23+
;;
24+
;; The reason to use the temporary variables is to avoid evaluating the
25+
;; arguments more than once.
26+
(defmacro or (expr . rest)
27+
(if rest
28+
(let var (gensym)
29+
(list 'let var expr
30+
(list 'if var var (cons 'or rest))))
31+
expr))
32+
33+
;; (let var val body ...)
34+
;; => ((lambda (var) body ...) val)
35+
(defmacro let (var val . body)
36+
(cons (cons 'lambda (cons (list var) body))
37+
(list val)))
38+
39+
;; (when expr body ...)
40+
;; => (if expr (progn body ...))
41+
(defmacro when (expr . body)
42+
(cons 'if (cons expr (list (cons 'progn body)))))
43+
44+
;; (unless expr body ...)
45+
;; => (if expr () body ...)
46+
(defmacro unless (expr . body)
47+
(cons 'if (cons expr (cons () body))))
48+
49+
;;;
50+
;;; List operators
51+
;;;
52+
53+
;;; Applies each element of lis to fn, and returns their return values as a list.
54+
(defun map (lis fn)
55+
(when lis
56+
(cons (fn (car lis))
57+
(map (cdr lis) fn))))
58+
59+
(defun reduce (fn lst init)
60+
(if (eq () lst)
61+
init
62+
(reduce fn
63+
(cdr lst)
64+
(fn init (car lst)))))
65+
66+
;; Applies each element of lis to pred. If pred returns a true value, terminate
67+
;; the evaluation and returns pred's return value. If all of them return (),
68+
;; returns ().
69+
(defun any (lis pred)
70+
(when lis
71+
(or (pred (car lis))
72+
(any (cdr lis) pred))))
73+
74+
;; returns t if elem exists in list l
75+
(defun member (l elem)
76+
(any l (lambda (x) (or (eq x elem) (= x elem)))))
77+
78+
;; Returns nth element of lis.
79+
(defun nth (lis n)
80+
(if (= n 0)
81+
(car lis)
82+
(nth (cdr lis) (- n 1))))
83+
84+
;; Returns the nth tail of lis.
85+
(defun nth-tail (lis n)
86+
(if (= n 0)
87+
lis
88+
(nth-tail (cdr lis) (- n 1))))
89+
90+
;; Returns a list consists of m .. n-1 integers.
91+
(defun %iota (m n)
92+
(unless (<= n m)
93+
(cons m (%iota (+ m 1) n))))
94+
95+
;; Returns a list consists of 0 ... n-1 integers.
96+
(defun iota (n) (%iota 0 n))
97+
98+
;; Returns a new list whose length is len and all members are init.
99+
(defun make-list (len init)
100+
(unless (= len 0)
101+
(cons init (make-list (- len 1) init))))
102+
103+
;; Applies fn to each element of lis.
104+
(defun for-each (lis fn)
105+
(or (not lis)
106+
(progn (fn (car lis))
107+
(for-each (cdr lis) fn))))
108+
109+
; Concatenates and flattens lists into a single list
110+
(defun append (first . rest)
111+
(if (eq () rest)
112+
first
113+
(append2 first
114+
(append-reduce rest))))
115+
116+
(defun append2 (x y)
117+
(if (eq () x)
118+
y
119+
(cons (car x)
120+
(append2 (cdr x) y))))
121+
122+
(defun append-reduce (lists)
123+
(if (eq () (cdr lists))
124+
(car lists)
125+
(append2 (car lists)
126+
(append-reduce (cdr lists)))))
127+
128+
(defun filter (pred lst)
129+
(if (eq () lst)
130+
()
131+
(if (pred (car lst))
132+
(cons (car lst)
133+
(filter pred (cdr lst)))
134+
(filter pred (cdr lst)))))
135+
136+
(defun quicksort (lst)
137+
(if (eq () lst)
138+
()
139+
(if (eq () (cdr lst))
140+
lst
141+
(let pivot (car lst)
142+
(append
143+
(quicksort (filter (lambda(x) (< x pivot)) (cdr lst)))
144+
(cons pivot ())
145+
(quicksort (filter (lambda(x) (>= x pivot)) (cdr lst)))) ))))
146+

examples/life.lisp

Lines changed: 1 addition & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -2,100 +2,7 @@
22
;;; Conway's game of life
33
;;;
44

5-
;; (progn expr ...)
6-
;; => ((lambda () expr ...))
7-
;(defmacro progn (expr . rest)
8-
; (list (cons 'lambda (cons () (cons expr rest)))))
9-
10-
(defun list (x . y)
11-
(cons x y))
12-
13-
14-
;(defun not (x)
15-
; (if x () t))
16-
17-
;; (let var val body ...)
18-
;; => ((lambda (var) body ...) val)
19-
(defmacro let (var val . body)
20-
(cons (cons 'lambda (cons (list var) body))
21-
(list val)))
22-
23-
;; (and e1 e2 ...)
24-
;; => (if e1 (and e2 ...))
25-
;; (and e1)
26-
;; => e1
27-
(defmacro and (expr . rest)
28-
(if rest
29-
(list 'if expr (cons 'and rest))
30-
expr))
31-
32-
;; (or e1 e2 ...)
33-
;; => (let <tmp> e1
34-
;; (if <tmp> <tmp> (or e2 ...)))
35-
;; (or e1)
36-
;; => e1
37-
;;
38-
;; The reason to use the temporary variables is to avoid evaluating the
39-
;; arguments more than once.
40-
(defmacro or (expr . rest)
41-
(if rest
42-
(let var (gensym)
43-
(list 'let var expr
44-
(list 'if var var (cons 'or rest))))
45-
expr))
46-
47-
;; (when expr body ...)
48-
;; => (if expr (progn body ...))
49-
(defmacro when (expr . body)
50-
(cons 'if (cons expr (list (cons 'progn body)))))
51-
52-
;; (unless expr body ...)
53-
;; => (if expr () body ...)
54-
(defmacro unless (expr . body)
55-
(cons 'if (cons expr (cons () body))))
56-
57-
;;;
58-
;;; Numeric operators
59-
;;;
60-
61-
;(defun <= (e1 e2)
62-
; (or (< e1 e2)
63-
; (= e1 e2)))
64-
65-
;;;
66-
;;; List operators
67-
;;;
68-
69-
;;; Applies each element of lis to fn, and returns their return values as a list.
70-
(defun map (lis fn)
71-
(when lis
72-
(cons (fn (car lis))
73-
(map (cdr lis) fn))))
74-
75-
;; Returns nth element of lis.
76-
(defun nth (lis n)
77-
(if (= n 0)
78-
(car lis)
79-
(nth (cdr lis) (- n 1))))
80-
81-
;; Returns the nth tail of lis.
82-
(defun nth-tail (lis n)
83-
(if (= n 0)
84-
lis
85-
(nth-tail (cdr lis) (- n 1))))
86-
87-
;; Returns a list consists of m .. n-1 integers.
88-
(defun %iota (m n)
89-
(unless (<= n m)
90-
(cons m (%iota (+ m 1) n))))
91-
92-
;; Returns a list consists of 0 ... n-1 integers.
93-
(defun iota (n)
94-
(%iota 0 n))
95-
96-
;;;
97-
;;; Main
98-
;;;
5+
(load "examples/library.lisp")
996

1007
(define width 10)
1018
(define height 10)

0 commit comments

Comments
 (0)