diff options
| author | Rose Hogenson <rhogenson@posteo.net> | 2022-07-28 15:41:42 -0700 |
|---|---|---|
| committer | Rose Hogenson <rhogenson@posteo.net> | 2022-07-28 15:41:42 -0700 |
| commit | 2c1bab05d6c2debf71ea313901dc751a753880c4 (patch) | |
| tree | 99dc7af695350b8606b17888f3bef0c6a2a4d79a /csc/linker.csc | |
| parent | 043088d914695baf54cea2296293e9e9ca1b325e (diff) | |
| download | chromatopelma-2c1bab05d6c2debf71ea313901dc751a753880c4.tar.zst | |
Use a better interface for linker.
Diffstat (limited to 'csc/linker.csc')
| -rw-r--r-- | csc/linker.csc | 73 |
1 files changed, 51 insertions, 22 deletions
diff --git a/csc/linker.csc b/csc/linker.csc index dc738b7..9095647 100644 --- a/csc/linker.csc +++ b/csc/linker.csc @@ -1,16 +1,25 @@ (define-library (csc linker) - (export link) + (export + add-to-environment + compare-globals + link) (import (scheme base) + (only (csc format) + sprintf) (only (csc hash-map) compare-numbers + hash-bytevector insert lookup + make-comparer make-map map-for-each) (only (csc loop) loop return) - (only (csc match) match)) + (only (csc match) match) + (only (scheme case-lambda) + case-lambda)) (begin ; A CSC bytecode program is a list of opcodes and labels. An opcode is a ; list of an opcode and arguments. Arguments can be any of: @@ -50,37 +59,57 @@ finally (return m))) - (define (translate-globals program environment) + (define (add-to-environment environment programs) (define next-global-id 0) (map-for-each (lambda (k v) (when (>= v next-global-id) (set! next-global-id (+ 1 v)))) environment) - (define (translate-global x) - (or (lookup environment x #f) - (let ((id next-global-id)) - (set! next-global-id (+ 1 next-global-id)) - (set! environment (insert environment x id)) - id))) + (loop for opcode in (apply append programs) + do (loop for arg in (cdr opcode) + do (match arg + (('global name lib) + (define id next-global-id) + (set! next-global-id (+ 1 next-global-id)) + (set! environment (insert environment arg id)))))) + environment) + + + (define compare-globals + (make-comparer + (lambda (x) + (hash-bytevector (string->utf8 (sprintf "{}" x)))) + (lambda (x y) + (cond + ((equal? x y) 0) + ((string<? (sprintf "{}" x) (sprintf "{}" y)) -1) + (else 1))))) + + + (define (translate-globals program environment) (loop for opcode in program for op = (car opcode) for args = (cdr opcode) collect (cons op (loop for arg in args collect (match arg (('global x lib) - (list 'const (translate-global arg))) + (list 'const (lookup environment arg))) (_ arg)))))) - (define (link programs environment) - (translate-globals - (loop for prog in programs - for off = 0 then (+ off (length converted-prog)) - for converted-prog = (let ((prog-prelude (cons - (list 'jmp '(label init)) - prog))) - (translate-labels - prog-prelude - (make-label-map off prog-prelude))) - append converted-prog) - environment)))) + (define link + (case-lambda + ((programs environment) + (translate-globals + (loop for prog in programs + for off = 0 then (+ off (length converted-prog)) + for converted-prog = (let ((prog-prelude (cons + (list 'jmp '(label init)) + prog))) + (translate-labels + prog-prelude + (make-label-map off prog-prelude))) + append converted-prog) + environment)) + ((programs) + (link programs (add-to-environment (make-map compare-globals) programs))))))) |
