BenchCookie  0.0.1
A simple, intuitive open source language.
mips_compiler.cpp
Go to the documentation of this file.
1 // allocate enough space for drew-sized strings.
2 #define MAX_STRING_SIZE 100
3 void Command::doBSS(std::ostream & file)
4 {
5  file<<"\t.lcomm locals, 400";
6  file<<std::endl;
7 }
8 
9 void Command::doData(std::ostream & file)
10 {
11  file<<"\t.data"<<std::endl<<std::endl;
12 
15  for (int x = 0; x < m_literals.size(); ++x) {
16  file<<".data"<<std::endl;
17  file<<"S"<<x<<":\t.ascii \""<<m_literals[x]<<"\\0\""<<std::endl;
18  std::endl;
19  }
20 
21  std::cout<<std::endl;
22 
25  for (int x =0; x < m_string_vars.size(); ++x) {
26  file<<"IS"<<x<<":\t.space "<<MAX_STRING_SIZE<<std::endl;
27  }
30  for (int x = 0; x < m_int_vars.size() - m_int_declarations.size(); ++x) {
31  file<<"I"<<x<<":\t.word 0"<<std::endl;
32  }
33 
35  file<<"locals:\t.word 400"<<std::endl;
36 
37  // file<<std::endl<<"string_fmt:\t.ascii \"%s\\0\""<<std::endl;
38  // file<<"num_fmt:\t.ascii \"%d\\0\""<<std::endl;
39  file<<"TRUE_STORY:\t.ascii \"true\\0\""<<std::endl;
40  file<<"FALSE:\t.ascii \"false\\0\""<<std::endl;
41 }
42 
43 void Command::doMain(std::ostream & file)
44 {
45  int y; size_t divcount = 0, nszcount = 0;
46  const size_t local_count = 0;// Idk, yo. Just... somewhere.
47  file<<"main:"<<std::endl;
48  file<<"\tldr %r9, =locals"<<std::endl;
49  file<<"\t@ Make space for locals"<<std::endl;
54  for (int x = 0, intassdex = 0, stringdex = 0, exprdex = 0,
55  intdex = 0, pintdex = 0, pstringdex = 0, litdex = 0,
56  pbooldex = 0, sints = 0, ifndex = 0, forndex = 0;
57  x < m_execOrder.size(); ++x) {
58 
59  if (m_execOrder[x] == cmd_type::READ_STRING) {
60  file<<"\tldr %r0, =string_fmt"<<std::endl;
61  file<<"\tldr %r1, =IS"<<stringdex<<std::endl;
62  file<<"\tbl scanf"<<std::endl;
63  file<<std::endl;
64 
65  ++stringdex;
66  } else if (m_execOrder[x] == cmd_type::DECL_INT) {
67  file<<"\tli %a0, 4"<<std::endl;
68  file<<"\tbl malloc"<<std::endl;
69  file<<"\tstr %r0, [%r9, #"<<sints * 4<<"]"<<std::endl;
70 
71  file<<std::endl;
72  m_int_vars.push_back(m_int_declarations[sints++]);
73  } else if (m_execOrder[x] == cmd_type::BEGIN_IF) {
74  // find the variable we depend on!
75  std::string var_name = m_if_deps[ifndex];
76  for (y = 0; y < m_int_vars.size(); ++y) {
77  if (m_int_vars[y] == var_name) break;
78  } int z = 0;
79  for (z = 0; z < m_int_declarations.size(); ++z) {
80  if (m_int_declarations[z] == var_name) break;
81  } if (z < m_int_declarations.size()) {
82  file<<"\tmov %r1, %r9"<<std::endl;
83  file<<"\tldr %r1, [%r1, #"<<4*z<<"]"<<std::endl;
84  file<<"\tldr %r0, [%r1]"<<std::endl;
85  } else if (y < m_int_vars.size()) {
86  file<<"\tldr %r0, =I"<<y<<std::endl;
87  file<<"\tldr %r0, [%r0]"<<std::endl;
88  } else {
89  std::cerr<<"Error: if-dependent variable "<<var_name;
90  std::cerr<<" not yet declared!"<<std::endl;
91  exit(6);
92  }
93 
94  file<<"IF"<<ifndex<<":\tcmp %r0, $0"<<std::endl;
95  file<<"\tbeq END_IF"<<ifndex<<std::endl;
96  ++ifndex;
97  } else if (m_execOrder[x] == cmd_type::BEGIN_FOR) {
98  std::string var_name = m_for_deps[forndex];
99  for (y = 0; y < m_int_vars.size(); ++y) {
100  if (m_int_vars[y] == var_name) break;
101  } int z = 0;
102  for (; z < m_int_declarations.size(); ++z) {
103  if (m_int_declarations[z] == var_name) break;
104  } if (z < m_int_declarations.size()) {
105  file<<"FOR"<<forndex<<":";
106  file<<"\tmov %r8, %r9"<<std::endl;
107  file<<"\tldr %r8, [%r8, #"<<4 * z<<"]"<<std::endl;
108  file<<"\tldr %r8, [%r8]"<<std::endl;
109  } else if (y < m_int_vars.size()) {
110  file<<"FOR"<<forndex<<":";
111  file<<"\tmov %r8, =I"<<y<<std::endl;
112  file<<"\tldr %r8, [%r8]"<<std::endl;
113  } else {
114  std::cerr<<"Error: for-dependent variable "<<var_name;
115  std::cerr<<" not yet declared!"<<std::endl;
116  exit(7);
117  }
118 
119  file<<"\tcmp %r8, $0"<<std::endl;
120  file<<"\tbeq END_FOR"<<forndex<<std::endl;
121  } else if (m_execOrder[x] == cmd_type::END_FOR) {
122  file<<"b FOR"<<forndex<<std::endl;
123  file<<"END_FOR"<<forndex++<<":"<<std::endl;
124  } else if (m_execOrder[x] == cmd_type::END_IF) {
125  file<<"END_IF"<<ifndex-1<<":"<<std::endl;
126  } else if (m_execOrder[x] == cmd_type::READ_INT) {
127  file<<"\tldr %r0, =num_fmt"<<std::endl;
128  file<<"\tldr %r1, =I"<<intdex<<std::endl;
129  file<<"\tbl scanf"<<std::endl;
130  file<<std::endl;
131 
132  ++intdex;
133  } else if (m_execOrder[x] == cmd_type::PRINT) {
134  file<<"\tldr %r0, =S"<<litdex++<<std::endl;
135  file<<"\tbl printf"<<std::endl<<std::endl;
136  } else if (m_execOrder[x] == cmd_type::PRINT_STR) {
137  file<<"\tldr %r0, =string_fmt"<<std::endl;
138  for (y = 0; y < m_string_vars.size(); ++y) {
139  if (m_string_vars[y] == m_print_strings[pstringdex]) break;
140  } if (y == m_string_vars.size()) {
141  std::cerr<<"Error: variable "<<m_string_vars[y]<<" was not declared!"<<std::endl;
142  exit(3);
143  }
145  file<<"\tldr %r1, =IS"<<y<<std::endl;
146  file<<"\tbl printf"<<std::endl;
147  ++pstringdex;
148  } else if (m_execOrder[x] == cmd_type::PRINT_NUM) {
149  file<<"\tldr %r0, =num_fmt"<<std::endl;
150  for (y = 0; y < m_int_vars.size(); ++y) {
151  if (m_int_vars[y] == m_print_ints[pintdex]) break;
152  } if (y == m_int_vars.size()) {
153  std::cerr<<"Error: variable "<<m_int_vars[y]<<" was not declared!"<<std::endl;
154  exit(3);
155  } int z;
156  for (z = 0; z < m_int_declarations.size(); ++z) {
157  if (m_print_ints[pintdex] == m_int_declarations[z]) break;
158  } if (z != m_int_declarations.size()) {
159  file<<"\tldr %r1, =locals"<<std::endl;
160  file<<"\tldr %r1, [%r1, #"<<4 * z<<"]"<<std::endl;
161  file<<"\tldr %r1, [%r1]"<<std::endl;
162  } else {
163  file<<"\tldr %r1, =I"<<y<<std::endl;
164  file<<"\tldr %r1, [%r1]"<<std::endl;
165  } file<<"\tbl printf"<<std::endl;
166  ++pintdex;
167  } else if (m_execOrder[x] == cmd_type::PRINT_BOOL) {
168  for (y = 0; y < m_bool_vars.size(); ++y) {
169  if (m_bool_vars[y] == m_print_bools[pbooldex]) break;
170  } if (y == m_bool_vars.size()) {
171  std::cerr<<"Error: variable "<<m_bool_vars[y]<<" was not declared!"<<std::endl;
172  }
173  file<<"\tldr %r1, =B"<<y<<std::endl;
174  file<<"\tldr %r1, [%r1]"<<std::endl;
175  file<<"\tcmp %r1, $0"<<std::endl;
176  file<<"\tbne LIES"<<nszcount++<<std::endl;
177  file<<"\tldr %r0, =TRUE_STORY"<<std::endl;
178  file<<"\tb NOISTRUE"<<nszcount-1<<std::endl;
179  file<<"LIES"<<nszcount-1<<":"<<std::endl;
180  file<<"\tldr %r0, =FALSE"<<std::endl;
181  file<<"NOISTRUE"<<nszcount-1<<":"<<std::endl;
182  file<<"\tbl printf"<<std::endl;
183  ++pbooldex;
184  } else if (m_execOrder[x] == cmd_type::INTGETS) {
185  std::string int_gets = m_int_assigns[intassdex];
186  ssize_t offset;
187  for (y = 0; y < m_int_vars.size(); ++y) {
188  if (m_int_vars[y] == m_int_assigns[intassdex]) break;
189  } int z; bool on_stack = false; int * last_z = new int;
190  for (z = 0; z < m_int_declarations.size(); ++z) {
191  if (m_int_vars[y] == m_int_declarations[z]) { on_stack = true; break; }
192  } offset = (z != m_int_declarations.size()) ? 4 * z : y;
193  if (y == m_int_vars.size()) {
194  std::cerr<<"Error: variable "<<m_int_vars[y];
195  std::cerr<<" was not declared!"<<std::endl;
196  exit(3);
197  } *last_z = z;
198 
200  std::stack<math_expression> * expr = m_evaluations[exprdex++];
201 
202  ssize_t stack_depth = 0;
203 
204  std::stack<math_expression> eval;// = *expr;
205  for(; !expr->empty(); eval.push(expr->top()), expr->pop(), 1);
206  std::stack<math_expression> curr;
207 
208  for (; eval.size();) {
209  math_expression a = eval.top(); eval.pop();
210  Command::exp_type type = static_cast<Command::exp_type>(a.expr_type);
211  exp_type aExpType = static_cast<Command::exp_type>(a.expr_type);
212 
213  if (aExpType == VAR) {
214  for (y = 0; y < m_int_vars.size(); ++y) {
215  if (m_int_vars[y] == a.pirate_name) break;
216  } if (y == m_int_vars.size()) {
217  std::cerr<<"Error: variable "<<a.pirate_name<<" was not declared!"<<std::endl;
218  exit(3);
219  } int z;
220  for (z = 0; z < m_int_declarations.size(); ++z) {
221  if (m_int_declarations[z] == m_int_vars[y]) break;
222  } if (z != m_int_declarations.size()) {
223  file<<"\tmov %r1, %r9"<<std::endl;
224  file<<"\tldr %r1, [%r9, #"<<4 * z<<"]"<<std::endl;
225  file<<"\tldr %r1, [%r1]"<<std::endl;
226  } else {
227  file<<"\tldr %r1, =I"<<y<<std::endl;
228  file<<"\tldr %r1, [%r1]"<<std::endl;
229  }
230  file<<"\tstr %r1, [%sp, #-4]"<<std::endl;
231  file<<"\tsub %sp, %sp, $4"<<std::endl;
232  stack_depth += 4; continue;
233  } else if (aExpType == AN_INT) {
234  file<<"\tmov %r1, $"<<a.int_arg<<std::endl;
235  file<<"\tstr %r1, [%sp, #-4]"<<std::endl;
236  file<<"\tsub %sp, %sp, $4"<<std::endl;
237  stack_depth += 4;
238  continue;
239  }
240 
241  if (stack_depth >= 8) {
242  file<<std::endl<<"\tldr %r1, [%sp]"<<std::endl;
243  file<<"\tldr %r2, [%sp, #4]"<<std::endl;
244  file<<"\tadd %sp, %sp, $8"<<std::endl;
245  stack_depth -= 8;
246  } else continue;
247  switch (type) {
248  case ADD:
254  file<<"\tadd %r0, %r1, %r2"<<std::endl;
255  goto do_default;
256  case SUB:
257  file<<"\tsub %r0, %r2, %r1"<<std::endl;
258  goto do_default;
259  case MUL:
260  file<<"\tmul %r0, %r1, %r2"<<std::endl;
261  goto do_default;
262  case DIV:
263  /* @todo case divide by zero */
264  file<<"\tmov %r0, $0"<<std::endl<<std::endl;
265  file<<"DIVIDE"<<divcount++<<": cmp %r1, %r2"<<std::endl;
266  file<<"\t bgt DONEDIVIDE"<<divcount-1<<std::endl;
267  file<<"\t sub %r2, %r2, %r1"<<std::endl;
268  file<<"\t add %r0, $1"<<std::endl;
269  file<<"\t b DIVIDE"<<divcount-1<<std::endl;
270  file<<"DONEDIVIDE"<<divcount-1<<":"<<std::endl;
271  goto do_default;
272  case GT:
273  file<<"\tmov %r0, $1"<<std::endl;
274  file<<"\tcmp %r2, %r1"<<"\t@ Backwards because stack"<<std::endl;
275  file<<std::endl;
276  file<<"\tbgt NOSETZERO"<<nszcount<<std::endl;
277  file<<"\tmov %r0, $0"<<std::endl;
278  file<<"NOSETZERO"<<nszcount<<": # label used to set as true"<<std::endl;
279  nszcount++;
280  goto do_default;
281  case GEQ:
282  file<<"\tmov %r0, $1"<<std::endl;
283  file<<"\tcmp %r2, %r1"<<std::endl;
284  file<<"\tbge NOSETZERO"<<nszcount<<std::endl;
285  file<<"\tmov %r0, $0"<<std::endl;
286  file<<"NOSETZERO"<<nszcount<<": # label used to set as true"<<std::endl;
287  nszcount++;
288  goto do_default;
289  case LT:
290  file<<"\tmov %r0, $1"<<std::endl;
291  file<<"\tcmp %r2, %r1"<<std::endl;
292  file<<"\tblt NOSETZERO"<<nszcount<<std::endl;
293  file<<"\tmov %r0, $0"<<std::endl;
294  file<<"NOSETZERO"<<nszcount<<": # label used to set as true"<<std::endl;
295  nszcount++;
296  goto do_default;
297  case LEQ:
298  file<<"\tmov %r0, $1"<<std::endl;
299  file<<"\tcmp %r2, %r1"<<std::endl;
300  file<<"\tble NOSETZERO"<<nszcount<<std::endl;
301  file<<"\tmov %r0, $0"<<std::endl;
302  file<<"NOSETZERO"<<nszcount<<": # label used to set as true"<<std::endl;
303  nszcount++;
304  goto do_default;
305  default:
306  std::cerr<<"Welp. You did it. You tried it."<<std::endl;
307  std::cerr<<"This is what happens. You get mad."<<std::endl;
308  std::cerr<<"Don't use things I didn't implement yet."<<std::endl;
309  exit(101);
310  do_default:
311  file<<"\tstr %r0, -4($sp)"<<std::endl;
312  file<<"\tsubi $sp, 4"<<std::endl;
313  stack_depth += 4;
314  }
315  }
316 
317  file<<"\tldr %r0, [%sp, #0]"<<std::endl;
318  file<<"\tadd %sp, %sp, $0"<<std::endl;
319  stack_depth -= 4;
320  if (!on_stack) {
321  int x;
322  for (x = 0; x < m_int_vars.size(); ++x) {
323  if (m_int_vars[x] == int_gets) break;
324  }
325  file<<"\tldr %r3, =I"<<x<<std::endl;
326  } else {
327  file<<"\tmov %r3, %r9"<<std::endl;
328  file<<"\tldr %r3, [%r3, #"<<*last_z * 4<<"]"<<std::endl;
329  delete last_z;
330  }
331  file<<"\tstr %r0, [%r3]"<<std::endl;
332  if (stack_depth) file<<"\tadd %sp, $"<<stack_depth<<"\t@ Destroy stack"<<std::endl;
333  else file<<"\t@ Yayy! Stack has nothing left."<<std::endl<<"\t@ You should be happy. I am."<<std::endl;
334  file<<std::endl; intassdex++;
335  }
336  }
337 }
338 
340 {
341  std::ofstream file;
342  file.open(m_filename);
343  if (!file.is_open()) {
344  std::cerr<<"Error: unable to open output file!";
345  exit(2);
346  }
347  file <<"/**"<<std::endl;
348  file <<" *"<<m_filename<<std::endl;
349  file <<" *"<<std::endl;
350  file <<" * Generated by Bench Cookie Compiler!"<<std::endl;
351  file <<" * Bench Cookie is... Experimental. Don't be mad."<<std::endl;
352  file <<" */"<<std::endl;
353 
354  doBSS(file);
355 
356  file<<std::endl;
357 
358  doData(file);
359 
360  file<<std::endl<<std::endl;
361  file<<"\t.text"<<std::endl;
362  // file<<"\t.global main"<<std::endl;
363  // file<<"\t.global printf"<<std::endl;
364  // file<<"\t.global scanf"<<std::endl;
365  // file<<"\t.global malloc"<<std::endl;
366 
367  doMain(file);
368 
376  file<<"\t@ Free local vars"<<std::endl;
377  for (int x = 0; x < m_int_declarations.size(); ++x) {
378  file<<"\tldr %r0, =locals"<<std::endl;
379  file<<"\tldr %r0, [%r0, #"<<4 * x<<"]"<<std::endl;
380  file<<"\tbl free"<<std::endl<<std::endl;
381  }
382 
383  file<<"\t@ locals are free"<<std::endl<<std::endl;
384 
385  file<<std::endl;
386  file<<"\tmov %r0, $0"<<std::endl;
390  file<<"\tbl fflush"<<std::endl;
391  file<<"\tmov %r7, $1"<<std::endl;
392 
395  file<<"\tswi $0"<<std::endl;
396  file<<"\t.end"<<std::endl;
397  file.close();
398 }// allocate enough space for drew-sized strings.
std::string pirate_name
Definition: command.h:45
#define MAX_STRING_SIZE
void writeAssembly()
exp_type
Definition: command.h:65