-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathc-compile.rkt
109 lines (95 loc) · 2.65 KB
/
c-compile.rkt
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#lang racket
(require "lexer.rkt")
(define (resolve val)
(match val
[(list 'num n) n]
[(list 'reg r) (format "r~a" r)]))
(define (compile-inst inst)
(match inst
[(list 'SHN val)
(format "printf(\"%d\\n\", ~a)"
(resolve val))]
[(list 'SHA val)
(format "printf(\"%c\\n\", ~a)"
(resolve val))]
[(list 'MOV reg val)
(format "r~a = ~a" reg (resolve val))]
[(list 'ADD reg val1 val2)
(format "r~a = ~a + ~a" reg
(resolve val1)
(resolve val2))]
[(list 'SUB reg val1 val2)
(format "r~a = ~a - ~a" reg
(resolve val1)
(resolve val2))]
[(list 'JMP lab)
(format "goto ~a" lab)]
[(list 'JLT lab val1 val2)
(format "if (~a < ~a){goto ~a;}"
(resolve val1)
(resolve val2)
lab)]
[(list 'JGT lab val1 val2)
(format "if (~a > ~a){goto ~a;}"
(resolve val1)
(resolve val2)
lab)]
[(list 'JET lab val1 val2)
(format "if (~a == ~a){goto ~a;}"
(resolve val1)
(resolve val2)
lab)]
[(list 'HLT)
"return 0"]
[(list 'MFICOFSR reg)
(format "r~a = 0" reg)]
[x (error 'compiler
(format "what is ~v"
inst))]))
(define (compile prog)
(define op (open-output-string))
(parameterize ([current-output-port op])
; header
(printf "#include <stdio.h>\nint main()\n{\n")
; register setup
(printf "int r0 = 0")
(for ([idx (in-range 1 12)])
(printf ", r~a = 0" idx))
(printf ";\n")
; translate labels/instructions
(map (match-lambda
[(list 'lab-decl lab-name)
(printf "~a:\n" lab-name)]
[(list-rest 'inst args)
(printf "~a;\n"
(compile-inst args))]
[else '()])
prog)
; close main
(printf "}"))
(get-output-string op))
(define (esAsm->c ip)
(compile (parse-esAsm-to-datum ip)))
#;(display (esAsm->c
(open-input-file "examples/fibonacci.es.rkt")))
;;; sublanguage stuff
(require (for-syntax syntax/parse)
syntax/strip-context)
(provide #%top #%app #%datum #%top-interaction
(rename-out [esAsm-mod-begin #%module-begin]))
(provide read-syntax)
(define (read-syntax path port)
(define ast
(parse-esAsm port))
(strip-context
#`(module esAsm-mod esAsm/c-compile
#,ast)))
(define-syntax (esAsm-mod-begin stx)
(syntax-parse stx
[(esAsm-mod-begin (program LINE ...))
#'(#%module-begin
(displayln
(compile (list
'LINE ...))))]))
(module+ reader
(provide read-syntax))