1 /** 2 * Copyright: Enalye 3 * License: Zlib 4 * Authors: Enalye 5 */ 6 module grimoire.compiler.type; 7 8 import std.conv : to; 9 10 import grimoire.runtime; 11 import grimoire.assembly; 12 import grimoire.compiler.mangle; 13 import grimoire.compiler.data; 14 15 /** 16 Type category. 17 18 Complex types use mangledType and mangledReturnType 19 to represent them. 20 */ 21 enum GrBaseType { 22 void_, 23 null_, 24 int_, 25 float_, 26 bool_, 27 string_, 28 array_, 29 function_, 30 task, 31 class_, 32 foreign, 33 chan, 34 enum_, 35 internalTuple, 36 reference 37 } 38 39 /** 40 Compiler type definition for Grimoire's type system. 41 It doesn't mean anything for the VM. 42 */ 43 struct GrType { 44 /// General type, basic types only use that while compound types also use mangledType 45 /// and mangledReturnType. 46 GrBaseType baseType; 47 /// Used for compound types like arrays, functions, etc. 48 string mangledType, mangledReturnType; 49 /// Is this from an object field ? 50 bool isField; 51 /// Can this type match with others ? 52 bool isAny; 53 /// Is the type abstract ? 54 /// An abstract type cannot be used in signatures. 55 bool isAbstract; 56 /// Predicate to validate any type 57 bool function(GrType, GrAnyData) predicate; 58 59 /// Init as a basic type. 60 this(GrBaseType baseType_) { 61 baseType = baseType_; 62 } 63 64 /// Compound type. 65 this(GrBaseType baseType_, string mangledType_) { 66 baseType = baseType_; 67 mangledType = mangledType_; 68 } 69 70 /// Only assign a simple type (baseType). 71 GrType opOpAssign(string op)(GrBaseType t) { 72 mixin("baseType = baseType" ~ op ~ "t;"); 73 return this; 74 } 75 76 /// Check general type equality. 77 bool opEquals(const GrBaseType v) const { 78 return (baseType == v); 79 } 80 81 /// Check full type equality. 82 bool opEquals(const GrType v) const { 83 if (baseType != v.baseType) 84 return false; 85 if (baseType == GrBaseType.function_ || baseType == GrBaseType.task) 86 return mangledType == v.mangledType && mangledReturnType == v.mangledReturnType; 87 if (baseType == GrBaseType.foreign || baseType == GrBaseType.class_ 88 || baseType == GrBaseType.enum_ || baseType == GrBaseType.array_) 89 return mangledType == v.mangledType; 90 return true; 91 } 92 93 /// Only to disable warnings because of opEquals. 94 size_t toHash() const @safe pure nothrow { 95 return 0; 96 } 97 } 98 99 /// No type 100 const GrType grVoid = GrType(GrBaseType.void_); 101 /// Integer 102 const GrType grInt = GrType(GrBaseType.int_); 103 /// Float 104 const GrType grFloat = GrType(GrBaseType.float_); 105 /// Bool 106 const GrType grBool = GrType(GrBaseType.bool_); 107 /// String 108 const GrType grString = GrType(GrBaseType.string_); 109 /// Int array 110 const GrType grIntArray = GrType(GrBaseType.array_, grMangleSignature([grInt])); 111 /// Float array 112 const GrType grFloatArray = GrType(GrBaseType.array_, grMangleSignature([ 113 grFloat 114 ])); 115 /// Bool array 116 const GrType grBoolArray = GrType(GrBaseType.array_, grMangleSignature([grBool])); 117 /// String array 118 const GrType grStringArray = GrType(GrBaseType.array_, grMangleSignature([ 119 grString 120 ])); 121 /// Int channel 122 const GrType grIntChannel = GrType(GrBaseType.chan, grMangleSignature([grInt])); 123 /// Float channel 124 const GrType grFloatChannel = GrType(GrBaseType.chan, grMangleSignature([ 125 grFloat 126 ])); 127 /// Bool channel 128 const GrType grBoolChannel = GrType(GrBaseType.chan, grMangleSignature([grBool])); 129 /// String channel 130 const GrType grStringChannel = GrType(GrBaseType.chan, grMangleSignature([ 131 grString 132 ])); 133 134 /// Returns an array GrType of `subType` subtype. 135 GrType grArray(GrType subType) { 136 return GrType(GrBaseType.array_, grMangleSignature([subType])); 137 } 138 139 /// Returns a channel GrType of `subType` subtype. 140 GrType grChannel(GrType subType) { 141 return GrType(GrBaseType.chan, grMangleSignature([subType])); 142 } 143 144 /// Special type the matches another type with a predicate. 145 GrType grAny(string name, bool function(GrType, GrAnyData) predicate = (a, b) => true) { 146 GrType type; 147 type.baseType = GrBaseType.void_; 148 type.mangledType = name; 149 type.isAny = true; 150 type.predicate = predicate; 151 return type; 152 } 153 154 /// The type is handled by a int based register 155 bool grIsKindOfInt(GrBaseType type) { 156 return type == GrBaseType.int_ || type == GrBaseType.bool_ 157 || type == GrBaseType.function_ || type == GrBaseType.task || type == GrBaseType.enum_; 158 } 159 160 /// The type is handled by a float based register 161 bool grIsKindOfFloat(GrBaseType type) { 162 return type == GrBaseType.float_; 163 } 164 165 /// The type is handled by a string based register 166 bool grIsKindOfString(GrBaseType type) { 167 return type == GrBaseType.string_; 168 } 169 170 /// The type is handled by a ptr based register 171 bool grIsKindOfObject(GrBaseType type) { 172 return type == GrBaseType.class_ || type == GrBaseType.array_ || type == GrBaseType.foreign 173 || type == GrBaseType.chan || type == GrBaseType.reference || type == GrBaseType.null_; 174 } 175 176 /// Context for any validation 177 final class GrAnyData { 178 private { 179 GrType[string] _types; 180 } 181 182 /// Clear any stored type definition 183 void clear() { 184 _types.clear; 185 } 186 187 /// Define a new type 188 void set(string key, GrType type) { 189 _types[key] = type; 190 } 191 192 /// Fetch an already defined type 193 GrType get(string key) { 194 return _types.get(key, grVoid); 195 } 196 } 197 198 /// Pack multiple types as a single one. 199 package GrType grPackTuple(GrType[] types) { 200 const string mangledName = grMangleSignature(types); 201 GrType type = GrBaseType.internalTuple; 202 type.mangledType = mangledName; 203 return type; 204 } 205 206 /// Unpack multiple types from a single one. 207 package GrType[] grUnpackTuple(GrType type) { 208 if (type.baseType != GrBaseType.internalTuple) 209 throw new Exception("Cannot unpack a not tuple type."); 210 return grUnmangleSignature(type.mangledType); 211 } 212 213 /** 214 A local or global variable. 215 */ 216 package class GrVariable { 217 /// Its type. 218 GrType type; 219 /// Register position, separate for each type (int, float, string and objects); 220 uint register = uint.max; 221 /// Declared from the global scope ? 222 bool isGlobal; 223 /// Declared from an object definition ? 224 bool isField; 225 /// Does it have a value yet ? 226 bool isInitialized; 227 /// Is the type to be infered automatically ? (e.g. the `let` keyword). 228 bool isAuto; 229 /// Can we modify its value ? 230 bool isConstant; 231 /// Its unique name inside its scope (function based scope). 232 string name; 233 /// Is the variable visible from other files ? (Global only) 234 bool isPublic; 235 /// The file where the variable is declared. 236 uint fileId; 237 /// Position information in case of errors. 238 uint lexPosition; 239 } 240 241 /// Define an arbitrary D pointer. 242 final class GrForeignDefinition { 243 /// Identifier. 244 string name; 245 /// Mother class it inherit from. 246 string parent; 247 } 248 249 /// Ditto 250 final class GrAbstractForeignDefinition { 251 /// Identifier. 252 string name; 253 /// Mother class it inherits from. 254 string parent; 255 /// Template values 256 string[] templateVariables; 257 /// Template signature 258 GrType[] parentTemplateSignature; 259 } 260 261 /// Create a foreign GrType for the type system. 262 GrType grGetForeignType(string name, GrType[] signature = []) { 263 GrType type = GrBaseType.foreign; 264 type.mangledType = grMangleComposite(name, signature); 265 return type; 266 } 267 268 /** 269 Define the content of a type alias. \ 270 Not to be confused with GrType used by the type system. 271 --- 272 type MyNewType = AnotherType; 273 --- 274 */ 275 final class GrTypeAliasDefinition { 276 /// Identifier. 277 string name; 278 /// The type aliased. 279 GrType type; 280 /// Is the type visible from other files ? 281 bool isPublic; 282 /// The file where the type is declared. 283 uint fileId; 284 } 285 286 /** 287 Define the content of an enum. \ 288 Not to be confused with GrType used by the type system. 289 --- 290 enum MyEnum { 291 field1; 292 field2; 293 } 294 --- 295 */ 296 final class GrEnumDefinition { 297 /// Identifier. 298 string name; 299 /// List of field names. 300 string[] fields; 301 /// Unique ID of the enum definition. 302 size_t index; 303 /// Is the type visible from other files ? 304 bool isPublic; 305 /// The file where the type is declared. 306 uint fileId; 307 308 /// Does the field name exists ? 309 bool hasField(string name) const { 310 foreach (field; fields) { 311 if (field == name) 312 return true; 313 } 314 return false; 315 } 316 317 /// Returns the value of the field 318 int getField(string name) const { 319 import std.conv : to; 320 321 int fieldIndex = 0; 322 foreach (field; fields) { 323 if (field == name) 324 return fieldIndex; 325 fieldIndex++; 326 } 327 assert(false, "Undefined enum \'" ~ name ~ "\'"); 328 } 329 } 330 331 /// Create a GrType of enum for the type system. 332 GrType grGetEnumType(string name) { 333 GrType stType = GrBaseType.enum_; 334 stType.mangledType = name; 335 return stType; 336 } 337 338 /** 339 Define the content of a class. \ 340 Not to be confused with GrType used by the type system. 341 --- 342 class MyClass { 343 // Fields 344 } 345 --- 346 */ 347 final class GrClassDefinition { 348 /// Identifier. 349 string name; 350 /// Mother class it inherit from. 351 string parent; 352 /// List of field types. 353 GrType[] signature; 354 /// List of field names. 355 string[] fields; 356 /// List of template variables. 357 string[] templateVariables; 358 /// List of template types. 359 GrType[] templateTypes, parentTemplateSignature; 360 361 package { 362 struct FieldInfo { 363 bool isPublic; 364 uint fileId; 365 uint position; 366 } 367 368 FieldInfo[] fieldsInfo; 369 370 /// The lexeme that declared it. 371 uint position; 372 } 373 /// Unique ID of the object definition. 374 size_t index; 375 /// Is the type visible from other files ? 376 bool isPublic; 377 /// The file where the type is declared. 378 uint fileId; 379 /// Is the declaration of the class already parsed ? 380 bool isParsed; 381 } 382 383 /// Create a GrType of class for the type system. 384 GrType grGetClassType(string name, GrType[] signature = []) { 385 GrType stType = GrBaseType.class_; 386 stType.mangledType = grMangleComposite(name, signature); 387 return stType; 388 } 389 390 /// Define a variable defined from a library 391 final class GrVariableDefinition { 392 /// Identifier. 393 string name; 394 /// Its type 395 GrType type; 396 /// Does the variable use a custom initialization value ? 397 bool isInitialized; 398 /// Integral init value 399 GrInt ivalue; 400 /// Floating init value 401 GrFloat fvalue; 402 /// String init value 403 GrString svalue; 404 /// Can the variable be mutated in script ? 405 bool isConstant; 406 /// Register. 407 uint register; 408 } 409 410 /// A single instruction used by the VM. 411 struct GrInstruction { 412 /// What needs to be done. 413 GrOpcode opcode; 414 /// Payload, may not be used. 415 uint value; 416 } 417 418 /** 419 Function/Task/Event definition. 420 */ 421 package class GrFunction { 422 /// Local scoping 423 struct Scope { 424 /// Every variable declared within its scope. 425 GrVariable[string] localVariables; 426 } 427 /// Ditto 428 Scope[] scopes; 429 430 uint[] iregisterAvailables, fregisterAvailables, sregisterAvailables, oregisterAvailables; 431 432 /// All the function instructions. 433 GrInstruction[] instructions; 434 uint stackSize, index, offset; 435 436 /// Unmangled function name. 437 string name; 438 /// Mangled function name. 439 string mangledName; 440 /// Function input parameters' name. 441 string[] inputVariables, templateVariables; 442 /// Function parameters' type. 443 GrType[] inSignature, outSignature, templateSignature; 444 bool isTask, isAnonymous, isEvent, isMain; 445 446 /// Function calls made from within its scope. 447 GrFunctionCall[] functionCalls; 448 GrFunction anonParent; 449 uint position, anonReference; 450 451 uint nbIntegerParameters, nbFloatParameters, nbStringParameters, nbObjectParameters; 452 uint ilocalsCount, flocalsCount, slocalsCount, olocalsCount; 453 454 GrDeferrableSection[] deferrableSections; 455 GrDeferBlock[] registeredDeferBlocks; 456 bool[] isDeferrableSectionLocked = [false]; 457 458 /// Is the function visible from other files ? 459 bool isPublic; 460 /// The file where the function is declared. 461 uint fileId; 462 463 uint lexPosition; 464 465 struct DebugPositionSymbol { 466 uint line, column; 467 } 468 469 DebugPositionSymbol[] debugSymbol; 470 471 this() { 472 scopes.length = 1; 473 } 474 475 GrVariable getLocal(string name) { 476 foreach_reverse (ref Scope scope_; scopes) { 477 //Check if declared locally. 478 GrVariable* variable = (name in scope_.localVariables); 479 if (variable !is null) 480 return *variable; 481 } 482 return null; 483 } 484 485 void setLocal(GrVariable variable_) { 486 GrVariable* oldVariable = (variable_.name in scopes[$ - 1].localVariables); 487 if (oldVariable !is null) { 488 freeRegister(*oldVariable); 489 } 490 scopes[$ - 1].localVariables[variable_.name] = variable_; 491 } 492 493 void openScope() { 494 scopes.length++; 495 } 496 497 void closeScope() { 498 foreach (GrVariable variable; scopes[$ - 1].localVariables) { 499 freeRegister(variable); 500 } 501 scopes.length--; 502 } 503 504 private void freeRegister(GrVariable variable) { 505 final switch (variable.type.baseType) with (GrBaseType) { 506 case int_: 507 case bool_: 508 case function_: 509 case task: 510 case enum_: 511 iregisterAvailables ~= variable.register; 512 break; 513 case float_: 514 fregisterAvailables ~= variable.register; 515 break; 516 case string_: 517 sregisterAvailables ~= variable.register; 518 break; 519 case array_: 520 case class_: 521 case foreign: 522 case chan: 523 oregisterAvailables ~= variable.register; 524 break; 525 case internalTuple: 526 case reference: 527 case null_: 528 case void_: 529 break; 530 } 531 } 532 } 533 534 /// Get the type of the function. 535 GrType grGetFunctionAsType(GrFunction func) { 536 GrType type = func.isTask ? GrBaseType.task : GrBaseType.function_; 537 type.mangledType = grMangleSignature(func.inSignature); 538 type.mangledReturnType = grMangleSignature(func.outSignature); 539 return type; 540 } 541 542 package class GrTemplateFunction { 543 /// Unmangled function name. 544 string name; 545 /// Function input parameters' name. 546 string[] inputVariables; 547 /// Function parameters' type. 548 GrType[] inSignature, outSignature; 549 bool isTask; 550 bool isConversion; 551 /// Is the function visible from other files ? 552 bool isPublic; 553 /// The file where the template is declared. 554 uint fileId; 555 556 string[] templateVariables; 557 558 uint lexPosition; 559 } 560 561 package class GrFunctionCall { 562 string name; 563 GrType[] signature; 564 uint position; 565 GrFunction caller, functionToCall; 566 GrType expectedType; 567 bool isAddress; 568 uint fileId; 569 } 570 571 package class GrDeferrableSection { 572 GrDeferBlock[] deferredBlocks; 573 uint deferInitPositions; 574 uint[] deferredCalls; 575 } 576 577 package class GrDeferBlock { 578 uint position; 579 uint parsePosition; 580 uint scopeLevel; 581 }