@@ -13,8 +13,9 @@ class CGenerator(val programAst: Program) extends CodeGenerator {
1313
1414 def generate : Try [CodeGenRes ] = Try {
1515
16- addLine(" #include <stdio.h>" )
1716 addLine(" #include <stdbool.h>" )
17+ addLine(" #include <string.h>" )
18+ addLine(" #include <stdio.h>" )
1819
1920 genMain()
2021 programAst.functions.foreach(genFunction)
@@ -68,12 +69,94 @@ class CGenerator(val programAst: Program) extends CodeGenerator {
6869 case d : Declare =>
6970 val key = SymbolKey (d.name, Symbol .Kind .Variable , d.id)
7071 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)
77160
78161 case Assign (id, name, value) =>
79162 val genValue = parseGenExpr(value)
@@ -93,11 +176,11 @@ class CGenerator(val programAst: Program) extends CodeGenerator {
93176 }
94177 val tpe = Try (symTab.getSymbolVar(" " , name).tpe).toOption.getOrElse(Type .String )
95178 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" )
101184 addLine(s """ scanf(" ${format}", ${pointer}); """ , id)
102185
103186 case Output (id, value, newline) =>
@@ -152,24 +235,27 @@ class CGenerator(val programAst: Program) extends CodeGenerator {
152235 override def predefFun (name : String , genArgs : List [String ]): String = {
153236 def argOpt (idx : Int ) = genArgs.lift(idx).getOrElse(" " )
154237 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])) "
173259 }
174260 }
175261
@@ -180,10 +266,18 @@ class CGenerator(val programAst: Program) extends CodeGenerator {
180266 private def genType (tpe : Expression .Type ): String =
181267 import Expression .Type , Type ._
182268 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"
188282
189283}
0 commit comments