Compiler bones, definitely not correct right now

This commit is contained in:
2026-01-19 22:02:26 -06:00
parent 244cd5e967
commit 43642ca025

View File

@@ -1,6 +1,7 @@
(define-module (scmvm language scheme) (define-module (scmvm language scheme)
#:use-module (scmvm assembler) #:use-module (scmvm assembler)
#:use-module (srfi srfi-1) #:use-module (srfi srfi-1)
#:use-module (srfi srfi-9)
#:use-module (srfi srfi-26) #:use-module (srfi srfi-26)
#:use-module (ice-9 match) #:use-module (ice-9 match)
#:use-module ((rnrs base) #:use-module ((rnrs base)
@@ -34,6 +35,11 @@
(define (primitive? x) (define (primitive? x)
(memq x primitives)) (memq x primitives))
(define (constant? x)
(or (number? x)
(boolean? x)
(and (pair? x) (eq? 'quote (car x)))))
(define-syntax-rule (define-cps-loop name unit) (define-syntax-rule (define-cps-loop name unit)
(define (name v* k) (define (name v* k)
(if (null? v*) (if (null? v*)
@@ -99,15 +105,18 @@
;; "lambda-like" format ;; "lambda-like" format
;; - begin expressions are decomposed ;; - begin expressions are decomposed
;; - let expressions are transformed into closed function applications ;; - let expressions are transformed into closed function applications
;; <prgm> ::= <top> ... ;; - defines are replaced with letrecs
;; <top> ::= <def> | <exp> ;; - All arguments to applications are atomic
;; <def> ::= (define <var> <exp>) ;; - All abstractions take an explicit continuation, all applications pass an
;; explicit continuation as the final parameter
;;
;; <prgm> ::= (<exp>)
;; <exp> ::= <aexp> ;; <exp> ::= <aexp>
;; | <cexp> ;; | <cexp>
;; <cexp> ::= (<aexp> <aexp> ...) ;; <cexp> ::= (<aexp> <aexp> ...)
;; | (if <aexp> <cexp> <cexp>) ;; | (if <aexp> <cexp> <cexp>)
;; | (set-then! <var> <aexp> <cexp>) ;; | (set-then! <var> <aexp> <cexp>)
;; | (define-then! <var> <aexp> <cexp>) ;; | (letrec ((<var> <aexp>)) <cexp>)
;; <aexp> ::= (lambda (<var> ...) exp) ;; <aexp> ::= (lambda (<var> ...) exp)
;; | <num> | <var> | #t | #f ;; | <num> | <var> | #t | #f
;; ;;
@@ -118,6 +127,7 @@
(define (M expr) (define (M expr)
;; M dispatches to the appropriate transformer ;; M dispatches to the appropriate transformer
;; expr -> aexp
(match expr (match expr
[('lambda (var ...) e) [('lambda (var ...) e)
(let ([$k (gensym "$k-")]) (let ([$k (gensym "$k-")])
@@ -125,42 +135,17 @@
[(? primitive?) `(cps-prim ,expr)] [(? primitive?) `(cps-prim ,expr)]
[(? atomic?) expr])) [(? atomic?) expr]))
(define (T-k expr k)
;; T-k takes an explicit continuation and calls it when done
;; As an invariant, T-k cannot nest a T-c call directly
(match expr
[`(lambda . ,_) (k (M expr))]
[ (? atomic?) (k (M expr))]
[ ('define v e) (T-k e (lambda ($e) `(letrec ([,v ,$e]) ,(k))))]
[ ('begin e) (T-k e k)]
[ ('begin e e* ...)
(T-k e (lambda _ (T-k `(begin ,@e*) k)))]
[ ('let ([v* e*] ...) body)
(T-k `((lambda (,@v*) ,body) ,@e*) k)]
[ ('if exp1 exp2 exp3)
(T-k exp1 (lambda ($exp1)
`(if ,$exp1
,(T-k exp2 k)
,(T-k exp3 k))))]
[ ('set! var expr)
(T-k expr (lambda ($expr)
`(set-then! ,var ,$expr ,(k undefined-value))))]
[(f e* ...)
(let* ([$rv (gensym "$rv-")]
[cont `(lambda (,$rv) ,(k $rv))])
(T-k f (lambda ($f)
(T*-k e* (lambda ($e*)
`(,$f ,@$e* ,cont))))))]))
(define (T-c expr c) (define (T-c expr c)
;; T-c takes a symbolic continuation, and uses it to construct CPS ;; T-c takes a symbolic continuation, and uses it to construct CPS
;; (expr * aexp) -> cexp
(match expr (match expr
[`(lambda . ,_) `(,c ,(M expr))] [`(lambda . ,_) `(,c ,(M expr))]
[ (? atomic?) `(,c ,(M expr))] [ (? atomic?) `(,c ,(M expr))]
[ ('define v e) (T-k e (lambda ($e) `(letrec ([,v ,$e]) ,c)))] [ ('define v e) (T-k e (lambda ($e) `(letrec ([,v ,$e]) ,c)))]
[ ('begin e) (T-c e c)] [ ('begin e) (T-c e c)]
[ ('begin e e* ...) [ ('begin e e* ...)
(T-k e (lambda _ (T-c `(begin ,@e*) c)))] (T-k e (lambda _
(T-c `(begin ,@e*) c)))]
[ ('let ([v* e*] ...) body) [ ('let ([v* e*] ...) body)
(T-c `((lambda (,@v*) ,body) ,@e*) c)] (T-c `((lambda (,@v*) ,body) ,@e*) c)]
[ ('if exp1 exp2 exp3) [ ('if exp1 exp2 exp3)
@@ -179,11 +164,41 @@
(T*-k e* (lambda ($e*) (T*-k e* (lambda ($e*)
`(,$f ,@$e* ,c)))))])) `(,$f ,@$e* ,c)))))]))
(define (T-k expr k)
;; T-k takes an explicit continuation and calls it when done
;; As an invariant, T-k cannot nest a T-c call directly
;; (expr * (aexp -> cexp) -> cexp)
(match expr
[`(lambda . ,_) (k (M expr))]
[ (? atomic?) (k (M expr))]
[ ('define v e) (T-k e (lambda ($e) `(letrec ([,v ,$e]) ,(k))))]
[ ('begin e) (T-k e k)]
[ ('begin e e* ...)
(T-k e (lambda _
(T-k `(begin ,@e*) k)))]
[ ('let ([v* e*] ...) body)
(T-k `((lambda (,@v*) ,body) ,@e*) k)]
[ ('if exp1 exp2 exp3)
(T-k exp1 (lambda ($exp1)
`(if ,$exp1
,(T-k exp2 k)
,(T-k exp3 k))))]
[ ('set! var expr)
(T-k expr (lambda ($expr)
`(set-then! ,var ,$expr ,(k undefined-value))))]
[(f e* ...)
(let* ([$rv (gensym "$rv-")]
[cont `(lambda (,$rv) ,(k $rv))])
(T-k f (lambda ($f)
(T*-k e* (lambda ($e*)
`(,$f ,@$e* ,cont))))))]))
;; (expr* * (aexp* -> cexp) -> cexp)
(define-cps-loop T*-k T-k)
(define (cps-convert-prgm prgm tail) (define (cps-convert-prgm prgm tail)
(T-c `(begin ,@prgm) tail)) (T-c `(begin ,@prgm) tail))
(define-cps-loop T*-k T-k)
(define* (ir-convert prgm #:optional (tail 'ktail)) (define* (ir-convert prgm #:optional (tail 'ktail))
(cps-convert-prgm (desugar-prgm prgm) tail)) (cps-convert-prgm (desugar-prgm prgm) tail))
@@ -193,3 +208,134 @@
(match-lambda* (match-lambda*
[(args ... k) (k (apply x args))]) [(args ... k) (k (apply x args))])
x)) x))
;; Compilation
(define (meaning e r)
(match e
[(? constant?) (meaning-constant e)]
[(? symbol?) (meaning-reference e r)]
[('cps-prim e) (meaning-primitive-reference e)]
[('lambda (v* ...) e)
(meaning-abstraction v* e r)]
[('set-then! v e k)
(meaning-assignment v e r k)]
[('if e k1 k2)
(meaning-alternative e r k1 k2)]
[('letrec ([v e]) k)
(meaning-definition v e r k)]
[(f e* ... k)
(meaning-application f e* r k)]
[_ (signal-exception "Unrecognized cps" e)]))
(define (meaning-constant e)
(cond
[(number? e) (+number+ e)]
[(boolean? e) (+boolean+ e)]
[else (+quotation+ e)]))
(define (meaning-reference e r)
(match (locate-reference e r)
[('local 0 i) (+shallow-reference+ i)]
[('local j i) (+deep-reference+ j i)]
[('global i) (+global-reference+ i)]
[_ (signal-exception "Undefined reference" e)]))
(define (meaning-primitive-reference e)
(+primitive-reference+ e))
(define (meaning-abstraction v* e r)
(let* ([lambda-label (gensym "lambda-")]
[endlambda-label (gensym "endlambda-")]
[r0 (r-extend* r v*)]
[m (meaning e r0)])
(meaning-append
(+closure+ 1)
(+goto+ endlambda-label)
(+label+ lambda-label)
(+extend-environment+)
m
(+unlink-environment+)
(+return+)
(+label+ endlambda-label))))
(define (meaning-application f e* r k)
(let* ([mf (meaning f r)]
[m* (meaning* e* r)]
[mk (meaning k r)])
(meaning-append
mf
m*
(+function-invoke+)
mk)))
(define (meaning-alternative e r k1 k2)
(let* ([m (meaning e r)]
[mk1 (meaning k1 r)]
[mk2 (meaning k2 r)]
[jump-false-label (gensym "jump-false-")]
[endif-label (gensym "endif-")])
(meaning-append
m
(+jump-false+ jump-false-label)
mk1
(+goto+ endif-label)
(+label+ jump-false-label)
mk2
(+label+ endif-label))))
(define (meaning-assignment v e r k)
(let* ([m (meaning e r)]
[r0 (r-extend r v)]
[mk (meaning k r0)])
(meaning-append
m mk)))
(define (meaning-definition v e r k)
(let* ([r0 (r-extend r v)]
[m (meaning e r0)]
[mk (meaning k r0)])
(meaning-append m mk)))
(define (meaning* e* r)
(map (lambda (e) (meaning e r)) e*))
(define meaning-append append)
(define signal-exception error)
(define (r-extend r v)
(cons (list v) r))
(define (r-extend* r v*)
(cons v* r))
(define (locate-local-reference n j r)
(cond
[(null? r) #f]
[(list-index (lambda (n0) (eq? n n0)) (car r)) => (lambda (i) `(local ,j ,i))]
[else (locate-local-reference n (+ j 1) (cdr r))]))
(define (locate-reference n r)
(cond
[(locate-local-reference n 0 r) => identity]))
(define-syntax define-combinator
(syntax-rules ()
[(_ (name args ...))
(define (name args ...) `((name ,@(list args ...))))]))
(define-combinator (+number+ val))
(define-combinator (+boolean+ val))
(define-combinator (+quotation+ val))
(define-combinator (+global-reference+ i))
(define-combinator (+deep-reference+ i j))
(define-combinator (+shallow-reference+ i))
(define-combinator (+primitive-reference+ p))
(define-combinator (+closure+ offset))
(define-combinator (+goto+ label))
(define-combinator (+label+ name))
(define-combinator (+extend-environment+))
(define-combinator (+unlink-environment+))
(define-combinator (+function-invoke+))
(define-combinator (+jump-false+ label))
(define-combinator (+return+))