rewriting some primitives to take advantage of the full language; they
do not need to be written in terms of the base language any more moving handling of internal define and multiple-body-lambda to the compiler where it belongs. macroexpand now only handles syntax.
This commit is contained in:
		
							parent
							
								
									2c304edf42
								
							
						
					
					
						commit
						642d1e1bd4
					
				| 
						 | 
					@ -1,6 +1,8 @@
 | 
				
			||||||
; definitions of standard scheme procedures in terms of
 | 
					; definitions of standard scheme procedures in terms of
 | 
				
			||||||
; femtolisp procedures
 | 
					; femtolisp procedures
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define top-level-bound? bound?)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define vector-ref aref)
 | 
					(define vector-ref aref)
 | 
				
			||||||
(define vector-set! aset!)
 | 
					(define vector-set! aset!)
 | 
				
			||||||
(define vector-length length)
 | 
					(define vector-length length)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -418,6 +418,12 @@
 | 
				
			||||||
		  (else      (emit g b))))
 | 
							  (else      (emit g b))))
 | 
				
			||||||
	      (emit g (if tail? :tcall :call) nargs)))))))
 | 
						      (emit g (if tail? :tcall :call) nargs)))))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (expand-define form body)
 | 
				
			||||||
 | 
					  (if (symbol? form)
 | 
				
			||||||
 | 
					      `(set! ,form ,(car body))
 | 
				
			||||||
 | 
					      `(set! ,(car form)
 | 
				
			||||||
 | 
						     (lambda ,(cdr form) ,@body . ,(car form)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (fits-i8 x) (and (fixnum? x) (>= x -128) (<= x 127)))
 | 
					(define (fits-i8 x) (and (fixnum? x) (>= x -128) (<= x 127)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (compile-in g env tail? x)
 | 
					(define (compile-in g env tail? x)
 | 
				
			||||||
| 
						 | 
					@ -449,6 +455,8 @@
 | 
				
			||||||
		     (emit g :ret))
 | 
							     (emit g :ret))
 | 
				
			||||||
	   (set!     (compile-in g env #f (caddr x))
 | 
						   (set!     (compile-in g env #f (caddr x))
 | 
				
			||||||
		     (compile-sym g env (cadr x) [:seta :setc :setg]))
 | 
							     (compile-sym g env (cadr x) [:seta :setc :setg]))
 | 
				
			||||||
 | 
						   (define   (compile-in g env tail?
 | 
				
			||||||
 | 
									 (expand-define (cadr x) (cddr x))))
 | 
				
			||||||
	   (trycatch (compile-in g env #f `(lambda () ,(cadr x)))
 | 
						   (trycatch (compile-in g env #f `(lambda () ,(cadr x)))
 | 
				
			||||||
		     (unless (1arg-lambda? (caddr x))
 | 
							     (unless (1arg-lambda? (caddr x))
 | 
				
			||||||
			     (error "trycatch: second form must be a 1-argument lambda"))
 | 
								     (error "trycatch: second form must be a 1-argument lambda"))
 | 
				
			||||||
| 
						 | 
					@ -461,25 +469,67 @@
 | 
				
			||||||
	   (apply compile-f- env f let?)
 | 
						   (apply compile-f- env f let?)
 | 
				
			||||||
	   ff))
 | 
						   ff))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (compile-f- env f . let?)
 | 
					(define get-defined-vars
 | 
				
			||||||
  (let ((g    (make-code-emitter))
 | 
					  (letrec ((get-defined-vars-
 | 
				
			||||||
	(args (cadr f)))
 | 
						    (lambda (expr)
 | 
				
			||||||
    (cond ((not (null? let?))      (emit g :let))
 | 
						      (cond ((atom? expr) ())
 | 
				
			||||||
	  ((length> args MAX_ARGS) (emit g (if (null? (lastcdr args))
 | 
							    ((and (eq? (car expr) 'define)
 | 
				
			||||||
					       :largc :lvargc)
 | 
								  (pair? (cdr expr)))
 | 
				
			||||||
					 (length args)))
 | 
							     (or (and (symbol? (cadr expr))
 | 
				
			||||||
	  ((null? (lastcdr args))  (emit g :argc  (length args)))
 | 
								      (list (cadr expr)))
 | 
				
			||||||
	  (else  (emit g :vargc (if (atom? args) 0 (length args)))))
 | 
								 (and (pair? (cadr expr))
 | 
				
			||||||
    (compile-in g (cons (to-proper args) env) #t (caddr f))
 | 
								      (symbol? (caadr expr))
 | 
				
			||||||
    (emit g :ret)
 | 
								      (list (caadr expr)))
 | 
				
			||||||
    (values (function (encode-byte-code (bcode:code g))
 | 
								 ()))
 | 
				
			||||||
		      (const-to-idx-vec g) (lastcdr f))
 | 
							    ((eq? (car expr) 'begin)
 | 
				
			||||||
	    (aref g 3))))
 | 
							     (apply append (map get-defined-vars- (cdr expr))))
 | 
				
			||||||
 | 
							    (else ())))))
 | 
				
			||||||
 | 
					    (lambda (expr) (delete-duplicates (get-defined-vars- expr)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define compile-f-
 | 
				
			||||||
 | 
					  (let ((*defines-processed-token* (gensym)))
 | 
				
			||||||
 | 
					    ; to eval a top-level expression we need to avoid internal define
 | 
				
			||||||
 | 
					    (set-top-level-value!
 | 
				
			||||||
 | 
					     'compile-thunk
 | 
				
			||||||
 | 
					     (lambda (expr)
 | 
				
			||||||
 | 
					       (compile `(lambda () ,expr . ,*defines-processed-token*))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (lambda (env f . let?)
 | 
				
			||||||
 | 
					      ; convert lambda to one body expression and process internal defines
 | 
				
			||||||
 | 
					      (define (lambda-body e)
 | 
				
			||||||
 | 
						(let ((B (if (pair? (cddr e))
 | 
				
			||||||
 | 
							     (if (pair? (cdddr e))
 | 
				
			||||||
 | 
								 (cons 'begin (cddr e))
 | 
				
			||||||
 | 
								 (caddr e))
 | 
				
			||||||
 | 
							     #f)))
 | 
				
			||||||
 | 
						  (let ((V (get-defined-vars B)))
 | 
				
			||||||
 | 
						    (if (null? V)
 | 
				
			||||||
 | 
							B
 | 
				
			||||||
 | 
							(cons (list* 'lambda V B *defines-processed-token*)
 | 
				
			||||||
 | 
							      (map (lambda (x) #f) V))))))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      (let ((g    (make-code-emitter))
 | 
				
			||||||
 | 
						    (args (cadr f))
 | 
				
			||||||
 | 
						    (name (if (eq? (lastcdr f) *defines-processed-token*)
 | 
				
			||||||
 | 
							      'lambda
 | 
				
			||||||
 | 
							      (lastcdr f))))
 | 
				
			||||||
 | 
						(cond ((not (null? let?))      (emit g :let))
 | 
				
			||||||
 | 
						      ((length> args MAX_ARGS) (emit g (if (null? (lastcdr args))
 | 
				
			||||||
 | 
											   :largc :lvargc)
 | 
				
			||||||
 | 
										     (length args)))
 | 
				
			||||||
 | 
						      ((null? (lastcdr args))  (emit g :argc  (length args)))
 | 
				
			||||||
 | 
						      (else  (emit g :vargc (if (atom? args) 0 (length args)))))
 | 
				
			||||||
 | 
						(compile-in g (cons (to-proper args) env) #t
 | 
				
			||||||
 | 
							    (if (eq? (lastcdr f) *defines-processed-token*)
 | 
				
			||||||
 | 
								(caddr f)
 | 
				
			||||||
 | 
								(lambda-body f)))
 | 
				
			||||||
 | 
						(emit g :ret)
 | 
				
			||||||
 | 
						(values (function (encode-byte-code (bcode:code g))
 | 
				
			||||||
 | 
								  (const-to-idx-vec g) name)
 | 
				
			||||||
 | 
							(aref g 3))))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (compile f) (compile-f () f))
 | 
					(define (compile f) (compile-f () f))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (compile-thunk expr) (compile `(lambda () ,expr)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(define (ref-int32-LE a i)
 | 
					(define (ref-int32-LE a i)
 | 
				
			||||||
  (int32 (+ (ash (aref a (+ i 0)) 0)
 | 
					  (int32 (+ (ash (aref a (+ i 0)) 0)
 | 
				
			||||||
	    (ash (aref a (+ i 1)) 8)
 | 
						    (ash (aref a (+ i 1)) 8)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
						 | 
					@ -3,26 +3,18 @@
 | 
				
			||||||
; by Jeff Bezanson (C) 2009
 | 
					; by Jeff Bezanson (C) 2009
 | 
				
			||||||
; Distributed under the BSD License
 | 
					; Distributed under the BSD License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(set! *syntax-environment* (table))
 | 
					(if (not (bound? '*syntax-environment*))
 | 
				
			||||||
 | 
					    (define *syntax-environment* (table)))
 | 
				
			||||||
(set! set-syntax!
 | 
					 | 
				
			||||||
      (lambda (s v) (put! *syntax-environment* s v)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(set-syntax! 'define-macro
 | 
					 | 
				
			||||||
             (lambda (form . body)
 | 
					 | 
				
			||||||
               (list 'set-syntax! (list 'quote (car form))
 | 
					 | 
				
			||||||
                     (cons 'lambda (cons (cdr form) body)))))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(define-macro (define form . body)
 | 
					 | 
				
			||||||
  (if (symbol? form)
 | 
					 | 
				
			||||||
      (list 'set! form (car body))
 | 
					 | 
				
			||||||
      (list 'set! (car form)
 | 
					 | 
				
			||||||
	    (list* 'lambda (cdr form) (append body (car form))))))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (set-syntax! s v) (put! *syntax-environment* s v))
 | 
				
			||||||
(define (symbol-syntax s) (get *syntax-environment* s #f))
 | 
					(define (symbol-syntax s) (get *syntax-environment* s #f))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define-macro (define-macro form . body)
 | 
				
			||||||
 | 
					  `(set-syntax! ',(car form)
 | 
				
			||||||
 | 
							(lambda ,(cdr form) ,@body)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-macro (label name fn)
 | 
					(define-macro (label name fn)
 | 
				
			||||||
  (list (list 'lambda (list name) (list 'set! name fn)) #f))
 | 
					  `((lambda (,name) (set! ,name ,fn)) #f))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (map f lst . lsts)
 | 
					(define (map f lst . lsts)
 | 
				
			||||||
  (define (map1 f lst acc)
 | 
					  (define (map1 f lst acc)
 | 
				
			||||||
| 
						 | 
					@ -42,28 +34,27 @@
 | 
				
			||||||
      (mapn f (cons lst lsts))))
 | 
					      (mapn f (cons lst lsts))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-macro (let binds . body)
 | 
					(define-macro (let binds . body)
 | 
				
			||||||
  ((lambda (lname)
 | 
					  (let (lname)
 | 
				
			||||||
     (begin
 | 
					    (if (symbol? binds)
 | 
				
			||||||
       (if (symbol? binds)
 | 
						(begin (set! lname binds)
 | 
				
			||||||
	   (begin (set! lname binds)
 | 
						       (set! binds (car body))
 | 
				
			||||||
		  (set! binds (car body))
 | 
						       (set! body (cdr body))))
 | 
				
			||||||
		  (set! body (cdr body))))
 | 
					    (let ((thelambda
 | 
				
			||||||
       ((lambda (thelambda theargs)
 | 
						   `(lambda ,(map (lambda (c) (if (pair? c) (car c) c))
 | 
				
			||||||
	  (cons (if lname
 | 
								  binds)
 | 
				
			||||||
		    (list 'label lname thelambda)
 | 
						      ,@body))
 | 
				
			||||||
		    thelambda)
 | 
						  (theargs
 | 
				
			||||||
		theargs))
 | 
						   (map (lambda (c) (if (pair? c) (cadr c) #f)) binds)))
 | 
				
			||||||
	(cons 'lambda
 | 
					      (cons (if lname
 | 
				
			||||||
	      (cons (map (lambda (c) (if (pair? c) (car c) c)) binds)
 | 
							`(label ,lname ,thelambda)
 | 
				
			||||||
		    body))
 | 
							thelambda)
 | 
				
			||||||
	(map (lambda (c) (if (pair? c) (cadr c) #f)) binds))))
 | 
						    theargs))))
 | 
				
			||||||
   #f))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-macro (letrec binds . body)
 | 
					(define-macro (letrec binds . body)
 | 
				
			||||||
  (cons (cons 'lambda (cons (map car binds)
 | 
					  `((lambda ,(map car binds)
 | 
				
			||||||
			    (nconc (map (lambda (b) (cons 'set! b)) binds)
 | 
					      ,.(map (lambda (b) `(set! ,@b)) binds)
 | 
				
			||||||
				   body)))
 | 
					      ,@body)
 | 
				
			||||||
	(map (lambda (x) #f) binds)))
 | 
					    ,.(map (lambda (x) #f) binds)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-macro (cond . clauses)
 | 
					(define-macro (cond . clauses)
 | 
				
			||||||
  (define (cond-clauses->if lst)
 | 
					  (define (cond-clauses->if lst)
 | 
				
			||||||
| 
						 | 
					@ -390,7 +381,7 @@
 | 
				
			||||||
	  (else            `(memv ,key ',v))))
 | 
						  (else            `(memv ,key ',v))))
 | 
				
			||||||
  (let ((g (gensym)))
 | 
					  (let ((g (gensym)))
 | 
				
			||||||
    `(let ((,g ,key))
 | 
					    `(let ((,g ,key))
 | 
				
			||||||
       (cond ,@(map (lambda (clause)
 | 
					       (cond ,.(map (lambda (clause)
 | 
				
			||||||
		      (cons (vals->cond g (car clause))
 | 
							      (cons (vals->cond g (car clause))
 | 
				
			||||||
			    (cdr clause)))
 | 
								    (cdr clause)))
 | 
				
			||||||
		    clauses)))))
 | 
							    clauses)))))
 | 
				
			||||||
| 
						 | 
					@ -411,8 +402,8 @@
 | 
				
			||||||
			     ,@(cdr test-spec))
 | 
								     ,@(cdr test-spec))
 | 
				
			||||||
			   (begin
 | 
								   (begin
 | 
				
			||||||
			     ,@commands
 | 
								     ,@commands
 | 
				
			||||||
			     (,loop ,@steps))))))
 | 
								     (,loop ,.steps))))))
 | 
				
			||||||
       (,loop ,@inits))))
 | 
					       (,loop ,.inits))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
; SRFI 8
 | 
					; SRFI 8
 | 
				
			||||||
(define-macro (receive formals expr . body)
 | 
					(define-macro (receive formals expr . body)
 | 
				
			||||||
| 
						 | 
					@ -618,23 +609,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
; toplevel --------------------------------------------------------------------
 | 
					; toplevel --------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define get-defined-vars
 | 
					 | 
				
			||||||
  (letrec ((get-defined-vars-
 | 
					 | 
				
			||||||
	    (lambda (expr)
 | 
					 | 
				
			||||||
	      (cond ((atom? expr) ())
 | 
					 | 
				
			||||||
		    ((and (eq? (car expr) 'define)
 | 
					 | 
				
			||||||
			  (pair? (cdr expr)))
 | 
					 | 
				
			||||||
		     (or (and (symbol? (cadr expr))
 | 
					 | 
				
			||||||
			      (list (cadr expr)))
 | 
					 | 
				
			||||||
			 (and (pair? (cadr expr))
 | 
					 | 
				
			||||||
			      (symbol? (caadr expr))
 | 
					 | 
				
			||||||
			      (list (caadr expr)))
 | 
					 | 
				
			||||||
			 ()))
 | 
					 | 
				
			||||||
		    ((eq? (car expr) 'begin)
 | 
					 | 
				
			||||||
		     (apply append (map get-defined-vars- (cdr expr))))
 | 
					 | 
				
			||||||
		    (else ())))))
 | 
					 | 
				
			||||||
    (lambda (expr) (delete-duplicates (get-defined-vars- expr)))))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(define (macrocall? e) (and (symbol? (car e))
 | 
					(define (macrocall? e) (and (symbol? (car e))
 | 
				
			||||||
			    (get *syntax-environment* (car e) #f)))
 | 
								    (get *syntax-environment* (car e) #f)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -645,21 +619,6 @@
 | 
				
			||||||
	    e))))
 | 
						    e))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (macroexpand e)
 | 
					(define (macroexpand e)
 | 
				
			||||||
  (define (expand-lambda e env)
 | 
					 | 
				
			||||||
    (let ((B (if (pair? (cddr e))
 | 
					 | 
				
			||||||
		 (if (pair? (cdddr e))
 | 
					 | 
				
			||||||
		     (cons 'begin (cddr e))
 | 
					 | 
				
			||||||
		     (caddr e))
 | 
					 | 
				
			||||||
		 #f)))
 | 
					 | 
				
			||||||
      (let ((V  (get-defined-vars B))
 | 
					 | 
				
			||||||
	    (Be (macroexpand-in B env)))
 | 
					 | 
				
			||||||
	(list* 'lambda
 | 
					 | 
				
			||||||
	       (cadr e)
 | 
					 | 
				
			||||||
	       (if (null? V)
 | 
					 | 
				
			||||||
		   Be
 | 
					 | 
				
			||||||
		   (cons (list 'lambda V Be)
 | 
					 | 
				
			||||||
			 (map (lambda (x) #f) V)))
 | 
					 | 
				
			||||||
	       (lastcdr e)))))
 | 
					 | 
				
			||||||
  (define (macroexpand-in e env)
 | 
					  (define (macroexpand-in e env)
 | 
				
			||||||
    (if (atom? e) e
 | 
					    (if (atom? e) e
 | 
				
			||||||
	(let ((f (assq (car e) env)))
 | 
						(let ((f (assq (car e) env)))
 | 
				
			||||||
| 
						 | 
					@ -669,7 +628,15 @@
 | 
				
			||||||
		(if f
 | 
							(if f
 | 
				
			||||||
		    (macroexpand-in (apply f (cdr e)) env)
 | 
							    (macroexpand-in (apply f (cdr e)) env)
 | 
				
			||||||
		    (cond ((eq (car e) 'quote)  e)
 | 
							    (cond ((eq (car e) 'quote)  e)
 | 
				
			||||||
			  ((eq (car e) 'lambda) (expand-lambda e env))
 | 
								  ((eq (car e) 'lambda)
 | 
				
			||||||
 | 
								   `(lambda ,(cadr e)
 | 
				
			||||||
 | 
								      ,.(map (lambda (x) (macroexpand-in x env))
 | 
				
			||||||
 | 
									     (cddr e))
 | 
				
			||||||
 | 
								      . ,(lastcdr e)))
 | 
				
			||||||
 | 
								  ((eq (car e) 'define)
 | 
				
			||||||
 | 
								   `(define ,(cadr e)
 | 
				
			||||||
 | 
								      ,.(map (lambda (x) (macroexpand-in x env))
 | 
				
			||||||
 | 
									     (cddr e))))
 | 
				
			||||||
			  ((eq (car e) 'let-syntax)
 | 
								  ((eq (car e) 'let-syntax)
 | 
				
			||||||
			   (let ((binds (cadr e))
 | 
								   (let ((binds (cadr e))
 | 
				
			||||||
				 (body  `((lambda () ,@(cddr e)))))
 | 
									 (body  `((lambda () ,@(cddr e)))))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -159,6 +159,7 @@ bugs:
 | 
				
			||||||
  . write a function to evaluate directly from list to list, use it for
 | 
					  . write a function to evaluate directly from list to list, use it for
 | 
				
			||||||
    Nth arg and for user function rest args
 | 
					    Nth arg and for user function rest args
 | 
				
			||||||
  . modify vararg builtins accordingly
 | 
					  . modify vararg builtins accordingly
 | 
				
			||||||
 | 
					- filter should be stable. right now it reverses.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
femtoLisp3...with symbolic C interface
 | 
					femtoLisp3...with symbolic C interface
 | 
				
			||||||
| 
						 | 
					@ -1040,6 +1041,8 @@ new evaluator todo:
 | 
				
			||||||
* maxstack calculation, make Stack growable
 | 
					* maxstack calculation, make Stack growable
 | 
				
			||||||
  * stack traces and better debugging support
 | 
					  * stack traces and better debugging support
 | 
				
			||||||
  - make maxstack calculation robust against invalid bytecode
 | 
					  - make maxstack calculation robust against invalid bytecode
 | 
				
			||||||
 | 
					* improve internal define
 | 
				
			||||||
 | 
					- try removing MAX_ARGS trickery
 | 
				
			||||||
- let eversion
 | 
					- let eversion
 | 
				
			||||||
* lambda lifting
 | 
					* lambda lifting
 | 
				
			||||||
* let optimization
 | 
					* let optimization
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue