~ chicken-core (master) /eval.scm
Trap1;;;; eval.scm - Interpreter for CHICKEN2;3; Copyright (c) 2008-2022, The CHICKEN Team4; Copyright (c) 2000-2007, Felix L. Winkelmann5; All rights reserved.6;7; Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following8; conditions are met:9;10; Redistributions of source code must retain the above copyright notice, this list of conditions and the following11; disclaimer.12; Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following13; disclaimer in the documentation and/or other materials provided with the distribution.14; Neither the name of the author nor the names of its contributors may be used to endorse or promote15; products derived from this software without specific prior written permission.16;17; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS18; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY19; AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR20; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR21; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR22; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY23; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR24; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE25; POSSIBILITY OF SUCH DAMAGE.262728(declare29 (unit eval)30 (uses modules)31 (not inline ##sys#alias-global-hook ##sys#user-read-hook ##sys#syntax-error-hook))3233#>34#ifndef C_INSTALL_EGG_HOME35# define C_INSTALL_EGG_HOME "."36#endif3738#ifndef C_INSTALL_SHARE_HOME39# define C_INSTALL_SHARE_HOME NULL40#endif4142#ifndef C_BINARY_VERSION43# define C_BINARY_VERSION 044#endif45<#4647(module chicken.eval48 (eval-handler module-environment)4950(import scheme51 chicken.base52 chicken.bytevector53 chicken.fixnum54 chicken.internal55 chicken.keyword56 chicken.syntax57 chicken.type58 chicken.foreign)59(import (only (scheme base) make-parameter open-output-string get-output-string port?))6061(include "common-declarations.scm")6263(define-syntax d (syntax-rules () ((_ . _) (void))))646566;;; Compile lambda to closure:6768(define (eval-decorator p ll h cntr)69 (##sys#decorate-lambda70 p71 (lambda (x) (and (not (##sys#immediate? x)) (##core#inline "C_lambdainfop" x)))72 (lambda (p i)73 (##sys#setslot74 p i75 (##sys#make-lambda-info76 (let ((o (open-output-string)))77 (write ll o)78 (get-output-string o))))79 p) ) )8081(define ##sys#unbound-in-eval #f)82(define ##sys#eval-debug-level (make-parameter 1))8384(define compile-to-closure85 (let ((reverse reverse))86 (lambda (exp env #!optional cntr evalenv static tl?)87 (define-syntax thread-id88 (syntax-rules ()89 ((_ t) (##sys#slot t 14))))9091 (define (find-id id se) ; ignores macro bindings92 (cond ((null? se) #f)93 ((and (eq? id (caar se)) (symbol? (cdar se))) (cdar se))94 (else (find-id id (cdr se)))))9596 (define (rename var)97 (cond ((find-id var (##sys#current-environment)))98 ((##sys#get var '##core#macro-alias) symbol? => values)99 (else var)))100101 (define (lookup var0 e)102 (let ((var (rename var0)))103 (d `(LOOKUP/EVAL: ,var0 ,var ,e ,(map (lambda (x) (car x)) (##sys#current-environment))))104 (let loop ((envs e) (ei 0))105 (cond ((null? envs) (values #f var))106 ((posq var (##sys#slot envs 0)) => (lambda (p) (values ei p)))107 (else (loop (##sys#slot envs 1) (fx+ ei 1))) ) ) ))108109 (define (posq x lst)110 (let loop ((lst lst) (i 0))111 (cond ((null? lst) #f)112 ((eq? x (##sys#slot lst 0)) i)113 (else (loop (##sys#slot lst 1) (fx+ i 1))) ) ) )114115 (define (emit-trace-info tf ln info cntr e v)116 (when tf117 (##core#inline "C_emit_trace_info"118 ln119 info120 (##sys#make-structure 'frameinfo cntr e v)121 (thread-id ##sys#current-thread) ) ) )122123 (define (emit-syntax-trace-info tf info cntr)124 (when tf125 (##core#inline "C_emit_trace_info"126 (or (get-line-number info) "<syntax>")127 info128 cntr129 (thread-id ##sys#current-thread) ) ) )130131 (define (decorate p ll h cntr)132 (eval-decorator p ll h cntr))133134 (define (handle-expansion-result outer-ln)135 (lambda (input output)136 (and-let* (((not (eq? input output)))137 (ln (or (get-line-number input) outer-ln)))138 (##sys#update-line-number-database! output ln))139 output))140141 (define (include-file x ci e tf cntr tl?)142 (##sys#include-forms-from-file143 (cadr x) (caddr x) ci144 (lambda (forms path)145 (let ((code (if (pair? (cdddr x)) ; body?146 (##sys#canonicalize-body147 (append forms (cadddr x))148 (##sys#current-environment))149 `(##core#begin ,@forms))))150 (fluid-let ((##sys#current-source-filename path))151 (compile code e #f tf cntr tl?))))))152153 (define (compile x e h tf cntr tl?)154 (cond ((keyword? x) (lambda v x))155 ((symbol? x)156 (receive (i j) (lookup x e)157 (cond ((not i)158 (let ((var (cond ((not (symbol? j)) x) ; syntax?159 ((assq x (##sys#current-environment)) j)160 ((not static)161 (##sys#alias-global-hook j #f cntr))162 ((not (eq? x j)) j) ; has macro-alias163 (else #f))))164 (when (and ##sys#unbound-in-eval165 (or (not var)166 (not (##sys#symbol-has-toplevel-binding? var))))167 (set! ##sys#unbound-in-eval168 (cons (cons var cntr) ##sys#unbound-in-eval)) )169 (cond ((not var)170 (lambda (v)171 (##sys#error "unbound variable" x)))172 ((##sys#symbol-has-toplevel-binding? var)173 (lambda v (##sys#slot var 0)))174 (else175 (lambda v (##core#inline "C_fast_retrieve" var))))))176 (else177 (case i178 ((0) (lambda (v)179 (##sys#slot (##sys#slot v 0) j)))180 ((1) (lambda (v)181 (##sys#slot (##sys#slot (##sys#slot v 1) 0) j)))182 ((2) (lambda (v)183 (##sys#slot184 (##sys#slot (##sys#slot (##sys#slot v 1) 1) 0)185 j)))186 ((3) (lambda (v)187 (##sys#slot188 (##sys#slot189 (##sys#slot (##sys#slot (##sys#slot v 1) 1) 1)190 0)191 j)))192 (else193 (lambda (v)194 (##sys#slot (##core#inline "C_u_i_list_ref" v i) j))))))))195 [(number? x)196 (case x197 [(-1) (lambda v -1)]198 [(0) (lambda v 0)]199 [(1) (lambda v 1)]200 [(2) (lambda v 2)]201 [else (lambda v x)] ) ]202 [(boolean? x)203 (if x204 (lambda v #t)205 (lambda v #f) ) ]206 ((or (char? x)207 (eof-object? x)208 (bwp-object? x)209 (string? x)210 (bytevector? x)211 (vector? x)212 (##sys#srfi-4-vector? x))213 (lambda v x) )214 [(not (pair? x))215 (##sys#syntax-error/context "illegal non-atomic object" x)]216 [(symbol? (##sys#slot x 0))217 (emit-syntax-trace-info tf x cntr)218 (let* ((ln (get-line-number x))219 (x2 (fluid-let ((chicken.syntax#expansion-result-hook220 (handle-expansion-result ln)))221 (expand x (##sys#current-environment)))))222 (d `(EVAL/EXPANDED: ,x2))223 (if (not (eq? x2 x))224 (compile x2 e h tf cntr tl?)225 (let ((head (rename (##sys#slot x 0))))226 ;; here we did't resolve ##core#primitive, but that is done in compile-call (via227 ;; a normal walking of the operator)228 (case head229230 [(##core#quote)231 (let* ((c (strip-syntax (cadr x))))232 (case c233 [(-1) (lambda v -1)]234 [(0) (lambda v 0)]235 [(1) (lambda v 1)]236 [(2) (lambda v 2)]237 [(#t) (lambda v #t)]238 [(#f) (lambda v #f)]239 [(()) (lambda v '())]240 [else (lambda v c)] ) ) ]241242 ((##core#syntax)243 (let ((c (cadr x)))244 (lambda v c)))245246 [(##core#check)247 (compile (cadr x) e h tf cntr #f) ]248249 [(##core#immutable)250 (compile (cadr x) e #f tf cntr #f) ]251252 [(##core#undefined) (lambda (v) (##core#undefined))]253254 [(##core#if)255 (let* ((test (compile (cadr x) e #f tf cntr #f))256 (cns (compile (caddr x) e #f tf cntr #f))257 (alt (if (pair? (cdddr x))258 (compile (cadddr x) e #f tf cntr #f)259 (compile '(##core#undefined) e #f tf cntr #f) ) ) )260 (lambda (v) (if (##core#app test v) (##core#app cns v) (##core#app alt v))) ) ]261262 [(##core#begin)263 (let* ((body (##sys#slot x 1))264 (len (length body)) )265 (case len266 ((0) (compile '(##core#undefined) e #f tf cntr tl?))267 ((1) (compile (##sys#slot body 0) e #f tf cntr tl?))268 ((2) (let* ((x1 (compile (##sys#slot body 0) e #f tf cntr tl?))269 (x2 (compile (cadr body) e #f tf cntr tl?)) )270 (lambda (v) (##core#app x1 v) (##core#app x2 v)) ) )271 (else272 (let* ((x1 (compile (##sys#slot body 0) e #f tf cntr tl?))273 (x2 (compile (cadr body) e #f tf cntr tl?))274 (x3 (compile `(##core#begin ,@(##sys#slot (##sys#slot body 1) 1)) e #f tf cntr tl?)) )275 (lambda (v) (##core#app x1 v) (##core#app x2 v) (##core#app x3 v)) ) ) ) ) ]276277 ((##core#ensure-toplevel-definition)278 (unless tl?279 (##sys#error "toplevel definition in non-toplevel context for variable" (cadr x)))280 (##sys#put/restore! (cadr x) '##sys#override 'value)281 (compile282 '(##core#undefined) e #f tf cntr #f))283284 [(##core#set!)285 (let ((var (cadr x)))286 (receive (i j) (lookup var e)287 (let ((val (compile (caddr x) e var tf cntr #f)))288 (cond ((not i)289 (when ##sys#notices-enabled290 (and-let* ((a (assq var (##sys#current-environment)))291 ((symbol? (cdr a))))292 (##sys#notice "assignment to imported value binding" var)))293 (if static294 (lambda (v)295 (##sys#error 'eval "environment is not mutable" evalenv var)) ;XXX var?296 (let ((var (##sys#alias-global-hook j #t cntr)))297 (lambda (v)298 (let ((result (##core#app val v)))299 (##core#inline "C_i_persist_symbol" var)300 (##sys#setslot var 0 result))))))301 ((zero? i) (lambda (v) (##sys#setslot (##sys#slot v 0) j (##core#app val v))))302 (else303 (lambda (v)304 (##sys#setslot305 (##core#inline "C_u_i_list_ref" v i) j (##core#app val v))))))))]306307 [(##core#let)308 (let* ((bindings (cadr x))309 (n (length bindings))310 (vars (map (lambda (x) (car x)) bindings))311 (aliases (map gensym vars))312 (e2 (cons aliases e))313 (se2 (##sys#extend-se (##sys#current-environment) vars aliases))314 (body (parameterize ((##sys#current-environment se2))315 (compile-to-closure316 (##sys#canonicalize-body (cddr x) (##sys#current-environment) #f)317 e2 cntr evalenv static #f)) ) )318 (case n319 ((1) (let ([val (compile (cadar bindings) e (car vars) tf cntr #f)])320 (lambda (v)321 (##core#app body (cons (vector (##core#app val v)) v)) ) ) )322 ((2) (let ((val1 (compile (cadar bindings) e (car vars) tf cntr #f))323 (val2 (compile (cadadr bindings) e (cadr vars) tf cntr #f)) )324 (lambda (v)325 (##core#app body (cons (vector (##core#app val1 v) (##core#app val2 v)) v)) ) ) )326 ((3) (let* ((val1 (compile (cadar bindings) e (car vars) tf cntr #f))327 (val2 (compile (cadadr bindings) e (cadr vars) tf cntr #f))328 (t (cddr bindings))329 (val3 (compile (cadar t) e (caddr vars) tf cntr #f)) )330 (lambda (v)331 (##core#app332 body333 (cons (vector (##core#app val1 v) (##core#app val2 v) (##core#app val3 v)) v)) ) ) )334 ((4) (let* ((val1 (compile (cadar bindings) e (car vars) tf cntr #f))335 (val2 (compile (cadadr bindings) e (cadr vars) tf cntr #f))336 (t (cddr bindings))337 (val3 (compile (cadar t) e (caddr vars) tf cntr #f))338 (val4 (compile (cadadr t) e (cadddr vars) tf cntr #f)) )339 (lambda (v)340 (##core#app341 body342 (cons (vector (##core#app val1 v)343 (##core#app val2 v)344 (##core#app val3 v)345 (##core#app val4 v))346 v)) ) ) )347 [else348 (let ((vals (map (lambda (x) (compile (cadr x) e (car x) tf cntr #f)) bindings)))349 (lambda (v)350 (let ([v2 (##sys#make-vector n)])351 (do ([i 0 (fx+ i 1)]352 [vlist vals (##sys#slot vlist 1)] )353 ((fx>= i n))354 (##sys#setslot v2 i (##core#app (##sys#slot vlist 0) v)) )355 (##core#app body (cons v2 v)) ) ) ) ] ) ) ]356357 ((##core#letrec*)358 (let ((bindings (cadr x))359 (body (cddr x)) )360 (compile361 `(##core#let362 ,(##sys#map (lambda (b)363 (list (car b) '(##core#undefined)))364 bindings)365 ,@(##sys#map (lambda (b)366 `(##core#set! ,(car b) ,(cadr b)))367 bindings)368 (##core#let () ,@body) )369 e h tf cntr #f)))370371 ((##core#letrec)372 (let* ((bindings (cadr x))373 (vars (map car bindings))374 (tmps (map gensym vars))375 (body (cddr x)) )376 (compile377 `(##core#let378 ,(map (lambda (b)379 (list (car b) '(##core#undefined)))380 bindings)381 (##core#let ,(map (lambda (t b) (list t (cadr b))) tmps bindings)382 ,@(map (lambda (v t)383 `(##core#set! ,v ,t))384 vars tmps)385 (##core#let () ,@body) ) )386 e h tf cntr #f)))387388 [(##core#lambda)389 (##sys#check-syntax 'lambda x '(_ lambda-list . #(_ 1)) #f (##sys#current-environment))390 (let* ([llist (cadr x)]391 [body (cddr x)]392 [info (cons (or h '?) llist)] )393 (when (##sys#extended-lambda-list? llist)394 (set!-values395 (llist body)396 (##sys#expand-extended-lambda-list397 llist body ##sys#syntax-error (##sys#current-environment)) ) )398 (##sys#decompose-lambda-list399 llist400 (lambda (vars argc rest)401 (let* ((aliases (map gensym vars))402 (se2 (##sys#extend-se (##sys#current-environment) vars aliases))403 (e2 (cons aliases e))404 (body405 (parameterize ((##sys#current-environment se2))406 (compile-to-closure407 (##sys#canonicalize-body body se2 #f)408 e2 (or h cntr) evalenv static #f)) ) )409 (case argc410 [(0) (if rest411 (lambda (v)412 (decorate413 (lambda r414 (##core#app body (cons (vector r) v)))415 info h cntr) )416 (lambda (v)417 (decorate418 (lambda () (##core#app body (cons #f v)))419 info h cntr) ) ) ]420 [(1) (if rest421 (lambda (v)422 (decorate423 (lambda (a1 . r)424 (##core#app body (cons (vector a1 r) v)))425 info h cntr) )426 (lambda (v)427 (decorate428 (lambda (a1)429 (##core#app body (cons (vector a1) v)))430 info h cntr) ) ) ]431 [(2) (if rest432 (lambda (v)433 (decorate434 (lambda (a1 a2 . r)435 (##core#app body (cons (vector a1 a2 r) v)))436 info h cntr) )437 (lambda (v)438 (decorate439 (lambda (a1 a2)440 (##core#app body (cons (vector a1 a2) v)))441 info h cntr) ) ) ]442 [(3) (if rest443 (lambda (v)444 (decorate445 (lambda (a1 a2 a3 . r)446 (##core#app body (cons (vector a1 a2 a3 r) v)))447 info h cntr) )448 (lambda (v)449 (decorate450 (lambda (a1 a2 a3)451 (##core#app body (cons (vector a1 a2 a3) v)))452 info h cntr) ) ) ]453 [(4) (if rest454 (lambda (v)455 (decorate456 (lambda (a1 a2 a3 a4 . r)457 (##core#app body (cons (vector a1 a2 a3 a4 r) v)))458 info h cntr) )459 (lambda (v)460 (decorate461 (lambda (a1 a2 a3 a4)462 (##core#app body (##sys#cons (##sys#vector a1 a2 a3 a4) v)))463 info h cntr) ) ) ]464 [else465 (if rest466 (lambda (v)467 (decorate468 (lambda as469 (##core#app470 body471 (##sys#cons (apply ##sys#vector (fudge-argument-list argc as)) v)) )472 info h cntr) )473 (lambda (v)474 (decorate475 (lambda as476 (let ([len (length as)])477 (if (not (fx= len argc))478 (##sys#error "bad argument count" argc len)479 (##core#app body (##sys#cons (apply ##sys#vector as) v)))))480 info h cntr) ) ) ] ) ) ) ) ) ]481482 ((##core#let-syntax)483 (parameterize484 ((##sys#current-environment485 (append486 (map (lambda (b)487 (list488 (car b)489 (##sys#current-environment)490 (##sys#ensure-transformer491 (##sys#eval/meta (cadr b))492 (strip-syntax (car b)))))493 (cadr x) )494 (##sys#current-environment)) ) )495 (compile496 (##sys#canonicalize-body (cddr x) (##sys#current-environment) #f)497 e #f tf cntr #f)))498499 ((##core#letrec-syntax)500 (let* ((ms (map (lambda (b)501 (list502 (car b)503 #f504 (##sys#ensure-transformer505 (##sys#eval/meta (cadr b))506 (strip-syntax (car b)))))507 (cadr x) ) )508 (se2 (append ms (##sys#current-environment))) )509 (for-each510 (lambda (sb)511 (set-car! (cdr sb) se2) )512 ms)513 (parameterize ((##sys#current-environment se2))514 (compile515 (##sys#canonicalize-body (cddr x) (##sys#current-environment) #f)516 e #f tf cntr #f))))517518 ((##core#define-syntax)519 (let* ((var (cadr x))520 (body (caddr x))521 (name (rename var)))522 (when (and static (not (assq var (##sys#current-environment))))523 (##sys#error 'eval "environment is not mutable" evalenv var))524 (##sys#put/restore! name '##sys#override 'syntax)525 (##sys#register-syntax-export526 name (##sys#current-module)527 body) ; not really necessary, it only shouldn't be #f528 (##sys#extend-macro-environment529 name530 (##sys#current-environment)531 (##sys#eval/meta body))532 (compile '(##core#undefined) e #f tf cntr #f) ) )533534 ((##core#define-compiler-syntax)535 (compile '(##core#undefined) e #f tf cntr #f))536537 ((##core#let-compiler-syntax)538 (compile539 (##sys#canonicalize-body (cddr x) (##sys#current-environment) #f)540 e #f tf cntr #f))541542 ((##core#include)543 (include-file x #f e tf cntr tl?))544545 ((##core#include-ci)546 (include-file x #t e tf cntr tl?))547548 ((##core#let-module-alias)549 (##sys#with-module-aliases550 (map (lambda (b)551 (##sys#check-syntax 'functor b '(symbol symbol))552 (strip-syntax b))553 (cadr x))554 (lambda ()555 (compile `(##core#begin ,@(cddr x)) e #f tf cntr tl?))))556557 ((##core#module)558 (let* ((x (strip-syntax x))559 (name (cadr x))560 (exports561 (or (eq? #t (caddr x))562 (map (lambda (exp)563 (cond ((symbol? exp) exp)564 ((and (pair? exp)565 (let loop ((exp exp))566 (or (null? exp)567 (and (symbol? (car exp))568 (loop (cdr exp))))))569 exp)570 (else571 (##sys#syntax-error572 'module573 "invalid export syntax" exp name))))574 (caddr x)))))575 (when (##sys#current-module)576 (##sys#syntax-error 'module "modules may not be nested" name))577 (parameterize ((##sys#current-module578 (##sys#register-module name #f exports))579 (##sys#current-environment '())580 (##sys#macro-environment581 ##sys#initial-macro-environment)582 (##sys#module-alias-environment583 (##sys#module-alias-environment)))584 (##sys#with-property-restore585 (lambda ()586 (let loop ((body (cdddr x)) (xs '()))587 (if (null? body)588 (let ((xs (reverse xs)))589 (##sys#finalize-module (##sys#current-module))590 (##sys#provide (module-requirement name))591 (lambda (v)592 (let loop2 ((xs xs))593 (if (null? xs)594 (##sys#void)595 (let ((n (cdr xs)))596 (cond ((pair? n)597 ((car xs) v)598 (loop2 n))599 (else600 ((car xs) v))))))))601 (loop602 (cdr body)603 (cons (compile604 (car body)605 '() #f tf cntr606 #t) ; reset back to toplevel!607 xs))))) ) )))608609 [(##core#loop-lambda)610 (compile `(,(rename 'lambda) ,@(cdr x)) e #f tf cntr #f) ]611612 [(##core#provide)613 (compile `(##sys#provide (##core#quote ,(cadr x))) e #f tf cntr #f)]614615 [(##core#require-for-syntax)616 (chicken.load#load-extension (cadr x) #f #f)617 (compile '(##core#undefined) e #f tf cntr #f)]618619 [(##core#require)620 (let ((lib (cadr x))621 (mod (and (pair? (cddr x)) (caddr x))))622 (compile (##sys#process-require lib mod #f) e #f tf cntr #f))]623624 [(##core#elaborationtimeonly ##core#elaborationtimetoo) ; <- Note this!625 (##sys#eval/meta (cadr x))626 (compile '(##core#undefined) e #f tf cntr tl?) ]627628 [(##core#compiletimetoo)629 (compile (cadr x) e #f tf cntr tl?) ]630631 [(##core#compiletimeonly ##core#callunit ##core#local-specialization)632 (compile '(##core#undefined) e #f tf cntr tl?) ]633634 [(##core#declare)635 (##sys#notice "declarations are ignored in interpreted code" x)636 (compile '(##core#undefined) e #f tf cntr #f) ]637638 [(##core#define-inline ##core#define-constant)639 (compile `(,(rename 'define) ,@(cdr x)) e #f tf cntr tl?) ]640641 [(##core#primitive ##core#inline ##core#inline_allocate ##core#foreign-lambda642 ##core#define-foreign-variable643 ##core#define-external-variable ##core#let-location644 ##core#foreign-primitive ##core#location645 ##core#foreign-lambda* ##core#define-foreign-type)646 (##sys#syntax-error "cannot evaluate compiler-special-form" x) ]647648 [(##core#app)649 (compile-call (cdr x) e tf cntr (##sys#current-environment)) ]650651 ((##core#the)652 (compile (cadddr x) e h tf cntr tl?))653654 ((##core#typecase)655 ;; drops exp and requires "else" clause656 (cond ((assq 'else (strip-syntax (cdddr x))) =>657 (lambda (cl)658 (compile (cadr cl) e h tf cntr tl?)))659 (else660 (##sys#syntax-error661 'compiler-typecase662 "no `else-clause' in unresolved `compiler-typecase' form"663 x))))664665 (else666 (fluid-let ((##sys#syntax-context (cons head ##sys#syntax-context)))667 (compile-call x e tf cntr (##sys#current-environment))))))))]668669 [else670 (emit-syntax-trace-info tf x cntr)671 (compile-call x e tf cntr (##sys#current-environment))] ) )672673 (define (fudge-argument-list n alst)674 (if (null? alst)675 (list alst)676 (do ((n n (fx- n 1))677 (c 0 (fx+ c 1))678 (args alst679 (if (eq? '() args)680 (##sys#error "bad argument count" n c)681 (##sys#slot args 1)))682 (last #f args) )683 ((fx= n 0)684 (##sys#setslot last 1 (list args))685 alst) ) ) )686687 (define (checked-length lst)688 (let loop ([lst lst] [n 0])689 (cond [(null? lst) n]690 [(pair? lst) (loop (##sys#slot lst 1) (fx+ n 1))]691 [else #f] ) ) )692693 (define (compile-call x e tf cntr se)694 (let* ((head (##sys#slot x 0))695 (fn (if (procedure? head)696 (lambda _ head)697 (compile (##sys#slot x 0) e #f tf cntr #f)))698 (args (##sys#slot x 1))699 (argc (checked-length args))700 (info x)701 (ln (or (get-line-number info) "<eval>")))702 (case argc703 ((#f) (##sys#syntax-error/context "malformed expression" x))704 ((0) (lambda (v)705 (emit-trace-info tf ln info cntr e v)706 ((##core#app fn v))))707 ((1) (let ((a1 (compile (##sys#slot args 0) e #f tf cntr #f)))708 (lambda (v)709 (emit-trace-info tf ln info cntr e v)710 ((##core#app fn v) (##core#app a1 v))) ) )711 ((2) (let* ((a1 (compile (##sys#slot args 0) e #f tf cntr #f))712 (a2 (compile (##core#inline "C_u_i_list_ref" args 1) e #f tf cntr #f)) )713 (lambda (v)714 (emit-trace-info tf ln info cntr e v)715 ((##core#app fn v) (##core#app a1 v) (##core#app a2 v))) ) )716 ((3) (let* ((a1 (compile (##sys#slot args 0) e #f tf cntr #f))717 (a2 (compile (##core#inline "C_u_i_list_ref" args 1) e #f tf cntr #f))718 (a3 (compile (##core#inline "C_u_i_list_ref" args 2) e #f tf cntr #f)) )719 (lambda (v)720 (emit-trace-info tf ln info cntr e v)721 ((##core#app fn v) (##core#app a1 v) (##core#app a2 v) (##core#app a3 v))) ) )722 ((4) (let* ((a1 (compile (##sys#slot args 0) e #f tf cntr #f))723 (a2 (compile (##core#inline "C_u_i_list_ref" args 1) e #f tf cntr #f))724 (a3 (compile (##core#inline "C_u_i_list_ref" args 2) e #f tf cntr #f))725 (a4 (compile (##core#inline "C_u_i_list_ref" args 3) e #f tf cntr #f)) )726 (lambda (v)727 (emit-trace-info tf ln info cntr e v)728 ((##core#app fn v) (##core#app a1 v) (##core#app a2 v) (##core#app a3 v) (##core#app a4 v))) ) )729 (else (let ((as (##sys#map (lambda (a) (compile a e #f tf cntr #f)) args)))730 (lambda (v)731 (emit-trace-info tf ln info cntr e v)732 (apply (##core#app fn v) (##sys#map (lambda (a) (##core#app a v)) as))) ) ) ) ) )733734 (compile exp env #f (fx> (##sys#eval-debug-level) 0) cntr tl?) ) ) )735736737;;; evaluate in the macro-expansion/compile-time environment738(define (##sys#eval/meta form)739 (parameterize ((##sys#current-module #f)740 (##sys#macro-environment (##sys#meta-macro-environment))741 (##sys#current-environment (##sys#current-meta-environment)))742 (dynamic-wind743 void744 (lambda ()745 ((compile-to-closure746 form747 '()748 #f #f #f749 #t) ; toplevel.750 '()) )751 (lambda ()752 ;; Just before restoring the parameters, update "meta"753 ;; environments to receive a copy of the current754 ;; environments one level "down". We don't support more755 ;; than two evaluation phase levels currently.756 (##sys#current-meta-environment (##sys#current-environment))757 (##sys#meta-macro-environment (##sys#macro-environment))))))758759(define eval-handler760 (make-parameter761 (lambda (x #!optional env)762 (let ((se (##sys#current-environment)))763 ;; When se is empty, it's the first time eval was called:764 ;; ensure an active default environment. We do it here because765 ;; eval does not work yet at the end of modules.scm, and we766 ;; don't want to inject calls into every toplevel (see #1437)767 (when (null? se)768 ((compile-to-closure769 `(##core#begin (import-for-syntax ,@default-syntax-imports)770 (import ,@default-imports))771 '() #f #f #f #t) '()))772 (cond (env773 (##sys#check-structure env 'environment 'eval)774 (let ((ve2 (##sys#slot env 2))775 (se2 (##sys#slot env 3)))776 ((if ve2 ; not interaction-environment?777 (parameterize ((##sys#macro-environment se2)778 (##sys#current-environment ve2))779 (compile-to-closure x '() #f env (##sys#slot env 4) #t))780 (compile-to-closure x '() #f env #f #t))781 '())))782 (else783 ((compile-to-closure x '() #f #f #f #t) '())))))))784785(set! scheme#eval786 (lambda (x . env)787 (apply (eval-handler) x env)))788789;;; User-facing `module-environment` procedure:790791(define (module-environment name)792 (chicken.module#module-environment name))793794795;;; Setting properties dynamically scoped796797(define-values (##sys#put/restore! ##sys#with-property-restore)798 (let ((trail '())799 (restoring #f))800 (values801 (lambda (sym prop val)802 (when restoring803 (set! trail (cons (list sym prop (##sys#get sym prop)) trail)))804 (##sys#put! sym prop val)805 val)806 (lambda (thunk)807 (let ((t0 #f)808 (r0 restoring))809 (dynamic-wind810 (lambda ()811 (set! t0 trail)812 (set! restoring #t))813 thunk814 (lambda ()815 (do () ((eq? t0 trail))816 (apply ##sys#put! (car trail))817 (set! trail (cdr trail)))818 (set! restoring r0))))))))819820821;;; Split lambda-list into its parts:822823(define ##sys#decompose-lambda-list824 (let ([reverse reverse])825 (lambda (llist0 k)826827 (define (err)828 (set! ##sys#syntax-error-culprit #f)829 (##sys#syntax-error "illegal lambda-list syntax" llist0) )830831 (let loop ([llist llist0] [vars '()] [argc 0])832 (cond [(eq? llist '()) (k (reverse vars) argc #f)]833 [(not (##core#inline "C_blockp" llist)) (err)]834 [(##core#inline "C_symbolp" llist) (k (reverse (cons llist vars)) argc llist)]835 [(not (##core#inline "C_pairp" llist)) (err)]836 [else (loop (##sys#slot llist 1)837 (cons (##sys#slot llist 0) vars)838 (fx+ argc 1) ) ] ) ) ) ) )839840(set! scheme#interaction-environment841 (let ((e (##sys#make-structure 'environment 'interaction-environment #f #f #f)))842 (lambda () e)))843844(set-record-printer! 'environment845 (lambda (e p)846 (##sys#print "#<environment " #f p)847 (##sys#print (##sys#slot e 1) #f p)848 (##sys#write-char-0 #\> p)))849850(let* ((r4s (chicken.module#module-environment 'scheme.r4rs 'scheme-report-environment/4))851 (r5s (chicken.module#module-environment 'scheme.r5rs 'scheme-report-environment/5))852 (r4n (chicken.module#module-environment 'scheme.r4rs-null 'null-environment/4))853 (r5n (chicken.module#module-environment 'scheme.r5rs-null 'null-environment/5)))854 (define (strip se)855 (foldr856 (lambda (s r)857 (if (memq (car s)858 '(cond-expand859 define-interface860 delay-force861 export862 export/rename863 functor864 define-library865 import866 import-for-syntax867 import-syntax868 import-syntax-for-syntax869 letrec*870 module871 reexport872 require-library873 syntax))874 r875 (cons s r)))876 '()877 se))878 ;; Strip non-std syntax from SEs879 (##sys#setslot r4s 3 (strip (##sys#slot r4s 3)))880 (##sys#setslot r4n 3 (strip (##sys#slot r4n 3)))881 (##sys#setslot r5s 3 (strip (##sys#slot r5s 3)))882 (##sys#setslot r5n 3 (strip (##sys#slot r5n 3)))883 (set! scheme#scheme-report-environment884 (lambda (n)885 (##sys#check-fixnum n 'scheme-report-environment)886 (case n887 ((4) r4s)888 ((5) r5s)889 (else890 (##sys#error891 'scheme-report-environment892 "unsupported scheme report environment version" n)))))893 (set! scheme#null-environment894 (lambda (n)895 (##sys#check-fixnum n 'null-environment)896 (case n897 ((4) r4n)898 ((5) r5n)899 (else900 (##sys#error901 'null-environment902 "unsupported null environment version" n))))))903904) ; eval module905906907(module chicken.load908 (dynamic-load-libraries set-dynamic-load-mode!909 load-library load-noisily load-relative load-verbose910 provide provided? require)911912(import scheme913 chicken.base914 chicken.eval915 chicken.fixnum916 chicken.foreign917 chicken.internal918 chicken.platform919 chicken.syntax920 chicken.time)921(import (only (scheme base) make-parameter port?))922923(include "mini-srfi-1.scm")924925;;; Installation locations926927(define-foreign-variable binary-version int "C_BINARY_VERSION")928(define-foreign-variable install-lib-name c-string "C_INSTALL_LIB_NAME")929(define-foreign-variable uses-soname? bool "C_USES_SONAME")930931;;; Core unit information932933;; this maps built-in library names to require forms when the mapping isn't 1:1934(define-constant core-unit-requirements935 '((chicken.foreign936 . (##core#require-for-syntax chicken-ffi-syntax))937 (chicken.condition938 . (##core#begin939 (##core#require-for-syntax chicken-syntax)940 (##core#require library)))))941942;; this list contains built-in units that are provided by libchicken943;; and should not be treated as separate extension libraries during944;; linking (they are omitted from types/inline/link files etc.)945(define-constant core-units946 '(chicken-syntax chicken-ffi-syntax continuation data-structures947 debugger-client eval eval-modules expand extras file internal948 irregex library lolevel pathname port posix profiler read-syntax949 repl scheduler srfi-4 tcp r7lib))950951(define-constant cygwin-default-dynamic-load-libraries '("cygchicken-0"))952(define-constant macosx-load-library-extension ".dylib")953(define-constant windows-load-library-extension ".dll")954(define-constant hppa-load-library-extension ".sl")955(define-constant default-load-library-extension ".so")956(define-constant source-file-extension ".scm")957958(define load-library-extension959 (cond ((eq? (software-type) 'windows) windows-load-library-extension)960 ((eq? (software-version) 'macosx) macosx-load-library-extension)961 ((and (eq? (software-version) 'hpux)962 (eq? (machine-type) 'hppa)) hppa-load-library-extension)963 (else default-load-library-extension)))964965(define ##sys#load-dynamic-extension default-load-library-extension)966967(define (chicken.load#core-library? id) ; used by core.scm968 (or (memq id core-units)969 (assq id core-unit-requirements)))970971(define default-dynamic-load-libraries972 (case (software-version)973 ((cygwin) cygwin-default-dynamic-load-libraries)974 (else `(,(string-append "lib" install-lib-name)))))975976977;;; Library registration (used for code loading):978979(define (##sys#provide id)980 (##core#inline_allocate ("C_a_i_provide" 8) id))981982(define (##sys#provided? id)983 (##core#inline "C_i_providedp" id))984985986;;; Pathname helpers:987988(define path-separators989 (if ##sys#windows-platform '(#\\ #\/) '(#\/)))990991(define (path-separator-index/right s)992 (let loop ((i (fx- (string-length s) 1)))993 (if (memq (string-ref s i) path-separators)994 i995 (and (fx< 0 i) (loop (fx- i 1))))))996997(define (make-relative-pathname from file)998 (let ((i (and (string? from)999 (positive? (string-length file)) ; XXX probably an error?1000 (not (memq (string-ref file 0) path-separators))1001 (path-separator-index/right from))))1002 (if (not i) file (string-append (##sys#substring from 0 i) "/" file))))100310041005;;; Loading source/object files:10061007(define load-verbose (make-parameter (##sys#debug-mode?)))10081009(define ##sys#current-load-filename #f)1010(define ##sys#dload-disabled #f)10111012(define-foreign-variable _dlerror c-string "C_dlerror")10131014(define (set-dynamic-load-mode! mode)1015 (let ([mode (if (pair? mode) mode (list mode))]1016 [now #f]1017 [global #t] )1018 (let loop ([mode mode])1019 (when (pair? mode)1020 (case (##sys#slot mode 0)1021 [(global) (set! global #t)]1022 [(local) (set! global #f)]1023 [(lazy) (set! now #f)]1024 [(now) (set! now #t)]1025 [else (##sys#signal-hook 'set-dynamic-load-mode! "invalid dynamic-load mode" (##sys#slot mode 0))] )1026 (loop (##sys#slot mode 1)) ) )1027 (##sys#set-dlopen-flags! now global) ) )10281029(define (toplevel name)1030 (if (not name)1031 "toplevel"1032 (##sys#string-append1033 (string->c-identifier (##sys#symbol->string/shared name))1034 "_toplevel")))10351036(define (c-toplevel name loc)1037 (##sys#make-c-string (##sys#string-append "C_" (toplevel name)) loc))10381039(define load/internal1040 (let ((write write)1041 (display display)1042 (newline newline)1043 (eval eval)1044 (case-sensitive case-sensitive)1045 (open-input-file open-input-file)1046 (close-input-port close-input-port))1047 (lambda (input evaluator #!optional pf timer printer unit)10481049 (define evalproc1050 (or evaluator eval))10511052 ;; dload doesn't consider filenames without slashes to be paths,1053 ;; so we prepend a dot to force a relative pathname.1054 (define (dload-path path)1055 (if (path-separator-index/right path)1056 path1057 (##sys#string-append "./" path)))10581059 (define (dload path)1060 (let ((c-path (##sys#make-c-string (dload-path path) 'load)))1061 (or (##sys#dload c-path (c-toplevel unit 'load))1062 (and (symbol? unit)1063 (##sys#dload c-path (c-toplevel #f 'load))))))10641065 (define dload?1066 (and (not ##sys#dload-disabled)1067 (feature? #:dload)))10681069 (define fname1070 (cond ((port? input) #f)1071 ((not (string? input))1072 (##sys#signal-hook #:type-error 'load "bad argument type - not a port or string" input))1073 ((##sys#file-exists? input #t #f 'load) input)1074 ((let ((f (##sys#string-append input ##sys#load-dynamic-extension)))1075 (and dload? (##sys#file-exists? f #t #f 'load) f)))1076 ((let ((f (##sys#string-append input source-file-extension)))1077 (and (##sys#file-exists? f #t #f 'load) f)))1078 (else1079 (##sys#signal-hook #:file-error 'load "cannot open file" input))))10801081 (when (and (load-verbose) fname)1082 (display "; loading ")1083 (display fname)1084 (display " ...\n")1085 (flush-output))10861087 (or (and fname dload? (dload fname))1088 (call-with-current-continuation1089 (lambda (abrt)1090 (fluid-let ((##sys#read-error-with-line-number #t)1091 (##sys#current-load-filename fname)1092 (##sys#current-source-filename fname))1093 (let ((in (if fname (open-input-file fname) input))1094 (cs (case-sensitive))1095 (read-with-source-info chicken.syntax#read-with-source-info)) ; OBSOLETE - after bootstrapping we can get rid of this explicit namespacing1096 (##sys#dynamic-wind1097 (lambda () (set! cs (case-sensitive)))1098 (lambda ()1099 (let ((c1 (peek-char in)))1100 (when (eq? c1 (integer->char 127))1101 (##sys#error1102 'load1103 (##sys#string-append1104 "unable to load compiled module - "1105 (or _dlerror "unknown reason"))1106 fname)))1107 (let ((x1 (read-with-source-info in)))1108 (do ((x x1 (read-with-source-info in)))1109 ((eof-object? x))1110 (when printer (printer x))1111 (##sys#call-with-values1112 (lambda ()1113 (if timer1114 (time (evalproc x))1115 (evalproc x)))1116 (lambda results1117 (when pf1118 (for-each1119 (lambda (r)1120 (write r)1121 (newline))1122 results)))))))1123 (lambda ()1124 (case-sensitive cs)1125 (close-input-port in))))))))1126 (##core#undefined))))11271128(define evaluator1129 (let ((eval eval))1130 (lambda (x)1131 (cond ((procedure? x) x)1132 ((not x) #f)1133 (else (lambda (y) (eval y x)))))))11341135(set! scheme#load1136 (lambda (filename #!optional env)1137 (load/internal filename (evaluator env))))11381139(define (load-relative filename #!optional env)1140 (let ((fn (make-relative-pathname ##sys#current-load-filename filename)))1141 (load/internal fn (evaluator env))))11421143(define (load-noisily filename #!key env (time #f) (printer #f))1144 (load/internal filename (evaluator env) #t time printer))11451146(define dynamic-load-libraries1147 (let ((ext1148 (if uses-soname?1149 (string-append1150 load-library-extension1151 "."1152 (number->string binary-version))1153 load-library-extension)))1154 (define complete1155 (cut ##sys#string-append <> ext))1156 (make-parameter1157 (map complete default-dynamic-load-libraries)1158 (lambda (x)1159 (##sys#check-list x)1160 x) ) ) )11611162(define (load-unit unit-name lib loc)1163 (unless (##sys#provided? unit-name)1164 (let ((libs1165 (if lib1166 (##sys#list lib)1167 (cons (##sys#string-append (##sys#symbol->string/shared unit-name) load-library-extension)1168 (dynamic-load-libraries))))1169 (top1170 (c-toplevel unit-name loc)))1171 (when (load-verbose)1172 (display "; loading library ")1173 (display unit-name)1174 (display " ...\n"))1175 (let loop ((libs libs))1176 (cond ((null? libs)1177 (##sys#error loc "unable to load library" unit-name (or _dlerror "library not found")))1178 ((##sys#dload (##sys#make-c-string (##sys#slot libs 0) 'load-library) top)1179 (##core#undefined))1180 (else1181 (loop (##sys#slot libs 1))))))))11821183(define (load-library unit-name #!optional lib)1184 (##sys#check-symbol unit-name 'load-library)1185 (unless (not lib) (##sys#check-string lib 'load-library))1186 (load-unit unit-name lib 'load-library))11871188(define ##sys#include-forms-from-file1189 (let ((call-with-input-file call-with-input-file)1190 (reverse reverse))1191 (lambda (filename source ci k)1192 (let ((path (##sys#resolve-include-filename filename #t #f source))1193 (read-with-source-info chicken.syntax#read-with-source-info)) ; OBSOLETE - after bootstrapping we can get rid of this explicit namespacing1194 (when (not path)1195 (##sys#signal-hook #:file-error 'include "cannot open file" filename))1196 (when (load-verbose)1197 (print "; including " path " ..."))1198 (call-with-input-file path1199 (lambda (in)1200 (let ((oldci (##sys#slot in 13)))1201 (k (fluid-let ((##sys#current-source-filename path))1202 (##sys#setislot in 13 (not ci))1203 (do ((x (read-with-source-info in) (read-with-source-info in))1204 (xs '() (cons x xs)))1205 ((eof-object? x)1206 (##sys#setislot in 13 oldci)1207 (reverse xs))))1208 path))))))))120912101211;;; Extensions:12121213(define ##sys#setup-mode #f)12141215(define (file-exists? name) ; defined here to avoid file unit dependency1216 (and (##sys#file-exists? name #t #f #f) name))12171218(define (find-file name search-path)1219 (cond ((not search-path) #f)1220 ((null? search-path) #f)1221 ((string? search-path) (find-file name (list search-path)))1222 ((file-exists? (string-append (car search-path) "/" name)))1223 (else (find-file name (cdr search-path)))))12241225(define find-dynamic-extension1226 (let ((string-append string-append))1227 (lambda (id inc?)1228 (let ((rp (repository-path))1229 (basename (if (symbol? id) (symbol->string id) id)))1230 (define (check path)1231 (let ((p0 (string-append path "/" basename)))1232 (or (and rp1233 (not ##sys#dload-disabled)1234 (feature? #:dload)1235 (file-exists? (##sys#string-append p0 ##sys#load-dynamic-extension)))1236 (file-exists? (##sys#string-append p0 source-file-extension)))))1237 (let loop ((paths (##sys#append1238 (if ##sys#setup-mode '(".") '())1239 (or rp '())1240 (if inc? ##sys#include-pathnames '())1241 (if ##sys#setup-mode '() '("."))) ))1242 (and (pair? paths)1243 (let ((pa (##sys#slot paths 0)))1244 (or (check pa)1245 (loop (##sys#slot paths 1)) ) ) ) ) ) ) ))12461247(define-inline (extension-loaded? lib mod)1248 (cond ((##sys#provided? lib))1249 ((eq? mod #t)1250 (##sys#provided? (module-requirement lib)))1251 ((symbol? mod)1252 (##sys#provided? (module-requirement mod)))1253 (else #f)))12541255(define (load-extension lib mod loc)1256 (unless (extension-loaded? lib mod)1257 (cond ((memq lib core-units)1258 (load-unit lib #f loc))1259 ((find-dynamic-extension lib #f) =>1260 (lambda (ext)1261 (load/internal ext #f #f #f #f #f lib)1262 (##sys#provide lib)1263 (##core#undefined)))1264 (else1265 (##sys#error loc "cannot load extension" lib)))))12661267(define (require . ids)1268 (for-each (cut ##sys#check-symbol <> 'require) ids)1269 (for-each (cut load-extension <> #f 'require) ids))12701271(define (provide . ids)1272 (for-each (cut ##sys#check-symbol <> 'provide) ids)1273 (for-each (cut ##sys#provide <>) ids))12741275(define (provided? . ids)1276 (for-each (cut ##sys#check-symbol <> 'provided?) ids)1277 (every ##sys#provided? ids))12781279;; Export for internal use in the expansion of `##core#require':1280(define chicken.load#load-unit load-unit)1281(define chicken.load#load-extension load-extension)12821283;; Export for internal use in csc, modules and batch-driver:1284(define chicken.load#find-file find-file)1285(define chicken.load#find-dynamic-extension find-dynamic-extension)12861287;; Do the right thing with a `##core#require' form.1288(define (##sys#process-require lib mod compile-mode)1289 (let ((mod (or (eq? lib mod) mod)))1290 (cond1291 ((assq lib core-unit-requirements) => cdr)1292 ((memq lib core-units)1293 (if compile-mode1294 `(##core#callunit ,lib)1295 `(chicken.load#load-unit (##core#quote ,lib)1296 (##core#quote #f)1297 (##core#quote #f))))1298 ((eq? compile-mode 'static)1299 `(##core#callunit ,lib))1300 (else1301 `(chicken.load#load-extension (##core#quote ,lib)1302 (##core#quote ,mod)1303 (##core#quote #f))))))13041305;;; Find included file:13061307(define ##sys#resolve-include-filename1308 (let ((string-append string-append) )1309 (lambda (fname exts repo source)1310 (define (test-extensions fname lst)1311 (if (null? lst)1312 (and (file-exists? fname) fname)1313 (let ((fn (##sys#string-append fname (car lst))))1314 (or (file-exists? fn)1315 (test-extensions fname (cdr lst))))))1316 (define (test fname)1317 (test-extensions1318 fname1319 (cond ((pair? exts) exts) ; specific list of extensions1320 ((not (feature? #:dload)) ; no dload -> source only1321 (list source-file-extension))1322 ((not exts) ; prefer compiled1323 (list ##sys#load-dynamic-extension source-file-extension))1324 (else ; prefer source1325 (list source-file-extension ##sys#load-dynamic-extension)))))1326 (or (test (make-relative-pathname source fname))1327 (let loop ((paths (if repo1328 (##sys#append1329 ##sys#include-pathnames1330 (or (repository-path) '()) )1331 ##sys#include-pathnames) ) )1332 (cond ((eq? paths '()) #f)1333 ((test (string-append (##sys#slot paths 0)1334 "/"1335 fname) ) )1336 (else (loop (##sys#slot paths 1))) ) ) ) ) ) )13371338) ; chicken.load133913401341;;; Simple invocation API:13421343(import scheme chicken.base chicken.condition chicken.eval chicken.fixnum chicken.load)1344(import (only (scheme base) open-output-string get-output-string open-input-string))13451346(declare1347 (hide last-error run-safe store-result store-string1348 CHICKEN_yield CHICKEN_eval CHICKEN_eval_string1349 CHICKEN_eval_to_string CHICKEN_eval_string_to_string1350 CHICKEN_apply CHICKEN_apply_to_string CHICKEN_eval_apply1351 CHICKEN_read CHICKEN_load CHICKEN_get_error_message))13521353(define last-error #f)13541355(define (run-safe thunk)1356 (set! last-error #f)1357 (handle-exceptions ex1358 (let ((o (open-output-string)))1359 (print-error-message ex o)1360 (set! last-error (get-output-string o))1361 #f)1362 (thunk) ) )13631364#>1365#define C_store_result(x, ptr) (*((C_word *)C_block_item(ptr, 0)) = (x), C_SCHEME_TRUE)1366<#13671368(define (store-result x result)1369 (##sys#gc #f)1370 (when result1371 (##core#inline "C_store_result" x result) )1372 #t)13731374(define-external (CHICKEN_yield) bool1375 (run-safe (lambda () (begin (##sys#thread-yield!) #t))) )13761377(define-external (CHICKEN_eval (scheme-object exp) ((c-pointer "C_word") result)) bool1378 (run-safe1379 (lambda ()1380 (store-result (eval exp) result))))13811382(define-external (CHICKEN_eval_string (c-string str) ((c-pointer "C_word") result)) bool1383 (run-safe1384 (lambda ()1385 (let ((i (open-input-string str)))1386 (store-result (eval (read i)) result)))))13871388#>1389#define C_copy_result_string(str, buf, n) (C_memcpy((char *)C_block_item(buf, 0), C_c_string(str), C_unfix(n)), ((char *)C_block_item(buf, 0))[ C_unfix(n) ] = '\0', C_SCHEME_TRUE)1390<#13911392(define (store-string str bufsize buf)1393 (let* ((bv (##sys#slot str 0))1394 (len (fx- (##sys#size bv) 1)))1395 (cond ((fx>= len bufsize)1396 (set! last-error "Error: not enough room for result string")1397 #f)1398 (else (##core#inline "C_copy_result_string" bv buf len)) ) ) )13991400(define-external (CHICKEN_eval_to_string (scheme-object exp) ((c-pointer "char") buf)1401 (int bufsize))1402 bool1403 (run-safe1404 (lambda ()1405 (let ((o (open-output-string)))1406 (write (eval exp) o)1407 (store-string (get-output-string o) bufsize buf)) ) ) )14081409(define-external (CHICKEN_eval_string_to_string (c-string str) ((c-pointer "char") buf)1410 (int bufsize) )1411 bool1412 (run-safe1413 (lambda ()1414 (let ((o (open-output-string)))1415 (write (eval (read (open-input-string str))) o)1416 (store-string (get-output-string o) bufsize buf)) ) ) )14171418(define-external (CHICKEN_apply (scheme-object func) (scheme-object args)1419 ((c-pointer "C_word") result))1420 bool1421 (run-safe (lambda () (store-result (apply func args) result))) )14221423(define-external (CHICKEN_apply_to_string (scheme-object func) (scheme-object args)1424 ((c-pointer "char") buf) (int bufsize))1425 bool1426 (run-safe1427 (lambda ()1428 (let ((o (open-output-string)))1429 (write (apply func args) o)1430 (store-string (get-output-string o) bufsize buf)) ) ) )14311432(define-external (CHICKEN_read (c-string str) ((c-pointer "C_word") result)) bool1433 (run-safe1434 (lambda ()1435 (let ((i (open-input-string str)))1436 (store-result (read i) result) ) ) ) )14371438(define-external (CHICKEN_load (c-string str)) bool1439 (run-safe (lambda () (load str) #t)))14401441(define-external (CHICKEN_get_error_message ((c-pointer "char") buf) (int bufsize)) void1442 (store-string (or last-error "No error") bufsize buf) )