1 /// Author: Aziz Köksal 2 /// License: GPL3 3 /// $(Maturity average) 4 module dil.ast.Types; 5 6 public import dil.ast.Type; 7 import dil.ast.Node, 8 dil.ast.Expression, 9 dil.ast.Parameters, 10 dil.ast.NodeCopier, 11 dil.ast.Meta; 12 import dil.lexer.Identifier; 13 import dil.semantic.Types; 14 import dil.Enums; 15 import common; 16 17 /// Syntax error. 18 class IllegalType : TypeNode 19 { 20 mixin(memberInfo()); 21 this() 22 { 23 mixin(set_kind); 24 } 25 mixin methods; 26 } 27 28 /// $(BNF IntegralType := char | int | float | ...) 29 class IntegralType : TypeNode 30 { 31 TOK tok; 32 mixin(memberInfo("tok")); 33 this(TOK tok) 34 { 35 mixin(set_kind); 36 this.tok = tok; 37 } 38 mixin methods; 39 } 40 41 /// $(BNF ModuleScopeType := ".") 42 class ModuleScopeType : TypeNode 43 { 44 mixin(memberInfo()); 45 this() 46 { 47 mixin(set_kind); 48 } 49 mixin methods; 50 } 51 52 /// $(BNF IdentifierType := Type? Identifier) 53 class IdentifierType : TypeNode 54 { 55 Token* name; 56 mixin(memberInfo("next?", "name")); 57 this(TypeNode next, Token* name) 58 { 59 super(next); 60 mixin(set_kind); 61 this.name = name; 62 } 63 64 @property Identifier* id() 65 { 66 return name.ident; 67 } 68 69 mixin methods; 70 } 71 72 /// $(BNF TypeofType := typeof "(" (Expression | return) ")") 73 class TypeofType : TypeNode 74 { 75 Expression expr; 76 77 mixin(memberInfo("expr?")); 78 this(Expression e) 79 { 80 mixin(set_kind); 81 addOptChild(e); 82 this.expr = e; 83 } 84 85 /// Returns true for typeof "(" return ")". 86 bool isTypeofReturn() 87 { 88 return expr is null; 89 } 90 91 mixin methods; 92 } 93 94 /// $(BNF TemplateInstanceType := 95 //// Identifier "!" (TemplateArgumentList | TemplateArgumentSingle)) 96 class TmplInstanceType : TypeNode 97 { 98 Token* name; 99 TemplateArguments targs; 100 mixin(memberInfo("next?", "name", "targs")); 101 this(TypeNode next, Token* name, TemplateArguments targs) 102 { 103 super(next); 104 mixin(set_kind); 105 addOptChild(targs); 106 this.name = name; 107 this.targs = targs; 108 } 109 110 @property Identifier* id() 111 { 112 return name.ident; 113 } 114 115 mixin methods; 116 } 117 118 /// $(BNF PointerType:= Type "*") 119 class PointerType : TypeNode 120 { 121 mixin(memberInfo("next")); 122 this(TypeNode next) 123 { 124 super(next); 125 mixin(set_kind); 126 } 127 mixin methods; 128 } 129 130 /// $(BNF 131 ////ArrayType := DynamicArray | StaticArray | SliceArray | AssociativeArray 132 ////DynamicArray := T "[" "]" 133 ////StaticArray := T "[" E "]" 134 ////SliceArray := T "[" E ".." E "]" # for slicing tuples 135 ////AssociativeArray := T "[" T "]" 136 ////) 137 class ArrayType : TypeNode 138 { 139 Expression index1, index2; 140 TypeNode assocType; 141 142 mixin(memberInfo("next", "index1?", "index2?", "assocType?")); 143 /// DynamicArray. 144 this(TypeNode next) 145 { 146 super(next); 147 mixin(set_kind); 148 } 149 150 /// StaticArray or SliceArray. 151 this(TypeNode next, Expression e1, Expression e2 = null) 152 { 153 this(next); 154 addChild(e1); 155 addOptChild(e2); 156 this.index1 = e1; 157 this.index2 = e2; 158 } 159 160 /// AssociativeArray. 161 this(TypeNode next, TypeNode assocType) 162 { 163 this(next); 164 addChild(assocType); 165 this.assocType = assocType; 166 } 167 168 /// For ASTSerializer. 169 this(TypeNode next, Expression e1, Expression e2, TypeNode assocType) 170 { 171 if (e1) 172 this(next, e1, e2); 173 else if (assocType) 174 this(next, assocType); 175 else 176 this(next); 177 } 178 179 bool isDynamic() 180 { 181 return assocType is null && index1 is null; 182 } 183 184 bool isStatic() 185 { 186 return index1 !is null && index2 is null; 187 } 188 189 bool isSlice() 190 { 191 return index1 !is null && index2 !is null; 192 } 193 194 bool isAssociative() 195 { 196 return assocType !is null; 197 } 198 199 mixin methods; 200 } 201 202 /// $(BNF FunctionType := ReturnType function ParameterList) 203 class FunctionType : TypeNode 204 { 205 alias returnType = next; 206 Parameters params; 207 mixin(memberInfo("returnType", "params")); 208 this(TypeNode returnType, Parameters params) 209 { 210 super(returnType); 211 mixin(set_kind); 212 addChild(params); 213 this.params = params; 214 } 215 mixin methods; 216 } 217 218 /// $(BNF DelegateType := ReturnType delegate ParameterList) 219 class DelegateType : TypeNode 220 { 221 alias returnType = next; 222 Parameters params; 223 mixin(memberInfo("returnType", "params")); 224 this(TypeNode returnType, Parameters params) 225 { 226 super(returnType); 227 mixin(set_kind); 228 addChild(params); 229 this.params = params; 230 } 231 mixin methods; 232 } 233 234 /// $(BNF BaseClassType := Protection? BasicType) 235 class BaseClassType : TypeNode 236 { 237 Protection prot; 238 mixin(memberInfo("prot", "next")); 239 this(Protection prot, TypeNode type) 240 { 241 super(type); 242 mixin(set_kind); 243 this.prot = prot; 244 } 245 mixin methods; 246 } 247 248 /// $(BNF ModifierType := ModAttrType | ModParenType 249 ////ModAttrType := Modifier Type 250 ////ModParenType := Modifier "(" Type ")" 251 ////Modifier := const | immutable | shared | inout) 252 class ModifierType : TypeNode 253 { 254 Token* mod; 255 bool hasParen; // True if, e.g.: const "(" Type ")" 256 mixin(memberInfo("next?", "mod", "hasParen")); 257 258 this(TypeNode next, Token* mod, bool hasParen) 259 { 260 super(next); 261 mixin(set_kind); 262 this.mod = mod; 263 this.hasParen = hasParen; 264 } 265 266 this(Token* mod) 267 { 268 this(null, mod, false); 269 } 270 271 bool isImmutable() @property 272 { 273 return mod.kind == TOK.Immutable; 274 } 275 276 bool isConst() @property 277 { 278 return mod.kind == TOK.Const; 279 } 280 281 bool isShared() @property 282 { 283 return mod.kind == TOK.Shared; 284 } 285 286 bool isInout() @property 287 { 288 return mod.kind == TOK.Inout; 289 } 290 291 mixin methods; 292 }