comparison ast/Exp.d @ 195:4e1a7265d620

Made a BuildTypes pass, to give all exp's a type.
author Anders Johnsen <skabet@gmail.com>
date Tue, 29 Jul 2008 15:50:24 +0200
parents 08f68d684047
children
comparison
equal deleted inserted replaced
194:08f68d684047 195:4e1a7265d620
64 Identifiers and member references can have a sensible value. 64 Identifiers and member references can have a sensible value.
65 **/ 65 **/
66 Symbol getSymbol() { return null; } 66 Symbol getSymbol() { return null; }
67 67
68 /// Get the type of the expression 68 /// Get the type of the expression
69 abstract DType type(); 69 DType type;
70 70
71 /// Indicates which type the expression is - to avoid a lot of casts 71 /// Indicates which type the expression is - to avoid a lot of casts
72 ExpType expType; 72 ExpType expType;
73 73
74 /// The environment of the expression 74 /// The environment of the expression
75 Scope env; 75 Scope env;
76
77 Symbol symbol;
78 76
79 int stmtIndex; 77 int stmtIndex;
80 78
81 /** 79 /**
82 The "main" location of the expression. 80 The "main" location of the expression.
102 super(ExpType.CallExp, exp.loc); 100 super(ExpType.CallExp, exp.loc);
103 this.exp = exp; 101 this.exp = exp;
104 this.args = args; 102 this.args = args;
105 } 103 }
106 104
107 override DType type()
108 {
109 DFunction f = exp.type.asCallable();
110 assert(f !is null, "Can only call functions");
111 return f.returnType;
112 }
113
114 DType callerType() 105 DType callerType()
115 { 106 {
116 DFunction f = new DFunction(new Identifier("function")); 107 DFunction f = new DFunction(new Identifier("function"));
117 f.returnType = type; 108 f.returnType = type;
118 foreach (a ; args) 109 foreach (a ; args)
163 override SourceRange sourceRange() 154 override SourceRange sourceRange()
164 { 155 {
165 return identifier.sourceRange + exp.sourceRange; 156 return identifier.sourceRange + exp.sourceRange;
166 } 157 }
167 158
168 override DType type() { return identifier.type(); }
169
170 Exp identifier; 159 Exp identifier;
171 Exp exp; 160 Exp exp;
172 } 161 }
173 162
174 class BinaryExp : Exp 163 class BinaryExp : Exp
211 this.op = op; 200 this.op = op;
212 this.left = left; 201 this.left = left;
213 this.right = right; 202 this.right = right;
214 } 203 }
215 204
216 override DType type()
217 {
218 if (myType)
219 return myType;
220
221 if (op == Operator.Eq ||
222 op == Operator.Ne ||
223 op == Operator.Lt ||
224 op == Operator.Le ||
225 op == Operator.Gt ||
226 op == Operator.Ge)
227 {
228 myType = DType.Bool;
229 return myType;
230 }
231
232 DType l = left.type;
233 DType r = right.type;
234 if (l is r)
235 myType = l;
236 else if (l.hasImplicitConversionTo(r))
237 myType = r;
238 else if (r.hasImplicitConversionTo(l))
239 myType = l;
240 else
241 return null;
242 return myType;
243 }
244
245 override SLoc startLoc() { return left.startLoc(); } 205 override SLoc startLoc() { return left.startLoc(); }
246 206
247 override SourceRange sourceRange() 207 override SourceRange sourceRange()
248 { 208 {
249 return left.sourceRange + right.sourceRange; 209 return left.sourceRange + right.sourceRange;
263 return this; 223 return this;
264 } 224 }
265 225
266 Operator op; 226 Operator op;
267 Exp left, right; 227 Exp left, right;
268 private DType myType;
269 } 228 }
270 229
271 class NegateExp : Exp 230 class NegateExp : Exp
272 { 231 {
273 this(SLoc op, Exp exp) 232 this(SLoc op, Exp exp)
280 { 239 {
281 exp = exp.simplify(); 240 exp = exp.simplify();
282 return this; 241 return this;
283 } 242 }
284 243
285 override DType type() { return exp.type(); }
286
287 override SourceRange sourceRange() 244 override SourceRange sourceRange()
288 { 245 {
289 return SourceRange(loc) + exp.sourceRange; 246 return SourceRange(loc) + exp.sourceRange;
290 } 247 }
291 248
304 { 261 {
305 exp = exp.simplify(); 262 exp = exp.simplify();
306 return this; 263 return this;
307 } 264 }
308 265
309 override DType type()
310 {
311 if (_type)
312 return _type;
313 return exp.type().asPointer().pointerOf;
314 }
315
316 override SourceRange sourceRange() 266 override SourceRange sourceRange()
317 { 267 {
318 return SourceRange(loc) + exp.sourceRange; 268 return SourceRange(loc) + exp.sourceRange;
319 } 269 }
320 270
321 DType _type;
322 public Exp exp; 271 public Exp exp;
323 } 272 }
324 273
325 class AddressOfExp : Exp 274 class AddressOfExp : Exp
326 { 275 {
332 281
333 override AddressOfExp simplify() 282 override AddressOfExp simplify()
334 { 283 {
335 exp = exp.simplify(); 284 exp = exp.simplify();
336 return this; 285 return this;
337 }
338
339 override DType type()
340 {
341 return exp.type().getPointerTo;
342 } 286 }
343 287
344 override SourceRange sourceRange() 288 override SourceRange sourceRange()
345 { 289 {
346 return SourceRange(loc) + exp.sourceRange; 290 return SourceRange(loc) + exp.sourceRange;
364 } 308 }
365 309
366 override IntegerLit simplify() 310 override IntegerLit simplify()
367 { 311 {
368 return this; 312 return this;
369 }
370
371 override DType type()
372 {
373 switch(number.type)
374 {
375 case NumberType.Int:
376 return DType.Int;
377 case NumberType.Long:
378 return DType.Long;
379 case NumberType.ULong:
380 return DType.ULong;
381 case NumberType.Double:
382 return DType.Double;
383 case NumberType.Real:
384 return DType.Real;
385 }
386 } 313 }
387 314
388 override SourceRange sourceRange() 315 override SourceRange sourceRange()
389 { 316 {
390 return range; 317 return range;
427 { 354 {
428 target = target.simplify(); 355 target = target.simplify();
429 return this; 356 return this;
430 } 357 }
431 358
432 override DType type()
433 {
434 if (myType)
435 return myType;
436
437 if ( target.type.isStruct )
438 {
439 Symbol st = target.getSymbol;
440 if (auto t = st.findMembers(child.name))
441 myType = t[0].type;
442 // else assert(0, "Referencing non-existant member");
443 }
444 else if ( target.type.isClass )
445 {
446 Symbol cl = target.getSymbol;
447 if (auto t = cl.findMembers(child.name))
448 myType = t[0].type;
449 // else assert(0, "Referencing non-existant member");
450 }
451 else
452 assert(0, "Only structs and classes have members");
453 // no error reporting here
454
455 return myType;
456 }
457
458 override SLoc startLoc() { return target.startLoc(); } 359 override SLoc startLoc() { return target.startLoc(); }
459 360
460 override SourceRange sourceRange() 361 override SourceRange sourceRange()
461 { 362 {
462 return target.sourceRange + child.sourceRange; 363 return target.sourceRange + child.sourceRange;
463 } 364 }
464 365
465 Identifier child; 366 Identifier child;
466 Exp target; 367 Exp target;
467 private DType myType;
468 } 368 }
469 369
470 class IndexExp : Exp 370 class IndexExp : Exp
471 { 371 {
472 this(Exp target, SLoc left_bracket, Exp index, SLoc right_bracket) 372 this(Exp target, SLoc left_bracket, Exp index, SLoc right_bracket)
476 this.left_bracket = left_bracket; 376 this.left_bracket = left_bracket;
477 this.index = index; 377 this.index = index;
478 this.right_bracket = right_bracket; 378 this.right_bracket = right_bracket;
479 } 379 }
480 380
481 override DType type()
482 {
483 DType type = target.type();
484 if (type.isStaticArray())
485 return type.asStaticArray().arrayOf;
486 else if (type.isPointer())
487 return type.asPointer().pointerOf;
488 else assert(0, "Can only index pointers and arrays");
489 }
490
491 override SourceRange sourceRange() 381 override SourceRange sourceRange()
492 { 382 {
493 return target.sourceRange + SourceRange(right_bracket); 383 return target.sourceRange + SourceRange(right_bracket);
494 } 384 }
495 385
512 super(ExpType.CastExp, loc); 402 super(ExpType.CastExp, loc);
513 this.castType = castType; 403 this.castType = castType;
514 this.exp = exp; 404 this.exp = exp;
515 } 405 }
516 406
517 override DType type()
518 {
519 return env.findType(this.castType.get);
520 }
521
522 override CastExp simplify() 407 override CastExp simplify()
523 { 408 {
524 castType = castType.simplify(); 409 castType = castType.simplify();
525 exp = exp.simplify(); 410 exp = exp.simplify();
526 return this; 411 return this;
539 { 424 {
540 this(SLoc loc, char[] str) 425 this(SLoc loc, char[] str)
541 { 426 {
542 super(ExpType.StringExp, loc); 427 super(ExpType.StringExp, loc);
543 this.str = str; 428 this.str = str;
544 }
545
546 override DType type()
547 {
548 switch (data.type)
549 {
550 case StringType.Char:
551 return DType.Char.getAsStaticArray(data.data.length);
552 case StringType.WChar:
553 return DType.WChar.getAsStaticArray(data.data.length/2);
554 case StringType.DChar:
555 return DType.DChar.getAsStaticArray(data.data.length/4);
556 }
557 } 429 }
558 430
559 char[] str; 431 char[] str;
560 String data; 432 String data;
561 } 433 }
568 this.newType = newType; 440 this.newType = newType;
569 this.a_args = a_args; 441 this.a_args = a_args;
570 this.c_args = c_args; 442 this.c_args = c_args;
571 } 443 }
572 444
573 override DType type()
574 {
575 return env.findType(this.newType.get);
576 }
577
578 Exp[] a_args, c_args; 445 Exp[] a_args, c_args;
579 Identifier newType; 446 Identifier newType;
580 Symbol callSym; 447 Symbol callSym;
581 } 448 }
582 449
584 { 451 {
585 this(SLoc loc) 452 this(SLoc loc)
586 { 453 {
587 super(ExpType.NullExp, loc); 454 super(ExpType.NullExp, loc);
588 } 455 }
589
590 override DType type()
591 {
592 return new DPointer(DType.Int);
593 }
594 } 456 }
595 457
596 class Identifier : Exp 458 class Identifier : Exp
597 { 459 {
598 this(SLoc loc, char[] name) 460 this(SLoc loc, char[] name)
616 return Integer.toString(name.length) ~ name; 478 return Integer.toString(name.length) ~ name;
617 } 479 }
618 480
619 override Symbol getSymbol() 481 override Symbol getSymbol()
620 { 482 {
483 if (!env)
484 return null;
621 if (auto decl = env.find(this.get)) 485 if (auto decl = env.find(this.get))
622 if(decl.length) 486 if(decl.length)
623 return decl[$-1].sym; 487 return decl[$-1].sym;
624 return null; 488 return null;
625 } 489 }
626 490
627 override DType type()
628 {
629 if (myType !is null)
630 return myType;
631 else if (auto sym = getSymbol)
632 myType = sym.type;
633 else
634 myType = DType.Int;
635
636 return myType;
637 }
638
639 this(char[] name) 491 this(char[] name)
640 { 492 {
641 super(ExpType.Identifier, SLoc.Invalid); 493 super(ExpType.Identifier, SLoc.Invalid);
642 this.name = name; 494 this.name = name;
643 } 495 }
669 override Identifier simplify() 521 override Identifier simplify()
670 { 522 {
671 return this; 523 return this;
672 } 524 }
673 525
674 void setType(DType myType)
675 {
676 this.myType = myType;
677 }
678
679 override SourceRange sourceRange() 526 override SourceRange sourceRange()
680 { 527 {
681 return SourceRange(loc, loc + name.length); 528 return SourceRange(loc, loc + name.length);
682 } 529 }
683 530
684 char[] name; 531 char[] name;
685 private DType myType;
686 } 532 }
687 533
688 class IdentifierTypeExp : Identifier 534 class IdentifierTypeExp : Identifier
689 { 535 {
690 this(SLoc loc, char[] name) 536 this(SLoc loc, char[] name)
704 this(IdentifierTypeExp pointerOf) 550 this(IdentifierTypeExp pointerOf)
705 { 551 {
706 super(ExpType.PointerTypeExp, pointerOf.loc); 552 super(ExpType.PointerTypeExp, pointerOf.loc);
707 this.pointerOf = pointerOf; 553 this.pointerOf = pointerOf;
708 this.name = pointerOf.name; 554 this.name = pointerOf.name;
709 }
710
711 override DType type()
712 {
713 return pointerOf.type.getPointerTo();
714 } 555 }
715 556
716 Identifier pointerOf; 557 Identifier pointerOf;
717 } 558 }
718 559
724 this.arrayOf = arrayOf; 565 this.arrayOf = arrayOf;
725 this.size = Integer.parse(size.get); 566 this.size = Integer.parse(size.get);
726 this.name = arrayOf.name; 567 this.name = arrayOf.name;
727 } 568 }
728 569
729 override DType type()
730 {
731 return arrayOf.type.getAsStaticArray(size);
732 }
733
734 Identifier arrayOf; 570 Identifier arrayOf;
735 int size; 571 int size;
736
737 private DType myType;
738 } 572 }
739 573
740 class ArrayTypeExp : IdentifierTypeExp 574 class ArrayTypeExp : IdentifierTypeExp
741 { 575 {
742 this(IdentifierTypeExp arrayOf) 576 this(IdentifierTypeExp arrayOf)
744 super(ExpType.ArrayTypeExp, arrayOf.loc); 578 super(ExpType.ArrayTypeExp, arrayOf.loc);
745 this.arrayOf = arrayOf; 579 this.arrayOf = arrayOf;
746 this.name = arrayOf.name; 580 this.name = arrayOf.name;
747 } 581 }
748 582
749 override DType type()
750 {
751 return arrayOf.type.getAsArray();
752 }
753
754 Identifier arrayOf; 583 Identifier arrayOf;
755
756 private DType myType;
757 } 584 }
758 585
759 class FunctionTypeExp : IdentifierTypeExp 586 class FunctionTypeExp : IdentifierTypeExp
760 { 587 {
761 this(IdentifierTypeExp returnType, VarDecl[] decls) 588 this(IdentifierTypeExp returnType, VarDecl[] decls)
763 super(ExpType.FunctionTypeExp, returnType.loc); 590 super(ExpType.FunctionTypeExp, returnType.loc);
764 this.returnType = returnType; 591 this.returnType = returnType;
765 this.decls = decls; 592 this.decls = decls;
766 } 593 }
767 594
768 override DType type()
769 {
770 if (myType)
771 return myType;
772 auto t = new DFunction(returnType);
773 t.returnType = returnType.type;
774 foreach (decl ; decls)
775 t.params ~= decl.identifier.type;
776
777 myType = t.getPointerTo;
778 return myType;
779 }
780
781 VarDecl[] decls; 595 VarDecl[] decls;
782 IdentifierTypeExp returnType; 596 IdentifierTypeExp returnType;
783 private DType myType;
784 } 597 }
785 598
786 class ArrayLiteralExp : Exp 599 class ArrayLiteralExp : Exp
787 { 600 {
788 this(Exp[] exps, SLoc begin, SLoc end) 601 this(Exp[] exps, SLoc begin, SLoc end)
791 this.exps = exps; 604 this.exps = exps;
792 this.begin = begin; 605 this.begin = begin;
793 this.end = end; 606 this.end = end;
794 } 607 }
795 608
796 override DType type()
797 {
798 return exps[0].type.getAsStaticArray(exps.length);
799 }
800
801 Exp[] exps; 609 Exp[] exps;
802 SLoc begin, end; 610 SLoc begin, end;
803 } 611 }
804 612