adding #b, #o, #d, #x numeric literals
accepting r6rs IEEE literals +-nan.0 and +-inf.0 printing distinguished -0.0, indicating float with .0f instead of #float, double with .0 instead of #double more renaming (? on predicates, ! on mutating operators) changing T to #t :( all those #s are so ugly
This commit is contained in:
		
							parent
							
								
									a55b46e9a6
								
							
						
					
					
						commit
						17d81eb4e6
					
				| 
						 | 
				
			
			@ -10,23 +10,23 @@
 | 
			
		|||
    (cons item lst)))
 | 
			
		||||
 | 
			
		||||
(define (index-of item lst start)
 | 
			
		||||
  (cond ((null lst) #f)
 | 
			
		||||
  (cond ((null? lst) #f)
 | 
			
		||||
	((eq item (car lst)) start)
 | 
			
		||||
	(T (index-of item (cdr lst) (+ start 1)))))
 | 
			
		||||
	(#t (index-of item (cdr lst) (+ start 1)))))
 | 
			
		||||
 | 
			
		||||
(define (each f l)
 | 
			
		||||
  (if (null l) l
 | 
			
		||||
  (if (null? l) l
 | 
			
		||||
    (begin (f (car l))
 | 
			
		||||
           (each f (cdr l)))))
 | 
			
		||||
 | 
			
		||||
(define (maptree-pre f tr)
 | 
			
		||||
  (let ((new-t (f tr)))
 | 
			
		||||
    (if (consp new-t)
 | 
			
		||||
    (if (pair? new-t)
 | 
			
		||||
        (map (lambda (e) (maptree-pre f e)) new-t)
 | 
			
		||||
      new-t)))
 | 
			
		||||
 | 
			
		||||
(define (maptree-post f tr)
 | 
			
		||||
  (if (not (consp tr))
 | 
			
		||||
  (if (not (pair? tr))
 | 
			
		||||
      (f tr)
 | 
			
		||||
    (let ((new-t (map (lambda (e) (maptree-post f e)) tr)))
 | 
			
		||||
      (f new-t))))
 | 
			
		||||
| 
						 | 
				
			
			@ -70,10 +70,10 @@
 | 
			
		|||
; collapse forms like (&& (&& (&& (&& a b) c) d) e) to (&& a b c d e)
 | 
			
		||||
(define (flatten-left-op op e)
 | 
			
		||||
  (maptree-post (lambda (node)
 | 
			
		||||
                  (if (and (consp node)
 | 
			
		||||
                  (if (and (pair? node)
 | 
			
		||||
                           (eq (car node) op)
 | 
			
		||||
                           (consp (cdr node))
 | 
			
		||||
                           (consp (cadr node))
 | 
			
		||||
                           (pair? (cdr node))
 | 
			
		||||
                           (pair? (cadr node))
 | 
			
		||||
                           (eq (caadr node) op))
 | 
			
		||||
                      (cons op
 | 
			
		||||
                            (append (cdadr node) (cddr node)))
 | 
			
		||||
| 
						 | 
				
			
			@ -85,31 +85,31 @@
 | 
			
		|||
; name is just there for reference
 | 
			
		||||
; this assumes lambda is the only remaining naming form
 | 
			
		||||
(define (lookup-var v env lev)
 | 
			
		||||
  (if (null env) v
 | 
			
		||||
  (if (null? env) v
 | 
			
		||||
    (let ((i (index-of v (car env) 0)))
 | 
			
		||||
      (if i (list 'lexref lev i v)
 | 
			
		||||
        (lookup-var v (cdr env) (+ lev 1))))))
 | 
			
		||||
(define (lvc- e env)
 | 
			
		||||
  (cond ((symbolp e) (lookup-var e env 0))
 | 
			
		||||
        ((consp e)
 | 
			
		||||
  (cond ((symbol? e) (lookup-var e env 0))
 | 
			
		||||
        ((pair? e)
 | 
			
		||||
         (if (eq (car e) 'quote)
 | 
			
		||||
             e
 | 
			
		||||
           (let* ((newvs (and (eq (car e) 'lambda) (cadr e)))
 | 
			
		||||
                  (newenv (if newvs (cons newvs env) env)))
 | 
			
		||||
             (if newvs
 | 
			
		||||
                 (cons 'lambda
 | 
			
		||||
                       (cons (cadr e)
 | 
			
		||||
                             (map (lambda (se) (lvc- se newenv))
 | 
			
		||||
                                  (cddr e))))
 | 
			
		||||
               (map (lambda (se) (lvc- se env)) e)))))
 | 
			
		||||
        (T e)))
 | 
			
		||||
	     (let* ((newvs (and (eq (car e) 'lambda) (cadr e)))
 | 
			
		||||
		    (newenv (if newvs (cons newvs env) env)))
 | 
			
		||||
	       (if newvs
 | 
			
		||||
		   (cons 'lambda
 | 
			
		||||
			 (cons (cadr e)
 | 
			
		||||
			       (map (lambda (se) (lvc- se newenv))
 | 
			
		||||
				    (cddr e))))
 | 
			
		||||
		   (map (lambda (se) (lvc- se env)) e)))))
 | 
			
		||||
        (#t e)))
 | 
			
		||||
(define (lexical-var-conversion e)
 | 
			
		||||
  (lvc- e ()))
 | 
			
		||||
 | 
			
		||||
; convert let to lambda
 | 
			
		||||
(define (let-expand e)
 | 
			
		||||
  (maptree-post (lambda (n)
 | 
			
		||||
		  (if (and (consp n) (eq (car n) 'let))
 | 
			
		||||
		  (if (and (pair? n) (eq (car n) 'let))
 | 
			
		||||
		      `((lambda ,(map car (cadr n)) ,@(cddr n))
 | 
			
		||||
			,@(map cadr (cadr n)))
 | 
			
		||||
                    n))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,11 +3,11 @@
 | 
			
		|||
; by Jeff Bezanson
 | 
			
		||||
 | 
			
		||||
(define (unique lst)
 | 
			
		||||
  (if (null lst)
 | 
			
		||||
  (if (null? lst)
 | 
			
		||||
      ()
 | 
			
		||||
    (cons (car lst)
 | 
			
		||||
          (filter (lambda (x) (not (eq x (car lst))))
 | 
			
		||||
                  (unique (cdr lst))))))
 | 
			
		||||
      (cons (car lst)
 | 
			
		||||
	    (filter (lambda (x) (not (eq x (car lst))))
 | 
			
		||||
		    (unique (cdr lst))))))
 | 
			
		||||
 | 
			
		||||
; list of special pattern symbols that cannot be variable names
 | 
			
		||||
(define metasymbols '(_ ...))
 | 
			
		||||
| 
						 | 
				
			
			@ -39,18 +39,18 @@
 | 
			
		|||
; This is NP-complete. Be careful.
 | 
			
		||||
;
 | 
			
		||||
(define (match- p expr state)
 | 
			
		||||
  (cond ((symbolp p)
 | 
			
		||||
  (cond ((symbol? p)
 | 
			
		||||
	 (cond ((eq p '_) state)
 | 
			
		||||
	       (T
 | 
			
		||||
	       (#t
 | 
			
		||||
		(let ((capt (assq p state)))
 | 
			
		||||
		  (if capt
 | 
			
		||||
		      (and (equal expr (cdr capt)) state)
 | 
			
		||||
                    (cons (cons p expr) state))))))
 | 
			
		||||
		      (cons (cons p expr) state))))))
 | 
			
		||||
	
 | 
			
		||||
	((function? p)
 | 
			
		||||
	((procedure? p)
 | 
			
		||||
	 (and (p expr) state))
 | 
			
		||||
	
 | 
			
		||||
	((consp p)
 | 
			
		||||
	((pair? p)
 | 
			
		||||
	 (cond ((eq (car p) '-/)  (and (equal (cadr p) expr)             state))
 | 
			
		||||
	       ((eq (car p) '-^)  (and (not (match- (cadr p) expr state)) state))
 | 
			
		||||
	       ((eq (car p) '--)
 | 
			
		||||
| 
						 | 
				
			
			@ -58,43 +58,43 @@
 | 
			
		|||
		     (cons (cons (cadr p) expr) state)))
 | 
			
		||||
	       ((eq (car p) '-$)  ; greedy alternation for toplevel pattern
 | 
			
		||||
		(match-alt (cdr p) () (list expr) state #f 1))
 | 
			
		||||
	       (T
 | 
			
		||||
		(and (consp expr)
 | 
			
		||||
	       (#t
 | 
			
		||||
		(and (pair? expr)
 | 
			
		||||
		     (equal (car p) (car expr))
 | 
			
		||||
		     (match-seq (cdr p) (cdr expr) state (length (cdr expr)))))))
 | 
			
		||||
	
 | 
			
		||||
	(T
 | 
			
		||||
	(#t
 | 
			
		||||
	 (and (equal p expr) state))))
 | 
			
		||||
 | 
			
		||||
; match an alternation
 | 
			
		||||
(define (match-alt alt prest expr state var L)
 | 
			
		||||
  (if (null alt) #f  ; no alternatives left
 | 
			
		||||
    (let ((subma (match- (car alt) (car expr) state)))
 | 
			
		||||
      (or (and subma
 | 
			
		||||
               (match-seq prest (cdr expr)
 | 
			
		||||
                          (if var
 | 
			
		||||
                              (cons (cons var (car expr))
 | 
			
		||||
                                    subma)
 | 
			
		||||
                            subma)
 | 
			
		||||
                          (- L 1)))
 | 
			
		||||
          (match-alt (cdr alt) prest expr state var L)))))
 | 
			
		||||
  (if (null? alt) #f  ; no alternatives left
 | 
			
		||||
      (let ((subma (match- (car alt) (car expr) state)))
 | 
			
		||||
	(or (and subma
 | 
			
		||||
		 (match-seq prest (cdr expr)
 | 
			
		||||
			    (if var
 | 
			
		||||
				(cons (cons var (car expr))
 | 
			
		||||
				      subma)
 | 
			
		||||
				subma)
 | 
			
		||||
			    (- L 1)))
 | 
			
		||||
	    (match-alt (cdr alt) prest expr state var L)))))
 | 
			
		||||
 | 
			
		||||
; match generalized kleene star (try consuming min to max)
 | 
			
		||||
(define (match-star- p prest expr state var min max L sofar)
 | 
			
		||||
  (cond ; case 0: impossible to match
 | 
			
		||||
   ((> min max) #f)
 | 
			
		||||
    ; case 1: only allowed to match 0 subexpressions
 | 
			
		||||
   ; case 1: only allowed to match 0 subexpressions
 | 
			
		||||
   ((= max 0) (match-seq prest expr
 | 
			
		||||
                         (if var (cons (cons var (reverse sofar)) state)
 | 
			
		||||
                           state)
 | 
			
		||||
			     state)
 | 
			
		||||
                         L))
 | 
			
		||||
    ; case 2: must match at least 1
 | 
			
		||||
   ; case 2: must match at least 1
 | 
			
		||||
   ((> min 0)
 | 
			
		||||
    (and (match- p (car expr) state)
 | 
			
		||||
         (match-star- p prest (cdr expr) state var (- min 1) (- max 1) (- L 1)
 | 
			
		||||
                      (cons (car expr) sofar))))
 | 
			
		||||
    ; otherwise, must match either 0 or between 1 and max subexpressions
 | 
			
		||||
   (T
 | 
			
		||||
   ; otherwise, must match either 0 or between 1 and max subexpressions
 | 
			
		||||
   (#t
 | 
			
		||||
    (or (match-star- p prest expr state var 0 0   L sofar)
 | 
			
		||||
        (match-star- p prest expr state var 1 max L sofar)))))
 | 
			
		||||
(define (match-star p prest expr state var min max L) 
 | 
			
		||||
| 
						 | 
				
			
			@ -103,16 +103,16 @@
 | 
			
		|||
; match sequences of expressions
 | 
			
		||||
(define (match-seq p expr state L)
 | 
			
		||||
  (cond ((not state) #f)
 | 
			
		||||
	((null p) (if (null expr) state #f))
 | 
			
		||||
	(T
 | 
			
		||||
	((null? p) (if (null? expr) state #f))
 | 
			
		||||
	(#t
 | 
			
		||||
	 (let ((subp (car p))
 | 
			
		||||
	       (var  #f))
 | 
			
		||||
	   (if (and (consp subp)
 | 
			
		||||
	   (if (and (pair? subp)
 | 
			
		||||
		    (eq (car subp) '--))
 | 
			
		||||
	       (begin (set! var (cadr subp))
 | 
			
		||||
                      (set! subp (caddr subp)))
 | 
			
		||||
             #f)
 | 
			
		||||
	   (let ((head (if (consp subp) (car subp) ())))
 | 
			
		||||
	       #f)
 | 
			
		||||
	   (let ((head (if (pair? subp) (car subp) ())))
 | 
			
		||||
	     (cond ((eq subp '...)
 | 
			
		||||
		    (match-star '_ (cdr p) expr state var 0 L L))
 | 
			
		||||
		   ((eq head '-*)
 | 
			
		||||
| 
						 | 
				
			
			@ -123,8 +123,8 @@
 | 
			
		|||
		    (match-star (cadr subp) (cdr p) expr state var 0 1 L))
 | 
			
		||||
		   ((eq head '-$)
 | 
			
		||||
		    (match-alt (cdr subp) (cdr p) expr state var L))
 | 
			
		||||
		   (T
 | 
			
		||||
		    (and (consp expr)
 | 
			
		||||
		   (#t
 | 
			
		||||
		    (and (pair? expr)
 | 
			
		||||
			 (match-seq (cdr p) (cdr expr)
 | 
			
		||||
				    (match- (car p) (car expr) state)
 | 
			
		||||
				    (- L 1))))))))))
 | 
			
		||||
| 
						 | 
				
			
			@ -133,32 +133,32 @@
 | 
			
		|||
 | 
			
		||||
; given a pattern p, return the list of capturing variables it uses
 | 
			
		||||
(define (patargs- p)
 | 
			
		||||
  (cond ((and (symbolp p)
 | 
			
		||||
  (cond ((and (symbol? p)
 | 
			
		||||
              (not (member p metasymbols)))
 | 
			
		||||
         (list p))
 | 
			
		||||
        
 | 
			
		||||
        ((consp p)
 | 
			
		||||
        ((pair? p)
 | 
			
		||||
         (if (eq (car p) '-/)
 | 
			
		||||
             ()
 | 
			
		||||
           (unique (apply append (map patargs- (cdr p))))))
 | 
			
		||||
	     (unique (apply append (map patargs- (cdr p))))))
 | 
			
		||||
        
 | 
			
		||||
        (T ())))
 | 
			
		||||
        (#t ())))
 | 
			
		||||
(define (patargs p)
 | 
			
		||||
  (cons '__ (patargs- p)))
 | 
			
		||||
 | 
			
		||||
; try to transform expr using a pattern-lambda from plist
 | 
			
		||||
; returns the new expression, or expr if no matches
 | 
			
		||||
(define (apply-patterns plist expr)
 | 
			
		||||
  (if (null plist) expr
 | 
			
		||||
    (if (function? plist)
 | 
			
		||||
        (let ((enew (plist expr)))
 | 
			
		||||
          (if (not enew)
 | 
			
		||||
              expr
 | 
			
		||||
            enew))
 | 
			
		||||
      (let ((enew ((car plist) expr)))
 | 
			
		||||
        (if (not enew)
 | 
			
		||||
            (apply-patterns (cdr plist) expr)
 | 
			
		||||
          enew)))))
 | 
			
		||||
  (if (null? plist) expr
 | 
			
		||||
      (if (procedure? plist)
 | 
			
		||||
	  (let ((enew (plist expr)))
 | 
			
		||||
	    (if (not enew)
 | 
			
		||||
		expr
 | 
			
		||||
		enew))
 | 
			
		||||
	  (let ((enew ((car plist) expr)))
 | 
			
		||||
	    (if (not enew)
 | 
			
		||||
		(apply-patterns (cdr plist) expr)
 | 
			
		||||
		enew)))))
 | 
			
		||||
 | 
			
		||||
; top-down fixed-point macroexpansion. this is a typical algorithm,
 | 
			
		||||
; but it may leave some structure that matches a pattern unexpanded.
 | 
			
		||||
| 
						 | 
				
			
			@ -170,13 +170,12 @@
 | 
			
		|||
; (pattern-lambda (/ 2 3) '(/ 3 2)), (pattern-lambda (/ 3 2) '(/ 2 3))
 | 
			
		||||
; TODO: ignore quoted expressions
 | 
			
		||||
(define (pattern-expand plist expr)
 | 
			
		||||
  (if (not (consp expr))
 | 
			
		||||
  (if (not (pair? expr))
 | 
			
		||||
      expr
 | 
			
		||||
    (let ((enew (apply-patterns plist expr)))
 | 
			
		||||
      (if (eq enew expr)
 | 
			
		||||
	  ; expr didn't change; move to subexpressions
 | 
			
		||||
          (cons (car expr)
 | 
			
		||||
                (map (lambda (subex) (pattern-expand plist subex)) (cdr expr)))
 | 
			
		||||
	  ; expr changed; iterate
 | 
			
		||||
 | 
			
		||||
        (pattern-expand plist enew)))))
 | 
			
		||||
      (let ((enew (apply-patterns plist expr)))
 | 
			
		||||
	(if (eq enew expr)
 | 
			
		||||
            ; expr didn't change; move to subexpressions
 | 
			
		||||
	    (cons (car expr)
 | 
			
		||||
		  (map (lambda (subex) (pattern-expand plist subex)) (cdr expr)))
 | 
			
		||||
	    ; expr changed; iterate
 | 
			
		||||
	    (pattern-expand plist enew)))))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,9 +7,9 @@
 | 
			
		|||
; tree inspection utils
 | 
			
		||||
 | 
			
		||||
(define (assigned-var e)
 | 
			
		||||
  (and (consp e)
 | 
			
		||||
  (and (pair? e)
 | 
			
		||||
       (or (eq (car e) '<-) (eq (car e) 'ref=))
 | 
			
		||||
       (symbolp (cadr e))
 | 
			
		||||
       (symbol? (cadr e))
 | 
			
		||||
       (cadr e)))
 | 
			
		||||
 | 
			
		||||
(define (func-argnames f)
 | 
			
		||||
| 
						 | 
				
			
			@ -26,13 +26,13 @@
 | 
			
		|||
(define (dollarsign-transform e)
 | 
			
		||||
  (pattern-expand
 | 
			
		||||
   (pattern-lambda ($ lhs name)
 | 
			
		||||
		   (let* ((g (if (not (consp lhs)) lhs (r-gensym)))
 | 
			
		||||
			  (n (if (symbolp name)
 | 
			
		||||
		   (let* ((g (if (not (pair? lhs)) lhs (r-gensym)))
 | 
			
		||||
			  (n (if (symbol? name)
 | 
			
		||||
				 name ;(symbol->string name)
 | 
			
		||||
                               name))
 | 
			
		||||
			  (expr `(r-call
 | 
			
		||||
				  r-aref ,g (index-in-strlist ,n (r-call attr ,g "names")))))
 | 
			
		||||
		     (if (not (consp lhs))
 | 
			
		||||
		     (if (not (pair? lhs))
 | 
			
		||||
			 expr
 | 
			
		||||
                       `(r-block (ref= ,g ,lhs) ,expr))))
 | 
			
		||||
   e))
 | 
			
		||||
| 
						 | 
				
			
			@ -46,9 +46,9 @@
 | 
			
		|||
  (pattern-expand
 | 
			
		||||
   (pattern-lambda (-$ (<-  (r-call f lhs ...) rhs)
 | 
			
		||||
                       (<<- (r-call f lhs ...) rhs))
 | 
			
		||||
		   (let ((g  (if (consp rhs) (r-gensym) rhs))
 | 
			
		||||
		   (let ((g  (if (pair? rhs) (r-gensym) rhs))
 | 
			
		||||
                         (op (car __)))
 | 
			
		||||
		     `(r-block ,@(if (consp rhs) `((ref= ,g ,rhs)) ())
 | 
			
		||||
		     `(r-block ,@(if (pair? rhs) `((ref= ,g ,rhs)) ())
 | 
			
		||||
                               (,op ,lhs (r-call ,(symconcat f '<-) ,@(cddr (cadr __)) ,g))
 | 
			
		||||
                               ,g)))
 | 
			
		||||
   e))
 | 
			
		||||
| 
						 | 
				
			
			@ -68,10 +68,10 @@
 | 
			
		|||
; convert r function expressions to lambda
 | 
			
		||||
(define (normalize-r-functions e)
 | 
			
		||||
  (maptree-post (lambda (n)
 | 
			
		||||
		  (if (and (consp n) (eq (car n) 'function))
 | 
			
		||||
		  (if (and (pair? n) (eq (car n) 'function))
 | 
			
		||||
		      `(lambda ,(func-argnames n)
 | 
			
		||||
			 (r-block ,@(gen-default-inits (cadr n))
 | 
			
		||||
				  ,@(if (and (consp (caddr n))
 | 
			
		||||
				  ,@(if (and (pair? (caddr n))
 | 
			
		||||
					     (eq (car (caddr n)) 'r-block))
 | 
			
		||||
					(cdr (caddr n))
 | 
			
		||||
                                      (list (caddr n)))))
 | 
			
		||||
| 
						 | 
				
			
			@ -81,19 +81,19 @@
 | 
			
		|||
(define (find-assigned-vars n)
 | 
			
		||||
  (let ((vars ()))
 | 
			
		||||
    (maptree-pre (lambda (s)
 | 
			
		||||
		   (if (not (consp s)) s
 | 
			
		||||
		   (if (not (pair? s)) s
 | 
			
		||||
                     (cond ((eq (car s) 'lambda) ())
 | 
			
		||||
                           ((eq (car s) '<-)
 | 
			
		||||
                            (set! vars (list-adjoin (cadr s) vars))
 | 
			
		||||
                            (cddr s))
 | 
			
		||||
                           (T s))))
 | 
			
		||||
                           (#t s))))
 | 
			
		||||
		 n)
 | 
			
		||||
    vars))
 | 
			
		||||
 | 
			
		||||
; introduce let based on assignment statements
 | 
			
		||||
(define (letbind-locals e)
 | 
			
		||||
  (maptree-post (lambda (n)
 | 
			
		||||
                  (if (and (consp n) (eq (car n) 'lambda))
 | 
			
		||||
                  (if (and (pair? n) (eq (car n) 'lambda))
 | 
			
		||||
                      (let ((vars (find-assigned-vars (cddr n))))
 | 
			
		||||
                        `(lambda ,(cadr n) (let ,(map (lambda (v) (list v ()))
 | 
			
		||||
                                                      vars)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,23 +1,17 @@
 | 
			
		|||
; -*- scheme -*-
 | 
			
		||||
; uncomment for compatibility with CL
 | 
			
		||||
;(defun mapp (f l) (mapcar f l))
 | 
			
		||||
;(defmacro define (name &rest body)
 | 
			
		||||
;  (if (symbolp name)
 | 
			
		||||
;      (list 'setq name (car body))
 | 
			
		||||
;    (list 'defun (car name) (cdr name) (cons 'progn body))))
 | 
			
		||||
 | 
			
		||||
; dictionaries ----------------------------------------------------------------
 | 
			
		||||
(define (dict-new) ())
 | 
			
		||||
 | 
			
		||||
(define (dict-extend dl key value)
 | 
			
		||||
  (cond ((null dl)              (list (cons key value)))
 | 
			
		||||
        ((equal key (caar dl))  (cons (cons key value) (cdr dl)))
 | 
			
		||||
        (T (cons (car dl) (dict-extend (cdr dl) key value)))))
 | 
			
		||||
  (cond ((null? dl)              (list (cons key value)))
 | 
			
		||||
        ((equal? key (caar dl))  (cons (cons key value) (cdr dl)))
 | 
			
		||||
        (else (cons (car dl) (dict-extend (cdr dl) key value)))))
 | 
			
		||||
 | 
			
		||||
(define (dict-lookup dl key)
 | 
			
		||||
  (cond ((null dl)              ())
 | 
			
		||||
        ((equal key (caar dl))  (cdar dl))
 | 
			
		||||
        (T (dict-lookup (cdr dl) key))))
 | 
			
		||||
  (cond ((null? dl)              ())
 | 
			
		||||
        ((equal? key (caar dl))  (cdar dl))
 | 
			
		||||
        (else (dict-lookup (cdr dl) key))))
 | 
			
		||||
 | 
			
		||||
(define (dict-keys dl) (map car dl))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +33,7 @@
 | 
			
		|||
(define (graph-add-node g n1) (dict-extend g n1 ()))
 | 
			
		||||
 | 
			
		||||
(define (graph-from-edges edge-list)
 | 
			
		||||
  (if (null edge-list)
 | 
			
		||||
  (if (null? edge-list)
 | 
			
		||||
      (graph-empty)
 | 
			
		||||
    (graph-connect (graph-from-edges (cdr edge-list))
 | 
			
		||||
                   (caar edge-list)
 | 
			
		||||
| 
						 | 
				
			
			@ -52,17 +46,17 @@
 | 
			
		|||
        (map
 | 
			
		||||
         (lambda (n)
 | 
			
		||||
           (let ((color-pair (assq n coloring)))
 | 
			
		||||
             (if (consp color-pair) (cdr color-pair) ())))
 | 
			
		||||
             (if (pair? color-pair) (cdr color-pair) ())))
 | 
			
		||||
         (graph-neighbors g node-to-color)))))
 | 
			
		||||
 | 
			
		||||
(define (try-each f lst)
 | 
			
		||||
  (if (null lst) #f
 | 
			
		||||
  (if (null? lst) #f
 | 
			
		||||
      (let ((ret (f (car lst))))
 | 
			
		||||
	(if ret ret (try-each f (cdr lst))))))
 | 
			
		||||
 | 
			
		||||
(define (color-node g coloring colors uncolored-nodes color)
 | 
			
		||||
  (cond
 | 
			
		||||
   ((null uncolored-nodes) coloring)
 | 
			
		||||
   ((null? uncolored-nodes) coloring)
 | 
			
		||||
   ((node-colorable? g coloring (car uncolored-nodes) color)
 | 
			
		||||
    (let ((new-coloring
 | 
			
		||||
           (cons (cons (car uncolored-nodes) color) coloring)))
 | 
			
		||||
| 
						 | 
				
			
			@ -71,8 +65,8 @@
 | 
			
		|||
                colors)))))
 | 
			
		||||
 | 
			
		||||
(define (color-graph g colors)
 | 
			
		||||
  (if (null colors)
 | 
			
		||||
      (and (null (graph-nodes g)) ())
 | 
			
		||||
  (if (null? colors)
 | 
			
		||||
      (and (null? (graph-nodes g)) ())
 | 
			
		||||
      (color-node g () colors (graph-nodes g) (car colors))))
 | 
			
		||||
 | 
			
		||||
(define (color-pairs pairs colors)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
(define (cond->if form)
 | 
			
		||||
  (cond-clauses->if (cdr form)))
 | 
			
		||||
(define (cond-clauses->if lst)
 | 
			
		||||
  (if (atom lst)
 | 
			
		||||
  (if (atom? lst)
 | 
			
		||||
      lst
 | 
			
		||||
    (let ((clause (car lst)))
 | 
			
		||||
      `(if ,(car clause)
 | 
			
		||||
| 
						 | 
				
			
			@ -10,11 +10,11 @@
 | 
			
		|||
         ,(cond-clauses->if (cdr lst))))))
 | 
			
		||||
 | 
			
		||||
(define (begin->cps forms k)
 | 
			
		||||
  (cond ((atom forms)       `(,k ,forms))
 | 
			
		||||
        ((null (cdr forms)) (cps- (car forms) k))
 | 
			
		||||
        (T (let ((_ (gensym)))   ; var to bind ignored value
 | 
			
		||||
             (cps- (car forms) `(lambda (,_)
 | 
			
		||||
                                  ,(begin->cps (cdr forms) k)))))))
 | 
			
		||||
  (cond ((atom? forms)       `(,k ,forms))
 | 
			
		||||
        ((null? (cdr forms))  (cps- (car forms) k))
 | 
			
		||||
        (#t (let ((_ (gensym)))   ; var to bind ignored value
 | 
			
		||||
	      (cps- (car forms) `(lambda (,_)
 | 
			
		||||
				   ,(begin->cps (cdr forms) k)))))))
 | 
			
		||||
 | 
			
		||||
(define-macro (lambda/cc args body)
 | 
			
		||||
  `(rplaca (lambda ,args ,body) 'lambda/cc))
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +44,7 @@
 | 
			
		|||
 | 
			
		||||
(define (rest->cps xformer form k argsyms)
 | 
			
		||||
  (let ((el (car form)))
 | 
			
		||||
    (if (or (atom el) (constant? el))
 | 
			
		||||
    (if (or (atom? el) (constant? el))
 | 
			
		||||
        (xformer (cdr form) k (cons el argsyms))
 | 
			
		||||
      (let ((g (gensym)))
 | 
			
		||||
        (cps- el `(lambda (,g)
 | 
			
		||||
| 
						 | 
				
			
			@ -58,17 +58,17 @@
 | 
			
		|||
 | 
			
		||||
; (f x) => (cps- f `(lambda (F) ,(cps- x `(lambda (X) (F ,k X)))))
 | 
			
		||||
(define (app->cps form k argsyms)
 | 
			
		||||
  (cond ((atom form)
 | 
			
		||||
  (cond ((atom? form)
 | 
			
		||||
         (let ((r (reverse argsyms)))
 | 
			
		||||
           (make-funcall/cc (car r) k (cdr r))))
 | 
			
		||||
        (T (rest->cps app->cps form k argsyms))))
 | 
			
		||||
        (#t (rest->cps app->cps form k argsyms))))
 | 
			
		||||
 | 
			
		||||
; (+ x) => (cps- x `(lambda (X) (,k (+ X))))
 | 
			
		||||
(define (builtincall->cps form k)
 | 
			
		||||
  (prim->cps (cdr form) k (list (car form))))
 | 
			
		||||
(define (prim->cps form k argsyms)
 | 
			
		||||
  (cond ((atom form) `(,k ,(reverse argsyms)))
 | 
			
		||||
        (T           (rest->cps prim->cps form k argsyms))))
 | 
			
		||||
  (cond ((atom? form) `(,k ,(reverse argsyms)))
 | 
			
		||||
        (#t           (rest->cps prim->cps form k argsyms))))
 | 
			
		||||
 | 
			
		||||
(define *top-k* (gensym))
 | 
			
		||||
(set *top-k* identity)
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +80,7 @@
 | 
			
		|||
     (cps- (macroexpand form) *top-k*)))))
 | 
			
		||||
(define (cps- form k)
 | 
			
		||||
  (let ((g (gensym)))
 | 
			
		||||
    (cond ((or (atom form) (constant? form))
 | 
			
		||||
    (cond ((or (atom? form) (constant? form))
 | 
			
		||||
           `(,k ,form))
 | 
			
		||||
 | 
			
		||||
          ((eq (car form) 'lambda)
 | 
			
		||||
| 
						 | 
				
			
			@ -96,7 +96,7 @@
 | 
			
		|||
           (let ((test (cadr form))
 | 
			
		||||
                 (then (caddr form))
 | 
			
		||||
                 (else (cadddr form)))
 | 
			
		||||
             (if (atom k)
 | 
			
		||||
             (if (atom? k)
 | 
			
		||||
                 (cps- test `(lambda (,g)
 | 
			
		||||
                               (if ,g
 | 
			
		||||
                                   ,(cps- then k)
 | 
			
		||||
| 
						 | 
				
			
			@ -105,9 +105,9 @@
 | 
			
		|||
                  ,(cps- form g)))))
 | 
			
		||||
 | 
			
		||||
          ((eq (car form) 'and)
 | 
			
		||||
           (cond ((atom (cdr  form)) `(,k T))
 | 
			
		||||
                 ((atom (cddr form)) (cps- (cadr form) k))
 | 
			
		||||
                 (T
 | 
			
		||||
           (cond ((atom? (cdr  form)) `(,k #t))
 | 
			
		||||
                 ((atom? (cddr form)) (cps- (cadr form) k))
 | 
			
		||||
                 (#t
 | 
			
		||||
                  (if (atom k)
 | 
			
		||||
                      (cps- (cadr form)
 | 
			
		||||
                            `(lambda (,g)
 | 
			
		||||
| 
						 | 
				
			
			@ -117,10 +117,10 @@
 | 
			
		|||
                       ,(cps- form g))))))
 | 
			
		||||
 | 
			
		||||
          ((eq (car form) 'or)
 | 
			
		||||
           (cond ((atom (cdr  form)) `(,k #f))
 | 
			
		||||
                 ((atom (cddr form)) (cps- (cadr form) k))
 | 
			
		||||
                 (T
 | 
			
		||||
                  (if (atom k)
 | 
			
		||||
           (cond ((atom? (cdr  form)) `(,k #f))
 | 
			
		||||
                 ((atom? (cddr form)) (cps- (cadr form) k))
 | 
			
		||||
                 (#t
 | 
			
		||||
                  (if (atom? k)
 | 
			
		||||
                      (cps- (cadr form)
 | 
			
		||||
                            `(lambda (,g)
 | 
			
		||||
                               (if ,g (,k ,g)
 | 
			
		||||
| 
						 | 
				
			
			@ -168,23 +168,23 @@
 | 
			
		|||
                (eq (caar form) 'lambda))
 | 
			
		||||
           (let ((largs (cadr (car form)))
 | 
			
		||||
                 (lbody (caddr (car form))))
 | 
			
		||||
             (cond ((null largs)    ; ((lambda () body))
 | 
			
		||||
             (cond ((null? largs)   ; ((lambda () body))
 | 
			
		||||
                    (cps- lbody k))
 | 
			
		||||
                   ((symbolp largs) ; ((lambda x body) args...)
 | 
			
		||||
                   ((symbol? largs) ; ((lambda x body) args...)
 | 
			
		||||
                    (cps- `((lambda (,largs) ,lbody) (list ,@(cdr form))) k))
 | 
			
		||||
                   (T
 | 
			
		||||
                   (#t
 | 
			
		||||
                    (cps- (cadr form) `(lambda (,(car largs))
 | 
			
		||||
                                         ,(cps- `((lambda ,(cdr largs) ,lbody)
 | 
			
		||||
                                                  ,@(cddr form))
 | 
			
		||||
                                                k)))))))
 | 
			
		||||
 | 
			
		||||
          (T
 | 
			
		||||
          (#t
 | 
			
		||||
           (app->cps form k ())))))
 | 
			
		||||
 | 
			
		||||
; (lambda (args...) (f args...)) => f
 | 
			
		||||
; but only for constant, builtin f
 | 
			
		||||
(define (η-reduce form)
 | 
			
		||||
  (cond ((or (atom form) (constant? form)) form)
 | 
			
		||||
  (cond ((or (atom? form) (constant? form)) form)
 | 
			
		||||
        ((and (eq (car form) 'lambda)
 | 
			
		||||
              (let ((body (caddr form))
 | 
			
		||||
                    (args (cadr form)))
 | 
			
		||||
| 
						 | 
				
			
			@ -192,16 +192,16 @@
 | 
			
		|||
                     (equal (cdr body) args)
 | 
			
		||||
                     (constant? (car (caddr form))))))
 | 
			
		||||
         (car (caddr form)))
 | 
			
		||||
        (T (map η-reduce form))))
 | 
			
		||||
        (#t (map η-reduce form))))
 | 
			
		||||
 | 
			
		||||
(define (contains x form)
 | 
			
		||||
  (or (eq form x)
 | 
			
		||||
      (any (lambda (p) (contains x p)) form)))
 | 
			
		||||
 | 
			
		||||
(define (β-reduce form)
 | 
			
		||||
  (if (or (atom form) (constant? form))
 | 
			
		||||
  (if (or (atom? form) (constant? form))
 | 
			
		||||
      form
 | 
			
		||||
    (β-reduce- (map β-reduce form))))
 | 
			
		||||
      (β-reduce- (map β-reduce form))))
 | 
			
		||||
 | 
			
		||||
(define (β-reduce- form)
 | 
			
		||||
        ; ((lambda (f) (f arg)) X) => (X arg)
 | 
			
		||||
| 
						 | 
				
			
			@ -215,7 +215,7 @@
 | 
			
		|||
                     (= (length args) 1)
 | 
			
		||||
                     (eq (car body) (car args))
 | 
			
		||||
                     (not (eq (cadr body) (car args)))
 | 
			
		||||
                     (symbolp (cadr body)))))
 | 
			
		||||
                     (symbol? (cadr body)))))
 | 
			
		||||
         `(,(cadr form)
 | 
			
		||||
           ,(cadr (caddr (car form)))))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -230,7 +230,7 @@
 | 
			
		|||
        ((and (= (length form) 2)
 | 
			
		||||
              (pair? (car form))
 | 
			
		||||
              (eq (caar form) 'lambda)
 | 
			
		||||
              (or (atom (cadr form)) (constant? (cadr form)))
 | 
			
		||||
              (or (atom? (cadr form)) (constant? (cadr form)))
 | 
			
		||||
              (let ((args (cadr (car form)))
 | 
			
		||||
                    (s (cadr form))
 | 
			
		||||
                    (body (caddr (car form))))
 | 
			
		||||
| 
						 | 
				
			
			@ -247,7 +247,7 @@
 | 
			
		|||
                              ,s
 | 
			
		||||
                              ,@params)))))))
 | 
			
		||||
 | 
			
		||||
        (T form)))
 | 
			
		||||
        (#t form)))
 | 
			
		||||
 | 
			
		||||
(define-macro (with-delimited-continuations . code)
 | 
			
		||||
  (cps (f-body code)))
 | 
			
		||||
| 
						 | 
				
			
			@ -287,7 +287,7 @@
 | 
			
		|||
          (cons 'a (reset (cons 'b (shift f (cons 1 (f (f (cons 'c ())))))))))
 | 
			
		||||
         '(a 1 b b c)))
 | 
			
		||||
 | 
			
		||||
T
 | 
			
		||||
#t
 | 
			
		||||
 | 
			
		||||
#|
 | 
			
		||||
todo:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -791,7 +791,7 @@ static value_t cvalue_array_aset(value_t *args)
 | 
			
		|||
{
 | 
			
		||||
    char *data; ulong_t index;
 | 
			
		||||
    fltype_t *eltype = cv_class((cvalue_t*)ptr(args[0]))->eltype;
 | 
			
		||||
    check_addr_args("aset", args[0], args[1], &data, &index);
 | 
			
		||||
    check_addr_args("aset!", args[0], args[1], &data, &index);
 | 
			
		||||
    char *dest = data + index*eltype->size;
 | 
			
		||||
    cvalue_init(eltype, args[2], dest);
 | 
			
		||||
    return args[2];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,7 +60,7 @@ static char *builtin_names[] =
 | 
			
		|||
      "cons", "list", "car", "cdr", "set-car!", "set-cdr!",
 | 
			
		||||
      "eval", "eval*", "apply", "prog1", "raise",
 | 
			
		||||
      "+", "-", "*", "/", "<", "~", "&", "!", "$",
 | 
			
		||||
      "vector", "aref", "aset", "length", "assq", "compare", "for",
 | 
			
		||||
      "vector", "aref", "aset!", "length", "assq", "compare", "for",
 | 
			
		||||
      "", "", "" };
 | 
			
		||||
 | 
			
		||||
#define N_STACK 98304
 | 
			
		||||
| 
						 | 
				
			
			@ -1004,19 +1004,19 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
 | 
			
		|||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case F_ASET:
 | 
			
		||||
            argcount("aset", nargs, 3);
 | 
			
		||||
            argcount("aset!", nargs, 3);
 | 
			
		||||
            e = Stack[SP-3];
 | 
			
		||||
            if (isvector(e)) {
 | 
			
		||||
                i = tofixnum(Stack[SP-2], "aset");
 | 
			
		||||
                i = tofixnum(Stack[SP-2], "aset!");
 | 
			
		||||
                if (__unlikely((unsigned)i >= vector_size(e)))
 | 
			
		||||
                    bounds_error("aref", v, Stack[SP-1]);
 | 
			
		||||
                    bounds_error("aset!", v, Stack[SP-1]);
 | 
			
		||||
                vector_elt(e, i) = (v=Stack[SP-1]);
 | 
			
		||||
            }
 | 
			
		||||
            else if (isarray(e)) {
 | 
			
		||||
                v = cvalue_array_aset(&Stack[SP-3]);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                type_error("aset", "sequence", e);
 | 
			
		||||
                type_error("aset!", "sequence", e);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case F_ATOM:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -520,14 +520,22 @@ static void cvalue_printdata(ios_t *f, void *data, size_t len, value_t type,
 | 
			
		|||
            else
 | 
			
		||||
                HPOS+=ios_printf(f, "%s", rep);
 | 
			
		||||
        }
 | 
			
		||||
        else if (d == 0) {
 | 
			
		||||
            if (1/d < 0)
 | 
			
		||||
                HPOS+=ios_printf(f, "-0.0%s", type==floatsym?"f":"");
 | 
			
		||||
            else
 | 
			
		||||
                HPOS+=ios_printf(f, "0.0%s",  type==floatsym?"f":"");
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            snprint_real(buf, sizeof(buf), d, 0, ndec, 3, 10);
 | 
			
		||||
            if (weak || princ || strpbrk(buf, ".eE")) {
 | 
			
		||||
                outs(buf, f);
 | 
			
		||||
            int hasdec = (strpbrk(buf, ".eE") != NULL);
 | 
			
		||||
            outs(buf, f);
 | 
			
		||||
            if (weak || princ || hasdec) {
 | 
			
		||||
                if (type == floatsym) outc('f', f);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                HPOS+=ios_printf(f, "#%s(%s)", symbol_name(type), buf);
 | 
			
		||||
                if (!hasdec) outs(".0", f);
 | 
			
		||||
                if (type==floatsym) outc('f', f);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,16 @@ static int symchar(char c)
 | 
			
		|||
    return (!isspace(c) && !strchr(special, c));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int isnumtok(char *tok, value_t *pval)
 | 
			
		||||
static int isdigit_base(char c, int base)
 | 
			
		||||
{
 | 
			
		||||
    if (base < 11)
 | 
			
		||||
        return (c >= '0' && c < '0'+base);
 | 
			
		||||
    return ((c >= '0' && c <= '9') ||
 | 
			
		||||
            (c >= 'a' && c < 'a'+base-10) ||
 | 
			
		||||
            (c >= 'A' && c < 'A'+base-10));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int isnumtok_base(char *tok, value_t *pval, int base)
 | 
			
		||||
{
 | 
			
		||||
    char *end;
 | 
			
		||||
    int64_t i64;
 | 
			
		||||
| 
						 | 
				
			
			@ -24,50 +33,63 @@ static int isnumtok(char *tok, value_t *pval)
 | 
			
		|||
    double d;
 | 
			
		||||
    if (*tok == '\0')
 | 
			
		||||
        return 0;
 | 
			
		||||
    if (!(tok[0]=='0' && isdigit(tok[1])) &&
 | 
			
		||||
        strpbrk(tok, ".eEpP")) {
 | 
			
		||||
    if (strpbrk(tok, ".eEpP")) {
 | 
			
		||||
        d = strtod(tok, &end);
 | 
			
		||||
        if (*end == '\0') {
 | 
			
		||||
            if (pval) *pval = mk_double(d);
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
        if (end > tok && end[0] == 'f' && end[1] == '\0') {
 | 
			
		||||
        // floats can end in f or f0
 | 
			
		||||
        if (end > tok && end[0] == 'f' &&
 | 
			
		||||
            (end[1] == '\0' ||
 | 
			
		||||
             (end[1] == '0' && end[2] == '\0'))) {
 | 
			
		||||
            if (pval) *pval = mk_float((float)d);
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (tok[0] == '+') {
 | 
			
		||||
        if (!strcmp(tok,"+NaN")) {
 | 
			
		||||
        if (!strcmp(tok,"+NaN") || !strcasecmp(tok,"+nan.0")) {
 | 
			
		||||
            if (pval) *pval = mk_double(D_PNAN);
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
        if (!strcmp(tok,"+Inf")) {
 | 
			
		||||
        if (!strcmp(tok,"+Inf") || !strcasecmp(tok,"+inf.0")) {
 | 
			
		||||
            if (pval) *pval = mk_double(D_PINF);
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else if (tok[0] == '-') {
 | 
			
		||||
        if (!strcmp(tok,"-NaN")) {
 | 
			
		||||
        if (!strcmp(tok,"-NaN") || !strcasecmp(tok,"-nan.0")) {
 | 
			
		||||
            if (pval) *pval = mk_double(D_NNAN);
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
        if (!strcmp(tok,"-Inf")) {
 | 
			
		||||
        if (!strcmp(tok,"-Inf") || !strcasecmp(tok,"-inf.0")) {
 | 
			
		||||
            if (pval) *pval = mk_double(D_NINF);
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
        i64 = strtoll(tok, &end, 0);
 | 
			
		||||
        i64 = strtoll(tok, &end, base);
 | 
			
		||||
        if (pval) *pval = return_from_int64(i64);
 | 
			
		||||
        return (*end == '\0');
 | 
			
		||||
    }
 | 
			
		||||
    else if (!isdigit(tok[0])) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    ui64 = strtoull(tok, &end, 0);
 | 
			
		||||
    ui64 = strtoull(tok, &end, base);
 | 
			
		||||
    if (pval) *pval = return_from_uint64(ui64);
 | 
			
		||||
    return (*end == '\0');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int isnumtok(char *tok, value_t *pval)
 | 
			
		||||
{
 | 
			
		||||
    return isnumtok_base(tok, pval, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int read_numtok(char *tok, value_t *pval, int base)
 | 
			
		||||
{
 | 
			
		||||
    int result;
 | 
			
		||||
    errno = 0;
 | 
			
		||||
    result = isnumtok_base(tok, pval, base);
 | 
			
		||||
    if (errno) lerror(ParseError, "read: overflow in numeric constant");
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static u_int32_t toktype = TOK_NONE;
 | 
			
		||||
static value_t tokval;
 | 
			
		||||
static char buf[256];
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +170,7 @@ static u_int32_t peek(ios_t *f)
 | 
			
		|||
{
 | 
			
		||||
    char c, *end;
 | 
			
		||||
    fixnum_t x;
 | 
			
		||||
    int ch;
 | 
			
		||||
    int ch, base;
 | 
			
		||||
 | 
			
		||||
    if (toktype != TOK_NONE)
 | 
			
		||||
        return toktype;
 | 
			
		||||
| 
						 | 
				
			
			@ -176,30 +198,30 @@ static u_int32_t peek(ios_t *f)
 | 
			
		|||
        toktype = TOK_DOUBLEQUOTE;
 | 
			
		||||
    }
 | 
			
		||||
    else if (c == '#') {
 | 
			
		||||
        ch = ios_getc(f);
 | 
			
		||||
        ch = ios_getc(f); c = (char)ch;
 | 
			
		||||
        if (ch == IOS_EOF)
 | 
			
		||||
            lerror(ParseError, "read: invalid read macro");
 | 
			
		||||
        if ((char)ch == '.') {
 | 
			
		||||
        if (c == '.') {
 | 
			
		||||
            toktype = TOK_SHARPDOT;
 | 
			
		||||
        }
 | 
			
		||||
        else if ((char)ch == '\'') {
 | 
			
		||||
        else if (c == '\'') {
 | 
			
		||||
            toktype = TOK_SHARPQUOTE;
 | 
			
		||||
        }
 | 
			
		||||
        else if ((char)ch == '\\') {
 | 
			
		||||
        else if (c == '\\') {
 | 
			
		||||
            uint32_t cval;
 | 
			
		||||
            if (ios_getutf8(f, &cval) == IOS_EOF)
 | 
			
		||||
                lerror(ParseError, "read: end of input in character constant");
 | 
			
		||||
            toktype = TOK_NUM;
 | 
			
		||||
            tokval = mk_wchar(cval);
 | 
			
		||||
        }
 | 
			
		||||
        else if ((char)ch == '(') {
 | 
			
		||||
        else if (c == '(') {
 | 
			
		||||
            toktype = TOK_SHARPOPEN;
 | 
			
		||||
        }
 | 
			
		||||
        else if ((char)ch == '<') {
 | 
			
		||||
        else if (c == '<') {
 | 
			
		||||
            lerror(ParseError, "read: unreadable object");
 | 
			
		||||
        }
 | 
			
		||||
        else if (isdigit((char)ch)) {
 | 
			
		||||
            read_token(f, (char)ch, 1);
 | 
			
		||||
        else if (isdigit(c)) {
 | 
			
		||||
            read_token(f, c, 1);
 | 
			
		||||
            c = (char)ios_getc(f);
 | 
			
		||||
            if (c == '#')
 | 
			
		||||
                toktype = TOK_BACKREF;
 | 
			
		||||
| 
						 | 
				
			
			@ -213,14 +235,14 @@ static u_int32_t peek(ios_t *f)
 | 
			
		|||
                lerror(ParseError, "read: invalid label");
 | 
			
		||||
            tokval = fixnum(x);
 | 
			
		||||
        }
 | 
			
		||||
        else if ((char)ch == '!') {
 | 
			
		||||
        else if (c == '!') {
 | 
			
		||||
            // #! single line comment for shbang script support
 | 
			
		||||
            do {
 | 
			
		||||
                ch = ios_getc(f);
 | 
			
		||||
            } while (ch != IOS_EOF && (char)ch != '\n');
 | 
			
		||||
            return peek(f);
 | 
			
		||||
        }
 | 
			
		||||
        else if ((char)ch == '|') {
 | 
			
		||||
        else if (c == '|') {
 | 
			
		||||
            // multiline comment
 | 
			
		||||
            int commentlevel=1;
 | 
			
		||||
            while (1) {
 | 
			
		||||
| 
						 | 
				
			
			@ -250,10 +272,10 @@ static u_int32_t peek(ios_t *f)
 | 
			
		|||
            // this was whitespace, so keep peeking
 | 
			
		||||
            return peek(f);
 | 
			
		||||
        }
 | 
			
		||||
        else if ((char)ch == ';') {
 | 
			
		||||
        else if (c == ';') {
 | 
			
		||||
            toktype = TOK_SHARPSEMI;
 | 
			
		||||
        }
 | 
			
		||||
        else if ((char)ch == ':') {
 | 
			
		||||
        else if (c == ':') {
 | 
			
		||||
            // gensym
 | 
			
		||||
            ch = ios_getc(f);
 | 
			
		||||
            if ((char)ch == 'g')
 | 
			
		||||
| 
						 | 
				
			
			@ -266,8 +288,18 @@ static u_int32_t peek(ios_t *f)
 | 
			
		|||
            toktype = TOK_GENSYM;
 | 
			
		||||
            tokval = fixnum(x);
 | 
			
		||||
        }
 | 
			
		||||
        else if (symchar((char)ch)) {
 | 
			
		||||
        else if (symchar(c)) {
 | 
			
		||||
            read_token(f, ch, 0);
 | 
			
		||||
 | 
			
		||||
            if (((c == 'b' && (base= 2)) ||
 | 
			
		||||
                 (c == 'o' && (base= 8)) ||
 | 
			
		||||
                 (c == 'd' && (base=10)) ||
 | 
			
		||||
                 (c == 'x' && (base=16))) && isdigit_base(buf[1],base)) {
 | 
			
		||||
                if (!read_numtok(&buf[1], &tokval, base))
 | 
			
		||||
                    lerror(ParseError, "read: invalid base %d constant", base);
 | 
			
		||||
                return (toktype=TOK_NUM);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            toktype = TOK_SHARPSYM;
 | 
			
		||||
            tokval = symbol(buf);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -293,12 +325,8 @@ static u_int32_t peek(ios_t *f)
 | 
			
		|||
                return (toktype=TOK_DOT);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                errno = 0;
 | 
			
		||||
                if (isnumtok(buf, &tokval)) {
 | 
			
		||||
                    if (errno)
 | 
			
		||||
                        lerror(ParseError,"read: overflow in numeric constant");
 | 
			
		||||
                if (read_numtok(buf, &tokval, 0))
 | 
			
		||||
                    return (toktype=TOK_NUM);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        toktype = TOK_SYM;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,28 +6,17 @@
 | 
			
		|||
(set-constant! 'eq       eq?)
 | 
			
		||||
(set-constant! 'eqv      eqv?)
 | 
			
		||||
(set-constant! 'equal    equal?)
 | 
			
		||||
(set-constant! 'booleanp boolean?)
 | 
			
		||||
(set-constant! 'consp    pair?)
 | 
			
		||||
(set-constant! 'null     null?)
 | 
			
		||||
(set-constant! 'atom     atom?)
 | 
			
		||||
(set-constant! 'symbolp  symbol?)
 | 
			
		||||
(set-constant! 'numberp  number?)
 | 
			
		||||
(set-constant! 'boundp   bound?)
 | 
			
		||||
(set-constant! 'builtinp builtin?)
 | 
			
		||||
(set-constant! 'vectorp  vector?)
 | 
			
		||||
(set-constant! 'fixnump  fixnum?)
 | 
			
		||||
(set-constant! 'rplaca   set-car!)
 | 
			
		||||
(set-constant! 'rplacd   set-cdr!)
 | 
			
		||||
(set-constant! 'char?    (lambda (x) (eq? (typeof x) 'wchar)))
 | 
			
		||||
(set-constant! 'T        #t)
 | 
			
		||||
 | 
			
		||||
; convert a sequence of body statements to a single expression.
 | 
			
		||||
; this allows define, defun, defmacro, let, etc. to contain multiple
 | 
			
		||||
; body expressions as in Common Lisp.
 | 
			
		||||
(set! f-body (lambda (e)
 | 
			
		||||
               (cond ((atom e)        e)
 | 
			
		||||
               (cond ((atom? e)       e)
 | 
			
		||||
                     ((eq (cdr e) ()) (car e))
 | 
			
		||||
                     (T               (cons 'begin e)))))
 | 
			
		||||
                     (#t              (cons 'begin e)))))
 | 
			
		||||
 | 
			
		||||
(set-syntax! 'define-macro
 | 
			
		||||
             (lambda (form . body)
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +27,7 @@
 | 
			
		|||
  (list (list 'lambda (list name) (list 'set! name fn)) #f))
 | 
			
		||||
 | 
			
		||||
(define-macro (define form . body)
 | 
			
		||||
  (if (symbolp form)
 | 
			
		||||
  (if (symbol? form)
 | 
			
		||||
      (list 'set! form (car body))
 | 
			
		||||
      (list 'set! (car form) (list 'lambda (cdr form) (f-body body)))))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -47,73 +36,73 @@
 | 
			
		|||
(define (identity x) x)
 | 
			
		||||
 | 
			
		||||
(define (map f lst)
 | 
			
		||||
  (if (atom lst) lst
 | 
			
		||||
  (if (atom? lst) lst
 | 
			
		||||
      (cons (f (car lst)) (map f (cdr lst)))))
 | 
			
		||||
 | 
			
		||||
(define-macro (let binds . body)
 | 
			
		||||
  (cons (list 'lambda
 | 
			
		||||
              (map (lambda (c) (if (consp c) (car c) c)) binds)
 | 
			
		||||
              (map (lambda (c) (if (pair? c) (car c) c)) binds)
 | 
			
		||||
              (f-body body))
 | 
			
		||||
        (map (lambda (c) (if (consp c) (cadr c) #f)) binds)))
 | 
			
		||||
        (map (lambda (c) (if (pair? c) (cadr c) #f)) binds)))
 | 
			
		||||
 | 
			
		||||
(define (nconc . lsts)
 | 
			
		||||
  (cond ((null lsts) ())
 | 
			
		||||
        ((null (cdr lsts)) (car lsts))
 | 
			
		||||
        ((null (car lsts)) (apply nconc (cdr lsts)))
 | 
			
		||||
        (T (prog1 (car lsts)
 | 
			
		||||
		  (rplacd (last (car lsts))
 | 
			
		||||
			  (apply nconc (cdr lsts)))))))
 | 
			
		||||
  (cond ((null? lsts) ())
 | 
			
		||||
        ((null? (cdr lsts)) (car lsts))
 | 
			
		||||
        ((null? (car lsts)) (apply nconc (cdr lsts)))
 | 
			
		||||
        (#t (prog1 (car lsts)
 | 
			
		||||
		   (rplacd (last (car lsts))
 | 
			
		||||
			   (apply nconc (cdr lsts)))))))
 | 
			
		||||
 | 
			
		||||
(define (append . lsts)
 | 
			
		||||
  (cond ((null lsts) ())
 | 
			
		||||
        ((null (cdr lsts)) (car lsts))
 | 
			
		||||
        (T ((label append2 (lambda (l d)
 | 
			
		||||
                             (if (null l) d
 | 
			
		||||
                               (cons (car l)
 | 
			
		||||
                                     (append2 (cdr l) d)))))
 | 
			
		||||
            (car lsts) (apply append (cdr lsts))))))
 | 
			
		||||
  (cond ((null? lsts) ())
 | 
			
		||||
        ((null? (cdr lsts)) (car lsts))
 | 
			
		||||
        (#t ((label append2 (lambda (l d)
 | 
			
		||||
			      (if (null? l) d
 | 
			
		||||
				  (cons (car l)
 | 
			
		||||
					(append2 (cdr l) d)))))
 | 
			
		||||
	     (car lsts) (apply append (cdr lsts))))))
 | 
			
		||||
 | 
			
		||||
(define (member item lst)
 | 
			
		||||
  (cond ((atom lst) #f)
 | 
			
		||||
        ((equal     (car lst) item) lst)
 | 
			
		||||
        (T          (member item (cdr lst)))))
 | 
			
		||||
  (cond ((atom? lst) #f)
 | 
			
		||||
        ((equal      (car lst) item) lst)
 | 
			
		||||
        (#t          (member item (cdr lst)))))
 | 
			
		||||
(define (memq item lst)
 | 
			
		||||
  (cond ((atom lst) #f)
 | 
			
		||||
        ((eq        (car lst) item) lst)
 | 
			
		||||
        (T          (memq item (cdr lst)))))
 | 
			
		||||
  (cond ((atom? lst) #f)
 | 
			
		||||
        ((eq         (car lst) item) lst)
 | 
			
		||||
        (#t          (memq item (cdr lst)))))
 | 
			
		||||
(define (memv item lst)
 | 
			
		||||
  (cond ((atom lst) #f)
 | 
			
		||||
        ((eqv       (car lst) item) lst)
 | 
			
		||||
        (T          (memv item (cdr lst)))))
 | 
			
		||||
  (cond ((atom? lst) #f)
 | 
			
		||||
        ((eqv        (car lst) item) lst)
 | 
			
		||||
        (#t          (memv item (cdr lst)))))
 | 
			
		||||
 | 
			
		||||
(define (assoc item lst)
 | 
			
		||||
  (cond ((atom lst) #f)
 | 
			
		||||
	((equal     (caar lst) item) (car lst))
 | 
			
		||||
	(T          (assoc item (cdr lst)))))
 | 
			
		||||
  (cond ((atom? lst) #f)
 | 
			
		||||
	((equal      (caar lst) item) (car lst))
 | 
			
		||||
	(#t          (assoc item (cdr lst)))))
 | 
			
		||||
(define (assv item lst)
 | 
			
		||||
  (cond ((atom lst) #f)
 | 
			
		||||
	((eqv       (caar lst) item) (car lst))
 | 
			
		||||
	(T          (assv item (cdr lst)))))
 | 
			
		||||
  (cond ((atom? lst) #f)
 | 
			
		||||
	((eqv        (caar lst) item) (car lst))
 | 
			
		||||
	(#t          (assv item (cdr lst)))))
 | 
			
		||||
 | 
			
		||||
(define (macrocall? e) (and (symbolp (car e))
 | 
			
		||||
(define (macrocall? e) (and (symbol? (car e))
 | 
			
		||||
			    (symbol-syntax (car e))))
 | 
			
		||||
 | 
			
		||||
(define (function? x)
 | 
			
		||||
  (or (builtinp x)
 | 
			
		||||
      (and (consp x) (eq (car x) 'lambda))))
 | 
			
		||||
  (or (builtin? x)
 | 
			
		||||
      (and (pair? x) (eq (car x) 'lambda))))
 | 
			
		||||
(define procedure? function?)
 | 
			
		||||
 | 
			
		||||
(define (macroexpand-1 e)
 | 
			
		||||
  (if (atom e) e
 | 
			
		||||
  (if (atom? e) e
 | 
			
		||||
      (let ((f (macrocall? e)))
 | 
			
		||||
	(if f (apply f (cdr e))
 | 
			
		||||
	    e))))
 | 
			
		||||
 | 
			
		||||
; convert to proper list, i.e. remove "dots", and append
 | 
			
		||||
(define (append.2 l tail)
 | 
			
		||||
  (cond ((null l)  tail)
 | 
			
		||||
        ((atom l)  (cons l tail))
 | 
			
		||||
        (T         (cons (car l) (append.2 (cdr l) tail)))))
 | 
			
		||||
  (cond ((null? l)  tail)
 | 
			
		||||
        ((atom? l)  (cons l tail))
 | 
			
		||||
        (#t         (cons (car l) (append.2 (cdr l) tail)))))
 | 
			
		||||
 | 
			
		||||
(define (cadr x) (car (cdr x)))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -124,27 +113,27 @@
 | 
			
		|||
  ((label mexpand
 | 
			
		||||
          (lambda (e env f)
 | 
			
		||||
            (begin
 | 
			
		||||
              (while (and (consp e)
 | 
			
		||||
              (while (and (pair? e)
 | 
			
		||||
                          (not (member (car e) env))
 | 
			
		||||
                          (set! f (macrocall? e)))
 | 
			
		||||
                (set! e (apply f (cdr e))))
 | 
			
		||||
              (cond ((and (consp e)
 | 
			
		||||
              (cond ((and (pair? e)
 | 
			
		||||
                          (not (eq (car e) 'quote)))
 | 
			
		||||
                     (let ((newenv
 | 
			
		||||
                            (if (and (eq (car e) 'lambda)
 | 
			
		||||
                                     (consp (cdr e)))
 | 
			
		||||
                                     (pair? (cdr e)))
 | 
			
		||||
                                (append.2 (cadr e) env)
 | 
			
		||||
                              env)))
 | 
			
		||||
                       (map (lambda (x) (mexpand x newenv ())) e)))
 | 
			
		||||
                    ;((and (symbolp e) (constant? e)) (eval e))
 | 
			
		||||
                    ;((and (symbolp e)
 | 
			
		||||
                    ;((and (symbol? e) (constant? e)) (eval e))
 | 
			
		||||
                    ;((and (symbol? e)
 | 
			
		||||
                    ;      (not (member e *special-forms*))
 | 
			
		||||
                    ;      (not (member e env))) (cons '%top e))
 | 
			
		||||
                    (T e)))))
 | 
			
		||||
                    (#t e)))))
 | 
			
		||||
   e () ()))
 | 
			
		||||
 | 
			
		||||
(define-macro (define form . body)
 | 
			
		||||
  (if (symbolp form)
 | 
			
		||||
  (if (symbol? form)
 | 
			
		||||
      (list 'set! form (car body))
 | 
			
		||||
      (list 'set! (car form)
 | 
			
		||||
	    (macroexpand (list 'lambda (cdr form) (f-body body))))))
 | 
			
		||||
| 
						 | 
				
			
			@ -163,6 +152,7 @@
 | 
			
		|||
(define (1+ n) (+ n 1))
 | 
			
		||||
(define (1- n) (- n 1))
 | 
			
		||||
(define (mod x y) (- x (* (/ x y) y)))
 | 
			
		||||
(define remainder mod)
 | 
			
		||||
(define (abs x)   (if (< x 0) (- x) x))
 | 
			
		||||
(define K prog1)  ; K combinator ;)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -180,99 +170,101 @@
 | 
			
		|||
(define (cdddr x) (cdr (cdr (cdr x))))
 | 
			
		||||
 | 
			
		||||
(define (every pred lst)
 | 
			
		||||
  (or (atom lst)
 | 
			
		||||
  (or (atom? lst)
 | 
			
		||||
      (and (pred (car lst))
 | 
			
		||||
           (every pred (cdr lst)))))
 | 
			
		||||
 | 
			
		||||
(define (any pred lst)
 | 
			
		||||
  (and (consp lst)
 | 
			
		||||
  (and (pair? lst)
 | 
			
		||||
       (or (pred (car lst))
 | 
			
		||||
           (any pred (cdr lst)))))
 | 
			
		||||
 | 
			
		||||
(define (listp a) (or (null a) (consp a)))
 | 
			
		||||
(define (list? a) (or (null a) (and (pair? a) (list? (cdr a)))))
 | 
			
		||||
(define (listp a) (or (null? a) (pair? a)))
 | 
			
		||||
(define (list? a) (or (null? a) (and (pair? a) (list? (cdr a)))))
 | 
			
		||||
 | 
			
		||||
(define (nthcdr lst n)
 | 
			
		||||
  (if (<= n 0) lst
 | 
			
		||||
      (nthcdr (cdr lst) (- n 1))))
 | 
			
		||||
(define list-tail nthcdr)
 | 
			
		||||
 | 
			
		||||
(define (list-ref lst n)
 | 
			
		||||
  (car (nthcdr lst n)))
 | 
			
		||||
 | 
			
		||||
(define (list* . l)
 | 
			
		||||
  (if (atom (cdr l))
 | 
			
		||||
  (if (atom? (cdr l))
 | 
			
		||||
      (car l)
 | 
			
		||||
      (cons (car l) (apply list* (cdr l)))))
 | 
			
		||||
 | 
			
		||||
(define (nlist* . l)
 | 
			
		||||
  (if (atom (cdr l))
 | 
			
		||||
  (if (atom? (cdr l))
 | 
			
		||||
      (car l)
 | 
			
		||||
      (rplacd l (apply nlist* (cdr l)))))
 | 
			
		||||
 | 
			
		||||
(define (lastcdr l)
 | 
			
		||||
  (if (atom l) l
 | 
			
		||||
  (if (atom? l) l
 | 
			
		||||
      (lastcdr (cdr l))))
 | 
			
		||||
 | 
			
		||||
(define (last l)
 | 
			
		||||
  (cond ((atom l)        l)
 | 
			
		||||
        ((atom (cdr l))  l)
 | 
			
		||||
        (T               (last (cdr l)))))
 | 
			
		||||
  (cond ((atom? l)        l)
 | 
			
		||||
        ((atom? (cdr l))  l)
 | 
			
		||||
        (#t               (last (cdr l)))))
 | 
			
		||||
(define last-pair last)
 | 
			
		||||
 | 
			
		||||
(define (map! f lst)
 | 
			
		||||
  (prog1 lst
 | 
			
		||||
	 (while (consp lst)
 | 
			
		||||
	 (while (pair? lst)
 | 
			
		||||
		(rplaca lst (f (car lst)))
 | 
			
		||||
		(set! lst (cdr lst)))))
 | 
			
		||||
 | 
			
		||||
(define (mapcar f . lsts)
 | 
			
		||||
  ((label mapcar-
 | 
			
		||||
          (lambda (lsts)
 | 
			
		||||
            (cond ((null lsts) (f))
 | 
			
		||||
                  ((atom (car lsts)) (car lsts))
 | 
			
		||||
                  (T (cons (apply f (map car lsts))
 | 
			
		||||
                           (mapcar- (map cdr lsts)))))))
 | 
			
		||||
            (cond ((null? lsts) (f))
 | 
			
		||||
                  ((atom? (car lsts)) (car lsts))
 | 
			
		||||
                  (#t (cons (apply f (map car lsts))
 | 
			
		||||
			    (mapcar- (map cdr lsts)))))))
 | 
			
		||||
   lsts))
 | 
			
		||||
 | 
			
		||||
(define (transpose M) (apply mapcar (cons list M)))
 | 
			
		||||
 | 
			
		||||
(define (filter pred lst) (filter- pred lst ()))
 | 
			
		||||
(define (filter- pred lst accum)
 | 
			
		||||
  (cond ((null lst) accum)
 | 
			
		||||
  (cond ((null? lst) accum)
 | 
			
		||||
        ((pred (car lst))
 | 
			
		||||
         (filter- pred (cdr lst) (cons (car lst) accum)))
 | 
			
		||||
        (T
 | 
			
		||||
        (#t
 | 
			
		||||
         (filter- pred (cdr lst) accum))))
 | 
			
		||||
 | 
			
		||||
(define (separate pred lst) (separate- pred lst () ()))
 | 
			
		||||
(define (separate- pred lst yes no)
 | 
			
		||||
  (cond ((null lst) (cons yes no))
 | 
			
		||||
  (cond ((null? lst) (cons yes no))
 | 
			
		||||
        ((pred (car lst))
 | 
			
		||||
         (separate- pred (cdr lst) (cons (car lst) yes) no))
 | 
			
		||||
        (T
 | 
			
		||||
        (#t
 | 
			
		||||
         (separate- pred (cdr lst) yes (cons (car lst) no)))))
 | 
			
		||||
 | 
			
		||||
(define (foldr f zero lst)
 | 
			
		||||
  (if (null lst) zero
 | 
			
		||||
  (if (null? lst) zero
 | 
			
		||||
    (f (car lst) (foldr f zero (cdr lst)))))
 | 
			
		||||
 | 
			
		||||
(define (foldl f zero lst)
 | 
			
		||||
  (if (null lst) zero
 | 
			
		||||
  (if (null? lst) zero
 | 
			
		||||
    (foldl f (f (car lst) zero) (cdr lst))))
 | 
			
		||||
 | 
			
		||||
(define (reverse lst) (foldl cons () lst))
 | 
			
		||||
 | 
			
		||||
(define (copy-list l)
 | 
			
		||||
  (if (atom l) l
 | 
			
		||||
  (if (atom? l) l
 | 
			
		||||
    (cons (car l)
 | 
			
		||||
          (copy-list (cdr l)))))
 | 
			
		||||
(define (copy-tree l)
 | 
			
		||||
  (if (atom l) l
 | 
			
		||||
  (if (atom? l) l
 | 
			
		||||
    (cons (copy-tree (car l))
 | 
			
		||||
          (copy-tree (cdr l)))))
 | 
			
		||||
 | 
			
		||||
(define (nreverse l)
 | 
			
		||||
  (let ((prev ()))
 | 
			
		||||
    (while (consp l)
 | 
			
		||||
    (while (pair? l)
 | 
			
		||||
	   (set! l (prog1 (cdr l)
 | 
			
		||||
			  (rplacd l (prog1 prev
 | 
			
		||||
					   (set! prev l))))))
 | 
			
		||||
| 
						 | 
				
			
			@ -324,7 +316,7 @@
 | 
			
		|||
(define-macro (catch tag expr)
 | 
			
		||||
  (let ((e (gensym)))
 | 
			
		||||
    `(trycatch ,expr
 | 
			
		||||
               (lambda (,e) (if (and (consp ,e)
 | 
			
		||||
               (lambda (,e) (if (and (pair? ,e)
 | 
			
		||||
                                     (eq (car  ,e) 'thrown-value)
 | 
			
		||||
                                     (eq (cadr ,e) ,tag))
 | 
			
		||||
                                (caddr ,e)
 | 
			
		||||
| 
						 | 
				
			
			@ -354,15 +346,15 @@
 | 
			
		|||
                                                   extype))
 | 
			
		||||
                                       (todo     (cddr catc)))
 | 
			
		||||
                                  `(,(if specific
 | 
			
		||||
                                         ; exception matching logic
 | 
			
		||||
					 ; exception matching logic
 | 
			
		||||
                                         `(or (eq ,e ',extype)
 | 
			
		||||
                                              (and (consp ,e)
 | 
			
		||||
                                              (and (pair? ,e)
 | 
			
		||||
                                                   (eq (car ,e)
 | 
			
		||||
                                                       ',extype)))
 | 
			
		||||
                                       T); (catch (e) ...), match anything
 | 
			
		||||
					 #t); (catch (e) ...), match anything
 | 
			
		||||
                                    (let ((,var ,e)) (begin ,@todo)))))
 | 
			
		||||
                              catches)
 | 
			
		||||
                       (T (raise ,e))))) ; no matches, reraise
 | 
			
		||||
                       (#t (raise ,e))))) ; no matches, reraise
 | 
			
		||||
    (if final
 | 
			
		||||
        (if catches
 | 
			
		||||
            ; form with both catch and finally
 | 
			
		||||
| 
						 | 
				
			
			@ -400,15 +392,15 @@
 | 
			
		|||
        (cddar   rplacd   cdar)
 | 
			
		||||
        (cdddr   rplacd   cddr)
 | 
			
		||||
        (list-ref rplaca  nthcdr)
 | 
			
		||||
        (get     put      identity)
 | 
			
		||||
        (aref    aset     identity)
 | 
			
		||||
        (get     put!     identity)
 | 
			
		||||
        (aref    aset!    identity)
 | 
			
		||||
        (symbol-syntax    set-syntax!        identity)))
 | 
			
		||||
 | 
			
		||||
(define (setf-place-mutator place val)
 | 
			
		||||
  (if (symbolp place)
 | 
			
		||||
  (if (symbol? place)
 | 
			
		||||
      (list 'set! place val)
 | 
			
		||||
    (let ((mutator (assq (car place) *setf-place-list*)))
 | 
			
		||||
      (if (null mutator)
 | 
			
		||||
      (if (null? mutator)
 | 
			
		||||
          (error "setf: unknown place " (car place))
 | 
			
		||||
	  (if (eq (caddr mutator) 'identity)
 | 
			
		||||
	      (cons (cadr mutator) (append (cdr place) (list val)))
 | 
			
		||||
| 
						 | 
				
			
			@ -420,7 +412,7 @@
 | 
			
		|||
  (f-body
 | 
			
		||||
   ((label setf-
 | 
			
		||||
           (lambda (args)
 | 
			
		||||
             (if (null args)
 | 
			
		||||
             (if (null? args)
 | 
			
		||||
                 ()
 | 
			
		||||
               (cons (setf-place-mutator (car args) (cadr args))
 | 
			
		||||
                     (setf- (cddr args))))))
 | 
			
		||||
| 
						 | 
				
			
			@ -439,8 +431,8 @@
 | 
			
		|||
    l))
 | 
			
		||||
 | 
			
		||||
(define (self-evaluating? x)
 | 
			
		||||
  (or (and (atom x)
 | 
			
		||||
           (not (symbolp x)))
 | 
			
		||||
  (or (and (atom? x)
 | 
			
		||||
           (not (symbol? x)))
 | 
			
		||||
      (and (constant? x)
 | 
			
		||||
           (eq x (eval x)))))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -448,54 +440,54 @@
 | 
			
		|||
(define-macro (backquote x) (bq-process x))
 | 
			
		||||
 | 
			
		||||
(define (splice-form? x)
 | 
			
		||||
  (or (and (consp x) (or (eq (car x) '*comma-at*)
 | 
			
		||||
  (or (and (pair? x) (or (eq (car x) '*comma-at*)
 | 
			
		||||
                         (eq (car x) '*comma-dot*)))
 | 
			
		||||
      (eq x '*comma*)))
 | 
			
		||||
 | 
			
		||||
(define (bq-process x)
 | 
			
		||||
  (cond ((self-evaluating? x)
 | 
			
		||||
         (if (vectorp x)
 | 
			
		||||
         (if (vector? x)
 | 
			
		||||
             (let ((body (bq-process (vector-to-list x))))
 | 
			
		||||
               (if (eq (car body) 'list)
 | 
			
		||||
                   (cons vector (cdr body))
 | 
			
		||||
                 (list apply vector body)))
 | 
			
		||||
           x))
 | 
			
		||||
        ((atom x)                     (list 'quote x))
 | 
			
		||||
        ((atom? x)                    (list 'quote x))
 | 
			
		||||
        ((eq (car x) 'backquote)      (bq-process (bq-process (cadr x))))
 | 
			
		||||
        ((eq (car x) '*comma*)        (cadr x))
 | 
			
		||||
        ((not (any splice-form? x))
 | 
			
		||||
         (let ((lc    (lastcdr x))
 | 
			
		||||
               (forms (map bq-bracket1 x)))
 | 
			
		||||
           (if (null lc)
 | 
			
		||||
           (if (null? lc)
 | 
			
		||||
               (cons 'list forms)
 | 
			
		||||
             (nconc (cons 'nlist* forms) (list (bq-process lc))))))
 | 
			
		||||
        (T (let ((p x) (q ()))
 | 
			
		||||
             (while (and (consp p)
 | 
			
		||||
                         (not (eq (car p) '*comma*)))
 | 
			
		||||
               (set! q (cons (bq-bracket (car p)) q))
 | 
			
		||||
               (set! p (cdr p)))
 | 
			
		||||
             (let ((forms
 | 
			
		||||
                    (cond ((consp p) (nreconc q (list (cadr p))))
 | 
			
		||||
                          ((null p)  (nreverse q))
 | 
			
		||||
                          (T         (nreconc q (list (bq-process p)))))))
 | 
			
		||||
               (if (null (cdr forms))
 | 
			
		||||
                   (car forms)
 | 
			
		||||
                 (cons 'nconc forms)))))))
 | 
			
		||||
        (#t (let ((p x) (q ()))
 | 
			
		||||
	      (while (and (pair? p)
 | 
			
		||||
			  (not (eq (car p) '*comma*)))
 | 
			
		||||
		     (set! q (cons (bq-bracket (car p)) q))
 | 
			
		||||
		     (set! p (cdr p)))
 | 
			
		||||
	      (let ((forms
 | 
			
		||||
		     (cond ((pair? p) (nreconc q (list (cadr p))))
 | 
			
		||||
			   ((null? p)  (nreverse q))
 | 
			
		||||
			   (#t        (nreconc q (list (bq-process p)))))))
 | 
			
		||||
		(if (null? (cdr forms))
 | 
			
		||||
		    (car forms)
 | 
			
		||||
		    (cons 'nconc forms)))))))
 | 
			
		||||
 | 
			
		||||
(define (bq-bracket x)
 | 
			
		||||
  (cond ((atom x)                   (list list (bq-process x)))
 | 
			
		||||
  (cond ((atom? x)                  (list list (bq-process x)))
 | 
			
		||||
        ((eq (car x) '*comma*)      (list list (cadr x)))
 | 
			
		||||
        ((eq (car x) '*comma-at*)   (list 'copy-list (cadr x)))
 | 
			
		||||
        ((eq (car x) '*comma-dot*)  (cadr x))
 | 
			
		||||
        (T                          (list list (bq-process x)))))
 | 
			
		||||
        (#t                         (list list (bq-process x)))))
 | 
			
		||||
 | 
			
		||||
; bracket without splicing
 | 
			
		||||
(define (bq-bracket1 x)
 | 
			
		||||
  (if (and (consp x) (eq (car x) '*comma*))
 | 
			
		||||
  (if (and (pair? x) (eq (car x) '*comma*))
 | 
			
		||||
      (cadr x)
 | 
			
		||||
      (bq-process x)))
 | 
			
		||||
 | 
			
		||||
(define-macro (assert expr) `(if ,expr T (raise '(assert-failed ,expr))))
 | 
			
		||||
(define-macro (assert expr) `(if ,expr #t (raise '(assert-failed ,expr))))
 | 
			
		||||
 | 
			
		||||
(define-macro (time expr)
 | 
			
		||||
  (let ((t0 (gensym)))
 | 
			
		||||
| 
						 | 
				
			
			@ -504,14 +496,16 @@
 | 
			
		|||
	,expr
 | 
			
		||||
	(princ "Elapsed time: " (- (time.now) ,t0) " seconds\n")))))
 | 
			
		||||
 | 
			
		||||
(define (display x) (princ x) (princ "\n"))
 | 
			
		||||
(define (display x) (princ x) #t)
 | 
			
		||||
 | 
			
		||||
(define (vu8 . elts) (apply array (cons 'uint8 elts)))
 | 
			
		||||
 | 
			
		||||
(define (vector.map f v)
 | 
			
		||||
  (let* ((n (length v))
 | 
			
		||||
         (nv (vector.alloc n)))
 | 
			
		||||
    (for 0 (- n 1)
 | 
			
		||||
         (lambda (i)
 | 
			
		||||
           (aset nv i (f (aref v i)))))
 | 
			
		||||
           (aset! nv i (f (aref v i)))))
 | 
			
		||||
    nv))
 | 
			
		||||
 | 
			
		||||
(define (table.pairs t)
 | 
			
		||||
| 
						 | 
				
			
			@ -525,6 +519,6 @@
 | 
			
		|||
               () t))
 | 
			
		||||
(define (table.clone t)
 | 
			
		||||
  (let ((nt (table)))
 | 
			
		||||
    (table.foldl (lambda (k v z) (put nt k v))
 | 
			
		||||
    (table.foldl (lambda (k v z) (put! nt k v))
 | 
			
		||||
                 () t)
 | 
			
		||||
    nt))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -103,11 +103,11 @@ value_t fl_table(value_t *args, uint32_t nargs)
 | 
			
		|||
    return nt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// (put table key value)
 | 
			
		||||
// (put! table key value)
 | 
			
		||||
value_t fl_table_put(value_t *args, uint32_t nargs)
 | 
			
		||||
{
 | 
			
		||||
    argcount("put", nargs, 3);
 | 
			
		||||
    htable_t *h = totable(args[0], "put");
 | 
			
		||||
    argcount("put!", nargs, 3);
 | 
			
		||||
    htable_t *h = totable(args[0], "put!");
 | 
			
		||||
    void **table0 = h->table;
 | 
			
		||||
    equalhash_put(h, (void*)args[1], (void*)args[2]);
 | 
			
		||||
    // register finalizer if we outgrew inline space
 | 
			
		||||
| 
						 | 
				
			
			@ -142,13 +142,13 @@ value_t fl_table_has(value_t *args, uint32_t nargs)
 | 
			
		|||
    return equalhash_has(h, (void*)args[1]) ? FL_T : FL_F;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// (del table key)
 | 
			
		||||
// (del! table key)
 | 
			
		||||
value_t fl_table_del(value_t *args, uint32_t nargs)
 | 
			
		||||
{
 | 
			
		||||
    argcount("del", nargs, 2);
 | 
			
		||||
    htable_t *h = totable(args[0], "del");
 | 
			
		||||
    argcount("del!", nargs, 2);
 | 
			
		||||
    htable_t *h = totable(args[0], "del!");
 | 
			
		||||
    if (!equalhash_remove(h, (void*)args[1]))
 | 
			
		||||
        lerror(KeyError, "del: key not found");
 | 
			
		||||
        lerror(KeyError, "del!: key not found");
 | 
			
		||||
    return args[0];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -178,10 +178,10 @@ value_t fl_table_foldl(value_t *args, uint32_t nargs)
 | 
			
		|||
static builtinspec_t tablefunc_info[] = {
 | 
			
		||||
    { "table", fl_table },
 | 
			
		||||
    { "table?", fl_tablep },
 | 
			
		||||
    { "put", fl_table_put },
 | 
			
		||||
    { "put!", fl_table_put },
 | 
			
		||||
    { "get", fl_table_get },
 | 
			
		||||
    { "has", fl_table_has },
 | 
			
		||||
    { "del", fl_table_del },
 | 
			
		||||
    { "del!", fl_table_del },
 | 
			
		||||
    { "table.foldl", fl_table_foldl },
 | 
			
		||||
    { NULL, NULL }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,20 +9,20 @@
 | 
			
		|||
 | 
			
		||||
;(define (reverse lst)
 | 
			
		||||
;  ((label rev-help (lambda (lst result)
 | 
			
		||||
;                     (if (null lst) result
 | 
			
		||||
;                     (if (null? lst) result
 | 
			
		||||
;                       (rev-help (cdr lst) (cons (car lst) result)))))
 | 
			
		||||
;   lst ()))
 | 
			
		||||
 | 
			
		||||
(define (append- . lsts)
 | 
			
		||||
  ((label append-h
 | 
			
		||||
          (lambda (lsts)
 | 
			
		||||
            (cond ((null lsts) ())
 | 
			
		||||
                  ((null (cdr lsts)) (car lsts))
 | 
			
		||||
                  (T ((label append2 (lambda (l d)
 | 
			
		||||
                                       (if (null l) d
 | 
			
		||||
                                         (cons (car l)
 | 
			
		||||
                                               (append2 (cdr l) d)))))
 | 
			
		||||
                      (car lsts) (append-h (cdr lsts)))))))
 | 
			
		||||
            (cond ((null? lsts) ())
 | 
			
		||||
                  ((null? (cdr lsts)) (car lsts))
 | 
			
		||||
                  (#t ((label append2 (lambda (l d)
 | 
			
		||||
					(if (null? l) d
 | 
			
		||||
					    (cons (car l)
 | 
			
		||||
						  (append2 (cdr l) d)))))
 | 
			
		||||
		       (car lsts) (append-h (cdr lsts)))))))
 | 
			
		||||
   lsts))
 | 
			
		||||
 | 
			
		||||
;(princ 'Hello '| | 'world! "\n")
 | 
			
		||||
| 
						 | 
				
			
			@ -38,13 +38,13 @@
 | 
			
		|||
; iterative filter
 | 
			
		||||
(define (ifilter pred lst)
 | 
			
		||||
  ((label f (lambda (accum lst)
 | 
			
		||||
              (cond ((null lst) (nreverse accum))
 | 
			
		||||
              (cond ((null? lst) (nreverse accum))
 | 
			
		||||
                    ((not (pred (car lst))) (f accum (cdr lst)))
 | 
			
		||||
                    (T (f (cons (car lst) accum) (cdr lst))))))
 | 
			
		||||
                    (#t (f (cons (car lst) accum) (cdr lst))))))
 | 
			
		||||
   () lst))
 | 
			
		||||
 | 
			
		||||
(define (sort l)
 | 
			
		||||
  (if (or (null l) (null (cdr l))) l
 | 
			
		||||
  (if (or (null? l) (null? (cdr l))) l
 | 
			
		||||
    (let* ((piv (car l))
 | 
			
		||||
           (halves (separate (lambda (x) (< x piv)) (cdr l))))
 | 
			
		||||
      (nconc (sort (car halves))
 | 
			
		||||
| 
						 | 
				
			
			@ -81,13 +81,13 @@
 | 
			
		|||
  (cond ((= p 0) 1)
 | 
			
		||||
        ((= b 0) 0)
 | 
			
		||||
        ((evenp p) (square (expt b (/ p 2))))
 | 
			
		||||
        (T (* b (expt b (- p 1))))))
 | 
			
		||||
        (#t (* b (expt b (- p 1))))))
 | 
			
		||||
 | 
			
		||||
(define (gcd a b)
 | 
			
		||||
  (cond ((= a 0) b)
 | 
			
		||||
        ((= b 0) a)
 | 
			
		||||
        ((< a b)  (gcd a (- b a)))
 | 
			
		||||
        (T        (gcd b (- a b)))))
 | 
			
		||||
        (#t       (gcd b (- a b)))))
 | 
			
		||||
 | 
			
		||||
; like eval-when-compile
 | 
			
		||||
(define-macro (literal expr)
 | 
			
		||||
| 
						 | 
				
			
			@ -95,7 +95,7 @@
 | 
			
		|||
    (if (self-evaluating? v) v (list quote v))))
 | 
			
		||||
 | 
			
		||||
(define (cardepth l)
 | 
			
		||||
  (if (atom l) 0
 | 
			
		||||
  (if (atom? l) 0
 | 
			
		||||
      (+ 1 (cardepth (car l)))))
 | 
			
		||||
 | 
			
		||||
(define (nestlist f zero n)
 | 
			
		||||
| 
						 | 
				
			
			@ -105,7 +105,7 @@
 | 
			
		|||
(define (mapl f . lsts)
 | 
			
		||||
  ((label mapl-
 | 
			
		||||
          (lambda (lsts)
 | 
			
		||||
            (if (null (car lsts)) ()
 | 
			
		||||
            (if (null? (car lsts)) ()
 | 
			
		||||
		(begin (apply f lsts) (mapl- (map cdr lsts))))))
 | 
			
		||||
   lsts))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -115,7 +115,7 @@
 | 
			
		|||
 | 
			
		||||
; swap the cars and cdrs of every cons in a structure
 | 
			
		||||
(define (swapad c)
 | 
			
		||||
  (if (atom c) c
 | 
			
		||||
  (if (atom? c) c
 | 
			
		||||
      (rplacd c (K (swapad (car c))
 | 
			
		||||
		   (rplaca c (swapad (cdr c)))))))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -123,7 +123,7 @@
 | 
			
		|||
  (filter (lambda (e) (not (eq e x))) l))
 | 
			
		||||
 | 
			
		||||
(define (conscount c)
 | 
			
		||||
  (if (consp c) (+ 1
 | 
			
		||||
  (if (pair? c) (+ 1
 | 
			
		||||
                   (conscount (car c))
 | 
			
		||||
                   (conscount (cdr c)))
 | 
			
		||||
      0))
 | 
			
		||||
| 
						 | 
				
			
			@ -163,7 +163,7 @@
 | 
			
		|||
                       (todo   (f-body (cddr  catc))))
 | 
			
		||||
                   `(lambda (,var)
 | 
			
		||||
                      (if (or (eq ,var ',extype)
 | 
			
		||||
                              (and (consp ,var)
 | 
			
		||||
                              (and (pair? ,var)
 | 
			
		||||
                                   (eq (car ,var) ',extype)))
 | 
			
		||||
                          ,todo
 | 
			
		||||
                        (,next ,var)))))
 | 
			
		||||
| 
						 | 
				
			
			@ -220,8 +220,8 @@
 | 
			
		|||
       (cdr ,first))))
 | 
			
		||||
 | 
			
		||||
(define (map-indexed f lst)
 | 
			
		||||
  (if (atom lst) lst
 | 
			
		||||
  (if (atom? lst) lst
 | 
			
		||||
    (let ((i 0))
 | 
			
		||||
      (accumulate-while (consp lst) (f (car lst) i)
 | 
			
		||||
      (accumulate-while (pair? lst) (f (car lst) i)
 | 
			
		||||
                        (begin (set! lst (cdr lst))
 | 
			
		||||
                               (set! i (1+ i)))))))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
; -*- scheme -*-
 | 
			
		||||
(define (maplist f l)
 | 
			
		||||
  (if (null l) ()
 | 
			
		||||
  (if (null? l) ()
 | 
			
		||||
    (cons (f l) (maplist f (cdr l)))))
 | 
			
		||||
 | 
			
		||||
; produce a beautiful, toroidal cons structure
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,9 +7,9 @@
 | 
			
		|||
  (list (fixnum n) (int8 n) (int16 n) (int32 n) (int64 n)))
 | 
			
		||||
 | 
			
		||||
(define (each f l)
 | 
			
		||||
  (if (atom l) ()
 | 
			
		||||
    (begin (f (car l))
 | 
			
		||||
           (each f (cdr l)))))
 | 
			
		||||
  (if (atom? l) ()
 | 
			
		||||
      (begin (f (car l))
 | 
			
		||||
	     (each f (cdr l)))))
 | 
			
		||||
 | 
			
		||||
(define (each^2 f l m)
 | 
			
		||||
  (each (lambda (o) (each (lambda (p) (f o p)) m)) l))
 | 
			
		||||
| 
						 | 
				
			
			@ -82,4 +82,4 @@
 | 
			
		|||
                 (3 . d) (2 . c) (0 . b) (1 . a))))
 | 
			
		||||
 | 
			
		||||
(princ "all tests pass\n")
 | 
			
		||||
T
 | 
			
		||||
#t
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue