1 /// Author: Aziz Köksal
2 /// License: GPL3
3 /// $(Maturity average)
4 module dil.Tables;
5 
6 import dil.lexer.Token,
7        dil.lexer.IdTable,
8        dil.lexer.Tables;
9 import dil.ast.Declarations;
10 import dil.semantic.Types,
11        dil.semantic.Symbols,
12        dil.semantic.Module;
13 import common;
14 
15 /// A collection of tables used by the Lexer and other classes.
16 class Tables
17 {
18   LexerTables lxtables; /// Tables for the Lexer.
19   TypeTable types; /// A table for D types.
20   ClassTable classes; /// Special classes.
21   IdTable idents; /// Alias to lxtables.idents.
22 
23   /// Contructs a Tables object.
24   this(bool[cstring] options = null)
25   {
26     // TODO: options should probably be a class.
27     this.lxtables = new LexerTables;
28     this.types = new TypeTable();
29     this.types.init(options);
30     this.classes = new ClassTable();
31     this.idents = this.lxtables.idents;
32   }
33 }
34 
35 /// A collection of special classes.
36 class ClassTable
37 {
38   // Classes from object.d:
39   ClassSymbol object; /// Class Object.
40   ClassSymbol classInfo; /// Class ClassInfo.
41   ClassSymbol moduleInfo; /// Class ModuleInfo.
42   ClassSymbol throwable; /// Class Throwable.
43   ClassSymbol exeption; /// Class Exeption.
44   ClassSymbol error; /// Class Error.
45   // Classes from runtime library files:
46   ClassSymbol tinfo; /// Class TypeInfo.
47   ClassSymbol tinfoPointer; /// Class TypeInfo_Pointer.
48   ClassSymbol tinfoArray; /// Class TypeInfo_Array.
49   ClassSymbol tinfoSArray; /// Class TypeInfo_StaticArray.
50   ClassSymbol tinfoAArray; /// Class TypeInfo_AssociativeArray.
51   ClassSymbol tinfoFunction; /// Class TypeInfo_Function.
52   ClassSymbol tinfoDelegate; /// Class TypeInfo_Delegate.
53   ClassSymbol tinfoEnum; /// Class TypeInfo_Enum.
54   ClassSymbol tinfoClass; /// Class TypeInfo_Class.
55   ClassSymbol tinfoInterface; /// Class TypeInfo_Interface.
56   ClassSymbol tinfoStruct; /// Class TypeInfo_Struct.
57   ClassSymbol tinfoTuple; /// Class TypeInfo_Tuple.
58   ClassSymbol tinfoTypedef; /// Class TypeInfo_Typedef.
59   // D2:
60   ClassSymbol tinfoVector; /// Class TypeInfo_Vector.
61   ClassSymbol tinfoConst; /// Class TypeInfo_Const.
62   ClassSymbol tinfoImmutable; /// Class TypeInfo_Invariant.
63   ClassSymbol tinfoShared; /// Class TypeInfo_Shared.
64   ClassSymbol tinfoInout; /// Class TypeInfo_Inout.
65 
66   /// If d.symbol is a special class, it is stored in this table
67   /// and a SpecialClassSymbol is assigned to it.
68   void lookForSpecialClasses(Module modul, ClassDecl d,
69     void delegate(Token* name, cstring format, ...) error)
70   {
71     ClassSymbol s = d.symbol;
72     ClassSymbol* ps; /// Assigned to, if special class.
73     auto name = s.name;
74 
75     if (name is Ident.Sizeof  ||
76         name is Ident.Alignof ||
77         name is Ident.Mangleof)
78       error(d.name, "the class name ‘{}’ is not allowed", name.str);
79     else if (name.startsWith("TypeInfo"))
80     {
81       switch (name.idKind)
82       {
83       case IDK.TypeInfo:                  ps = &tinfo;          break;
84       case IDK.TypeInfo_Pointer:          ps = &tinfoPointer;   break;
85       case IDK.TypeInfo_Array:            ps = &tinfoArray;     break;
86       case IDK.TypeInfo_StaticArray:      ps = &tinfoSArray;    break;
87       case IDK.TypeInfo_AssociativeArray: ps = &tinfoAArray;    break;
88       case IDK.TypeInfo_Function:         ps = &tinfoFunction;  break;
89       case IDK.TypeInfo_Delegate:         ps = &tinfoDelegate;  break;
90       case IDK.TypeInfo_Enum:             ps = &tinfoEnum;      break;
91       case IDK.TypeInfo_Class:            ps = &tinfoClass;     break;
92       case IDK.TypeInfo_Interface:        ps = &tinfoInterface; break;
93       case IDK.TypeInfo_Struct:           ps = &tinfoStruct;    break;
94       case IDK.TypeInfo_Tuple:            ps = &tinfoTuple;     break;
95       case IDK.TypeInfo_Typedef:          ps = &tinfoTypedef;   break;
96       version(D2)
97       {
98       case IDK.TypeInfo_Vector:           ps = &tinfoVector;    break;
99       case IDK.TypeInfo_Const:            ps = &tinfoConst;     break;
100       case IDK.TypeInfo_Invariant:        ps = &tinfoImmutable; break;
101       case IDK.TypeInfo_Shared:           ps = &tinfoShared;    break;
102       case IDK.TypeInfo_Inout:            ps = &tinfoInout;     break;
103       } //version(D2)
104       default:
105       }
106     }
107     else
108     if (modul.name is Ident.object && modul.parent.parent is null)
109     { // If object.d module and if in root package.
110       if (name is Ident.Object)
111         ps = &object;
112       else if (name is Ident.ClassInfo)
113         ps = &classInfo;
114       else if (name is Ident.ModuleInfo)
115         ps = &moduleInfo;
116       else if (name is Ident.Throwable)
117         ps = &throwable;
118       else if (name is Ident.Exception)
119         ps = &exeption;
120       else if (name is Ident.Error)
121         ps = &this.error;
122     }
123 
124     if (ps)
125     {
126       if (*ps !is null)
127         error(d.name,
128           "special class ‘{}’ already defined at ‘{}’",
129           name.str, (*ps).loc.t.getErrorLocation(modul.filePath()).repr());
130       else // Convert to SpecialClassSymbol, as it handles mangling differently.
131         d.symbol = *ps = new SpecialClassSymbol(s.name, s.loc);
132     }
133   }
134 }