blob: 238fbc5bfc9343ca3c3b17b76b8b5ec22f320b4b (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
(define-library (csc linker)
(export link)
(import (scheme base)
(only (csc hash-map)
compare-numbers
insert
lookup
make-map
map-for-each)
(only (csc loop)
loop
return)
(only (csc match) match))
(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:
; - (local x),
; - (global x lib),
; - (const x),
; - or (label x).
; The full list of opcodes can be found in encoding.csc.
; Rewrites each (label x) form into a integer constant.
(define (translate-labels program label-map)
(loop for opcode in program
for op = (car opcode)
for args = (cdr opcode)
unless (symbol=? op 'label)
collect (cons op (loop for arg in args
collect (match arg
(('label x)
(list 'const (lookup label-map x)))
(_ arg))))))
(define (make-label-map offset program)
(loop for op in program
for i from offset
with m = (make-map compare-numbers)
do (match op
(('label id)
(set! m (insert m id i))
(set! i (- i 1)))) ; Labels will be removed later.
finally (return m)))
(define (translate-globals program environment)
(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 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)))
(_ arg))))))
(define (link programs environment)
(translate-globals
(loop for prog in programs
for off = 0 then (+ off (length converted-prog))
for converted-prog = (translate-labels
prog
(make-label-map off prog))
append converted-prog)
environment))))
|