-
Notifications
You must be signed in to change notification settings - Fork 0
/
GeneratorC.scm
128 lines (124 loc) · 5.47 KB
/
GeneratorC.scm
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
;;; fcl code generator - C language
; generate-c : [Entry] -> string
(define (generate-c table)
(define (push stack . value)
(if (null? (car value))
stack
(cons (car value) (push stack (cdr value)))
)
)
; gen-expr : [Node] -> string
(define (gen-expr exp0 table)
(let gen-loop ((exp exp0) (s '()) (ad 0) (td 0))
(if debug.generate (fmt "gen-expr" (map node.unpack exp) "; " s ad td))
(if (null? exp)
(if (null? s) s (car s))
(let ((type (node-name (car exp))) (value (node-op (car exp))))
(case type
((cond-else end-cond) (if (null? s) s (car s)))
((begin-term)
(gen-loop (cdr exp) s ad (+ td 1))
)
((end-term)
(gen-loop
(cdr exp)
(if (= td 1)
(cond
((= ad 0) (string-append "(" (car s) ")"))
((eq? (node-name (cadr exp)) 'end-args) (push (cddr s) (string-append (cadr s) (car s))))
(else (push (cddr s) (string-append (cadr s) (car s) ",")))
)
;(push (cdr s) (string-append "(" (car s) ")"))
s
)
ad
(- td 1)
)
)
((val) (gen-loop (cdr exp) (push s (number->string value)) ad td))
((const) (gen-loop (cdr exp) (push s (symbol->string value)) ad td))
((begin-args)
(if (eq? (node-name (cadr exp)) 'end-args)
(gen-loop (cddr exp) (push (cdr s) (if (lookup table (string->symbol (car s))) (string-append (car s) "()") (car s))) ad td)
(gen-loop (cdr exp) (push (cdr s) (string-append (car s) "(")) (+ ad 1) 0)
)
)
((end-args)
(gen-loop (cdr exp)
(if (< ad 2)
(push (cdr s) (string-append (car s) ")"))
(push (cddr s) (string-append (cadr s) (car s) ")"))
)
(- ad 1) td
)
)
((add sub mul div lt gt ne eq)
(let ((l (cadr s))
(r (car s))
(op (case type
((add) "+")
((sub) "-")
((mul) "*")
((div) "/")
((eq) "==")
((ne) "!=")
((gt) ">")
((lt) "<")
)
)
)
(gen-loop (cdr exp) (push (cddr s) (string-append l op r)) ad td)
)
)
(else
(fmt "internal error: invalid node type" type "in gen-expr")
'!internal-error
)
)
)
)
)
)
(let generate-loop ((i 0))
(if (< i (length table))
(let ((e (list-ref table i)))
(if debug.generate (fmt "generate" (entry-name e) (entry-condn e)))
(string-append "int " (symbol->string (entry-name e)) "("
(if (null? (entry-params e))
"void"
(let param-loop ((p (entry-params e)))
(cond
((null? p) "")
((null? (cdr p)) (string-append "int " (symbol->string (car p))))
(else (string-append "int " (symbol->string (car p)) "," (param-loop (cdr p))))
)
)
)
") {\n"
(if (null? (entry-condn e))
""
(string-append
" if ("
(gen-expr (entry-condn e) table)
")\n"
)
)
" return " (gen-expr (entry-body e) table) ";\n"
(let ((ce (find-next (entry-condn e) 'cond-else 'end-cond)))
(if ce
(string-append
" else return "
(gen-expr (cdr ce) table)
";\n"
)
""
)
)
"}\n"
(generate-loop (+ i 1))
)
)
""
)
)
)