Mercurial > projects > dang
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 |