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

📄 c-backend.scm

📁 Scheme跨平台编译器
💻 SCM
📖 第 1 页 / 共 4 页
字号:
    (define (gen-string-constant str)      (let* ([len (##sys#size str)]	     [ns (fx/ len 80)]	     [srest (modulo len 80)] )	(do ([i ns (sub1 i)]	     [offset 0 (+ offset 80)] )	    ((zero? i)	     (when (or (zero? len) (not (zero? srest)))	       (gen (c-ify-string (string-like-substring str offset len))) ) )	  (gen (c-ify-string (string-like-substring str offset (+ offset 80))) #t) ) ) )     (define (string-like-substring s start end)      (let* ([len (- end start)]	     [s2 (make-string len)] )	(##sys#copy-bytes s s2 start 0 len)	s2) )    (define (procedures)      (for-each       (lambda (ll)	 (let* ([n (lambda-literal-argument-count ll)]		[id (lambda-literal-id ll)]		[rname (real-name id db)]		[demand (lambda-literal-allocated ll)]		[rest (lambda-literal-rest-argument ll)]		[customizable (lambda-literal-customizable ll)]		[empty-closure (and customizable (zero? (lambda-literal-closure-size ll)))]		[nec (- n (if empty-closure 1 0))]		[vlist0 (make-variable-list n "t")]		[alist0 (make-argument-list n "t")]		[varlist (intersperse (if empty-closure (cdr vlist0) vlist0) #\,)]		[arglist (intersperse (if empty-closure (cdr alist0) alist0) #\,)]		[external (lambda-literal-external ll)]		[looping (lambda-literal-looping ll)]		[direct (lambda-literal-direct ll)]		[rest-mode (lambda-literal-rest-argument-mode ll)]		[temps (lambda-literal-temporaries ll)]		[topname (if unit-name			     (string-append unit-name "_toplevel")			     "toplevel") ] )	   (when empty-closure (debugging 'o "dropping unused closure argument" id))	   (gen #t #t)	   (gen "/* " (cleanup rname) " */" #t)	   (cond [(not (eq? 'toplevel id)) 		  (gen "static ")		  (gen (if direct "C_word " "void "))		  (if customizable		      (gen "C_fcall ")		      (gen "C_ccall ") )		  (gen id) ]		 [else		  (gen "static C_TLS int toplevel_initialized=0;")		  (unless unit-name		    (gen #t "C_main_entry_point") )		  (gen #t "C_noret_decl(toplevel_trampoline)"		       #t "static void C_fcall toplevel_trampoline(void *dummy) C_regparm C_noret;"		       #t "C_regparm static void C_fcall toplevel_trampoline(void *dummy){"		       #t "C_" topname "(2,C_SCHEME_UNDEFINED,C_restore);}"		       #t #t "void C_ccall C_" topname) ] )	   (gen #\()	   (unless customizable (gen "C_word c,"))	   (when (and direct (not (zero? demand))) 	     (gen "C_word *a")	     (when (pair? varlist) (gen #\,)) )	   (apply gen varlist)	   (when rest (gen ",..."))	   (gen "){")	   (when (eq? rest-mode 'none) (set! rest #f))	   (gen #t "C_word tmp;")	   (if rest	       (gen #t "C_word t" n #\;) ; To hold rest-list if demand is met	       (do ([i n (add1 i)]		    [j (+ temps (if looping (sub1 n) 0)) (sub1 j)] )		   ((zero? j))		 (gen #t "C_word t" i #\;) ) )	   (cond [(eq? 'toplevel id) 		  (let ([ldemand (fold (lambda (lit n) (+ n (literal-size lit))) 0 literals)]			[llen (length literals)] )		    (gen #t "C_word *a;"			 #t "if(toplevel_initialized) C_kontinue(t1,C_SCHEME_UNDEFINED);"			 #t "else C_toplevel_entry(C_text(\"" topname "\"));")		    (when disable-stack-overflow-checking		      (gen #t "C_disable_overflow_check=1;") )		    (unless unit-name		      (cond [target-initial-heap-size			     (gen #t "C_set_or_change_heap_size(" target-initial-heap-size ",1);") ]			    [target-heap-size			     (gen #t "C_set_or_change_heap_size(" target-heap-size ",1);"				  #t "C_heap_size_is_fixed=1;") ] )		      (when target-heap-growth			(gen #t "C_heap_growth=" target-heap-growth #\;) )		      (when target-heap-shrinkage			(gen #t "C_heap_shrinkage=" target-heap-shrinkage #\;) )		      (when target-stack-size			(gen #t "C_resize_stack(" target-stack-size ");") ) )		    (gen #t "C_check_nursery_minimum(" demand ");"			 #t "if(!C_demand(" demand ")){"			 #t "C_save(t1);"			 #t "C_reclaim((void*)toplevel_trampoline,NULL);}"			 #t "toplevel_initialized=1;")		    (gen #t "if(!C_demand_2(" ldemand ")){"			 #t "C_save(t1);"			 #t "C_rereclaim2(" ldemand "*sizeof(C_word), 1);"			 #t "t1=C_restore;}")		    (gen #t "a=C_alloc(" demand ");")		    (when (not (zero? llen))		      (gen #t "C_initialize_lf(lf," llen ");")		      (literal-frame)		      (gen #t "C_register_lf2(lf," llen ",create_ptable());") ) ) ]		 [rest		  (gen #t "va_list v;")		  (gen #t "C_word *a,c2=c;")		  (gen #t "C_save_rest(")		  (if (> n 0)		      (gen #\t (- n 1))		      (gen "c") )		  (gen ",c2," n ");")		  (when (and (not unsafe) (not no-argc-checks) (> n 2) (not empty-closure))		    (gen #t "if(c<" n ") C_bad_min_argc_2(c," n ",t0);") )		  (when insert-timer-checks (gen #t "C_check_for_interrupt;"))		  (gen #t "if(!C_demand(c*C_SIZEOF_PAIR+" demand ")){") ]		 [else		  (cond [(and (not direct) (> demand 0))			 (if looping			     (gen #t "C_word *a;"				  #t "loop:"				  #t "a=C_alloc(" demand ");")			     (gen #t "C_word ab[" demand "],*a=ab;") ) ]			[else			 (unless direct (gen #t "C_word *a;"))			 (when looping (gen #t "loop:")) 			 (when (and direct (not unsafe) (not disable-stack-overflow-checking))			   (gen #t "C_stack_check;") ) ] )		  (when (and external (not unsafe) (not no-argc-checks) (not customizable))		    ;; (not customizable) implies empty-closure		    (if (eq? rest-mode 'none)			(when (> n 2) (gen #t "if(c<" n ") C_bad_min_argc_2(c," n ",t0);"))			(gen #t "if(c!=" n ") C_bad_argc_2(c," n ",t0);") ) )		  (when (and (not direct) (or external (> demand 0)))		    (when insert-timer-checks (gen #t "C_check_for_interrupt;"))		    (if (and looping (> demand 0))			(gen #t "if(!C_stack_probe(a)){")			(gen #t "if(!C_stack_probe(&a)){") ) ) ] )	   (when (and (not (eq? 'toplevel id))		      (not direct)		      (or rest external (> demand 0)) );; 	     (cond [(> nec 1);; 		    (gen #t "C_adjust_stack(" nec ");");; 		    (do ([i (if empty-closure 1 0) (+ i 1)]);; 			((>= i n));; 		      (gen #t "C_rescue(t" i #\, (- n i 1) ");") ) ];; 		   [(= nec 1) (gen #t "C_save(" (if empty-closure "t1" "t0") ");")] )	     (cond [rest		    (gen #t (if (> nec 0) "C_save_and_reclaim" "C_reclaim") "((void*)tr" n #\r)		    (when (eq? rest-mode 'vector) (gen #\v))		    (gen ",(void*)" id "r")		    (when (> nec 0)		      (gen #\, nec #\,)		      (apply gen arglist) )		    (gen ");}"			 #t "else{"			 #t "a=C_alloc((c-" n ")*3);")		    (case rest-mode		      [(list #f) (gen #t "t" n "=C_restore_rest(a,C_rest_count(0));")]		      [(vector) (gen #t "t" n "=C_restore_rest_vector(a,C_rest_count(0));")] )		    (gen #t id "r(")		    (apply gen (intersperse (make-argument-list n "t") #\,))		    (gen ",t" n ");}}")		    ;; Create secondary routine (no demand-check or argument-count-parameter):		    (gen #t #t "static void C_ccall " id "r(")		    (apply gen varlist)		    (gen ",C_word t" n "){")		    (gen #t "C_word tmp;")		    (do ([i (+ n 1) (+ i 1)]			 [j temps (- j 1)] )			((zero? j))		      (gen #t "C_word t" i #\;) )		    (when (> demand 0) (gen #t "C_word *a=C_alloc(" demand ");")) ]		   [else 		    (gen #t (if (> nec 0) "C_save_and_reclaim" "C_reclaim") "((void*)tr")		    (if customizable 			(gen id ",NULL")			(gen n ",(void*)" id) )		    (when (> nec 0)		      (gen #\, nec #\,)		      (apply gen arglist) )		    (gen ");}") ] ) )	   (expression	    (lambda-literal-body ll)	    (if rest		(add1 n) ; One temporary is needed to hold the rest-list		n)	    ll)	   (gen #\}) ) )       lambdas) )    (debugging 'p "code generation phase...")    (set! output out)    (header)    (declarations)    (generate-external-variables external-variables)    (generate-foreign-stubs foreign-lambda-stubs db)    (prototypes)    (generate-foreign-callback-stubs foreign-callback-stubs db)    (trampolines)    (procedures)    (emit-procedure-table-info lambdas source-file)    (trailer) ) );;; Emit procedure table:(define (emit-procedure-table-info lambdas sf)  (gen #t #t "#ifdef C_ENABLE_PTABLES"       #t "static C_PTABLE_ENTRY ptable[" (add1 (length lambdas)) "] = {")  (do ((ll lambdas (cdr ll)))      ((null? ll)       (gen #t "{NULL,NULL}};") )    (let ((id (lambda-literal-id (car ll))))      (gen #t "{\"" id sf "\",(void*)")      (if (eq? 'toplevel id)	  (if unit-name	      (gen "C_" unit-name "_toplevel},")	      (gen "C_toplevel},") )	  (gen id "},") ) ) )  (gen #t "#endif")  (gen #t #t "static C_PTABLE_ENTRY *create_ptable(void)")  (gen "{" #t "#ifdef C_ENABLE_PTABLES"       #t "return ptable;"       #t "#else"       #t "return NULL;"       #t "#endif"       #t "}") );;; Create name that is safe for C comments:(define (cleanup s)  (let ([s2 #f] 	[len (string-length s)] )    (let loop ([i 0])      (if (>= i len)	  (or s2 s)	  (let ([c (string-ref s i)])	    (if (or (char<? c #\space)		    (char>? c #\~)		    (and (char=? c #\*) (< i (sub1 len)) (char=? #\/ (string-ref s (add1 i)))) )		(begin		  (unless s2 (set! s2 (string-copy s)))		  (string-set! s2 i #\~) )		(when s2 (string-set! s2 i c)) ) 	    (loop (add1 i)) ) ) ) ) );;; Create list of variables/parameters, interspersed with a special token:(define (make-variable-list n prefix)  (list-tabulate   n   (lambda (i) (string-append "C_word " prefix (number->string i))) ) )  (define (make-argument-list n prefix)  (list-tabulate   n   (lambda (i) (string-append prefix (number->string i))) ) );;; Generate external variable declarations:(define (generate-external-variables vars)  (gen #t)  (for-each   (match-lambda      [#(name type exported)      (gen #t (if exported "" "static ") (foreign-type-declaration type name) #\;) ] )   vars) );;; Generate foreign stubs:(define (generate-foreign-callback-stub-prototypes stubs)  (for-each   (lambda (stub)     (gen #t)     (generate-foreign-callback-header "C_externexport " stub)     (gen #\;) )   stubs) )(define (generate-foreign-stubs stubs db)  (for-each   (lambda (stub)     (let* ([id (foreign-stub-id stub)]	    [rname (real-name2 id db)]	    [types (foreign-stub-argument-types stub)]	    [n (length types)]	    [varlist (intersperse (cons "C_word C_buf" (make-variable-list n "C_a")) #\,)]	    [rtype (foreign-stub-return-type stub)] 	    [sname (foreign-stub-name stub)] 	    [body (foreign-stub-body stub)]	    [names (or (foreign-stub-argument-names stub) (make-list n #f))]	    [rconv (foreign-result-conversion rtype "C_a")] 	    [cps (foreign-stub-cps stub)]	    [callback (foreign-stub-callback stub)] )       (gen #t)       (when rname	 (gen #t "/* from " (cleanup rname) " */") )       (when body	 (gen #t "#define return(x) C_cblock C_r = (" rconv 	      "(x))); goto C_ret; C_cblockend"))       (if cps	   (gen #t "C_noret_decl(" id ")"		#t "static void C_ccall " id "(C_word C_c,C_word C_self,C_word C_k,")	   (gen #t "static C_word C_fcall " id #\() )       (apply gen varlist)       (if cps	   (gen ") C_noret;" #t "static void C_ccall " id "(C_word C_c,C_word C_self,C_word C_k,")	   (gen ") C_regparm;" #t "C_regparm static C_word C_fcall " id #\() )       (apply gen varlist)       (gen "){")       (gen #t "C_word C_r=C_SCHEME_UNDEFINED,*C_a=(C_word*)C_buf;")       (for-each	(lambda (type index name)	  (gen #t 	       (foreign-type-declaration 		type		(if name (symbol->string name) (sprintf "t~a" index)) )	       "=(" (foreign-type-declaration type "") #\)	       (foreign-argument-conversion type) "C_a" index ");") )	types (iota n) names)       (when callback (gen #t "int C_level=C_save_callback_continuation(&C_a,C_k);"))       (cond [body	      (gen #t body		   #t "C_ret:")	      (gen #t "#undef return" #t)	      (cond [callback		     (gen #t "C_k=C_restore_callback_continuation2(C_level);"			  #t "C_kontinue(C_k,C_r);") ]		    [cps (gen #t "C_kontinue(C_k,C_r);")]		    [else (gen #t "return C_r;")] ) ]	     [else	      (if (not (eq? rtype 'void))		  (gen #t "C_r=" rconv)		  (gen #t) )	      (gen sname #\()	      (apply gen (intersperse (make-argument-list n "t") #\,))	      (unless (eq? rtype 'void) (gen #\)))	      (gen ");")

⌨️ 快捷键说明

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