Mercurial > projects > dil
comparison trunk/src/dil/ast/Declarations.d @ 585:05c375fb2d5c
Moved dil.Declarations to dil.ast.Declarations.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Sat, 05 Jan 2008 23:01:42 +0100 |
parents | trunk/src/dil/Declarations.d@556bfb18dff8 |
children | e25345656d10 |
comparison
equal
deleted
inserted
replaced
584:556bfb18dff8 | 585:05c375fb2d5c |
---|---|
1 /++ | |
2 Author: Aziz Köksal | |
3 License: GPL3 | |
4 +/ | |
5 module dil.ast.Declarations; | |
6 | |
7 import dil.ast.Node; | |
8 import dil.Expressions; | |
9 import dil.Types; | |
10 import dil.Statements; | |
11 import dil.Token; | |
12 import dil.Enums; | |
13 import dil.Scope; | |
14 import dil.IdTable; | |
15 import dil.semantic.Analysis; | |
16 import dil.Symbols; | |
17 import dil.semantic.Types; | |
18 import dil.Messages; | |
19 import common; | |
20 | |
21 abstract class Declaration : Node | |
22 { | |
23 bool hasBody; | |
24 this() | |
25 { | |
26 super(NodeCategory.Declaration); | |
27 } | |
28 | |
29 // Members relevant to semantic phase. | |
30 StorageClass stc; /// The storage class of this declaration. | |
31 Protection prot; /// The protection attribute of this declaration. | |
32 | |
33 void semantic(Scope sc) | |
34 { | |
35 foreach (node; this.children) | |
36 { | |
37 assert(node !is null); | |
38 if (node.category == NodeCategory.Declaration) | |
39 (cast(Declaration)cast(void*)node).semantic(sc); | |
40 } | |
41 } | |
42 | |
43 final bool isStatic() | |
44 { | |
45 return !!(stc & StorageClass.Static); | |
46 } | |
47 | |
48 final bool isPublic() | |
49 { | |
50 return !!(prot & Protection.Public); | |
51 } | |
52 | |
53 final void setStorageClass(StorageClass stc) | |
54 { | |
55 this.stc = stc; | |
56 } | |
57 | |
58 final void setProtection(Protection prot) | |
59 { | |
60 this.prot = prot; | |
61 } | |
62 | |
63 } | |
64 | |
65 class Declarations : Declaration | |
66 { | |
67 this() | |
68 { | |
69 hasBody = true; | |
70 mixin(set_kind); | |
71 } | |
72 | |
73 void opCatAssign(Declaration d) | |
74 { | |
75 addChild(d); | |
76 } | |
77 | |
78 void opCatAssign(Declarations ds) | |
79 { | |
80 addChildren(ds.children); | |
81 } | |
82 | |
83 override void semantic(Scope scop) | |
84 { | |
85 foreach (node; this.children) | |
86 { | |
87 assert(node.category == NodeCategory.Declaration); | |
88 (cast(Declaration)cast(void*)node).semantic(scop); | |
89 } | |
90 } | |
91 } | |
92 | |
93 /// Single semicolon. | |
94 class EmptyDeclaration : Declaration | |
95 { | |
96 this() | |
97 { | |
98 mixin(set_kind); | |
99 } | |
100 | |
101 override void semantic(Scope) | |
102 {} | |
103 } | |
104 | |
105 /++ | |
106 Illegal declarations encompass all tokens that don't | |
107 start a DeclarationDefinition. | |
108 See_Also: dil.Token.isDeclDefStartToken() | |
109 +/ | |
110 class IllegalDeclaration : Declaration | |
111 { | |
112 this() | |
113 { | |
114 mixin(set_kind); | |
115 } | |
116 | |
117 override void semantic(Scope) | |
118 {} | |
119 } | |
120 | |
121 /// FQN = fully qualified name | |
122 alias Identifier*[] ModuleFQN; // Identifier(.Identifier)* | |
123 | |
124 class ModuleDeclaration : Declaration | |
125 { | |
126 Identifier* moduleName; | |
127 Identifier*[] packages; | |
128 this(ModuleFQN moduleFQN) | |
129 { | |
130 mixin(set_kind); | |
131 assert(moduleFQN.length != 0); | |
132 this.moduleName = moduleFQN[$-1]; | |
133 this.packages = moduleFQN[0..$-1]; | |
134 } | |
135 | |
136 char[] getFQN() | |
137 { | |
138 auto pname = getPackageName('.'); | |
139 if (pname.length) | |
140 return pname ~ "." ~ getName(); | |
141 else | |
142 return getName(); | |
143 } | |
144 | |
145 char[] getName() | |
146 { | |
147 if (moduleName) | |
148 return moduleName.str; | |
149 return null; | |
150 } | |
151 | |
152 char[] getPackageName(char separator) | |
153 { | |
154 char[] pname; | |
155 foreach (pckg; packages) | |
156 if (pckg) | |
157 pname ~= pckg.str ~ separator; | |
158 if (pname.length) | |
159 pname = pname[0..$-1]; // Remove last separator | |
160 return pname; | |
161 } | |
162 } | |
163 | |
164 class ImportDeclaration : Declaration | |
165 { | |
166 private alias Identifier*[] Ids; | |
167 ModuleFQN[] moduleFQNs; | |
168 Ids moduleAliases; | |
169 Ids bindNames; | |
170 Ids bindAliases; | |
171 | |
172 this(ModuleFQN[] moduleFQNs, Ids moduleAliases, Ids bindNames, Ids bindAliases, bool isStatic) | |
173 { | |
174 mixin(set_kind); | |
175 this.moduleFQNs = moduleFQNs; | |
176 this.moduleAliases = moduleAliases; | |
177 this.bindNames = bindNames; | |
178 this.bindAliases = bindAliases; | |
179 if (isStatic) | |
180 this.stc |= StorageClass.Static; | |
181 } | |
182 | |
183 char[][] getModuleFQNs(char separator) | |
184 { | |
185 char[][] FQNs; | |
186 foreach (moduleFQN; moduleFQNs) | |
187 { | |
188 char[] FQN; | |
189 foreach (ident; moduleFQN) | |
190 if (ident) | |
191 FQN ~= ident.str ~ separator; | |
192 FQNs ~= FQN[0..$-1]; // Remove last separator | |
193 } | |
194 return FQNs; | |
195 } | |
196 } | |
197 | |
198 class AliasDeclaration : Declaration | |
199 { | |
200 Declaration decl; | |
201 this(Declaration decl) | |
202 { | |
203 mixin(set_kind); | |
204 addChild(decl); | |
205 this.decl = decl; | |
206 } | |
207 } | |
208 | |
209 class TypedefDeclaration : Declaration | |
210 { | |
211 Declaration decl; | |
212 this(Declaration decl) | |
213 { | |
214 mixin(set_kind); | |
215 addChild(decl); | |
216 this.decl = decl; | |
217 } | |
218 } | |
219 | |
220 class EnumDeclaration : Declaration | |
221 { | |
222 Identifier* name; | |
223 TypeNode baseType; | |
224 EnumMember[] members; | |
225 this(Identifier* name, TypeNode baseType, EnumMember[] members, bool hasBody) | |
226 { | |
227 super.hasBody = hasBody; | |
228 mixin(set_kind); | |
229 addOptChild(baseType); | |
230 addOptChildren(members); | |
231 | |
232 this.name = name; | |
233 this.baseType = baseType; | |
234 this.members = members; | |
235 } | |
236 } | |
237 | |
238 class EnumMember : Node | |
239 { | |
240 Identifier* name; | |
241 Expression value; | |
242 this(Identifier* name, Expression value) | |
243 { | |
244 super(NodeCategory.Other); | |
245 mixin(set_kind); | |
246 addOptChild(value); | |
247 | |
248 this.name = name; | |
249 this.value = value; | |
250 } | |
251 } | |
252 | |
253 abstract class AggregateDeclaration : Declaration | |
254 { | |
255 Identifier* name; | |
256 TemplateParameters tparams; | |
257 Declarations decls; | |
258 this(Identifier* name, TemplateParameters tparams, Declarations decls) | |
259 { | |
260 super.hasBody = decls !is null; | |
261 this.name = name; | |
262 this.tparams = tparams; | |
263 this.decls = decls; | |
264 } | |
265 } | |
266 | |
267 class ClassDeclaration : AggregateDeclaration | |
268 { | |
269 BaseClass[] bases; | |
270 this(Identifier* name, TemplateParameters tparams, BaseClass[] bases, Declarations decls) | |
271 { | |
272 super(name, tparams, decls); | |
273 mixin(set_kind); | |
274 addOptChild(tparams); | |
275 addOptChildren(bases); | |
276 addOptChild(decls); | |
277 | |
278 this.bases = bases; | |
279 } | |
280 | |
281 Class class_; /// The class symbol for this declaration. | |
282 | |
283 override void semantic(Scope scop) | |
284 { | |
285 if (class_) | |
286 return; | |
287 class_ = new Class(name, this); | |
288 // Create a new scope. | |
289 scop = scop.push(class_); | |
290 // Continue semantic analysis. | |
291 decls && decls.semantic(scop); | |
292 scop.pop(); | |
293 } | |
294 } | |
295 | |
296 class InterfaceDeclaration : AggregateDeclaration | |
297 { | |
298 BaseClass[] bases; | |
299 this(Identifier* name, TemplateParameters tparams, BaseClass[] bases, Declarations decls) | |
300 { | |
301 super(name, tparams, decls); | |
302 mixin(set_kind); | |
303 addOptChild(tparams); | |
304 addOptChildren(bases); | |
305 addOptChild(decls); | |
306 | |
307 this.bases = bases; | |
308 } | |
309 | |
310 alias dil.Symbols.Interface InterfaceSymbol; | |
311 | |
312 InterfaceSymbol interface_; /// The interface symbol for this declaration. | |
313 | |
314 override void semantic(Scope scop) | |
315 { | |
316 if (interface_) | |
317 return; | |
318 interface_ = new InterfaceSymbol(name, this); | |
319 // Create a new scope. | |
320 scop = scop.push(interface_); | |
321 // Continue semantic analysis. | |
322 decls && decls.semantic(scop); | |
323 scop.pop(); | |
324 } | |
325 } | |
326 | |
327 class StructDeclaration : AggregateDeclaration | |
328 { | |
329 uint alignSize; | |
330 this(Identifier* name, TemplateParameters tparams, Declarations decls) | |
331 { | |
332 super(name, tparams, decls); | |
333 mixin(set_kind); | |
334 addOptChild(tparams); | |
335 addOptChild(decls); | |
336 } | |
337 | |
338 void setAlignSize(uint alignSize) | |
339 { | |
340 this.alignSize = alignSize; | |
341 } | |
342 | |
343 Struct struct_; /// The struct symbol for this declaration. | |
344 | |
345 override void semantic(Scope scop) | |
346 { | |
347 if (struct_) | |
348 return; | |
349 struct_ = new Struct(name, this); | |
350 // Create a new scope. | |
351 scop = scop.push(struct_); | |
352 // Continue semantic analysis. | |
353 decls && decls.semantic(scop); | |
354 scop.pop(); | |
355 } | |
356 } | |
357 | |
358 class UnionDeclaration : AggregateDeclaration | |
359 { | |
360 this(Identifier* name, TemplateParameters tparams, Declarations decls) | |
361 { | |
362 super(name, tparams, decls); | |
363 mixin(set_kind); | |
364 addOptChild(tparams); | |
365 addOptChild(decls); | |
366 } | |
367 | |
368 Union union_; /// The union symbol for this declaration. | |
369 | |
370 override void semantic(Scope scop) | |
371 { | |
372 if (union_) | |
373 return; | |
374 union_ = new Union(name, this); | |
375 // Create a new scope. | |
376 scop = scop.push(union_); | |
377 // Continue semantic analysis. | |
378 decls && decls.semantic(scop); | |
379 scop.pop(); | |
380 } | |
381 } | |
382 | |
383 class ConstructorDeclaration : Declaration | |
384 { | |
385 Parameters parameters; | |
386 FunctionBody funcBody; | |
387 this(Parameters parameters, FunctionBody funcBody) | |
388 { | |
389 super.hasBody = true; | |
390 mixin(set_kind); | |
391 addChild(parameters); | |
392 addChild(funcBody); | |
393 | |
394 this.parameters = parameters; | |
395 this.funcBody = funcBody; | |
396 } | |
397 } | |
398 | |
399 class StaticConstructorDeclaration : Declaration | |
400 { | |
401 FunctionBody funcBody; | |
402 this(FunctionBody funcBody) | |
403 { | |
404 super.hasBody = true; | |
405 mixin(set_kind); | |
406 addChild(funcBody); | |
407 | |
408 this.funcBody = funcBody; | |
409 } | |
410 } | |
411 | |
412 class DestructorDeclaration : Declaration | |
413 { | |
414 FunctionBody funcBody; | |
415 this(FunctionBody funcBody) | |
416 { | |
417 super.hasBody = true; | |
418 mixin(set_kind); | |
419 addChild(funcBody); | |
420 | |
421 this.funcBody = funcBody; | |
422 } | |
423 } | |
424 | |
425 class StaticDestructorDeclaration : Declaration | |
426 { | |
427 FunctionBody funcBody; | |
428 this(FunctionBody funcBody) | |
429 { | |
430 super.hasBody = true; | |
431 mixin(set_kind); | |
432 addChild(funcBody); | |
433 | |
434 this.funcBody = funcBody; | |
435 } | |
436 } | |
437 | |
438 class FunctionDeclaration : Declaration | |
439 { | |
440 TypeNode returnType; | |
441 Identifier* funcName; | |
442 TemplateParameters tparams; | |
443 Parameters params; | |
444 FunctionBody funcBody; | |
445 LinkageType linkageType; | |
446 this(TypeNode returnType, Identifier* funcName, TemplateParameters tparams, | |
447 Parameters params, FunctionBody funcBody) | |
448 { | |
449 super.hasBody = funcBody.funcBody !is null; | |
450 mixin(set_kind); | |
451 addChild(returnType); | |
452 addOptChild(tparams); | |
453 addChild(params); | |
454 addChild(funcBody); | |
455 | |
456 this.returnType = returnType; | |
457 this.funcName = funcName; | |
458 this.tparams = tparams; | |
459 this.params = params; | |
460 this.funcBody = funcBody; | |
461 } | |
462 | |
463 void setLinkageType(LinkageType linkageType) | |
464 { | |
465 this.linkageType = linkageType; | |
466 } | |
467 } | |
468 | |
469 class VariableDeclaration : Declaration | |
470 { | |
471 TypeNode typeNode; | |
472 Identifier*[] idents; | |
473 Expression[] values; | |
474 LinkageType linkageType; | |
475 this(TypeNode typeNode, Identifier*[] idents, Expression[] values) | |
476 { | |
477 // No empty arrays allowed. Both arrays must be of same size. | |
478 assert(idents.length != 0 && idents.length == values.length); | |
479 // If no type (in case of AutoDeclaration), first value mustn't be null. | |
480 assert(typeNode ? 1 : values[0] !is null); | |
481 mixin(set_kind); | |
482 addOptChild(typeNode); | |
483 foreach(value; values) | |
484 addOptChild(value); | |
485 | |
486 this.typeNode = typeNode; | |
487 this.idents = idents; | |
488 this.values = values; | |
489 } | |
490 | |
491 void setLinkageType(LinkageType linkageType) | |
492 { | |
493 this.linkageType = linkageType; | |
494 } | |
495 | |
496 Variable[] variables; | |
497 | |
498 override void semantic(Scope scop) | |
499 { | |
500 Type type; | |
501 | |
502 if (typeNode) | |
503 // Get type from typeNode. | |
504 type = typeNode.semantic(scop); | |
505 else | |
506 { // Infer type from first initializer. | |
507 auto firstValue = values[0]; | |
508 firstValue = firstValue.semantic(scop); | |
509 type = firstValue.type; | |
510 } | |
511 assert(type !is null); | |
512 | |
513 // Check for interface. | |
514 if (scop.isInterface) | |
515 return scop.error(begin, MSG.InterfaceCantHaveVariables); | |
516 | |
517 // Iterate over variable identifiers in this declaration. | |
518 foreach (i, ident; idents) | |
519 { | |
520 // Perform semantic analysis on value. | |
521 if (values[i]) | |
522 values[i] = values[i].semantic(scop); | |
523 // Create a new variable symbol. | |
524 auto variable = new Variable(stc, linkageType, type, ident, this); | |
525 variables ~= variable; | |
526 // Add to scope. | |
527 scop.insert(variable); | |
528 } | |
529 } | |
530 } | |
531 | |
532 class InvariantDeclaration : Declaration | |
533 { | |
534 FunctionBody funcBody; | |
535 this(FunctionBody funcBody) | |
536 { | |
537 super.hasBody = true; | |
538 mixin(set_kind); | |
539 addChild(funcBody); | |
540 | |
541 this.funcBody = funcBody; | |
542 } | |
543 } | |
544 | |
545 class UnittestDeclaration : Declaration | |
546 { | |
547 FunctionBody funcBody; | |
548 this(FunctionBody funcBody) | |
549 { | |
550 super.hasBody = true; | |
551 mixin(set_kind); | |
552 addChild(funcBody); | |
553 | |
554 this.funcBody = funcBody; | |
555 } | |
556 } | |
557 | |
558 abstract class ConditionalCompilationDeclaration : Declaration | |
559 { | |
560 Token* spec; | |
561 Token* cond; | |
562 Declaration decls, elseDecls; | |
563 | |
564 this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls) | |
565 { | |
566 super.hasBody = decls !is null; | |
567 addOptChild(decls); | |
568 addOptChild(elseDecls); | |
569 | |
570 this.spec = spec; | |
571 this.cond = cond; | |
572 this.decls = decls; | |
573 this.elseDecls = elseDecls; | |
574 } | |
575 } | |
576 | |
577 class DebugDeclaration : ConditionalCompilationDeclaration | |
578 { | |
579 this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls) | |
580 { | |
581 super(spec, cond, decls, elseDecls); | |
582 mixin(set_kind); | |
583 } | |
584 } | |
585 | |
586 class VersionDeclaration : ConditionalCompilationDeclaration | |
587 { | |
588 this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls) | |
589 { | |
590 super(spec, cond, decls, elseDecls); | |
591 mixin(set_kind); | |
592 } | |
593 } | |
594 | |
595 class StaticIfDeclaration : Declaration | |
596 { | |
597 Expression condition; | |
598 Declaration ifDecls, elseDecls; | |
599 this(Expression condition, Declaration ifDecls, Declaration elseDecls) | |
600 { | |
601 super.hasBody = true; | |
602 mixin(set_kind); | |
603 addChild(condition); | |
604 addOptChild(ifDecls); | |
605 addOptChild(elseDecls); | |
606 | |
607 this.condition = condition; | |
608 this.ifDecls = ifDecls; | |
609 this.elseDecls = elseDecls; | |
610 } | |
611 } | |
612 | |
613 class StaticAssertDeclaration : Declaration | |
614 { | |
615 Expression condition, message; | |
616 this(Expression condition, Expression message) | |
617 { | |
618 super.hasBody = true; | |
619 mixin(set_kind); | |
620 addChild(condition); | |
621 addOptChild(message); | |
622 | |
623 this.condition = condition; | |
624 this.message = message; | |
625 } | |
626 } | |
627 | |
628 class TemplateDeclaration : Declaration | |
629 { | |
630 Identifier* name; | |
631 TemplateParameters tparams; | |
632 Declarations decls; | |
633 this(Identifier* name, TemplateParameters tparams, Declarations decls) | |
634 { | |
635 super.hasBody = true; | |
636 mixin(set_kind); | |
637 addOptChild(tparams); | |
638 addChild(decls); | |
639 | |
640 this.name = name; | |
641 this.tparams = tparams; | |
642 this.decls = decls; | |
643 } | |
644 } | |
645 | |
646 class NewDeclaration : Declaration | |
647 { | |
648 Parameters parameters; | |
649 FunctionBody funcBody; | |
650 this(Parameters parameters, FunctionBody funcBody) | |
651 { | |
652 super.hasBody = true; | |
653 mixin(set_kind); | |
654 addChild(parameters); | |
655 addChild(funcBody); | |
656 | |
657 this.parameters = parameters; | |
658 this.funcBody = funcBody; | |
659 } | |
660 } | |
661 | |
662 class DeleteDeclaration : Declaration | |
663 { | |
664 Parameters parameters; | |
665 FunctionBody funcBody; | |
666 this(Parameters parameters, FunctionBody funcBody) | |
667 { | |
668 super.hasBody = true; | |
669 mixin(set_kind); | |
670 addChild(parameters); | |
671 addChild(funcBody); | |
672 | |
673 this.parameters = parameters; | |
674 this.funcBody = funcBody; | |
675 } | |
676 } | |
677 | |
678 class AttributeDeclaration : Declaration | |
679 { | |
680 TOK attribute; | |
681 Declaration decls; | |
682 this(TOK attribute, Declaration decls) | |
683 { | |
684 super.hasBody = true; | |
685 mixin(set_kind); | |
686 addChild(decls); | |
687 | |
688 this.attribute = attribute; | |
689 this.decls = decls; | |
690 } | |
691 } | |
692 | |
693 class ProtectionDeclaration : AttributeDeclaration | |
694 { | |
695 Protection prot; | |
696 this(Protection prot, Declaration decls) | |
697 { | |
698 super(cast(TOK)0, decls); | |
699 mixin(set_kind); | |
700 this.prot = prot; | |
701 } | |
702 } | |
703 | |
704 class StorageClassDeclaration : AttributeDeclaration | |
705 { | |
706 StorageClass storageClass; | |
707 this(StorageClass storageClass, TOK tok, Declaration decl) | |
708 { | |
709 super(tok, decl); | |
710 mixin(set_kind); | |
711 | |
712 this.storageClass = storageClass; | |
713 } | |
714 } | |
715 | |
716 class LinkageDeclaration : AttributeDeclaration | |
717 { | |
718 LinkageType linkageType; | |
719 this(LinkageType linkageType, Declaration decls) | |
720 { | |
721 super(TOK.Extern, decls); | |
722 mixin(set_kind); | |
723 | |
724 this.linkageType = linkageType; | |
725 } | |
726 } | |
727 | |
728 class AlignDeclaration : AttributeDeclaration | |
729 { | |
730 int size; | |
731 this(int size, Declaration decls) | |
732 { | |
733 super(TOK.Align, decls); | |
734 mixin(set_kind); | |
735 this.size = size; | |
736 } | |
737 } | |
738 | |
739 class PragmaDeclaration : AttributeDeclaration | |
740 { | |
741 Identifier* ident; | |
742 Expression[] args; | |
743 this(Identifier* ident, Expression[] args, Declaration decls) | |
744 { | |
745 addOptChildren(args); // Add args before calling super(). | |
746 super(TOK.Pragma, decls); | |
747 mixin(set_kind); | |
748 | |
749 this.ident = ident; | |
750 this.args = args; | |
751 } | |
752 | |
753 override void semantic(Scope scop) | |
754 { | |
755 pragmaSemantic(scop, begin, ident, args); | |
756 decls.semantic(scop); | |
757 } | |
758 } | |
759 | |
760 class MixinDeclaration : Declaration | |
761 { | |
762 Expression[] templateIdents; | |
763 Identifier* mixinIdent; | |
764 Expression argument; // mixin ( AssignExpression ) | |
765 | |
766 this(Expression[] templateIdents, Identifier* mixinIdent) | |
767 { | |
768 mixin(set_kind); | |
769 addChildren(templateIdents); | |
770 | |
771 this.templateIdents = templateIdents; | |
772 this.mixinIdent = mixinIdent; | |
773 } | |
774 | |
775 this(Expression argument) | |
776 { | |
777 mixin(set_kind); | |
778 addChild(argument); | |
779 | |
780 this.argument = argument; | |
781 } | |
782 } |