Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ CTRL-Z SUSPEND PROCESS
```

The REPL also saves the history of commands in the file history.txt
<<<<<<< HEAD
=======

Known bugs:
* Operators "and" and "or" do not work like their typical Lisp counterpart
because they evaluate all their operands at the same time instead of one
by one.


Original README
=======
>>>>>>> 0822c20 (Update README)
This file is loaded at startup, so one can recall previous commands.

Future improvements:
Expand Down Expand Up @@ -260,22 +272,23 @@ exhaustion error.

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

(progn (print "I own ")
(defun add(x y)(+ x y))
(println (add 3 7) " cents")) ; -> prints "I own 10 cents"
( progn (print "I own ")
(defun add(x y)(+ x y))
(println (add 3 7) " cents") ) ; -> prints "I own 10 cents"

### Equivalence test operators

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

### String functions

`string=` compares two strings.
`eq` compares two strings.

(string= "Hello" "Hello") ; -> t
(string= "Hello" "World") ; -> ()
(eq "Hello" "Hello") ; -> t
(eq "Hello" "hello") ; -> ()

`string-concat` concatenates strings.

Expand Down
4 changes: 2 additions & 2 deletions examples/hanoi.lisp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(defun list (x . y) (cons x y))
(load "examples/library.lisp")

(defun hanoi-print (disk from to)
(println (string-concat "Move disk " disk
Expand All @@ -16,4 +16,4 @@
(defun hanoi (n)
(hanoi-move n 'L 'M 'R))

(hanoi 5)
(hanoi 5)
146 changes: 146 additions & 0 deletions examples/library.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
;;
;; Simple library of useful functions and macros
;;

(defun list (x . y)
(cons x y))


;; (and e1 e2 ...)
;; => (if e1 (and e2 ...))
;; (and e1)
;; => e1
(defmacro and (expr . rest)
(if rest
(list 'if expr (cons 'and rest))
expr))

;; (or e1 e2 ...)
;; => (let <tmp> e1
;; (if <tmp> <tmp> (or e2 ...)))
;; (or e1)
;; => e1
;;
;; The reason to use the temporary variables is to avoid evaluating the
;; arguments more than once.
(defmacro or (expr . rest)
(if rest
(let var (gensym)
(list 'let var expr
(list 'if var var (cons 'or rest))))
expr))

;; (let var val body ...)
;; => ((lambda (var) body ...) val)
(defmacro let (var val . body)
(cons (cons 'lambda (cons (list var) body))
(list val)))

;; (when expr body ...)
;; => (if expr (progn body ...))
(defmacro when (expr . body)
(cons 'if (cons expr (list (cons 'progn body)))))

;; (unless expr body ...)
;; => (if expr () body ...)
(defmacro unless (expr . body)
(cons 'if (cons expr (cons () body))))

;;;
;;; List operators
;;;

;;; Applies each element of lis to fn, and returns their return values as a list.
(defun map (lis fn)
(when lis
(cons (fn (car lis))
(map (cdr lis) fn))))

(defun reduce (fn lst init)
(if (eq () lst)
init
(reduce fn
(cdr lst)
(fn init (car lst)))))

;; Applies each element of lis to pred. If pred returns a true value, terminate
;; the evaluation and returns pred's return value. If all of them return (),
;; returns ().
(defun any (lis pred)
(when lis
(or (pred (car lis))
(any (cdr lis) pred))))

;; returns t if elem exists in list l
(defun member (l elem)
(any l (lambda (x) (or (eq x elem) (= x elem)))))

;; Returns nth element of lis.
(defun nth (lis n)
(if (= n 0)
(car lis)
(nth (cdr lis) (- n 1))))

;; Returns the nth tail of lis.
(defun nth-tail (lis n)
(if (= n 0)
lis
(nth-tail (cdr lis) (- n 1))))

;; Returns a list consists of m .. n-1 integers.
(defun %iota (m n)
(unless (<= n m)
(cons m (%iota (+ m 1) n))))

;; Returns a list consists of 0 ... n-1 integers.
(defun iota (n) (%iota 0 n))

;; Returns a new list whose length is len and all members are init.
(defun make-list (len init)
(unless (= len 0)
(cons init (make-list (- len 1) init))))

;; Applies fn to each element of lis.
(defun for-each (lis fn)
(or (not lis)
(progn (fn (car lis))
(for-each (cdr lis) fn))))

; Concatenates and flattens lists into a single list
(defun append (first . rest)
(if (eq () rest)
first
(append2 first
(append-reduce rest))))

(defun append2 (x y)
(if (eq () x)
y
(cons (car x)
(append2 (cdr x) y))))

(defun append-reduce (lists)
(if (eq () (cdr lists))
(car lists)
(append2 (car lists)
(append-reduce (cdr lists)))))

(defun filter (pred lst)
(if (eq () lst)
()
(if (pred (car lst))
(cons (car lst)
(filter pred (cdr lst)))
(filter pred (cdr lst)))))

(defun quicksort (lst)
(if (eq () lst)
()
(if (eq () (cdr lst))
lst
(let pivot (car lst)
(append
(quicksort (filter (lambda(x) (< x pivot)) (cdr lst)))
(cons pivot ())
(quicksort (filter (lambda(x) (>= x pivot)) (cdr lst)))) ))))

95 changes: 1 addition & 94 deletions examples/life.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -2,100 +2,7 @@
;;; Conway's game of life
;;;

;; (progn expr ...)
;; => ((lambda () expr ...))
;(defmacro progn (expr . rest)
; (list (cons 'lambda (cons () (cons expr rest)))))

(defun list (x . y)
(cons x y))


;(defun not (x)
; (if x () t))

;; (let var val body ...)
;; => ((lambda (var) body ...) val)
(defmacro let (var val . body)
(cons (cons 'lambda (cons (list var) body))
(list val)))

;; (and e1 e2 ...)
;; => (if e1 (and e2 ...))
;; (and e1)
;; => e1
(defmacro and (expr . rest)
(if rest
(list 'if expr (cons 'and rest))
expr))

;; (or e1 e2 ...)
;; => (let <tmp> e1
;; (if <tmp> <tmp> (or e2 ...)))
;; (or e1)
;; => e1
;;
;; The reason to use the temporary variables is to avoid evaluating the
;; arguments more than once.
(defmacro or (expr . rest)
(if rest
(let var (gensym)
(list 'let var expr
(list 'if var var (cons 'or rest))))
expr))

;; (when expr body ...)
;; => (if expr (progn body ...))
(defmacro when (expr . body)
(cons 'if (cons expr (list (cons 'progn body)))))

;; (unless expr body ...)
;; => (if expr () body ...)
(defmacro unless (expr . body)
(cons 'if (cons expr (cons () body))))

;;;
;;; Numeric operators
;;;

;(defun <= (e1 e2)
; (or (< e1 e2)
; (= e1 e2)))

;;;
;;; List operators
;;;

;;; Applies each element of lis to fn, and returns their return values as a list.
(defun map (lis fn)
(when lis
(cons (fn (car lis))
(map (cdr lis) fn))))

;; Returns nth element of lis.
(defun nth (lis n)
(if (= n 0)
(car lis)
(nth (cdr lis) (- n 1))))

;; Returns the nth tail of lis.
(defun nth-tail (lis n)
(if (= n 0)
lis
(nth-tail (cdr lis) (- n 1))))

;; Returns a list consists of m .. n-1 integers.
(defun %iota (m n)
(unless (<= n m)
(cons m (%iota (+ m 1) n))))

;; Returns a list consists of 0 ... n-1 integers.
(defun iota (n)
(%iota 0 n))

;;;
;;; Main
;;;
(load "examples/library.lisp")

(define width 10)
(define height 10)
Expand Down
Loading