OpenCores
URL https://opencores.org/ocsvn/c16/c16/trunk

Subversion Repositories c16

[/] [c16/] [trunk/] [compiler/] [Statement.cc] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jsauermann
// Statement.cc
2
 
3
#include <stdio.h>
4
#include <assert.h>
5
#include "Node.hh"
6
#include "Name.hh"
7
#include "Backend.hh"
8
 
9
class LoopStack
10
{
11
public:
12
   LoopStack(int num, LoopStack * prev)
13
   : number(num),
14
     previous(prev)
15
     {};
16
 
17
   static int Push(LoopStack * & stack);
18
   static void Pop(LoopStack * & stack, int val);
19
   static int Get(LoopStack * & stack)
20
      { assert(stack);   return stack->number; };
21
 
22
private:
23
   int number;
24
   LoopStack * previous;
25
 
26
   static int next_number;
27
};
28
 
29
int LoopStack::next_number = 1;
30
 
31
LoopStack * loop_stack  = 0;
32
LoopStack * break_stack = 0;
33
 
34
//-----------------------------------------------------------------------------
35
int LoopStack::Push(LoopStack * & stack)
36
{
37
   stack = new LoopStack(next_number++, stack);
38
   return stack->number;
39
}
40
//-----------------------------------------------------------------------------
41
void LoopStack::Pop(LoopStack * & stack, int val)
42
{
43
   assert(stack);
44
   assert(val == stack->number);
45
 
46
LoopStack * del = stack;
47
   stack = stack->previous;
48
   delete del;
49
}
50
//=============================================================================
51
void ExpressionStatement::Emit(FILE * out)
52
{
53
   EmitStart(out);
54
   if (expression)   expression->Emit(out);
55
   EmitEnd(out);
56
}
57
//-----------------------------------------------------------------------------
58
void SwitchStatement::Emit(FILE * out)
59
{
60
const int brk = LoopStack::Push(break_stack);
61
 
62
   EmitStart(out);
63
 
64
   assert(condition);
65
   condition->Emit(out);
66
   Backend::move_rr_to_ll();
67
 
68
   assert(case_stat);
69
   case_stat->EmitCaseJumps(out, condition->GetSize());
70
 
71
   EmitEnd(out);
72
 
73
   LoopStack::Pop(break_stack, brk);
74
}
75
//-----------------------------------------------------------------------------
76
void IfElseStatement::Emit(FILE * out)
77
{
78
const int loop = LoopStack::Push(loop_stack);   // just get a number
79
   LoopStack::Pop(loop_stack, loop);
80
 
81
   EmitStart(out);
82
   assert(condition);
83
   condition->Emit(out);
84
 
85
const int size = condition->GetSize();
86
 
87
   if (if_stat)
88
      {
89
        if (else_stat)   // if and else
90
           {
91
             Backend::branch_false("else", loop, size);
92
             if_stat->Emit(out);
93
             Backend::branch("endif", loop);
94
             Backend::label("else", loop);
95
             else_stat->Emit(out);
96
             Backend::label("endif", loop);
97
           }
98
        else             // if only
99
           {
100
             Backend::branch_false("endif", loop, size);
101
             if_stat->Emit(out);
102
             Backend::label("endif", loop);
103
           }
104
      }
105
   else
106
      {
107
        if (else_stat)   // else only
108
           {
109
             Backend::branch_true("endif", loop, size);
110
             else_stat->Emit(out);
111
             Backend::label("endif", loop);
112
           }
113
        else             // nothing
114
           {
115
           }
116
      }
117
 
118
   EmitEnd(out);
119
}
120
//-----------------------------------------------------------------------------
121
void DoWhileStatement::Emit(FILE * out)
122
{
123
const int loop = LoopStack::Push(loop_stack);
124
const int brk  = LoopStack::Push(break_stack);
125
 
126
   EmitStart(out);
127
 
128
   assert(condition);
129
   assert(body);
130
 
131
const int size = condition->GetSize();
132
 
133
   Backend::label("loop", loop);
134
   body->Emit(out);
135
 
136
   Backend::label("cont", loop);
137
   condition->Emit(out);
138
   Backend::branch_true("loop", loop, size);
139
 
140
   Backend::label("brk", brk);
141
 
142
   EmitEnd(out);
143
 
144
   LoopStack::Pop(break_stack, brk);
145
   LoopStack::Pop(loop_stack, loop);
146
}
147
//-----------------------------------------------------------------------------
148
void WhileStatement::Emit(FILE * out)
149
{
150
const int loop = LoopStack::Push(loop_stack);
151
const int brk  = LoopStack::Push(break_stack);
152
 
153
   EmitStart(out);
154
 
155
   assert(condition);
156
   assert(body);
157
 
158
const int size = condition->GetSize();
159
 
160
   if (body->NotEmpty())   Backend::branch("cont", loop);
161
 
162
   Backend::label("loop", loop);
163
   body->Emit(out);
164
 
165
   Backend::label("cont", loop);
166
   condition->Emit(out);
167
   Backend::branch_true("loop", loop, size);
168
 
169
   Backend::label("brk", brk);
170
 
171
   EmitEnd(out);
172
 
173
   LoopStack::Pop(break_stack,  brk);
174
   LoopStack::Pop(loop_stack, loop);
175
}
176
//-----------------------------------------------------------------------------
177
void ForStatement::Emit(FILE * out)
178
{
179
const int loop = LoopStack::Push(loop_stack);
180
const int brk  = LoopStack::Push(break_stack);
181
 
182
   EmitStart(out);
183
 
184
   assert(for_1);
185
   assert(for_2);
186
   assert(body);
187
 
188
Expression * cond = for_2->GetExpression();
189
 
190
int size = 0;
191
   if (cond)   size = cond->GetSize();
192
 
193
   for_1->Emit(out);
194
 
195
   if (cond)   Backend::branch("tst", loop);
196
 
197
   Backend::label("loop", loop);
198
   body->Emit(out);
199
 
200
   Backend::label("cont", loop);
201
   if (for_3)   for_3->Emit(out);
202
 
203
 
204
   if (cond)
205
      {
206
        Backend::label("tst", loop);
207
        cond->Emit(out);
208
        Backend::branch_true("loop", loop, size);
209
      }
210
   else
211
      {
212
        Backend::branch("loop", loop);
213
      }
214
 
215
   Backend::label("brk", brk);
216
 
217
   EmitEnd(out);
218
 
219
   LoopStack::Pop(break_stack, brk);
220
   LoopStack::Pop(loop_stack, loop);
221
}
222
//-----------------------------------------------------------------------------
223
void LabelStatement::Emit(FILE * out)
224
{
225
   EmitStart(out);
226
 
227
   assert(label_name);
228
   assert(statement);
229
 
230
   Backend::label(label_name);
231
   statement->Emit(out);
232
 
233
   EmitEnd(out);
234
}
235
//-----------------------------------------------------------------------------
236
void GotoStatement::Emit(FILE * out)
237
{
238
   EmitStart(out);
239
 
240
   assert(label_name);
241
 
242
   Backend::branch(label_name);
243
 
244
   EmitEnd(out);
245
}
246
//-----------------------------------------------------------------------------
247
void ReturnStatement::Emit(FILE * out)
248
{
249
   EmitStart(out);
250
 
251
   if (retval)   retval->Emit(out);
252
 
253
   Backend::branch("return");
254
 
255
   EmitEnd(out);
256
}
257
//-----------------------------------------------------------------------------
258
void ContStatement::Emit(FILE * out)
259
{
260
   EmitStart(out);
261
 
262
   if (do_break)
263
      {
264
        Backend::branch("brk", LoopStack::Get(break_stack));
265
      }
266
   else
267
      {
268
        Backend::branch("cont", LoopStack::Get(loop_stack));
269
      }
270
 
271
   EmitEnd(out);
272
}
273
//-----------------------------------------------------------------------------
274
void CompoundStatement::Emit(FILE * out)
275
{
276
   EmitStart(out);
277
   if (stat_list)   stat_list->Emit(out);
278
   EmitEnd(out);
279
}
280
//-----------------------------------------------------------------------------
281
int CompoundStatement::EmitAutovars(FILE * out)
282
{
283
int ret = 0;
284
 
285
   for (DeclarationList * d = decl_list; d; d = d->Tail())
286
       {
287
         Declaration * di = d->Head();
288
         assert(di);
289
         int len = di->EmitAutovars(out);
290
         assert(len > 0);
291
         ret += len;
292
       }
293
 
294
   return ret;
295
}
296
//-----------------------------------------------------------------------------
297
void CompoundStatement::EmitCaseJumps(FILE * out, int size)
298
{
299
const int brk = LoopStack::Get(break_stack);
300
 
301
bool has_default = false;
302
 
303
   for (StatementList * sl = stat_list; sl; sl = sl->Tail())
304
       {
305
         Statement * s = sl->Head();
306
         assert(s);
307
         s->EmitCaseJump(out, false, brk, size);
308
       }
309
 
310
   for (StatementList * sl = stat_list; sl; sl = sl->Tail())
311
       {
312
         Statement * s = sl->Head();
313
         assert(s);
314
         if (s->EmitCaseJump(out, true, brk, size))   has_default = true;
315
       }
316
 
317
   if (!has_default)
318
      {
319
        Backend::branch("brk", brk);
320
      }
321
 
322
   Emit(out);
323
 
324
   Backend::label("brk", brk);
325
}
326
//-----------------------------------------------------------------------------
327
void CaseStatement::Emit(FILE * out)
328
{
329
const int brk = LoopStack::Get(break_stack);
330
 
331
   EmitStart(out);
332
   if (case_value)
333
      {
334
        if (case_value->IsConstant())
335
           {
336
             const int value = case_value->GetConstantNumericValue();
337
             Backend::label("case", brk, value);
338
           }
339
        else
340
           {
341
             fprintf(stderr, "Case value not constant\r\n");
342
             semantic_errors++;
343
           }
344
      }
345
   else
346
      {
347
        Backend::label("deflt", brk);
348
      }
349
 
350
   if (statement)   statement->Emit(out);
351
   EmitEnd(out);
352
}
353
//-----------------------------------------------------------------------------
354
//
355
// return true iff this is a default clause
356
//
357
bool CaseStatement::EmitCaseJump(FILE * out, bool def, int loop, int size)
358
{
359
bool ret = false;
360
 
361
   if (def)   // default branch
362
      {
363
        if (!case_value)   { Backend::branch("deflt", loop);   ret = true; }
364
      }
365
   else       // case branch
366
      {
367
        if (case_value)
368
           {
369
             if (!case_value->IsConstant())
370
                {
371
                  fprintf(stderr, "case value not constant\r\n");
372
                  semantic_errors++;
373
                  return false;
374
                }
375
 
376
             const int value = case_value->GetConstantNumericValue();
377
             Backend::branch_case("case", loop, size, value);
378
           }
379
      }
380
 
381
   if (statement)   ret = ret || statement->EmitCaseJump(out, def, loop, size);
382
   return ret;
383
}
384
//-----------------------------------------------------------------------------

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.