X-Git-Url: http://git.lukelau.me/?a=blobdiff_plain;f=codegen.scm;h=571f1ef8498c0a662f3dfa7254b0cf2f535e4374;hb=a006c661a194672c2d8f5730d3c207dd083ddbf0;hp=9b3878a2e947f3d3314c8c9c4bc96bca38a83a7f;hpb=6f699d1ddbb1cd33ec3095a0e6e9a6eee157d708;p=scheme.git diff --git a/codegen.scm b/codegen.scm index 9b3878a..571f1ef 100644 --- a/codegen.scm +++ b/codegen.scm @@ -105,8 +105,25 @@ (set! cur-lambda (+ 1 cur-lambda)) (format "_lambda~a" (- cur-lambda 1))) +; a closure on the heap looks like: +; 0-x x+0 x+4 x+12 x+20 +; label #vars var1.... var2.... var3.... +(define (codegen-closure label captured si env) + (let* ((heap-offsets (range 4 (length captured))) ; 4, 12, 20, etc. + (inner-si (- si (* (length captured) wordsize)))) + (emit "movl $~a, (heap_start)") + (emit "add $4, (heap_start)") + (for-each (lambda (var-name new-offset) + (emit "movq ~a(%rbp), ~a(heap_start)" ; todo: do we need to copy this? + (cdr (assoc var-name env)) + new-offset) + (emit "add $8, (heap_start)") + captured + stack-offsets) +) ; for now we can only call closures (define (codegen-call closure args si env) +; (codegen-expr closure si env) (when (not (eq? (ast-type closure) 'closure)) (error #f (format "~a is not a closure" closure))) (let* ((captured (caddr closure)) @@ -190,7 +207,7 @@ (define (codegen-expr e si env) (case (ast-type e) ('builtin e) - ('closure e) + ('closure (codegen-closure (cadr e) (caddr e) si env)) ('app (let ((callee (codegen-expr (car e) si env))) (case callee