@@ -13,8 +13,9 @@ class CGenerator(val programAst: Program) extends CodeGenerator {
13
13
14
14
def generate : Try [CodeGenRes ] = Try {
15
15
16
- addLine(" #include <stdio.h>" )
17
16
addLine(" #include <stdbool.h>" )
17
+ addLine(" #include <string.h>" )
18
+ addLine(" #include <stdio.h>" )
18
19
19
20
genMain()
20
21
programAst.functions.foreach(genFunction)
@@ -68,12 +69,94 @@ class CGenerator(val programAst: Program) extends CodeGenerator {
68
69
case d : Declare =>
69
70
val key = SymbolKey (d.name, Symbol .Kind .Variable , d.id)
70
71
symTab.add(d.id, key, d.tpe, None )
71
- val initValue = d.initValue.getOrElse(defaultValue(d.tpe))
72
- val initValueExpr = parseGenExpr(initValue)
73
- d.tpe match
74
- case Expression .Type .String =>
75
- addLine(s " char ${d.name}[] = $initValueExpr; " , d.id)
76
- case _ => addLine(s " ${genType(d.tpe)} ${d.name} = $initValueExpr; " , d.id)
72
+ /*
73
+ int arr[5] = {0};
74
+ int m[5][5] = {{0}};
75
+ */
76
+ val generatedLine = d.tpe match {
77
+ case Type .Void => d.initValue.map(parseGenExpr).getOrElse(" {}" )
78
+ case Type .Integer =>
79
+ val initExpr = parseGenExpr(d.initValue.getOrElse(" 0" ))
80
+ s " int ${d.name} = $initExpr; "
81
+ case Type .Real =>
82
+ val initExpr = parseGenExpr(d.initValue.getOrElse(" 0.0" ))
83
+ s " double ${d.name} = $initExpr; "
84
+ case Type .String =>
85
+ val initExpr = parseGenExpr(d.initValue.getOrElse(""" "" """ .trim))
86
+ s " char ${d.name}[] = $initExpr; "
87
+ case Type .Boolean =>
88
+ val initExpr = parseGenExpr(d.initValue.getOrElse(" false" .trim))
89
+ s " bool ${d.name} = $initExpr; "
90
+ case Type .IntegerArray =>
91
+ val dim1 = parseGenExpr(d.lengthValue1)
92
+ s """ |int ${d.name}[ ${dim1}];
93
+ |for (int i = 0; i < ${dim1}; i++) {
94
+ | ${d.name}[i] = 0;
95
+ |}
96
+ | """ .stripMargin
97
+ case Type .RealArray =>
98
+ val dim1 = parseGenExpr(d.lengthValue1)
99
+ s """ |double ${d.name}[ ${dim1}];
100
+ |for (int i = 0; i < ${dim1}; i++) {
101
+ | ${d.name}[i] = 0.0;
102
+ |}
103
+ | """ .stripMargin
104
+ case Type .StringArray =>
105
+ val dim1 = parseGenExpr(d.lengthValue1)
106
+ s """ |char ${d.name}[ ${dim1}][100];
107
+ |for (int i = 0; i < ${dim1}; i++) {
108
+ | strcpy( ${d.name}[i], "");
109
+ |}
110
+ | """ .stripMargin
111
+ case Type .BooleanArray =>
112
+ val dim1 = parseGenExpr(d.lengthValue1)
113
+ s """ |bool ${d.name}[ ${dim1}];
114
+ |for (int i = 0; i < ${dim1}; i++) {
115
+ | ${d.name}[i] = false;
116
+ |}
117
+ | """ .stripMargin
118
+ case Type .IntegerMatrix =>
119
+ val dim1 = parseGenExpr(d.lengthValue1)
120
+ val dim2 = parseGenExpr(d.lengthValue2)
121
+ s """ |int ${d.name}[ ${dim1}];
122
+ |for (int i = 0; i < ${dim1}; i++) {
123
+ | for (int j = 0; j < ${dim2}; j++) {
124
+ | ${d.name}[i][j] = 0;
125
+ | }
126
+ |}
127
+ | """ .stripMargin
128
+ case Type .RealMatrix =>
129
+ val dim1 = parseGenExpr(d.lengthValue1)
130
+ val dim2 = parseGenExpr(d.lengthValue2)
131
+ s """ |double ${d.name}[ ${dim1}];
132
+ |for (int i = 0; i < ${dim1}; i++) {
133
+ | for (int j = 0; j < ${dim2}; j++) {
134
+ | ${d.name}[i][j] = 0.0;
135
+ | }
136
+ |}
137
+ | """ .stripMargin
138
+ case Type .StringMatrix =>
139
+ val dim1 = parseGenExpr(d.lengthValue1)
140
+ val dim2 = parseGenExpr(d.lengthValue2)
141
+ s """ |char ${d.name}[ ${dim1}][100];
142
+ |for (int i = 0; i < ${dim1}; i++) {
143
+ | for (int j = 0; j < ${dim2}; j++) {
144
+ | strcpy( ${d.name}[i][j], "");
145
+ | }
146
+ |}
147
+ | """ .stripMargin
148
+ case Type .BooleanMatrix =>
149
+ val dim1 = parseGenExpr(d.lengthValue1)
150
+ val dim2 = parseGenExpr(d.lengthValue2)
151
+ s """ |bool ${d.name}[ ${dim1}];
152
+ |for (int i = 0; i < ${dim1}; i++) {
153
+ | for (int j = 0; j < ${dim2}; j++) {
154
+ | ${d.name}[i][j] = false;
155
+ | }
156
+ |}
157
+ | """ .stripMargin
158
+ }
159
+ addLine(generatedLine)
77
160
78
161
case Assign (id, name, value) =>
79
162
val genValue = parseGenExpr(value)
@@ -93,11 +176,11 @@ class CGenerator(val programAst: Program) extends CodeGenerator {
93
176
}
94
177
val tpe = Try (symTab.getSymbolVar(" " , name).tpe).toOption.getOrElse(Type .String )
95
178
val (format, pointer) = tpe match
96
- case Expression . Type .String => (" %d" , name) // array is pointer
97
- case Expression . Type .Integer => (" %d" , s " & ${name}" )
98
- case Expression . Type .Real => (" %d" , s " & ${name}" )
99
- case Expression . Type .Boolean => (" %d" , s " & ${ name} " )
100
- case Expression . Type .Void => throw RuntimeException (" Void cannot be entered" )
179
+ case Type . Integer | Type .IntegerArray | Type . IntegerMatrix => (" %d" , s " & ${ name} " )
180
+ case Type . Real | Type .RealArray | Type . RealMatrix => (" %d" , s " & ${name}" )
181
+ case Type .Boolean | Type . BooleanArray | Type . BooleanMatrix => (" %d" , s " & ${name}" )
182
+ case Type . String | Type .StringArray | Type . StringMatrix => (" %d" , name) // array is pointer
183
+ case Type .Void => sys.error (" Void cannot be entered" )
101
184
addLine(s """ scanf(" ${format}", ${pointer}); """ , id)
102
185
103
186
case Output (id, value, newline) =>
@@ -152,24 +235,27 @@ class CGenerator(val programAst: Program) extends CodeGenerator {
152
235
override def predefFun (name : String , genArgs : List [String ]): String = {
153
236
def argOpt (idx : Int ) = genArgs.lift(idx).getOrElse(" " )
154
237
PredefinedFunction .withName(name).get match {
155
- case Abs => s " abs( ${argOpt(0 )}) "
156
- case Floor => s " floor( ${argOpt(0 )}) "
157
- case Ceil => s " ceil( ${argOpt(0 )}) "
158
- case RandomInteger => s " abs( ${argOpt(0 )}) " // TODO
159
- case Sin => s " sin( ${argOpt(0 )}) "
160
- case Cos => s " cos( ${argOpt(0 )}) "
161
- case Tan => s " tan( ${argOpt(0 )}) "
162
- case Ln => s " log( ${argOpt(0 )}) "
163
- case Log10 => s " log10( ${argOpt(0 )}) "
164
- case Log2 => s " log10( ${argOpt(0 )})/log10(2) "
165
- case Sqrt => s " Math.sqrt( ${argOpt(0 )}) "
166
- case Pow => s " Math.pow( ${argOpt(0 )}, ${argOpt(1 )}) "
167
- case Length => s " ${argOpt(0 )}.length() "
168
- case CharAt => s " ${argOpt(0 )}.charAt( ${argOpt(1 )}) "
169
- case RealToInteger => s " (int) ${argOpt(0 )}"
170
- case StringToInteger =>
171
- s """ try { Convert.ToInt32( ${argOpt(0 )}) } catch (FormatException) { 0 } """
172
- case ReadInput => " TODO"
238
+ case Abs => s " abs( ${argOpt(0 )}) "
239
+ case Floor => s " floor( ${argOpt(0 )}) "
240
+ case Ceil => s " ceil( ${argOpt(0 )}) "
241
+ case RandomInteger => s " (rand() % ${argOpt(0 )}) "
242
+ case Sin => s " sin( ${argOpt(0 )}) "
243
+ case Cos => s " cos( ${argOpt(0 )}) "
244
+ case Tan => s " tan( ${argOpt(0 )}) "
245
+ case Ln => s " log( ${argOpt(0 )}) "
246
+ case Log10 => s " log10( ${argOpt(0 )}) "
247
+ case Log2 => s " log10( ${argOpt(0 )})/log10(2) "
248
+ case Sqrt => s " Math.sqrt( ${argOpt(0 )}) "
249
+ case Pow => s " Math.pow( ${argOpt(0 )}, ${argOpt(1 )}) "
250
+ case Length => s " ${argOpt(0 )}.length() "
251
+ case CharAt => s " ${argOpt(0 )}.charAt( ${argOpt(1 )}) "
252
+ case RealToInteger => s " (int) ${argOpt(0 )}"
253
+ case StringToInteger => s " atoi( ${argOpt(0 )}) "
254
+ case ReadInput => s """ scanf("%s", ${argOpt(0 )}) """
255
+ case NumRows => s " sizeof( ${argOpt(0 )}) / sizeof( ${argOpt(0 )}[0]) "
256
+ case NumCols =>
257
+ val arr = argOpt(0 )
258
+ s " (sizeof( ${arr})/sizeof( ${arr}[0][0])) / (sizeof( ${arr})/sizeof( ${arr}[0])) "
173
259
}
174
260
}
175
261
@@ -180,10 +266,18 @@ class CGenerator(val programAst: Program) extends CodeGenerator {
180
266
private def genType (tpe : Expression .Type ): String =
181
267
import Expression .Type , Type ._
182
268
tpe match
183
- case Void => " void"
184
- case Integer => " int"
185
- case Real => " double"
186
- case String => " char"
187
- case Boolean => " bool"
269
+ case Void => " void"
270
+ case Integer => " int"
271
+ case IntegerArray => " int"
272
+ case IntegerMatrix => " int"
273
+ case Real => " double"
274
+ case RealArray => " double"
275
+ case RealMatrix => " double"
276
+ case String => " char"
277
+ case StringArray => " char"
278
+ case StringMatrix => " char"
279
+ case Boolean => " bool"
280
+ case BooleanArray => " bool"
281
+ case BooleanMatrix => " bool"
188
282
189
283
}
0 commit comments