Skip to content

Commit 6849586

Browse files
committed
Better approach to constructing and printing Mem structs.
1 parent 85a78fd commit 6849586

2 files changed

Lines changed: 113 additions & 49 deletions

File tree

a86/ast.rkt

Lines changed: 112 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
(unless (nasm-label? x)
2222
(error n "label names must conform to nasm restrictions"))
2323
(values a ($ x))]
24-
[($ _)
24+
[($ _)
2525
(values a x)]
2626
[_
2727
(error n "expects valid label name; given ~v" x)])))
@@ -275,15 +275,15 @@
275275
(values x))
276276

277277
#;#;#;#:methods gen:equal+hash
278-
[(define equal-proc
278+
[(define equal-proc
279279
(λ (i1 i2 equal?)
280280
(equal? (->symbol i1)
281281
(->symbol i2))))
282282
(define hash-proc (λ (i hash) (hash (->symbol i))))
283283
(define hash2-proc (λ (i hash) (hash (->symbol i))))]
284284
#:property prop:custom-print-quotable 'never
285285
#;#;#;#:methods gen:custom-write
286-
[(define (write-proc label port mode)
286+
[(define (write-proc label port mode)
287287
(let ([recur (case mode
288288
[(#t) write]
289289
[(#f) display]
@@ -293,79 +293,143 @@
293293
(begin (if (number? mode)
294294
(write-string "($ " port)
295295
(write-string "#(struct:$ " port))
296-
(recur s port)
296+
(recur s port)
297297
(if (number? mode)
298298
(write-string ")" port)
299299
(write-string ")" port)))
300300
(recur s port)))))])
301-
301+
302302

303303
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
304304
;; Effective Addresses
305305

306306
(provide Mem Mem?)
307307

308308
;; type Mem =
309-
;; | (Mem [Maybe Label] [Maybe Integer] [Maybe Register] [Maybe Register] [Maybe Scale])
309+
;; | (Mem [Maybe Label] [Maybe Register] [Maybe Register] [Maybe Integer] [Maybe Scale])
310310
;; where at least one of label, base, or index must be given,
311311
;; index cannot be 'rsp
312312

313313
;; type Scale = 1 | 2 | 4 | 8
314314

315+
(define (parse-mem-args orig)
316+
(define (parse-mem-args-lab args)
317+
(match args
318+
[(cons #f args)
319+
(cons #f (parse-mem-args-r1 args))]
320+
[(cons (or (? label? l) ($ l)) args)
321+
(cons ($ l) (parse-mem-args-r1 args))]
322+
[_
323+
(cons #f (parse-mem-args-r1 args))]))
324+
325+
(define (parse-mem-args-r1 args)
326+
(match args
327+
[(cons #f args)
328+
(cons #f (parse-mem-args-r2 args))]
329+
[(cons (? register? r1) args)
330+
(cons r1 (parse-mem-args-r2 args))]
331+
[_
332+
(cons #f (parse-mem-args-r2 args))]))
333+
334+
(define (parse-mem-args-r2 args)
335+
(match args
336+
[(cons #f args)
337+
(cons #f (parse-mem-args-off args))]
338+
[(cons (? register? r2) args)
339+
(cons r2 (parse-mem-args-off args))]
340+
[_
341+
(cons #f (parse-mem-args-off args))]))
342+
343+
(define (parse-mem-args-off args)
344+
(match args
345+
[(cons #f args)
346+
(cons #f (parse-mem-args-scale args))]
347+
[(cons (? exact-integer? o) args)
348+
(cons o (parse-mem-args-scale args))]
349+
[_
350+
(cons #f (parse-mem-args-scale args))]))
351+
352+
(define (parse-mem-args-scale args)
353+
(match args
354+
[(list #f) (list #f)]
355+
[(list (? scale? s)) (list s)]
356+
[(list) (list #f)]
357+
[else (error "Mem: bad args" orig)]))
358+
359+
(match (parse-mem-args-lab orig)
360+
[(list #f #f #f _ _)
361+
(error "Mem: at least one of label, base, or index must be given" orig)]
362+
[(list _ _ 'rsp _ _)
363+
(error "Mem: index cannot be rsp")]
364+
[as
365+
(apply %mem as)]))
366+
367+
;; Given list of 5 fields, construct unambiguous argument list with
368+
;; fewest #f's possible
369+
(define (unparse-mem-args args)
370+
(define (unparse-mem-args-lab args)
371+
(match args
372+
[(cons #f args)
373+
(unparse-mem-args-r1 args)]
374+
[(cons l args)
375+
(cons l (unparse-mem-args-r1 args))]))
376+
377+
(define (unparse-mem-args-r1 args)
378+
(match args
379+
[(cons #f (cons #f args))
380+
(unparse-mem-args-off args)]
381+
[(cons #f (cons r args))
382+
(cons #f (cons r (unparse-mem-args-off args)))]
383+
[(cons r (cons #f args))
384+
(cons r (unparse-mem-args-off args))]
385+
[(cons r1 (cons r2 args))
386+
(cons r1 (cons r2 (unparse-mem-args-off args)))]))
387+
388+
(define (unparse-mem-args-off args)
389+
(match args
390+
[(list #f #f) '()]
391+
[(list o #f) (list o)]
392+
[(list o s) (list o s)]))
393+
(unparse-mem-args-lab args))
394+
315395
(define (make-Mem . args)
316-
(match args
317-
[(list (? exact-integer? o) (? register? r))
318-
(%mem #f o r #f #f)]
319-
[(list (? register? r))
320-
(%mem #f #f r #f #f)]
321-
[(list (? register? r1) (? register? r2))
322-
(%mem #f #f r1 r2 #f)]
323-
[(list (or (? label? l) ($ l)))
324-
(%mem ($ l) #f #f #f #f)]
325-
[(list (? register? r) (? exact-integer? o))
326-
(%mem #f o r #f #f)]
327-
[(list (or (? label? l) ($ l)) (? exact-integer? o))
328-
(%mem ($ l) o #f #f #f)]
329-
330-
[(list (or (? label? l) ($ l))
331-
(? exact-integer? o)
332-
(? register? r1)
333-
(? register? r2)
334-
(? integer? s))
335-
(%mem ($ l) o r1 r2 s)]
336-
[_
337-
(error 'Mem "bad args: ~a" args)]))
396+
(parse-mem-args args))
338397

339398
(define (scale? x)
340399
(memq x '(1 2 4 8)))
341400

342-
(struct %mem (label off base index scale)
401+
(struct %mem (label base index off scale)
343402
#:reflection-name 'Mem
344403
#:transparent
345-
#:guard
346-
(λ (label off base index scale name)
347-
(when (and label (not ($? label)))
348-
(error name "label must be a label or #f, given ~v" label))
349-
(when (and off (not (exact-integer? off)))
350-
(error name "offset must be an exact integer or #f, given ~v" off))
351-
(when (and base (not (register? base)))
352-
(error name "base must be a register or #f, given ~v" base))
353-
(when (and index (not (register? index)))
354-
(error name "index must be a register (other than rsp) or #f, given ~v" index))
355-
(when (and scale (not (scale? scale)))
356-
(error name "scale must be 1,2,4,8 or #f, given ~v" scale))
357-
(when (not (or label base index))
358-
(error name "must have at least one of label, base, or index"))
359-
(when (eq? index 'rsp)
360-
(error name "index cannot be rsp"))
361-
(values label off base index scale)))
404+
#:property prop:custom-print-quotable 'never
405+
#:methods gen:custom-write
406+
[(define (write-proc mem port mode) (mem-print mem port mode))]
407+
)
408+
409+
(define (mem-print mem port mode)
410+
(if (number? mode)
411+
(write-string "(" port)
412+
(write-string "#(struct:" port))
413+
(write-string "Mem " port)
414+
(let ([recur (case mode
415+
[(#t) write]
416+
[(#f) display]
417+
[else (lambda (p port) (print p port mode))])])
418+
(for-each
419+
(λ (t) (t))
420+
(add-between
421+
(map
422+
(λ (x) (λ () (recur x port)))
423+
(unparse-mem-args (rest (vector->list (struct->vector mem)))))
424+
(λ () (write-string " " port)))))
425+
(write-string ")" port))
362426

363427
(define Mem? %mem?)
364428

365429
(define-match-expander Mem
366430
(λ (stx)
367431
(syntax-case stx ()
368-
[(_ l o b i s) #'(%mem l o b i s)]))
432+
[(_ l b i o s) #'(%mem l b i o s)]))
369433
(λ (stx)
370434
(syntax-case stx ()
371435
[m (identifier? #'m) #'make-Mem]
@@ -451,7 +515,7 @@
451515
#:property prop:custom-print-quotable 'never
452516
#:methods gen:custom-write
453517
[(define write-proc
454-
(instr-print 'Name)
518+
(instr-print 'Name)
455519
#;(make-constructor-style-printer
456520
(lambda (obj) 'Name)
457521
(lambda (obj)

a86/printer.rkt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
[(? symbol?) (symbol->string x)]
6464
[($ x) (label-symbol->string x)]))
6565
(match m
66-
[(Mem l o b i s)
66+
[(Mem l b i o s)
6767
(string-append
6868
(apply string-append (add-between (map x->string (filter identity (list l o b i))) " + "))
6969
(match s

0 commit comments

Comments
 (0)