Skip to content

Commit fdcec1d

Browse files
committed
Initial sketch of instruction annotation mechanism.
1 parent 99cece1 commit fdcec1d

3 files changed

Lines changed: 98 additions & 53 deletions

File tree

langs/a86/ast.rkt

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,46 +7,46 @@
77
;; with decent error messages.
88

99
(define check:label-symbol
10-
(λ (x n)
10+
(λ (a x n)
1111
(when (register? x)
1212
(error n "cannot use register as label name; given ~v" x))
1313
(unless (symbol? x)
1414
(error n "expects symbol; given ~v" x))
1515
(unless (label? x)
1616
(error n "label names must conform to nasm restrictions"))
17-
x))
17+
(values a x)))
1818

1919
(define check:label-symbol+integer
20-
(λ (x c n)
20+
(λ (a x c n)
2121
(check:label-symbol x n)
2222
(unless (integer? c)
2323
(error n "expects integer constant; given ~v" c))
24-
(values x c)))
24+
(values a x c)))
2525

2626
(define check:target
27-
(λ (x n)
27+
(λ (a x n)
2828
(unless (or (symbol? x) (offset? x)); either register or label
2929
(error n "expects symbol; given ~v" x))
30-
x))
30+
(values a x)))
3131

3232
(define check:arith
33-
(λ (a1 a2 n)
33+
(λ (a a1 a2 n)
3434
(unless (register? a1)
3535
(error n "expects register; given ~v" a1))
3636
(unless (or (exact-integer? a2) (register? a2) (offset? a2))
3737
(error n "expects exact integer, register, or offset; given ~v" a2))
3838
(when (and (exact-integer? a2) (> (integer-length a2) 32))
3939
(error n "literal must not exceed 32-bits; given ~v (~v bits); go through a register instead" a2 (integer-length a2)))
40-
(values a1 a2)))
40+
(values a a1 a2)))
4141

4242
(define check:register
43-
(λ (a1 n)
43+
(λ (a a1 n)
4444
(unless (register? a1)
4545
(error n "expects register; given ~v" a1))
46-
a1))
46+
(values a a1)))
4747

4848
(define check:src-dest
49-
(λ (a1 a2 n)
49+
(λ (a a1 a2 n)
5050
(unless (or (register? a1) (offset? a1))
5151
(error n "expects register or offset; given ~v" a1))
5252
(unless (or (register? a2) (offset? a2) (exact-integer? a2) (Const? a2))
@@ -57,10 +57,10 @@
5757
(error n "literal must not exceed 32-bits; given ~v (~v bits); go through a register instead" a2 (integer-length a2)))
5858
(when (and (offset? a1) (exact-integer? a2))
5959
(error n "cannot use a memory locations and literal; given ~v, ~v; go through a register instead" a1 a2))
60-
(values a1 a2)))
60+
(values a a1 a2)))
6161

6262
(define check:mov
63-
(λ (a1 a2 n)
63+
(λ (a a1 a2 n)
6464
(unless (or (register? a1) (offset? a1))
6565
(error n "expects register or offset; given ~v" a1))
6666
(unless (or (register? a2) (offset? a2) (exact-integer? a2) (Const? a2))
@@ -71,43 +71,43 @@
7171
(error n "literal must not exceed 64-bits; given ~v (~v bits)" a2 (integer-length a2)))
7272
(when (and (offset? a1) (exact-integer? a2))
7373
(error n "cannot use a memory locations and literal; given ~v, ~v; go through a register instead" a1 a2))
74-
(values a1 a2)))
74+
(values a a1 a2)))
7575

7676
(define check:shift
77-
(λ (a1 a2 n)
77+
(λ (a a1 a2 n)
7878
(unless (register? a1)
7979
(error n "expects register; given ~v" a1))
8080
(unless (or (and (exact-integer? a2) (<= 0 a2 63))
8181
(eq? 'cl a2))
8282
(error n "expects exact integer in [0,63]; given ~v" a2))
83-
(values a1 a2)))
83+
(values a a1 a2)))
8484

8585
(define check:offset
86-
(λ (r i n)
86+
(λ (a r i n)
8787
(unless (or (register? r) (label? r))
8888
(error n "expects register or label as first argument; given ~v" r))
8989
(unless (exact-integer? i)
9090
(error n "expects exact integer as second argument; given ~v" i))
91-
(values r i)))
91+
(values a r i)))
9292

9393
(define check:push
94-
(λ (a1 n)
94+
(λ (a a1 n)
9595
(unless (or (exact-integer? a1) (register? a1))
9696
(error n "expects exact integer or register; given ~v" a1))
9797
(when (and (exact-integer? a1) (> (integer-length a1) 32))
9898
(error n "literal must not exceed 32-bits; given ~v (~v bits); go through a register instead" a1 (integer-length a1)))
99-
a1))
99+
(values a a1)))
100100

101101
(define check:lea
102-
(λ (dst x n)
102+
(λ (a dst x n)
103103
(unless (or (register? dst) (offset? dst))
104104
(error n "expects register or offset; given ~v" dst))
105105
(unless (or (label? x) (offset? x) (exp? x))
106106
(error n "expects label, offset, or expression; given ~v" x))
107-
(values dst x)))
107+
(values a dst x)))
108108

109109
(define check:none
110-
(λ (n) (values)))
110+
(λ (a n) (values a)))
111111

112112
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
113113
;; Comments
@@ -132,12 +132,42 @@
132132
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
133133
;; Instructions
134134

135-
(define-syntax-rule
136-
(instruct Name (x ...) guard)
137-
(begin (provide (struct-out Name))
138-
(struct Name (x ...)
139-
#:transparent
140-
#:guard guard)))
135+
(require racket/struct)
136+
(define current-annotation (make-parameter #f))
137+
(provide instruction-annotation current-annotation)
138+
139+
(struct instruction (annotation))
140+
141+
(define-syntax (instruct stx)
142+
(syntax-case stx ()
143+
[(instruct Name (x ...) guard)
144+
(with-syntax ([Name? (datum->syntax stx (string->symbol (string-append (symbol->string (syntax->datum #'Name)) "?")))])
145+
#'(begin (provide Name Name?)
146+
(define-match-expander Name
147+
(lambda (stx)
148+
(syntax-case stx ()
149+
[(_ elts (... ...))
150+
#'(%Name _ elts (... ...))]))
151+
(lambda (stx)
152+
(syntax-case stx ()
153+
[m (identifier? #'m) #'(λ (x ...) (%Name (current-annotation) x ...))]
154+
[(m x ...) #'(%Name (current-annotation) x ...)])))
155+
(struct %Name instruction (x ...)
156+
#:transparent
157+
#:guard guard
158+
#:methods gen:equal+hash
159+
[(define equal-proc (λ (i1 i2 equal?)
160+
(equal? (struct->vector i1)
161+
(struct->vector i2))))
162+
(define hash-proc (λ (i hash) (hash (struct->vector i))))
163+
(define hash2-proc (λ (i hash) (hash (struct->vector i))))]
164+
#:methods gen:custom-write
165+
[(define write-proc
166+
(make-constructor-style-printer
167+
(lambda (obj) 'Name)
168+
(lambda (obj)
169+
(rest (rest (vector->list (struct->vector obj)))))))])
170+
(define Name? %Name?)))]))
141171

142172
(instruct Text () check:none)
143173
(instruct Data () check:none)
@@ -167,15 +197,15 @@
167197
(instruct Lea (dst x) check:lea)
168198
(instruct Div (den) check:register)
169199

170-
(instruct Offset (r i) check:offset)
200+
(instruct Offset (r i) check:offset) ;; May need to make this not an instruction
171201
(instruct Extern (x) check:label-symbol)
172202

173203
(instruct Equ (x v) check:label-symbol+integer)
174204
(instruct Const (x) check:label-symbol)
175205

176206
;; IMPROVE: do more checking
177-
(instruct Dd (x) (lambda (x n) x))
178-
(instruct Dq (x) (lambda (x n) x))
207+
(instruct Dd (x) (lambda (a x n) (values a x)))
208+
(instruct Dq (x) (lambda (a x n) (values a x)))
179209

180210
(provide (struct-out Plus))
181211
(struct Plus (e1 e2) #:transparent)
@@ -210,6 +240,7 @@
210240
(nasm-label? x)
211241
(not (register? x))))
212242

243+
#;
213244
(define (instruction? x)
214245
(or (Text? x)
215246
(Data? x)

langs/a86/printer.rkt

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,19 @@
7373
[_ (label-symbol->string e)]))
7474

7575
(define tab (make-string 8 #\space))
76+
77+
;; Instruction -> String
78+
(define (fancy-instr->string i)
79+
(let ((s (simple-instr->string i)))
80+
(if (instruction-annotation i)
81+
(if (< (string-length s) 40)
82+
(format "~a~a; ~.a" s (make-string (- 40 (string-length s)) #\space) (instruction-annotation i))
83+
(format "~a ; ~.a" s (instruction-annotation i)))
84+
s)))
85+
7686

7787
;; Instruction -> String
78-
(define (instr->string i)
88+
(define (simple-instr->string i)
7989
(match i
8090
[(Text) (string-append tab "section .text")]
8191
[(Data) (string-append tab "section .data align=8")] ; 8-byte aligned data
@@ -180,7 +190,7 @@
180190
[(%%% s) (string-append ";;; " s)]))
181191

182192
(define (line-comment i s)
183-
(let ((i-str (instr->string i)))
193+
(let ((i-str (simple-instr->string i)))
184194
(let ((pad (make-string (max 1 (- 32 (string-length i-str))) #\space)))
185195
(string-append i-str pad "; " s))))
186196

@@ -193,11 +203,11 @@
193203
(write-char #\newline)
194204
(instrs-display a))]
195205
[(cons i (cons (% s) a))
196-
(begin (write-string (line-comment i s))
206+
(begin (write-string (line-comment i s)) ; a line comment trumps an annotation
197207
(write-char #\newline)
198208
(instrs-display a))]
199209
[(cons i a)
200-
(begin (write-string (instr->string i))
210+
(begin (write-string (fancy-instr->string i))
201211
(write-char #\newline)
202212
(instrs-display a))]))
203213

langs/iniquity/compile.rkt

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
;; type CEnv = [Listof Variable]
1212

13+
(current-annotation "top-level")
14+
1315
;; Prog -> Asm
1416
(define (compile p)
1517
(match p
@@ -43,31 +45,33 @@
4345

4446
;; Defn -> Asm
4547
(define (compile-define d)
48+
(parameterize ([current-annotation d])
4649
(match d
4750
[(Defn f xs e)
4851
(seq (Label (symbol->label f))
4952
(compile-e e (reverse xs))
5053
(Add rsp (* 8 (length xs))) ; pop args
51-
(Ret))]))
54+
(Ret))])))
5255

5356
;; Expr CEnv -> Asm
5457
(define (compile-e e c)
55-
(match e
56-
[(Int i) (compile-value i)]
57-
[(Bool b) (compile-value b)]
58-
[(Char c) (compile-value c)]
59-
[(Eof) (compile-value eof)]
60-
[(Empty) (compile-value '())]
61-
[(Var x) (compile-variable x c)]
62-
[(Str s) (compile-string s)]
63-
[(Prim0 p) (compile-prim0 p c)]
64-
[(Prim1 p e) (compile-prim1 p e c)]
65-
[(Prim2 p e1 e2) (compile-prim2 p e1 e2 c)]
66-
[(Prim3 p e1 e2 e3) (compile-prim3 p e1 e2 e3 c)]
67-
[(If e1 e2 e3) (compile-if e1 e2 e3 c)]
68-
[(Begin e1 e2) (compile-begin e1 e2 c)]
69-
[(Let x e1 e2) (compile-let x e1 e2 c)]
70-
[(App f es) (compile-app f es c)]))
58+
(parameterize ([current-annotation e])
59+
(match e
60+
[(Int i) (compile-value i)]
61+
[(Bool b) (compile-value b)]
62+
[(Char c) (compile-value c)]
63+
[(Eof) (compile-value eof)]
64+
[(Empty) (compile-value '())]
65+
[(Var x) (compile-variable x c)]
66+
[(Str s) (compile-string s)]
67+
[(Prim0 p) (compile-prim0 p c)]
68+
[(Prim1 p e) (compile-prim1 p e c)]
69+
[(Prim2 p e1 e2) (compile-prim2 p e1 e2 c)]
70+
[(Prim3 p e1 e2 e3) (compile-prim3 p e1 e2 e3 c)]
71+
[(If e1 e2 e3) (compile-if e1 e2 e3 c)]
72+
[(Begin e1 e2) (compile-begin e1 e2 c)]
73+
[(Let x e1 e2) (compile-let x e1 e2 c)]
74+
[(App f es) (compile-app f es c)])))
7175

7276
;; Value -> Asm
7377
(define (compile-value v)

0 commit comments

Comments
 (0)