142 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			142 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								; Syntax and shorthands
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define = eq?)
							 | 
						||
| 
								 | 
							
								(define not null?)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define caar (lambda (lst) (car (car lst))))
							 | 
						||
| 
								 | 
							
								(define cdar (lambda (lst) (cdr (car lst))))
							 | 
						||
| 
								 | 
							
								(define caddr (lambda (lst) (car (cddr lst))))
							 | 
						||
| 
								 | 
							
								(define cadddr (lambda (lst) (cadr (cddr lst))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								; I/O
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define print
							 | 
						||
| 
								 | 
							
								  (lambda (object)
							 | 
						||
| 
								 | 
							
								    (write object)
							 | 
						||
| 
								 | 
							
								    (newline)))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								; The least dispensable list operations
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define equal?
							 | 
						||
| 
								 | 
							
								  (lambda (x1 x2)
							 | 
						||
| 
								 | 
							
								    (if (eq? x1 x2)
							 | 
						||
| 
								 | 
							
								        t
							 | 
						||
| 
								 | 
							
								        (if (pair? x1)
							 | 
						||
| 
								 | 
							
								            (if (pair? x2)
							 | 
						||
| 
								 | 
							
								                (if (equal? (car x1) (car x2))
							 | 
						||
| 
								 | 
							
								                    (equal? (cdr x1) (cdr x2))))))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define length
							 | 
						||
| 
								 | 
							
								  (lambda (lst)
							 | 
						||
| 
								 | 
							
								    ((lambda (n)
							 | 
						||
| 
								 | 
							
								       (while lst
							 | 
						||
| 
								 | 
							
								         (set! n (+ n 1))
							 | 
						||
| 
								 | 
							
								         (set! lst (cdr lst)))
							 | 
						||
| 
								 | 
							
								       n)
							 | 
						||
| 
								 | 
							
								     0)))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define append
							 | 
						||
| 
								 | 
							
								  (lambda (L1 L2)
							 | 
						||
| 
								 | 
							
								    (if (null? L1)
							 | 
						||
| 
								 | 
							
								        L2
							 | 
						||
| 
								 | 
							
								        (cons (car L1)
							 | 
						||
| 
								 | 
							
								              (append (cdr L1) L2)))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define map
							 | 
						||
| 
								 | 
							
								  (lambda (proc lst)
							 | 
						||
| 
								 | 
							
								    ((lambda (result)
							 | 
						||
| 
								 | 
							
								       (while lst
							 | 
						||
| 
								 | 
							
								         (set! result (cons (proc (car lst)) result))
							 | 
						||
| 
								 | 
							
								         (set! lst (cdr lst)))
							 | 
						||
| 
								 | 
							
								       (reverse! result))
							 | 
						||
| 
								 | 
							
								     '())))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define for-each
							 | 
						||
| 
								 | 
							
								  (lambda (proc lst)
							 | 
						||
| 
								 | 
							
								    (while lst
							 | 
						||
| 
								 | 
							
								      (proc (car lst))
							 | 
						||
| 
								 | 
							
								      (set! lst (cdr lst)))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								; Macros
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define macroexpand
							 | 
						||
| 
								 | 
							
								  (lambda (exp)
							 | 
						||
| 
								 | 
							
								    (if (atom? exp)
							 | 
						||
| 
								 | 
							
								        exp
							 | 
						||
| 
								 | 
							
								        (if (get (car exp) 'special-form)
							 | 
						||
| 
								 | 
							
								            ((get (car exp) 'special-form) exp)
							 | 
						||
| 
								 | 
							
								            (if (get (car exp) 'macro)
							 | 
						||
| 
								 | 
							
								                (macroexpand ((get (car exp) 'macro) (cdr exp)))
							 | 
						||
| 
								 | 
							
								                (map macroexpand exp))))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(put 'quote 'special-form
							 | 
						||
| 
								 | 
							
								  (lambda (exp) exp))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(put 'lambda 'special-form
							 | 
						||
| 
								 | 
							
								  (lambda (exp)
							 | 
						||
| 
								 | 
							
								    (cons 'lambda
							 | 
						||
| 
								 | 
							
								      (cons (cadr exp)
							 | 
						||
| 
								 | 
							
								        (map macroexpand (cddr exp))))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								; Other special forms don't need special treatment, but you might want
							 | 
						||
| 
								 | 
							
								; to add syntax-checking.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define define-macro
							 | 
						||
| 
								 | 
							
								  (lambda (keyword expander)
							 | 
						||
| 
								 | 
							
								    (put keyword 'macro expander)))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define-macro 'and
							 | 
						||
| 
								 | 
							
								  (lambda (args)
							 | 
						||
| 
								 | 
							
								    (if (null? args)
							 | 
						||
| 
								 | 
							
								        t
							 | 
						||
| 
								 | 
							
								        (if (null? (cdr args))
							 | 
						||
| 
								 | 
							
								            (car args)
							 | 
						||
| 
								 | 
							
								            (list 'if (car args) (cons 'and (cdr args)))))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define-macro 'or
							 | 
						||
| 
								 | 
							
								  (lambda (args)
							 | 
						||
| 
								 | 
							
								    (if (null? args)
							 | 
						||
| 
								 | 
							
								        nil
							 | 
						||
| 
								 | 
							
								        (if (null? (cdr args))
							 | 
						||
| 
								 | 
							
								            (car args)
							 | 
						||
| 
								 | 
							
								            (list
							 | 
						||
| 
								 | 
							
								              ((lambda (test-var)
							 | 
						||
| 
								 | 
							
								                (list 'lambda (list test-var)
							 | 
						||
| 
								 | 
							
								                  (list 'if test-var test-var (cons 'or (cdr args)))))
							 | 
						||
| 
								 | 
							
								               (gensym))
							 | 
						||
| 
								 | 
							
								              (car args))))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define-macro 'let
							 | 
						||
| 
								 | 
							
								  (lambda (args)
							 | 
						||
| 
								 | 
							
								    (cons
							 | 
						||
| 
								 | 
							
								      (cons 'lambda (cons (map car (car args)) (cdr args)))
							 | 
						||
| 
								 | 
							
								      (map cadr (car args)))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define make-begin
							 | 
						||
| 
								 | 
							
								  (lambda (lst)
							 | 
						||
| 
								 | 
							
								    (if (null? (cdr lst))
							 | 
						||
| 
								 | 
							
								        (car lst)
							 | 
						||
| 
								 | 
							
								        (cons 'begin lst))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define-macro 'cond
							 | 
						||
| 
								 | 
							
								  (lambda (clauses)
							 | 
						||
| 
								 | 
							
								    (if (null? clauses)
							 | 
						||
| 
								 | 
							
								        nil
							 | 
						||
| 
								 | 
							
								        (if (eq? (caar clauses) 'else)
							 | 
						||
| 
								 | 
							
								            (make-begin (cdar clauses))
							 | 
						||
| 
								 | 
							
								            (list 'if
							 | 
						||
| 
								 | 
							
								                  (caar clauses)
							 | 
						||
| 
								 | 
							
								                  (make-begin (cdar clauses))
							 | 
						||
| 
								 | 
							
								                  (cons 'cond (cdr clauses)))))))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								; This procedure replaces the system default read-eval-print loop:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(define top-level-driver
							 | 
						||
| 
								 | 
							
								  (lambda ()
							 | 
						||
| 
								 | 
							
								    (write '>)
							 | 
						||
| 
								 | 
							
								    ((lambda (exp)
							 | 
						||
| 
								 | 
							
								       (if (eq? the-eof-object exp)
							 | 
						||
| 
								 | 
							
								           (set! top-level-driver nil)
							 | 
						||
| 
								 | 
							
								           (print (eval (macroexpand exp)))))
							 | 
						||
| 
								 | 
							
								     (read))))
							 |