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

Subversion Repositories c16

[/] [c16/] [trunk/] [compiler/] [Expression.cc] - Blame information for rev 31

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

Line No. Rev Author Line
1 2 jsauermann
// Expression.cc
2
 
3
#include <stdio.h>
4
#include <assert.h>
5
#include "Node.hh"
6
#include "Name.hh"
7
#include "Backend.hh"
8
 
9
//-----------------------------------------------------------------------------
10
Expression * NumericExpression::OptNegate()
11
{
12
   int_value->Negate();
13
   return this;
14
}
15
//-----------------------------------------------------------------------------
16
Expression * NumericExpression::OptComplement()
17
{
18
   int_value->Complement();
19
   return this;
20
}
21
//-----------------------------------------------------------------------------
22
Expression * NumericExpression::OptLogNot()
23
{
24
   int_value->LogNot();
25
   return this;
26
}
27
//-----------------------------------------------------------------------------
28
TypeName * NumericExpression::SetType()
29
{
30
   assert(int_value);
31
   return new TypeName(TS_INT);
32
}
33
//-----------------------------------------------------------------------------
34
void NumericExpression::EmitInitialization(FILE * out, int size)
35
{
36
const int value = int_value->GetValue();
37
   assert(int_value);
38
   if (size == 1)        fprintf(out, "\t.BYTE\t%d\n", value);
39
   else if (size == 2)   fprintf(out, "\t.WORD\t%d\n", value);
40
   else                  assert(0 && "Bad size");
41
}
42
//-----------------------------------------------------------------------------
43
NumericExpression::NumericExpression(TypeName * t)
44
   : Expression("NumericExpression (sizeof type)")
45
{
46
   assert(t);
47
   int_value = new NumericConstant(t->GetSize());
48
}
49
//-----------------------------------------------------------------------------
50
NumericExpression::NumericExpression(Expression * r)
51
   : Expression("NumericExpression (sizeof expr)"),
52
     int_value(0)
53
{
54
   assert(r);
55
 
56
   int_value = new NumericConstant(r->GetSize());
57
}
58
//-----------------------------------------------------------------------------
59
const char * NumericExpression::GetPretty(int val)
60
{
61
char * cp = new char[50];
62
   assert(cp);
63
   sprintf(cp, "NumericExpression (constant %d = 0x%X)", val, val);
64
   return cp;
65
 
66
}
67
//-----------------------------------------------------------------------------
68
NumericExpression::NumericExpression(NumericConstant * n)
69
   : Expression(GetPretty(n->GetValue())),
70
      int_value(n)
71
{
72
   assert(n);
73
}
74
//-----------------------------------------------------------------------------
75
NumericExpression::NumericExpression(int value)
76
   : Expression(GetPretty(value)),
77
     int_value(0)
78
{
79
   int_value = new NumericConstant(value);
80
}
81
//-----------------------------------------------------------------------------
82
StringExpression::StringExpression(StringConstant * s)
83
   : Expression("StringExpression"),
84
     string_constant(s)
85
{
86
}
87
//-----------------------------------------------------------------------------
88
TypeName * StringExpression::SetType()
89
{
90
/*
91
TypeSpecifier * con = new TypeSpecifier(TQ_CONST);
92
Ptr * ptr           = new Ptr(con);
93
Pointer * pointer   = new Pointer(ptr, 0);
94
DeclItem * di       = new DeclItem(pointer);
95
Declarator * decl   = new Declarator(di, 0);
96
TypeSpecifier * ts  = new TypeSpecifier(TS_CHAR);
97
*/
98
 
99
char * name = new char[10];
100
   assert(string_constant);
101
   sprintf(name, "Cstr_%d", string_constant->GetStringNumber());
102
 
103
const int len = string_constant->GetLength() + 1;   // 1 for terminatin 0
104
Expression * lex = new NumericExpression(len);
105
 
106
TypeSpecifier * ts  = new TypeSpecifier(TS_CHAR);
107
 
108
DeclItem * na_it = new DeclItem(name);
109
DeclItem * ar_it = new DeclItem(lex);
110
 
111
Declarator * ar_dcl = new Declarator(ar_it, 0);
112
Declarator * na_dcl = new Declarator(na_it, ar_dcl);
113
   return new TypeName(ts, na_dcl);
114
}
115
//-----------------------------------------------------------------------------
116
void StringExpression::EmitInitialization(FILE * out, int size)
117
{
118
   assert(string_constant);
119
   assert(size == 2);
120
   fprintf(out, "\t.WORD\tCstr_%d\n", string_constant->GetStringNumber());
121
}
122
//-----------------------------------------------------------------------------
123
TypeName * IdentifierExpression::SetType()
124
{
125
   assert(varname);
126
TypeName * ret = Name::FindType(varname);
127
 
128
   if (ret)   return ret;
129
 
130
   fprintf(stderr, "Symbol '%s' not declared\n", varname);
131
   semantic_errors++;
132
   return new TypeName(TS_INT);
133
}
134
//-----------------------------------------------------------------------------
135
MemberExpression::MemberExpression(bool is_pointer, Expression * l,
136
                                   const char * s)
137
   : Expression("Expression l.member"),
138
     membername(s),
139
     left(l)
140
{
141
   if (is_pointer)   // map l->s to (*l).s
142
      {
143
        left = UnaryExpression::New(ET_CONTENT, left);
144
      }
145
}
146
//-----------------------------------------------------------------------------
147
TypeName * MemberExpression::SetType()
148
{
149
   assert(left);
150
   return left->GetType()->GetMemberType(membername);
151
}
152
//-----------------------------------------------------------------------------
153
void MemberExpression::Emit(FILE * out)
154
{
155
   EmitAddress(out, true);
156
}
157
//-----------------------------------------------------------------------------
158
void MemberExpression::EmitAddress(FILE * out)
159
{
160
   EmitAddress(out, false);
161
}
162
//-----------------------------------------------------------------------------
163
void MemberExpression::EmitAddress(FILE * out, bool content)
164
{
165
   assert(membername);
166
 
167
TypeName * struct_type = left->GetType();
168
   assert(struct_type);
169
 
170
   if (!struct_type->IsStruct())
171
      {
172
        fprintf(stderr, "request for member %s of non-struct\n", membername);
173
        semantic_errors++;
174
      }
175
 
176
TypeSpecifier * ts = struct_type->GetTypeSpecifier();
177
   assert(ts);
178
 
179
const char * sname = ts->GetName();
180
   if (sname == 0)
181
      {
182
        fprintf(stderr, "No struct name in member expression\n");
183
        semantic_errors++;
184
        return;
185
      }
186
 
187
StructDeclarationList * sdl = StructName::Find(sname);
188
   if (sdl == 0)
189
      {
190
        fprintf(stderr, "No struct %s defined\n", sname);
191
        semantic_errors++;
192
        return;
193
      }
194
 
195
int position = -1;
196
TypeName * membtype = 0;
197
 
198
   for (; sdl; sdl = sdl->Tail())
199
       {
200
         StructDeclaration * sd = sdl->Head();
201
         assert(sd);
202
         position = sd->GetMemberPosition(sname, membername, ts->IsUnion());
203
         if (position == -1)   continue;
204
 
205
         membtype = sd->GetMemberType(sname, membername);
206
         assert(membtype);
207
         break;
208
       }
209
 
210
   if (!membtype)
211
      {
212
        fprintf(stderr, "struct %s has no member %s\n", sname, membername);
213
        semantic_errors++;
214
        return;
215
      }
216
 
217
   left->EmitAddress(out);
218
   Backend::compute_binary(ET_ADD, true, position, "+ (member)");
219
   if (content)   Backend::content(membtype->GetSUW());
220
}
221
//-----------------------------------------------------------------------------
222
Expression * UnaryExpression::New(UnaExprType et, Expression * r)
223
{
224
   assert(r);
225
 
226
   if (r->IsConstant())
227
      {
228
        switch(et)
229
           {
230
             case ET_CONJUGATE:  return r;
231
             case ET_NEGATE:     return r->OptNegate();
232
             case ET_COMPLEMENT: return r->OptComplement();
233
             case ET_LOG_NOT:    return r->OptLogNot();
234
           }
235
      }
236
 
237
   switch(et)
238
      {
239
        case ET_POSTINC:   // x++ = ++x - 1
240
             {
241
               Expression * pre = UnaryExpression::New(ET_PREINC, r);
242
               NumericConstant   * num = new NumericConstant(1);
243
               NumericExpression * one = new NumericExpression(num);
244
               return SubtractionExpression::New(pre, one);
245
             }
246
 
247
        case ET_POSTDEC:   // x-- = --x + 1
248
             {
249
               Expression * pre = UnaryExpression::New(ET_PREDEC, r);
250
               NumericConstant   * num = new NumericConstant(1);
251
               NumericExpression * one = new NumericExpression(num);
252
               return AdditionExpression::New(pre, one);
253
             }
254
      }
255
 
256
   return new UnaryExpression(et, r);
257
}
258
//-----------------------------------------------------------------------------
259
TypeName * UnaryExpression::SetType()
260
{
261
   assert(right);
262
   switch(expr_type)
263
      {
264
        case ET_CONJUGATE:
265
        case ET_NEGATE:
266
        case ET_COMPLEMENT:
267
        case ET_PREINC:
268
        case ET_PREDEC:
269
        case ET_POSTINC:
270
        case ET_POSTDEC:
271
             return right->GetType();
272
 
273
        case ET_LOG_NOT:
274
             return new TypeName(TS_INT);
275
 
276
        case ET_ADDRESS:
277
             return right->GetType()->AddressOf();
278
 
279
        case ET_CONTENT:
280
             return right->GetType()->ContentOf();
281
 
282
        default: assert(0 && "Bad unary operator");
283
      }
284
}
285
//-----------------------------------------------------------------------------
286
UnaryExpression::UnaryExpression(TypeName * t, Expression * r)
287
   : Expression("Expression (cast)r"),
288
     expr_type(ET_CAST),
289
     right(r)
290
{
291
   assert(right);
292
   Expression::SetType(t);
293
}
294
//-----------------------------------------------------------------------------
295
Expression * AdditionExpression::New(Expression * l, Expression * r)
296
{
297
   if (l->IsVariable() && l->IsArray())
298
      {
299
         l = UnaryExpression::New(ET_ADDRESS, l);
300
      }
301
 
302
   if (r->IsVariable() && r->IsArray())
303
      {
304
         r = UnaryExpression::New(ET_ADDRESS, r);
305
      }
306
 
307
   if (l->IsNumericConstant() && r->IsNumericConstant())
308
      {
309
        const int lval = l->GetConstantNumericValue();
310
        const int rval = r->GetConstantNumericValue();
311
        delete l;
312
        delete r;
313
        return new NumericExpression(lval + rval);
314
      }
315
 
316
   return new AdditionExpression(l, r);
317
}
318
//-----------------------------------------------------------------------------
319
Expression * SubtractionExpression::New(Expression * l, Expression * r)
320
{
321
   if (l->IsNumericConstant() && r->IsNumericConstant())
322
      {
323
        const int lval = l->GetConstantNumericValue();
324
        const int rval = r->GetConstantNumericValue();
325
        delete l;
326
        delete r;
327
        return new NumericExpression(lval - rval);
328
      }
329
 
330
   return new SubtractionExpression(l, r);
331
}
332
//-----------------------------------------------------------------------------
333
Expression * BinaryExpression::New(BinExprType et, Expression * l,
334
                                   Expression * r)
335
{
336
   assert(l);
337
   if (!r)   return new BinaryExpression(et, l, r);   // function call
338
 
339
   if (l->IsNumericConstant() && r->IsNumericConstant())
340
      {
341
        const int lval = l->GetConstantNumericValue();
342
        const int rval = r->GetConstantNumericValue();
343
        switch(et)
344
           {
345
             case ET_LIST:
346
                  delete l;
347
                  return r;
348
 
349
             case ET_BIT_OR:
350
                  delete l;
351
                  delete r;
352
                  return new NumericExpression(lval | rval);
353
 
354
             case ET_BIT_AND:
355
                  delete l;
356
                  delete r;
357
                  return new NumericExpression(lval & rval);
358
 
359
             case ET_BIT_XOR:
360
                  delete l;
361
                  delete r;
362
                  return new NumericExpression(lval ^ rval);
363
 
364
             case ET_LOG_OR:
365
                  delete l;
366
                  delete r;
367
                  if (lval || rval)   return new NumericExpression(-1);
368
                  return new NumericExpression(0);
369
 
370
             case ET_LOG_AND:
371
                  delete l;
372
                  delete r;
373
                  if (lval || rval)   return new NumericExpression(-1);
374
                  return new NumericExpression(0);
375
 
376
             case ET_EQUAL:
377
                  delete l;
378
                  delete r;
379
                  if (lval == rval)   return new NumericExpression(-1);
380
                  return new NumericExpression(0);
381
 
382
             case ET_NOT_EQUAL:
383
                  delete l;
384
                  delete r;
385
                  if (lval != rval)   return new NumericExpression(-1);
386
                  return new NumericExpression(0);
387
 
388
             case ET_LESS_EQUAL:
389
                  delete l;
390
                  delete r;
391
                  if (lval <= rval)   return new NumericExpression(-1);
392
                  return new NumericExpression(0);
393
 
394
             case ET_LESS:
395
                  delete l;
396
                  delete r;
397
                  if (lval < rval)   return new NumericExpression(-1);
398
                  return new NumericExpression(0);
399
 
400
             case ET_GREATER_EQUAL:
401
                  delete l;
402
                  delete r;
403
                  if (lval >= rval)   return new NumericExpression(-1);
404
                  return new NumericExpression(0);
405
 
406
             case ET_GREATER:
407
                  delete l;
408
                  delete r;
409
                  if (lval > rval)   return new NumericExpression(-1);
410
                  return new NumericExpression(0);
411
 
412
             case ET_LEFT:
413
                  delete l;
414
                  delete r;
415
                  return new NumericExpression(lval << rval);
416
 
417
             case ET_RIGHT:
418
                  delete l;
419
                  delete r;
420
                  return new NumericExpression(lval >> rval);
421
 
422
             case ET_MULT:
423
                  delete l;
424
                  delete r;
425
                  return new NumericExpression(lval * rval);
426
 
427
             case ET_DIV:
428
                  delete l;
429
                  delete r;
430
                  assert(rval);
431
                  return new NumericExpression(lval / rval);
432
 
433
             case ET_MOD:
434
                  delete l;
435
                  delete r;
436
                  assert(rval);
437
                  return new NumericExpression(lval % rval);
438
           }
439
      }
440
 
441
   if (l->IsNumericConstant())
442
      {
443
        const int lval = l->GetConstantNumericValue();
444
        switch(et)
445
           {
446
             case ET_LIST:
447
                  delete l;
448
                  return r;
449
 
450
             case ET_LOG_OR:
451
                  delete l;
452
                  if (lval == 0)   return r;
453
                  delete r;
454
                  return  new NumericExpression(-1);
455
 
456
             case ET_LOG_AND:
457
                  delete l;
458
                  if (lval != 0)   return r;
459
                  delete r;
460
                  return  new NumericExpression(0);
461
           }
462
      }
463
   else if (l->IsConstant())   // otherwise string (pointer) : always nonzero
464
      {
465
        assert(l->IsStringConstant());
466
        switch(et)
467
           {
468
             case ET_LOG_OR:
469
                  delete l;
470
                  delete r;
471
                  return new NumericExpression(-1);
472
 
473
             case ET_LOG_AND:
474
                  delete l;
475
                  return r;
476
 
477
             case ET_LIST:
478
                  delete l;
479
                  return r;
480
           }
481
      }
482
 
483
   if (r->IsNumericConstant())
484
      {
485
        const int rval = r->GetConstantNumericValue();
486
        switch(et)
487
           {
488
             case ET_LOG_OR:
489
                  if (!rval)   return l;
490
                  break;
491
 
492
             case ET_LOG_AND:
493
                  if (rval)   return l;
494
                  break;
495
 
496
           }
497
      }
498
   else if (r->IsConstant())   // otherwise string (pointer) : always nonzero
499
      {
500
        assert(r->IsStringConstant());
501
        switch(et)
502
           {
503
             case ET_LOG_AND:   return r;
504
           }
505
      }
506
 
507
   return new BinaryExpression(et, l, r);
508
}
509
//-----------------------------------------------------------------------------
510
BinaryExpression::BinaryExpression(BinExprType et,
511
                                   Expression * l, Expression * r)
512
   : Expression(GetPrettyName(GetPretty(et))),
513
     expr_type(et),
514
     left(l),
515
     right(r)
516
{
517
   switch(expr_type)
518
      {
519
        case ET_ADD_ASSIGN:       // expr +=  expr
520
             right = AdditionExpression::New(l, right);
521
             expr_type = ET_ASSIGN;
522
             return;
523
 
524
        case ET_SUB_ASSIGN:       // expr -=  expr
525
             right = SubtractionExpression::New(l, right);
526
             expr_type = ET_ASSIGN;
527
             return;
528
 
529
        case ET_MULT_ASSIGN:      // expr *=  expr
530
        case ET_DIV_ASSIGN:       // expr /=  expr
531
        case ET_MOD_ASSIGN:       // expr %=  expr
532
        case ET_LEFT_ASSIGN:      // expr <<= expr
533
        case ET_RIGHT_ASSIGN:     // expr >>= expr
534
        case ET_AND_ASSIGN:       // expr &=  expr
535
        case ET_XOR_ASSIGN:       // expr ^=  expr
536
        case ET_OR_ASSIGN:        // expr |=  expr
537
             right = new BinaryExpression(MapAssign(expr_type), l, right);
538
             expr_type = ET_ASSIGN;
539
             return;
540
      }
541
}
542
//-----------------------------------------------------------------------------
543
TypeName * BinaryExpression::SetType()
544
{
545
   assert(left);
546
   assert(right || expr_type == ET_FUNCALL);   // zero if no args
547
 
548
   switch(expr_type)
549
      {
550
        case ET_LIST:             // expr  ,  expr
551
        case ET_LEFT:             // expr <<  expr
552
        case ET_RIGHT:            // expr >>  expr
553
             return right->GetType();
554
 
555
        case ET_ASSIGN:           // expr  =  expr
556
             return left->GetType();
557
 
558
        case ET_EQUAL:            // expr ==  expr
559
        case ET_NOT_EQUAL:        // expr !=  expr
560
        case ET_LESS_EQUAL:       // expr <=  expr
561
        case ET_LESS:             // expr <   expr
562
        case ET_GREATER_EQUAL:    // expr >=  expr
563
        case ET_GREATER:          // expr >   expr
564
        case ET_BIT_OR:           // expr |   expr
565
        case ET_BIT_AND:          // expr &   expr
566
        case ET_BIT_XOR:          // expr ^   expr
567
        case ET_MULT:             // expr *   expr
568
        case ET_DIV:              // expr /   expr
569
        case ET_MOD:              // expr %   expr
570
             return MaxType(left, right);
571
 
572
        case ET_LOG_OR:           // expr ||  expr
573
        case ET_LOG_AND:          // expr &&  expr
574
             return new TypeName(TS_INT);
575
 
576
        case ET_FUNCALL:          // expr (   ... )
577
             return left->FunReturnType();
578
 
579
        case ET_ELEMENT:          // expr [ expr ]
580
             return left->GetType()->ContentOf();
581
      }
582
   assert(0 && "Bad binary operator");
583
}
584
//-----------------------------------------------------------------------------
585
TypeName * AdditionExpression::SetType()
586
{
587
   assert(left);
588
   assert(right);
589
 
590
   if (left->GetType()->IsNumericType() && right->GetType()->IsNumericType())
591
      return MaxType(left, right);
592
 
593
   if (left ->GetType()->IsNumericType())   return right->GetType();
594
   if (right->GetType()->IsNumericType())   return left ->GetType();
595
 
596
   fprintf(stderr, "Illegal pointer arithmetic\n");
597
   semantic_errors++;
598
   return new TypeName(TS_INT);
599
}
600
//-----------------------------------------------------------------------------
601
TypeName * SubtractionExpression::SetType()
602
{
603
   assert(left);
604
   assert(right);
605
 
606
   if (left->GetType()->IsNumericType() && right->GetType()->IsNumericType())
607
      return MaxType(left, right);
608
 
609
   if (left ->GetType()->IsNumericType())   return right->GetType();
610
   if (right->GetType()->IsNumericType())   return left ->GetType();
611
 
612
   // TODO: check pointer compatibility
613
   return new TypeName(TS_INT);
614
}
615
//-----------------------------------------------------------------------------
616
TypeName * CondExpression::SetType()
617
{
618
   // TODO: check argument compatibility
619
   return right->GetType();
620
}
621
//-----------------------------------------------------------------------------
622
TypeName * ArgListExpression::SetType()
623
{
624
   assert(0);
625
   return 0;
626
}
627
//-----------------------------------------------------------------------------
628
void Expression::SetType(TypeName * t)
629
{
630
   assert(!type_name);
631
   type_name = t;
632
   assert(type_name);
633
}
634
//-----------------------------------------------------------------------------
635
TypeName * Expression::GetType()
636
{
637
   if (!type_name)   type_name = SetType();
638
 
639
   assert(type_name);
640
   return type_name;
641
}
642
//-----------------------------------------------------------------------------
643
bool Expression::IsPointer()
644
{
645
   return GetType()->IsPointer();
646
}
647
//-----------------------------------------------------------------------------
648
bool Expression::IsArray()
649
{
650
   return GetType()->IsArray();
651
}
652
//-----------------------------------------------------------------------------
653
bool Expression::IsUnsigned()
654
{
655
   return GetType()->IsUnsigned();
656
}
657
//-----------------------------------------------------------------------------
658
int Expression::PointeeSize()
659
{
660
   return GetType()->GetPointeeSize();
661
}
662
//-----------------------------------------------------------------------------
663
int Expression::GetSize()
664
{
665
   return GetType()->GetSize();
666
}
667
//-----------------------------------------------------------------------------
668
SUW Expression::GetSUW()
669
{
670
   return GetType()->GetSUW();
671
}
672
//-----------------------------------------------------------------------------
673
void IdentifierExpression::Emit(FILE * out)
674
{
675
   assert(this);
676
   assert(varname);
677
   EmitStart(out);
678
   EmitIndent(out);
679
   fprintf(out, "expr_type = \"identifier\" (%s)\n", varname);
680
 
681
const int spos = Name::FindPos(varname);
682
   if (spos == 1)
683
      {
684
        fprintf(stderr, "Variable %s not declared\n", varname);
685
        semantic_errors++;
686
      }
687
   else
688
      {
689
        if (spos == 0)   Backend::load_rr_var(varname,       GetSUW());
690
        else             Backend::load_rr_var(varname, spos, GetSUW());
691
      }
692
 
693
   EmitEnd(out);
694
}
695
//-----------------------------------------------------------------------------
696
void IdentifierExpression::Emit_to_ll(FILE * out)
697
{
698
   assert(this);
699
   EmitStart(out);
700
   EmitIndent(out);
701
   fprintf(out, "expr_type = \"identifier\" (%s)\n", varname);
702
 
703
   assert(varname);
704
const int spos = Name::FindPos(varname);
705
   if (spos == 1)
706
      {
707
        fprintf(stderr, "Variable %s not declared\n", varname);
708
        semantic_errors++;
709
      }
710
   else
711
      {
712
        if (spos == 0)   Backend::load_ll_var(varname,       GetSUW());
713
        else             Backend::load_ll_var(varname, spos, GetSUW());
714
      }
715
 
716
   EmitEnd(out);
717
}
718
//-----------------------------------------------------------------------------
719
void StringExpression::Emit(FILE * out)
720
{
721
   assert(this);
722
   EmitStart(out);
723
 
724
   assert(string_constant);
725
   string_constant->EmitValue_RR(out);
726
 
727
   EmitEnd(out);
728
}
729
//-----------------------------------------------------------------------------
730
void StringExpression::EmitAddress(FILE * out)
731
{
732
   assert(this);
733
   EmitStart(out);
734
 
735
   assert(string_constant);
736
   string_constant->EmitValue_RR(out);
737
 
738
   EmitEnd(out);
739
}
740
//-----------------------------------------------------------------------------
741
void StringExpression::Emit_to_ll(FILE * out)
742
{
743
   assert(this);
744
   EmitStart(out);
745
 
746
   assert(string_constant);
747
   string_constant->EmitValue_LL(out);
748
 
749
   EmitEnd(out);
750
}
751
//-----------------------------------------------------------------------------
752
void NumericExpression::Emit(FILE * out)
753
{
754
   assert(this);
755
   assert(int_value);
756
   EmitStart(out);
757
 
758
   assert(int_value);
759
   int_value->EmitValue_RR(out);
760
 
761
   EmitEnd(out);
762
}
763
//-----------------------------------------------------------------------------
764
void NumericExpression::Emit_to_ll(FILE * out)
765
{
766
   assert(this);
767
   assert(int_value);
768
   EmitStart(out);
769
 
770
   assert(int_value);
771
   int_value->EmitValue_LL(out);
772
 
773
   EmitEnd(out);
774
}
775
//-----------------------------------------------------------------------------
776
void CondExpression::Emit(FILE * out)
777
{
778
   assert(this);
779
   EmitStart(out);
780
 
781
   assert(left);
782
   assert(middle);
783
   assert(right);
784
   ExpressionStatement sm(middle);
785
   ExpressionStatement sr(right);
786
   IfElseStatement     sel(left, &sm, &sr);
787
   sel.Emit(out);
788
 
789
   EmitEnd(out);
790
}
791
//-----------------------------------------------------------------------------
792
void BinaryExpression::EmitAddress(FILE * out)
793
{
794
   assert(this);
795
   assert(left);
796
   EmitStart(out);
797
 
798
   switch(expr_type)
799
      {
800
         case ET_ELEMENT:             // expr[expr]
801
              {
802
                if (left->IsPointer())
803
                   {
804
                     assert(right);
805
                     right->Emit(out);
806
                     Backend::scale_rr(left->GetType()->GetPointeeSize());
807
                     Backend::push_rr(WO);
808
                     left->Emit(out);
809
                     Backend::pop_ll(WO);
810
                     Backend::compute_binary(ET_ADD, true, "+ (element)");
811
                   }
812
                else if (left->IsArray())
813
                   {
814
                     assert(right);
815
                     right->Emit(out);
816
                     Backend::scale_rr(left->GetType()->GetPointeeSize());
817
                     left->AddAddress(out);
818
                   }
819
                else
820
                   {
821
                     left->GetType()->Print(out);
822
                     fprintf(stderr, " is not a pointer\n");
823
                     semantic_errors++;
824
                   }
825
              }
826
              break;
827
 
828
         default:
829
              fprintf(stderr, "'expr %s expr' is not an lvalue\n",
830
                      GetPretty(expr_type));
831
              semantic_errors++;
832
              break;
833
      }
834
   EmitEnd(out);
835
}
836
//-----------------------------------------------------------------------------
837
void UnaryExpression::EmitAddress(FILE * out)
838
{
839
   assert(this);
840
   EmitStart(out);
841
 
842
   assert(right);
843
   switch(expr_type)
844
      {
845
         case ET_CAST:             // (type)   expr
846
         case ET_CONJUGATE:        //      +   expr
847
         case ET_LOG_NOT:          //      !   expr
848
         case ET_NEGATE:           //      -   expr
849
         case ET_COMPLEMENT:       //      ~   expr
850
              fprintf(stderr, "'%s expr' is not an lvalue\n",
851
                GetPretty(expr_type));
852
              semantic_errors++;
853
              break;
854
 
855
         case ET_CONTENT:          //      *   expr
856
              right->Emit(out);
857
              break;
858
 
859
         case ET_ADDRESS:          //      &   expr
860
              right->EmitAddress(out);
861
              break;
862
 
863
         default: assert(0 && "Bad expr_type");
864
      }
865
 
866
   EmitEnd(out);
867
}
868
//-----------------------------------------------------------------------------
869
void UnaryExpression::EmitInitialization(FILE * out, int size)
870
{
871
   assert(this);
872
   assert(right);
873
   switch(expr_type)
874
      {
875
         case ET_CAST: //      (type)expr
876
              right->EmitInitialization(out, size);
877
              return;
878
 
879
         case ET_ADDRESS: //      &   expr
880
             if (size != 2) right->Emit(stderr);
881
             assert(size == 2);
882
             if (right->IsVariable())
883
                {
884
                  const char * vname = right->GetVarname();
885
                  assert(vname);
886
 
887
                  // check that var is declared
888
                  const int spos = Name::FindPos(vname);
889
                     if (spos == 1)
890
                        {
891
                          fprintf(stderr, "Variable %s not declared\n", vname);
892
                          semantic_errors++;
893
                          return;
894
                        }
895
 
896
                  fprintf(out, "\t.WORD\tC%s\t\t\t; & %s\n", vname, vname);
897
                  return;
898
                }
899
      }
900
 
901
   fprintf(stderr, "Non-const initializer (not supported)\n");
902
   semantic_errors++;
903
}
904
//-----------------------------------------------------------------------------
905
void UnaryExpression::Emit(FILE * out)
906
{
907
   assert(this);
908
   EmitStart(out);
909
 
910
   assert(right);
911
   switch(expr_type)
912
      {
913
        case ET_PREINC:
914
        case ET_PREDEC:
915
             {
916
               BinExprType  op  = ET_ADD;
917
               const char * ops = "++";
918
               if (expr_type == ET_PREDEC)
919
                  {
920
                    op  = ET_SUB;
921
                    ops = "--";
922
                  }
923
 
924
               int amount = 1;
925
               if (right->IsPointer())
926
                  amount = right->GetType()->GetPointeeSize();
927
 
928
               if (right->IsVariable())
929
                  {
930
                    right->Emit(out);
931
                    Backend::compute_binary(op, true, ops, amount);
932
                    right->EmitAssign(out);
933
                    break;
934
                  }
935
 
936
               right->EmitAddress(out);
937
               Backend::move_rr_to_ll();
938
               Backend::content(right->GetSUW());
939
               Backend::compute_binary(op, true, ops, amount);
940
               Backend::assign(right->GetSUW());
941
             }
942
             break;
943
 
944
        case ET_LOG_NOT:          //      !   expr
945
        case ET_NEGATE:           //      -   expr
946
        case ET_COMPLEMENT:       //      ~   expr
947
             right->Emit(out);
948
             Backend::compute_unary(expr_type, GetPretty(expr_type));
949
             break;
950
 
951
        case ET_ADDRESS:          //      &   expr
952
             right->EmitAddress(out);
953
             break;
954
 
955
        case ET_CONTENT:          //      *   expr
956
             right->Emit(out);
957
             Backend::content(GetSUW());
958
             break;
959
 
960
        case ET_CONJUGATE:        //      +   expr
961
             right->Emit(out);
962
             break;
963
 
964
        case ET_CAST:             // (type)   expr
965
             right->Emit(out);
966
             break;
967
 
968
        default: assert(0 && "Bad expr_type");
969
      }
970
 
971
   EmitEnd(out);
972
}
973
//-----------------------------------------------------------------------------
974
void BinaryExpression::Emit(FILE * out)
975
{
976
   assert(this);
977
   EmitStart(out);
978
   ((TypeName *)GetType())->Emit(out);
979
 
980
   assert(left);
981
   assert(right || expr_type == ET_FUNCALL);   // zero if no args
982
   switch(expr_type)
983
      {
984
         case ET_FUNCALL:
985
              left ->EmitCall(out, right);
986
              break;
987
 
988
         case ET_LIST:
989
              left ->Emit(out);
990
              right->Emit(out);
991
              break;
992
 
993
         case ET_ASSIGN:           // expr = expr
994
              right->Emit(out);
995
              if (left->IsVariable())
996
                 {
997
                   left->EmitAssign(out);
998
                   break;
999
                 }
1000
              Backend::push_rr(left->GetSUW());
1001
              left->EmitAddress(out);
1002
              Backend::move_rr_to_ll();
1003
              Backend::pop_rr(left->GetSUW());
1004
              Backend::assign(GetSize());
1005
              break;
1006
 
1007
         case ET_BIT_OR:           // expr |   expr
1008
         case ET_BIT_AND:          // expr &   expr
1009
         case ET_BIT_XOR:          // expr ^   expr
1010
         case ET_MULT:             // expr *   expr
1011
         case ET_DIV:              // expr /   expr
1012
         case ET_MOD:              // expr %   expr
1013
         case ET_LEFT:             // expr <<  expr
1014
         case ET_RIGHT:            // expr >>  expr
1015
         case ET_EQUAL:            // expr ==  expr
1016
         case ET_NOT_EQUAL:        // expr !=  expr
1017
         case ET_LESS_EQUAL:       // expr <=  expr
1018
         case ET_LESS:             // expr <   expr
1019
         case ET_GREATER_EQUAL:    // expr >=  expr
1020
         case ET_GREATER:          // expr >   expr
1021
               if (right->IsConstant())
1022
                  {
1023
                    left->Emit(out);
1024
                    Backend::compute_binary(expr_type, IsUnsigned(),
1025
                                            GetPretty(expr_type),
1026
                                            right->GetConstantNumericValue());
1027
                  }
1028
               else if (left->IsConstant())
1029
                  {
1030
                    right->Emit(out);
1031
                    Backend::compute_binary(expr_type, IsUnsigned(),
1032
                                            left->GetConstantNumericValue(),
1033
                                            GetPretty(expr_type));
1034
                  }
1035
               else if (right->IsVariable())
1036
                  {
1037
                    left->Emit(out);
1038
                    Backend::move_rr_to_ll();
1039
                    right->Emit(out);
1040
                    Backend::compute_binary(expr_type, IsUnsigned(),
1041
                                            GetPretty(expr_type));
1042
                  }
1043
               else if (left->IsVariable())
1044
                  {
1045
                    right->Emit(out);
1046
                    left->Emit_to_ll(out);
1047
                    Backend::compute_binary(expr_type, IsUnsigned(),
1048
                                            GetPretty(expr_type));
1049
                  }
1050
               else
1051
                  {
1052
                    left->Emit(out);
1053
                    Backend::push_rr(WO);
1054
                    right->Emit(out);
1055
                    Backend::pop_ll(WO);
1056
                    Backend::compute_binary(expr_type, IsUnsigned(),
1057
                                            GetPretty(expr_type));
1058
                  }
1059
              break;
1060
 
1061
         case ET_LOG_AND:          // expr &&  expr
1062
                                   // if (left) right;
1063
              {
1064
                ExpressionStatement r(right);
1065
                IfElseStatement i(left, &r, 0);
1066
                i.Emit(out);
1067
              }
1068
              break;
1069
 
1070
         case ET_LOG_OR:           // expr ||  expr
1071
                                   // if (left) ; else right;
1072
              {
1073
                ExpressionStatement r(right);
1074
                IfElseStatement i(left, 0, &r);
1075
                i.Emit(out);
1076
              }
1077
              break;
1078
 
1079
         case ET_ELEMENT:           // expr [ expr ]
1080
              EmitAddress(out);
1081
              Backend::content(left->GetType()->ContentOf()->GetSUW());
1082
              break;
1083
 
1084
         default: assert(0 && "Bad expr_type");
1085
      }
1086
 
1087
   EmitEnd(out);
1088
}
1089
//-----------------------------------------------------------------------------
1090
void AdditionExpression::Emit(FILE * out)
1091
{
1092
   assert(this);
1093
   EmitStart(out);
1094
 
1095
   assert(left);
1096
   assert(right);
1097
 
1098
Expression * lft = left;
1099
Expression * rht = right;
1100
 
1101
   // move pointer to left side
1102
   if (right->IsPointer() || right->IsArray())
1103
      {
1104
        lft = right;
1105
        rht = left;
1106
      }
1107
 
1108
   if (rht->IsPointer() || rht->IsArray())   // error: pinter + pointer
1109
      {
1110
        fprintf(stderr, "Bad pointer arithmetic\n");
1111
        semantic_errors++;
1112
        EmitEnd(out);
1113
        return;
1114
      }
1115
 
1116
int rscale = 1;
1117
   if (lft ->IsPointer())   rscale = lft ->PointeeSize();
1118
 
1119
   if (rht->IsConstant())
1120
      {
1121
        lft->Emit(out);
1122
        Backend::compute_binary(expr_type, IsUnsigned(), GetPretty(ET_ADD),
1123
                                rscale * rht->GetConstantNumericValue());
1124
        EmitEnd(out);
1125
        return;
1126
      }
1127
 
1128
   if (lft->IsConstant())
1129
      {
1130
        rht->Emit(out);
1131
        Backend::compute_binary(expr_type, IsUnsigned(),
1132
                                lft->GetConstantNumericValue(),
1133
                                GetPretty(ET_ADD));
1134
        EmitEnd(out);
1135
        return;
1136
      }
1137
 
1138
   if (rht->IsVariable())
1139
      {
1140
        lft->Emit(out);
1141
        Backend::move_rr_to_ll();
1142
        rht->Emit(out);
1143
      }
1144
   else if (lft->IsVariable())
1145
      {
1146
        rht->Emit(out);
1147
        lft->Emit_to_ll(out);
1148
      }
1149
   else
1150
      {
1151
        rht->Emit(out);
1152
        Backend::push_rr(WO);
1153
        lft->Emit(out);
1154
        Backend::move_rr_to_ll();
1155
        Backend::pop_rr(WO);
1156
      }
1157
 
1158
   Backend::scale_rr(rscale);
1159
   Backend::compute_binary(ET_ADD, IsUnsigned(), GetPretty(ET_ADD));
1160
   EmitEnd(out);
1161
}
1162
//-----------------------------------------------------------------------------
1163
void SubtractionExpression::Emit(FILE * out)
1164
{
1165
   assert(this);
1166
   EmitStart(out);
1167
 
1168
   assert(left);
1169
   assert(right);
1170
 
1171
int rscale = 1;
1172
int uscale = 1;
1173
   if (left->IsPointer())
1174
      {
1175
        if (right->IsPointer())   uscale = left->PointeeSize();
1176
        else                      rscale = left->PointeeSize();
1177
      }
1178
   else if (right->IsPointer())
1179
      {
1180
        fprintf(stderr, "Bad pointer arithmetic\n");
1181
        semantic_errors++;
1182
        EmitEnd(out);
1183
        return;
1184
      }
1185
 
1186
   if (left->IsConstant())
1187
      {
1188
        right->Emit(out);
1189
        Backend::compute_binary(expr_type, IsUnsigned(),
1190
                                left->GetConstantNumericValue(),
1191
                                GetPretty(ET_SUB));
1192
        EmitEnd(out);
1193
        return;
1194
      }
1195
 
1196
   if (right->IsConstant())
1197
      {
1198
        left->Emit(out);
1199
        Backend::compute_binary(expr_type, IsUnsigned(), GetPretty(ET_SUB),
1200
                                rscale * right->GetConstantNumericValue());
1201
        EmitEnd(out);
1202
        return;
1203
      }
1204
 
1205
   if (right->IsVariable())
1206
      {
1207
        left->Emit(out);
1208
        Backend::move_rr_to_ll();
1209
        right->Emit(out);
1210
      }
1211
   else if (left->IsVariable())
1212
      {
1213
        right->Emit(out);
1214
        Backend::move_rr_to_ll();
1215
        left->Emit_to_ll(out);
1216
      }
1217
   else
1218
      {
1219
        right->Emit(out);
1220
        Backend::push_rr(WO);
1221
        left->Emit(out);
1222
        Backend::move_rr_to_ll();
1223
        Backend::pop_rr(WO);
1224
      }
1225
 
1226
   Backend::scale_rr(rscale);
1227
   Backend::compute_binary(ET_SUB, IsUnsigned(), GetPretty(ET_SUB));
1228
   Backend::unscale_rr(uscale, right->IsUnsigned());
1229
 
1230
   EmitEnd(out);
1231
}
1232
//-----------------------------------------------------------------------------
1233
const char * Expression::GetPrettyName(const char * pretty)
1234
{
1235
   assert(pretty);
1236
const int plen = strlen(pretty);
1237
char * ret = new char[plen + 10];
1238
   sprintf(ret, "Expr %s", pretty);
1239
   return ret;
1240
}
1241
//-----------------------------------------------------------------------------
1242
const char * UnaryExpression::GetPretty(UnaExprType expr_type)
1243
{
1244
   switch(expr_type)
1245
      {
1246
        case ET_ADDRESS:       return "& r";
1247
        case ET_CAST:          return "()r";
1248
        case ET_CONTENT:       return "* r";
1249
        case ET_CONJUGATE:     return "+ r";
1250
        case ET_NEGATE:        return "- r";
1251
        case ET_COMPLEMENT:    return "~ r";
1252
        case ET_LOG_NOT:       return "! r";
1253
        case ET_POSTINC:       return "r++";
1254
        case ET_POSTDEC:       return "r--";
1255
        case ET_PREINC:        return "++r";
1256
        case ET_PREDEC:        return "--r";
1257
 
1258
        default:               return "BAD UNARY EXPR_TYPE";
1259
      }
1260
}
1261
//-----------------------------------------------------------------------------
1262
const char * BinaryExpression::GetPretty(BinExprType expr_type)
1263
{
1264
   switch(expr_type)
1265
      {
1266
        case ET_LIST:          return "l , r";
1267
        case ET_ARGLIST:       return "(l , r)";
1268
        case ET_ASSIGN:        return "l = r";
1269
        case ET_MULT_ASSIGN:   return "l *- r";
1270
        case ET_DIV_ASSIGN:    return "l /= r";
1271
        case ET_MOD_ASSIGN:    return "l %= r";
1272
        case ET_ADD_ASSIGN:    return "l += r";
1273
        case ET_SUB_ASSIGN:    return "l -= r";
1274
        case ET_LEFT_ASSIGN:   return "l <<= r";
1275
        case ET_RIGHT_ASSIGN:  return "l >>= r";
1276
        case ET_AND_ASSIGN:    return "l & r";
1277
        case ET_XOR_ASSIGN:    return "l ^ r";
1278
        case ET_OR_ASSIGN:     return "l | r";
1279
        case ET_LOG_OR:        return "l || r";
1280
        case ET_LOG_AND:       return "l && r";
1281
        case ET_BIT_OR:        return "l | r";
1282
        case ET_BIT_AND:       return "l & r";
1283
        case ET_BIT_XOR:       return "l ^ r";
1284
        case ET_EQUAL:         return "l == r";
1285
        case ET_NOT_EQUAL:     return "l != r";
1286
        case ET_LESS_EQUAL:    return "l <= r";
1287
        case ET_LESS:          return "l < r";
1288
        case ET_GREATER_EQUAL: return "l >= r";
1289
        case ET_GREATER:       return "l > r";
1290
        case ET_LEFT:          return "l << r";
1291
        case ET_RIGHT:         return "l >> r";
1292
        case ET_ADD:           return "l + r";
1293
        case ET_SUB:           return "l - r";
1294
        case ET_MULT:          return "l * r";
1295
        case ET_DIV:           return "l / r";
1296
        case ET_MOD:           return "l % r";
1297
        case ET_FUNCALL:       return "l(r)";
1298
        case ET_ELEMENT:       return "l[r]";
1299
 
1300
        default:               return "BAD BINARY EXPR_TYPE";
1301
      }
1302
}
1303
//-----------------------------------------------------------------------------
1304
void IdentifierExpression::EmitAssign(FILE * out)
1305
{
1306
   assert(varname);
1307
const int spos = Name::FindPos(varname);
1308
   if (spos == 1)
1309
      {
1310
        fprintf(stderr, "Variable %s not declared\n", varname);
1311
        semantic_errors++;
1312
        return;
1313
      }
1314
 
1315
   if (spos == 0)   Backend::store_rr_var(varname, GetSUW());
1316
   else             Backend::store_rr_var(varname, spos, GetSUW());
1317
}
1318
//-----------------------------------------------------------------------------
1319
void IdentifierExpression::AddAddress(FILE * out)
1320
{
1321
   assert(varname);
1322
const int spos = Name::FindPos(varname);
1323
   if (spos == 1)
1324
      {
1325
        fprintf(stderr, "Variable %s not declared\n", varname);
1326
        semantic_errors++;
1327
        return;
1328
      }
1329
 
1330
   if (spos == 0)   Backend::add_address(varname);
1331
   else             Expression::AddAddress(out);
1332
}
1333
//-----------------------------------------------------------------------------
1334
void IdentifierExpression::EmitAddress(FILE * out)
1335
{
1336
   assert(varname);
1337
const int spos = Name::FindPos(varname);
1338
   if (spos == 1)
1339
      {
1340
        fprintf(stderr, "Variable %s not declared\n", varname);
1341
        semantic_errors++;
1342
        return;
1343
      }
1344
 
1345
   if (spos == 0)   Backend::load_address(varname);
1346
   else             Backend::load_address(varname, spos);
1347
}
1348
//-----------------------------------------------------------------------------
1349
void IdentifierExpression::EmitInitialization(FILE * out, int size)
1350
{
1351
   assert(varname);
1352
   fprintf(out, "\t.WORD\tC%s\n", varname);
1353
}
1354
//-----------------------------------------------------------------------------
1355
void Expression::EmitInitialization(FILE * out, int size)
1356
{
1357
   fprintf(stderr, "TODO: EmitInitialization %s\n", GetNodeType());
1358
   Emit(stderr);
1359
   fprintf(stderr, "----: EmitInitialization %s\n", GetNodeType());
1360
   assert(0);
1361
}
1362
//-----------------------------------------------------------------------------
1363
void Expression::EmitAddress(FILE * out)
1364
{
1365
   fprintf(stderr, "TODO: Expression::EmitAddress() %s\n", GetNodeType());
1366
   Emit(stderr);
1367
   fprintf(stderr, "----: Expression::EmitAddress() %s\n", GetNodeType());
1368
   assert(0);
1369
}
1370
//-----------------------------------------------------------------------------
1371
void Expression::AddAddress(FILE * out)
1372
{
1373
   Backend::push_rr(WO);
1374
   Emit(out);
1375
   Backend::pop_ll(WO);
1376
   Backend::compute_binary(ET_ADD, true, "&l[r]");
1377
}
1378
//-----------------------------------------------------------------------------
1379
BinExprType BinaryExpression::MapAssign(BinExprType et)
1380
{
1381
   switch(et)
1382
      {
1383
         case ET_MULT_ASSIGN:  return ET_MULT;
1384
         case ET_DIV_ASSIGN:   return ET_DIV;
1385
         case ET_MOD_ASSIGN:   return ET_MOD;
1386
         case ET_LEFT_ASSIGN:  return ET_LEFT;
1387
         case ET_RIGHT_ASSIGN: return ET_RIGHT;
1388
         case ET_AND_ASSIGN:   return ET_BIT_AND;
1389
         case ET_XOR_ASSIGN:   return ET_BIT_XOR;
1390
         case ET_OR_ASSIGN:    return ET_BIT_OR;
1391
      }
1392
 
1393
   assert(0 && "Bad expr_type");
1394
}
1395
//-----------------------------------------------------------------------------
1396
int Expression::FunReturnSize()
1397
{
1398
TypeName * funtn = FunReturnType();
1399
   assert(funtn);
1400
 
1401
   return funtn->GetFunReturnSize();
1402
}
1403
//-----------------------------------------------------------------------------
1404
TypeName * Expression::FunReturnType()
1405
{
1406
TypeName * tn = GetType();
1407
   assert(tn);
1408
   return tn->GetFunReturnType();
1409
}
1410
//-----------------------------------------------------------------------------
1411
Expression * IdentifierExpression::New(const char * s)
1412
{
1413
int value;
1414
bool is_enum = Name::FindEnum(s, value);
1415
 
1416
   if (!is_enum)   return new IdentifierExpression(s);
1417
 
1418
int spos = Name::FindPos(s);
1419
 
1420
   if (spos != 1)
1421
      {
1422
        fprintf(stderr, "Warning: variable %s shadows enum value\n", s);
1423
        return new IdentifierExpression(s);
1424
      }
1425
 
1426
   return new NumericExpression(value);
1427
}
1428
//-----------------------------------------------------------------------------
1429
TypeName * IdentifierExpression::FunReturnType()
1430
{
1431
   assert(varname);
1432
 
1433
TypeName * funtn = Name::FindType(varname);
1434
   if (funtn)   return funtn->GetFunReturnType();
1435
 
1436
   fprintf(stderr, "Function '%s' not declared\n", varname);
1437
   semantic_errors++;
1438
   return new TypeName(TS_INT);
1439
}
1440
//-----------------------------------------------------------------------------
1441
TypeName * BinaryExpression::MaxType(Expression * left, Expression * right)
1442
{
1443
TypeName * ltype = left ->GetType();   assert(ltype);
1444
TypeName * rtype = right->GetType();   assert(rtype);
1445
 
1446
   if (!ltype->IsNumericType())
1447
      {
1448
        if (  expr_type == ET_EQUAL         || expr_type == ET_NOT_EQUAL
1449
           || expr_type == ET_LESS_EQUAL    || expr_type == ET_LESS
1450
           || expr_type == ET_GREATER_EQUAL || expr_type == ET_GREATER)
1451
           {
1452
             if (ltype->IsPointer())   return ltype;
1453
           }
1454
 
1455
        fprintf(stderr, "Left argument of %s is not numeric\n",
1456
                        GetPretty(expr_type));
1457
        semantic_errors++;
1458
        return new TypeName(TS_INT);
1459
      }
1460
 
1461
   if (!rtype->IsNumericType())
1462
      {
1463
        if (  expr_type == ET_EQUAL         || expr_type == ET_NOT_EQUAL
1464
           || expr_type == ET_LESS_EQUAL    || expr_type == ET_LESS
1465
           || expr_type == ET_GREATER_EQUAL || expr_type == ET_GREATER)
1466
           {
1467
             if (rtype->IsPointer())   return rtype;
1468
           }
1469
 
1470
        fprintf(stderr, "Right argument of %s is not numeric\n",
1471
                        GetPretty(expr_type));
1472
        semantic_errors++;
1473
        return new TypeName(TS_INT);
1474
      }
1475
 
1476
Specifier spec = TS_INT;
1477
 
1478
   if (ltype->IsUnsigned())   spec = (Specifier)(TS_INT | TS_UNSIGNED);
1479
   if (rtype->IsUnsigned())   spec = (Specifier)(TS_INT | TS_UNSIGNED);
1480
   return new TypeName(spec);
1481
}
1482
//-----------------------------------------------------------------------------
1483
int NumericExpression::GetConstantNumericValue() const
1484
{
1485
   assert(int_value);
1486
   return int_value->GetValue();
1487
}
1488
//-----------------------------------------------------------------------------
1489
int Expression::GetConstantNumericValue() const
1490
{
1491
   fprintf(stderr, "Non-constant value where numeric constant expected\n");
1492
   semantic_errors++;
1493
   return 0;
1494
}
1495
//-----------------------------------------------------------------------------
1496
StringConstant * Expression::GetStringConstant() const
1497
{
1498
   fprintf(stderr, "Non-constant value where string constant expected\n");
1499
   semantic_errors++;
1500
   return 0;
1501
}
1502
//-----------------------------------------------------------------------------
1503
void Expression::EmitCall(FILE * out, Expression * args)
1504
{
1505
TypeName * tname;
1506
 
1507
   tname = GetType();
1508
   assert(tname);
1509
 
1510
ParameterDeclarationList * plist = tname->GetParameters();
1511
 
1512
int param_bytes_pushed = 0;
1513
   if (args)
1514
      {
1515
        if (!plist)
1516
           {
1517
             const char * funname = GetVarname();
1518
             if (funname == 0)   funname = "";
1519
             fprintf(stderr,
1520
                     "Arguments for function %s without parameters\n",
1521
                     funname);
1522
             semantic_errors++;
1523
             return;
1524
           }
1525
        param_bytes_pushed += args->EmitPush(out, plist);
1526
      }
1527
   else
1528
      {
1529
        if (plist)
1530
           {
1531
             const char * funname = GetVarname();
1532
             if (funname == 0)   funname = "";
1533
             fprintf(stderr,
1534
                     "No arguments for function %s with parameters\n",
1535
                     funname);
1536
             semantic_errors++;
1537
             return;
1538
           }
1539
      }
1540
 
1541
   // compute return value size
1542
const int ret_size = tname->GetFunReturnSize();
1543
   param_bytes_pushed += Backend::push_return(ret_size);
1544
 
1545
   if (GetType()->IsFunPtr())
1546
      {
1547
        Emit(out);
1548
        Backend::call_ptr();
1549
      }
1550
   else
1551
      {
1552
        assert(GetVarname());
1553
        Backend::call(GetVarname());
1554
      }
1555
 
1556
   Backend::pop(param_bytes_pushed);
1557
}
1558
//-----------------------------------------------------------------------------
1559
int ArgListExpression::EmitPush(FILE * out, ParameterDeclarationList * args)
1560
{
1561
   EmitStart(out);
1562
 
1563
   assert(left);
1564
   assert(right);
1565
 
1566
ParameterDeclarationList * a = args;
1567
   for (int l = left->GetParaLength(); a && l; l--)
1568
       {
1569
         if (!a->Head()->IsEllipsis())   a = a->Tail();
1570
       }
1571
 
1572
   if (a)
1573
      {
1574
        const int rpush = right->EmitPush(out, a);
1575
        const int lpush = left ->EmitPush(out, args);
1576
 
1577
        EmitEnd(out);
1578
        return rpush + lpush;
1579
      }
1580
 
1581
   semantic_errors++;
1582
   EmitEnd(out);
1583
   return 0;
1584
}
1585
//-----------------------------------------------------------------------------
1586
int Expression::EmitPush(FILE * out, ParameterDeclarationList * args)
1587
{
1588
   assert(args);
1589
 
1590
ParameterDeclaration * pd = args->Head();
1591
   assert(pd);
1592
 
1593
TypeName * tname = pd->GetTypeName();
1594
   assert(tname);
1595
 
1596
SUW suw;
1597
 
1598
   pd->Emit(out);   // just shows type
1599
   if (tname->IsPointer() && GetType()->IsArray())
1600
      {
1601
        EmitAddress(out);
1602
        suw = WO;
1603
      }
1604
   else
1605
      {
1606
        Emit(out);
1607
        suw = tname->GetSUW();
1608
      }
1609
 
1610
   Backend::push_rr(suw);
1611
 
1612
   if (suw == WO)   return 2;
1613
   return 1;
1614
}
1615
//-----------------------------------------------------------------------------
1616
int ArgListExpression::GetParaLength() const
1617
{
1618
   assert(left);
1619
   assert(right);
1620
 
1621
   return left->GetParaLength() + right->GetParaLength();
1622
}
1623
//-----------------------------------------------------------------------------
1624
AsmExpression::AsmExpression(StringConstant * string)
1625
   : Expression("asm Expression")
1626
{
1627
   asm_string = string->Kill();
1628
   assert(asm_string);
1629
}
1630
//-----------------------------------------------------------------------------
1631
void AsmExpression::Emit(FILE * out)
1632
{
1633
   Backend::asmbl(asm_string);
1634
}
1635
//-----------------------------------------------------------------------------
1636
TypeName * AsmExpression::SetType()
1637
{
1638
   return new TypeName(TS_INT);
1639
}
1640
//-----------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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