⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eval.scm

📁 Scheme跨平台编译器
💻 SCM
📖 第 1 页 / 共 5 页
字号:
			  (err "`#!rest' argument marker in wrong context") ) ]		     [(#!key)		      (if (not rvar) (set! rvar (gensym)))		      (if (fx<= mode 3)			  (loop 3 req opt '() r)			  (err "`#!key' argument marker in wrong context") ) ]		     [else		      (cond [(symbol? x)			     (case mode			       [(0) (loop 0 (cons x req) '() '() r)]			       [(1) (loop 1 req (cons (list x #f) opt) '() r)]			       [(2) (err "invalid lambda list syntax after `#!rest' marker")]			       [else (loop 3 req opt (cons (list x) key) r)] ) ]			    [(and (list? x) (eq? 2 (length x)))			     (case mode			       [(0) (err "invalid required argument syntax")]			       [(1) (loop 1 req (cons x opt) '() r)]			       [(2) (err "invalid lambda list syntax after `#!rest' marker")]			       [else (loop 3 req opt (cons x key) r)] ) ]			    [else (err "invalid lambda list syntax")] ) ] ) ) ] ) ) ) ) ) );;; Expansion of bodies (and internal definitions)(define ##sys#canonicalize-body  (let ([reverse reverse]	[map map] )    (lambda (body lookup #!optional me container)      (define (fini vars vals mvars mvals body)	(if (and (null? vars) (null? mvars))	    (let loop ([body2 body] [exps '()])	      (if (not (pair? body2)) 		  `(begin ,@body) ; no more defines, otherwise we would have called `expand'		  (let ([x (##sys#slot body2 0)])		    (if (and (pair? x) (memq (##sys#slot x 0) `(define define-values)))			`(begin . ,(##sys#append (reverse exps) (list (expand body2))))			(loop (##sys#slot body2 1) (cons x exps)) ) ) ) )	    (let ([vars (reverse vars)])	      `(let ,(##sys#map (lambda (v) (##sys#list v (##sys#list '##core#undefined))) 				(apply ##sys#append vars mvars) )		 ,@(map (lambda (v x) `(##core#set! ,v ,x)) vars (reverse vals))		 ,@(map (lambda (vs x)			  (let ([tmps (##sys#map gensym vs)])			    `(##sys#call-with-values			      (lambda () ,x)			      (lambda ,tmps 				,@(map (lambda (v t) `(##core#set! ,v ,t)) vs tmps) ) ) ) ) 			(reverse mvars)			(reverse mvals) )		 ,@body) ) ) )      (define (expand body)	(let loop ([body body] [vars '()] [vals '()] [mvars '()] [mvals '()])	  (if (not (pair? body))	      (fini vars vals mvars mvals body)	      (let* ([x (##sys#slot body 0)]		     [rest (##sys#slot body 1)] 		     [head (and (pair? x) (##sys#slot x 0))] )		(cond [(not head) (fini vars vals mvars mvals body)]		      [(and (symbol? head) (lookup head))		       (fini vars vals mvars mvals body) ]		      [(eq? 'define head)		       (##sys#check-syntax 'define x '(define _ . #(_ 0)) #f)		       (let loop2 ([x x])			 (let ([head (cadr x)])			   (cond [(not (pair? head))				  (##sys#check-syntax 'define x '(define variable . #(_ 0)) #f)				  (loop rest (cons head vars)					(cons (if (pair? (cddr x))						  (caddr x)						  '(##sys#void) )					      vals)					mvars mvals) ]				 [(pair? (##sys#slot head 0))				  (##sys#check-syntax 'define x '(define (_ . lambda-list) . #(_ 1)) #f)				  (loop2 (cons 'define (##sys#expand-curried-define head (cddr x)))) ]				 [else				  (##sys#check-syntax 'define x '(define (variable . lambda-list) . #(_ 1)) #f)				  (loop rest					(cons (##sys#slot head 0) vars)					(cons `(lambda ,(##sys#slot head 1) ,@(cddr x)) vals)					mvars mvals) ] ) ) ) ]		      [(eq? 'define-values head)		       (##sys#check-syntax 'define-values x '(define-values #(_ 0) _) #f)		       (loop rest vars vals (cons (cadr x) mvars) (cons (caddr x) mvals)) ]		      [(eq? 'begin head)		       (##sys#check-syntax 'begin x '(begin . #(_ 0)) #f)		       (loop (##sys#append (##sys#slot x 1) rest) vars vals mvars mvals) ]		      [else		       (let ([x2 (##sys#macroexpand-0 x me)])			 (if (eq? x x2)			     (fini vars vals mvars mvals body)			     (loop (cons x2 rest) vars vals mvars mvals) ) ) ] ) ) ) ) )      (expand body) ) ) );;; A simple expression matcher(define ##sys#match-expression  (lambda (exp pat vars)    (let ((env '()))      (define (mwalk x p)	(cond ((or (not (##core#inline "C_blockp" p)) (not (##core#inline "C_pairp" p)))	       (cond ((assq p env) => (lambda (a) (equal? x (##sys#slot a 1))))		     ((memq p vars)		      (set! env (cons (cons p x) env))		      #t)		     (else (eq? x p)) ) )	      ((or (not (##core#inline "C_blockp" x)) (not (##core#inline "C_pairp" x))) #f)	      ((mwalk (##sys#slot x 0) (##sys#slot p 0))	       (mwalk (##sys#slot x 1) (##sys#slot p 1)) )	      (else #f) ) )      (and (mwalk exp pat) env) ) ) );;; Expand "curried" lambda-list syntax for `define'(define (##sys#expand-curried-define head body)  (let* ([name #f])    (define (loop head body)      (if (symbol? (##sys#slot head 0))	  (begin	    (set! name (##sys#slot head 0))	    `(lambda ,(##sys#slot head 1) ,@body) )	  (loop (##sys#slot head 0) `((lambda ,(##sys#slot head 1) ,@body)) ) ))    (let ([exp (loop head body)])      (list name exp) ) ) );;; Lo-level hashtable support:;; Note:;;;; - Keys are compared using 'eq?'.;; - The fixed "not found" value is #f. So booleans as values are suspect.(define ##sys#hash-symbol  (let ([cache-s #f]	[cache-h #f] )    (lambda (s n)      (if (eq? s cache-s)	  (##core#inline "C_fixnum_modulo" cache-h n)	  (let ([h (##core#inline "C_hash_string" (##sys#slot s 1))])	    (set! cache-s s)	    (set! cache-h h)	    (##core#inline "C_fixnum_modulo" h n) ) ) ) ) )(define (##sys#hash-table-ref ht key)  (let ((k (##sys#hash-symbol key (##core#inline "C_block_size" ht))))    (let loop ((bucket (##sys#slot ht k)))      (if (eq? bucket '())	  #f	  (let ((b (##sys#slot bucket 0)))	    (if (eq? key (##sys#slot b 0))		(##sys#slot b 1)		(loop (##sys#slot bucket 1)) ) ) ) ) ) )(define (##sys#hash-table-set! ht key val)  (let* ((k (##sys#hash-symbol key (##core#inline "C_block_size" ht)))         (bucket0 (##sys#slot ht k)) )    (let loop ((bucket bucket0))      (if (eq? bucket '())          (##sys#setslot ht k (cons (cons key val) bucket0))          (let ((b (##sys#slot bucket 0)))            (if (eq? key (##sys#slot b 0))		(##sys#setslot b 1 val)		(loop (##sys#slot bucket 1)) ) ) ) ) ) )(define (##sys#hash-table-update! ht key updtfunc valufunc)  (##sys#hash-table-set! ht key (updtfunc (or (##sys#hash-table-ref ht key) (valufunc)))) )(define (##sys#hash-table-for-each p ht)  (let ((len (##core#inline "C_block_size" ht)))    (do ((i 0 (fx+ i 1)))	((fx>= i len))      (##sys#for-each (lambda (bucket) 		        (p (##sys#slot bucket 0) (##sys#slot bucket 1) ) )		      (##sys#slot ht i) ) ) ) )(define (##sys#hash-table->alist ht)  (let ([len (##core#inline "C_block_size" ht)] )    (let loop ([i 0] [lst '()])      (if (fx>= i len)	  lst	  (let loop2 ([bucket (##sys#slot vec i)]		      [lst lst])	    (if (null? bucket)		(loop (fx+ i 1) lst)		(loop2 (##sys#slot bucket 1)		       (let ([x (##sys#slot bucket 0)])			 (cons (cons (##sys#slot x 0) (##sys#slot x 1)) lst) ) ) ) ) ) ) ) )(define ##sys#hash-table-location  (let ([unbound (##sys#slot '##sys#arbitrary-unbound-symbol 0)])    (lambda (ht key addp)      (let* ([k (##sys#hash-symbol key (##sys#size ht))]	     [bucket0 (##sys#slot ht k)] )	(let loop ([bucket bucket0])	  (if (null? bucket)	      (and addp		   (let ([p (vector key unbound #t)])		     (##sys#setslot ht k (cons p bucket0))		     p) )	      (let ([b (##sys#slot bucket 0)])		(if (eq? key (##sys#slot b 0))		    b		    (loop (##sys#slot bucket 1)) ) ) ) ) ) ) ) );;; Compile lambda to closure:(define ##sys#eval-environment #f)(define ##sys#environment-is-mutable #f)(define (##sys#eval-decorator p ll h cntr)  (##sys#decorate-lambda   p    (lambda (x) (and (not (##sys#immediate? x)) (##core#inline "C_lambdainfop" x)))   (lambda (p i)     (##sys#setslot       p i       (##sys#make-lambda-info        (let ((o (open-output-string)))	 (write ll o)	 (get-output-string o))))     p) ) )(define ##sys#unbound-in-eval #f)(define ##sys#eval-debug-level 1)(define (##sys#alias-global-hook s) s)(define ##sys#compile-to-closure  (let ([macro? macro?]	[write write]	[cadadr cadadr]	[reverse reverse]	(keyword? keyword?)	[open-output-string open-output-string]	[get-output-string get-output-string] 	[with-input-from-file with-input-from-file]	[unbound (##sys#slot '##sys#arbitrary-unbound-symbol 0)]	[display display] )    (lambda (exp env me . cntr)      (define (lookup var e)	(let loop ((envs e) (ei 0))	  (cond ((null? envs) (values #f var))		((posq var (##sys#slot envs 0)) => (lambda (p) (values ei p)))		(else (loop (##sys#slot envs 1) (fx+ ei 1))) ) ) )      (define (defined? var e)	(receive (i j) (lookup var e) i) )      (define (undefine vars e)	(let loop ([envs e])	  (if (null? envs)	      '()	      (let ([envi (##sys#slot envs 0)])		(cons		 (let delq ([ee envi])		   (if (null? ee)		       '()		       (let ([h (##sys#slot ee 0)]			     [r (##sys#slot ee 1)] )			 (if (memq h vars)			     r			     (cons h (delq r)) ) ) ) )		 (loop (##sys#slot envs 1)) ) ) ) ) )      (define (posq x lst)	(let loop ((lst lst) (i 0))	  (cond ((null? lst) #f)		((eq? x (##sys#slot lst 0)) i)		(else (loop (##sys#slot lst 1) (fx+ i 1))) ) ) )      (define (macroexpand-1-checked x e)	(let ([x2 (##sys#macroexpand-1-local x '())])	  (if (pair? x2)	      (let ([h (##sys#slot x2 0)])		(if (and (eq? h 'let) (not (defined? 'let e)))		    (let ([next (##sys#slot x2 1)])		      (if (and (pair? next) (symbol? (##sys#slot next 0)))			  (macroexpand-1-checked x2 e)			  x2) )		    x2) )	      x2) ) )      (define (emit-trace-info tf info cntr) 	(when tf	  (##core#inline "C_emit_eval_trace_info" info cntr ##sys#current-thread) ) )      (define (emit-syntax-trace-info tf info cntr) 	(when tf	  (##core#inline "C_emit_syntax_trace_info" info cntr ##sys#current-thread) ) )	      (define (decorate p ll h cntr)	(##sys#eval-decorator p ll h cntr) )      (define (compile x e h tf cntr)	(cond [(symbol? x)	       (if (keyword? x)		   (lambda v x)		   (receive (i j) (lookup x e)		     (cond [(not i)			    (let ((x (##sys#alias-global-hook x)))			      (if ##sys#eval-environment				  (let ([loc (##sys#hash-table-location ##sys#eval-environment x #t)])				    (unless loc (##sys#syntax-error-hook "reference to undefined identifier" x))				    (cond-expand 				     [unsafe (lambda v (##sys#slot loc 1))]				     [else				      (lambda v 					(let ([val (##sys#slot loc 1)])					  (if (eq? unbound val)					      (##sys#error "unbound variable" x)					      val) ) ) ] ) )				  (cond-expand				   [unsafe (lambda v (##core#inline "C_slot" x 0))]				   [else				    (when (and ##sys#unbound-in-eval (not (##sys#symbol-has-toplevel-binding? x)))				      (set! ##sys#unbound-in-eval (cons (cons x cntr) ##sys#unbound-in-eval)) )				    (lambda v (##core#inline "C_retrieve" x))] ) ) ) ]			   [(zero? i) (lambda (v) (##sys#slot (##sys#slot v 0) j))]			   [else (lambda (v) (##sys#slot (##core#inline "C_u_i_list_ref" v i) j))] ) ) ) ]	      [(##sys#number? x)	       (case x		 [(-1) (lambda v -1)]		 [(0) (lambda v 0)]		 [(1) (lambda v 1)]		 [(2) (lambda v 2)]		 [else (lambda v x)] ) ]	      [(boolean? x)	       (if x		   (lambda v #t)		   (lambda v #f) ) ]	      [(or (char? x)		   (eof-object? x)		   (string? x) )	       (lambda v x) ]	      [(not (pair? x)) (##sys#syntax-error-hook "illegal non-atomic object" x)]	      [(symbol? (##sys#slot x 0))	       (emit-syntax-trace-info tf x cntr)	       (let ([head (##sys#slot x 0)])		 (if (defined? head e)		     (compile-call x e tf cntr)		     (let ([x2 (macroexpand-1-checked x e)])		       (if (eq? x2 x)			   (case head			     [(quote)			      (##sys#check-syntax 'quote x '(quote _) #f)			      (let* ([c (cadr x)])				(case c				  [(-1) (lambda v -1)]				  [(0) (lambda v 0)]				  [(1) (lambda v 1)]				  [(2) (lambda v 2)]				  [(#t) (lambda v #t)]				  [(#f) (lambda v #f)]				  [(()) (lambda v '())]				  [else (lambda v c)] ) ) ]			     [(##core#global-ref)			      (let ([var (cadr x)])				(if ##sys#eval-environment				    (let ([loc (##sys#hash-table-location ##sys#eval-environment var #t)])				      (lambda v (##sys#slot loc 1)) )				    (lambda v (##core#inline "C_slot" var 0)) ) ) ]

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -