13
13
// limitations under the License.
14
14
15
15
import database as db
16
+ import types
16
17
17
18
use clanguageclasses
19
+ use ctypegen
18
20
use escapestring
21
+ use sym
22
+
23
+ relation HashedClass CurrentScope CIdentifier cascade
24
+
25
+ class CurrentScope(self) {
26
+
27
+ func open(self) {
28
+ // todo
29
+ }
30
+
31
+ func close(self) {
32
+ // todo
33
+ }
34
+
35
+ func getIdentifier(self, name: Sym, type: CTypeExpr?, bindingInstance: bool) -> CIdentifier {
36
+ // todo: handle the case where the definition was in an outer scope.
37
+ id = CIdentifier(name, type, false, bindingInstance)
38
+ exists = self.findCIdentifier(id)
39
+ if isnull(exists) {
40
+ id.firstInstance = true
41
+ self.insertCIdentifier(id)
42
+ }
43
+ return id
44
+ }
45
+ }
19
46
20
47
relation DoublyLinked CBuilder CBlock cascade
21
48
22
- class CBuilder(self) {
49
+ class CBuilder(self, tc: types.TypeChecker ) {
23
50
self.currentParamList = null(CParamList)
24
51
self.currentExprList = null(CExprList)
25
52
self.program = CProgram()
26
53
self.currentBlock = null(CBlock)
54
+ self.identifierScope = CurrentScope()
55
+ self.typechecker = tc
56
+ self.typeGenerator = CTypeGenerator(tc)
27
57
28
58
func build(self, module: db.Function) -> CProgram {
29
59
module.genC(self)
@@ -35,9 +65,11 @@ class CBuilder(self) {
35
65
}
36
66
37
67
func openScope(self) {
68
+ self.identifierScope.open()
38
69
}
39
70
40
71
func closeScope(self) {
72
+ self.identifierScope.close()
41
73
}
42
74
43
75
func openBlock(self, location: db.Location?) {
@@ -85,10 +117,78 @@ class CBuilder(self) {
85
117
return CParameter(location, name, type)
86
118
}
87
119
120
+ func cIdentifier(self, symbol: Sym, bindingInstance: bool) -> CExpr {
121
+ type = self.typechecker.symbol(symbol)
122
+ if isnull(type) {
123
+ ctype = null(CTypeExpr)
124
+ } else {
125
+ ctype = self.typeGenerator.genCType(type!)
126
+ }
127
+ id = self.identifierScope.getIdentifier(symbol, ctype, bindingInstance)
128
+ if id.firstInstance {
129
+ if !isnull(self.currentBlock) {
130
+ self.currentBlock.declare(id)
131
+ } else {
132
+ self.program.mainCBlock.declare(id)
133
+ }
134
+ }
135
+ return CExpr(id)
136
+ }
137
+
88
138
func cType(self, type: CType) -> CTypeExpr {
89
139
return CTypeExpr(type)
90
140
}
91
141
142
+ func cIntType(self, location: db.Location, isSigned: bool, width: u32) -> CTypeExpr {
143
+ if isSigned {
144
+ if width <= 8 {
145
+ prim = CPrimitiveType(CPrimitiveType.Type.Int8)
146
+ } else if width <= 16 {
147
+ prim = CPrimitiveType(CPrimitiveType.Type.Int16)
148
+ } else if width <= 32 {
149
+ prim = CPrimitiveType(CPrimitiveType.Type.Int32)
150
+ } else if width <= 64 {
151
+ prim = CPrimitiveType(CPrimitiveType.Type.Int64)
152
+ } else {
153
+ raise Status.Unimplemented, "No support for primitive integers of width larger than 64"
154
+ }
155
+ } else {
156
+ if width <= 8 {
157
+ prim = CPrimitiveType(CPrimitiveType.Type.Uint8)
158
+ } else if width <= 16 {
159
+ prim = CPrimitiveType(CPrimitiveType.Type.Uint16)
160
+ } else if width <= 32 {
161
+ prim = CPrimitiveType(CPrimitiveType.Type.Uint32)
162
+ } else if width <= 64 {
163
+ prim = CPrimitiveType(CPrimitiveType.Type.Uint64)
164
+ } else {
165
+ raise Status.Unimplemented, "No support for primitive integers of width larger than 64"
166
+ }
167
+ }
168
+ return CTypeExpr(prim)
169
+ }
170
+
171
+ func cFloatType(self, location: db.Location, width: u32) -> CTypeExpr {
172
+ if width == 32 {
173
+ return CTypeExpr(CPrimitiveType(CPrimitiveType.Type.Float))
174
+ } else if width == 64 {
175
+ return CTypeExpr(CPrimitiveType(CPrimitiveType.Type.Double))
176
+ }
177
+ raise Status.Unimplemented, "No support for floating point width %u32." % width
178
+ }
179
+
180
+ func cStringType(self, location: db.Location) -> CTypeExpr {
181
+ return CTypeExpr(CDefinedType("string"))
182
+ }
183
+
184
+ func cBooleanType(self, location: db.Location) -> CTypeExpr {
185
+ return CTypeExpr(CPrimitiveType(CPrimitiveType.Type.Int8))
186
+ }
187
+
188
+ func cVoidType(self, location: db.Location) -> CTypeExpr {
189
+ return CTypeExpr(CPrimitiveType(CPrimitiveType.Type.Void))
190
+ }
191
+
92
192
/* Rune expressions *********************************************************************/
93
193
94
194
func openExprList(self) {
@@ -109,7 +209,7 @@ class CBuilder(self) {
109
209
}
110
210
111
211
func cStringLiteral(self, value: string) -> CExpr {
112
- return CExpr(CLiteral(escapeString( value) ))
212
+ return CExpr(CLiteral(value))
113
213
}
114
214
115
215
func cBoolLiteral(self, value: bool) -> CExpr {
0 commit comments