EMPL IR
EMPL Types — `mpl::ir::UIRType` and friends
EMPL Types — mpl::ir::UIRType and friends
The type system is declared in MPL_Compiler/core/ir/EMPLTypes.h (88 lines total). It defines the EMPLNodePtr smart-pointer alias, the closed TypeKind enum (32 values), the UIRType struct, the Visibility enum, SourceLocation, and the Parameter struct.
// MPL_Compiler/core/ir/EMPLTypes.h:7
namespace mpl { namespace ir {
class EMPLNode; // fwd decl
using EMPLNodePtr = std::shared_ptr<EMPLNode>; // line 11
enum class TypeKind { /* … 32 values … */ }; // line 13
struct UIRType { /* … */ }; // line 50
using UIRTypePtr = std::shared_ptr<UIRType>; // line 65
enum class Visibility { /* 4 values */ }; // line 67
struct SourceLocation { /* 3 fields */ }; // line 74
struct Parameter { /* 4 fields */ }; // line 80
}}
EMPLNodePtr — the canonical smart-pointer alias
// MPL_Compiler/core/ir/EMPLTypes.h:11
using EMPLNodePtr = std::shared_ptr<EMPLNode>;
Every IR node is heap-allocated and owned via std::shared_ptr. Parent nodes store their children in std::vector<EMPLNodePtr>. Frontends build trees with std::make_shared<ClassDeclNode>() and pass them by value into the appropriate std::vector field.
Convention. Always use the
EMPLNodePtralias — never spell outstd::shared_ptr<mpl::ir::EMPLNode>in client code. The legacy aliasUIRNodePtr(EMPLNode.h:86) is equivalent.
TypeKind — exhaustive table
TypeKind is the closed tag for UIRType. Each value identifies a kind of type; the actual generic / parameter / return information is carried in the corresponding UIRType fields.
| Index | TypeKind |
Meaning | Where it lives in UIRType |
|---|---|---|---|
| 0 | Void |
No value (return; without expression) |
kind |
| 1 | Bool |
true / false |
kind |
| 2 | Char |
Single code unit (rarely used directly) | kind |
| 3 | Int8 |
Signed 8-bit | kind |
| 4 | Int16 |
Signed 16-bit | kind |
| 5 | Int32 |
Signed 32-bit | kind |
| 6 | Int64 |
Signed 64-bit | kind |
| 7 | UInt8 |
Unsigned 8-bit | kind |
| 8 | UInt16 |
Unsigned 16-bit | kind |
| 9 | UInt32 |
Unsigned 32-bit | kind |
| 10 | UInt64 |
Unsigned 64-bit | kind |
| 11 | Float32 |
IEEE-754 single precision | kind |
| 12 | Float64 |
IEEE-754 double precision | kind |
| 13 | BigInt |
Arbitrary-precision integer (Boost cpp_int in C++) |
kind |
| 14 | String |
UTF-8 string (std::string in C++) |
kind |
| 15 | Symbol |
Interned unique value (ES Symbols, etc.) | kind |
| 16 | Array |
Fixed-size array | elementType, name |
| 17 | List |
Resizable sequence | elementType |
| 18 | Map |
Key → value | keyType, valueType |
| 19 | Set |
Unique collection | elementType |
| 20 | Function |
Callable signature | parameterTypes[], returnType |
| 21 | Class |
Class / nominal type | name |
| 22 | Interface |
Interface declaration | name |
| 23 | Enum |
Enumeration | name |
| 24 | Optional |
Nullable wrapper | elementType |
| 25 | Nullable |
Like Optional but allows null rather than absent |
elementType |
| 26 | Tuple |
Heterogeneous fixed-shape | typeArguments[] |
| 27 | Union |
Sum of alternatives | alternatives[] |
| 28 | Intersection |
Conjoined constraints | alternatives[] |
| 29 | Any |
Top type | kind |
| 30 | Generic |
Type parameter placeholder | name, constraints[] |
| 31 | UserDefined |
Anything else; name carries the source-language identifier |
name, typeArguments[] |
| 32 | Never |
Bottom type (throw, infinite loop) |
kind |
| 33 | Unknown |
Default / un-inferred | kind |
The default value of
UIRType::kindisTypeKind::Unknown(line 51) — a freshly-constructedUIRTyperepresents the unknown type and is the appropriate sentinel for "type not yet inferred".
UIRType — the type descriptor struct
// MPL_Compiler/core/ir/EMPLTypes.h:50
struct UIRType {
TypeKind kind = TypeKind::Unknown;
std::string name;
std::vector<std::shared_ptr<UIRType>> typeParameters; // for generics
std::vector<std::shared_ptr<UIRType>> typeArguments; // for instantiations
std::shared_ptr<UIRType> returnType; // Function
std::vector<std::shared_ptr<UIRType>> parameterTypes; // Function
std::shared_ptr<UIRType> keyType; // Map
std::shared_ptr<UIRType> valueType; // Map
std::shared_ptr<UIRType> elementType; // Array/List/Set/Optional/Nullable
std::vector<std::shared_ptr<UIRType>> alternatives; // Union/Intersection
std::vector<std::shared_ptr<UIRType>> constraints; // Generic
bool isConst = false;
bool isReadonly = false;
};
using UIRTypePtr = std::shared_ptr<UIRType>;
Field-by-field
| Field | Type | Used when kind is |
Description |
|---|---|---|---|
kind |
TypeKind |
always | The discriminator. |
name |
std::string |
Class, Interface, Enum, Generic, UserDefined, Array |
The bare identifier ("Array" for the built-in, "MyClass" for a user class). |
typeParameters |
vector<UIRTypePtr> |
Class, Interface (declaration sites) |
The generic parameters, e.g. <T extends Comparable> → one entry with kind=Generic, name="T", constraints=[…]. |
typeArguments |
vector<UIRTypePtr> |
instantiation sites | The concrete types bound at instantiation. |
returnType |
UIRTypePtr |
Function |
Return type. nullptr for void-returning functions (use kind=Void). |
parameterTypes |
vector<UIRTypePtr> |
Function |
Positional parameter types. |
keyType |
UIRTypePtr |
Map |
Type of keys. |
valueType |
UIRTypePtr |
Map |
Type of values. |
elementType |
UIRTypePtr |
Array, List, Set, Optional, Nullable |
Type of elements / wrapped value. |
alternatives |
vector<UIRTypePtr> |
Union, Intersection |
Constituent types. |
constraints |
vector<UIRTypePtr> |
Generic |
Upper bounds (e.g. T extends number & Comparable). |
isConst |
bool |
any | true for compile-time constants (const X = 42). |
isReadonly |
bool |
any | true for read-only references (readonly T[], const &). |
Examples
// "number[]"
UIRType listOfNumber;
listOfNumber.kind = TypeKind::List;
listOfNumber.elementType = std::make_shared<UIRType>();
listOfNumber.elementType->kind = TypeKind::Float64;
// "Map<string, number>"
UIRType mapStringNumber;
mapStringNumber.kind = TypeKind::Map;
mapStringNumber.keyType = std::make_shared<UIRType>(UIRType{TypeKind::String});
mapStringNumber.valueType = std::make_shared<UIRType>(UIRType{TypeKind::Float64});
// "(x: number) => string"
UIRType arrowType;
arrowType.kind = TypeKind::Function;
auto param = std::make_shared<UIRType>(UIRType{TypeKind::Float64});
arrowType.parameterTypes = { param };
arrowType.returnType = std::make_shared<UIRType>(UIRType{TypeKind::String});
// "string | undefined"
UIRType optString;
optString.kind = TypeKind::Union;
optString.alternatives = {
std::make_shared<UIRType>(UIRType{TypeKind::String}),
std::make_shared<UIRType>(UIRType{TypeKind::Void}) // 'undefined'
};
Visibility
// MPL_Compiler/core/ir/EMPLTypes.h:67
enum class Visibility {
Public,
Private,
Protected,
Internal,
};
| Value | Meaning |
|---|---|
Public |
Accessible everywhere. |
Private |
Accessible only within the declaring class (or module, in module-internal contexts). |
Protected |
Accessible within the declaring class and its subclasses. |
Internal |
Accessible within the declaring module / assembly / package. |
The IR does not store Visibility as a field on declarations directly; rather, the source-language frontend encodes visibility into the type system (e.g. as a Private field on a TS-style declaration) or stores it as metadata on the enclosing node.
SourceLocation
// MPL_Compiler/core/ir/EMPLTypes.h:74
struct SourceLocation {
std::string filename;
int line = 0;
int column = 0;
};
| Field | Meaning |
|---|---|
filename |
Path of the source file. May be empty if the node is synthesized. |
line |
1-based line number. 0 if unknown. |
column |
1-based column number. 0 if unknown. |
Every EMPLNode inherits SourceLocation location as a public field (EMPLNode.h:75). Backends use this for diagnostic emission (std::cerr << loc.filename << ":" << loc.line << ": error: …).
Parameter
// MPL_Compiler/core/ir/EMPLTypes.h:80
struct Parameter {
std::string name;
UIRTypePtr type;
EMPLNodePtr defaultValue;
bool isVariadic = false;
};
| Field | Meaning |
|---|---|
name |
Parameter identifier. May be empty for positional / variadic parameters. |
type |
Annotated type, or nullptr if un-annotated. |
defaultValue |
A LiteralNode / BinaryOpNode / etc. for the default expression, or nullptr if the parameter is required. |
isVariadic |
true for rest parameters (...args). |
Parameter is the typed parameter representation used by FunctionDeclNode::typedParameters (EMPLNode.h:168). Frontends populate BOTH the un-typed parameters: vector<pair<string,string>> (line 167 — (name, sourceText)) and the typed typedParameters: vector<Parameter> (line 168 — full type + default). The C++ backend prefers the typed list; the un-typed list is preserved for fallback name recovery.
See also
index.md— IR overviewnode-kind.md—NodeKindenumnodes/function-decl.md— primary consumer ofParameterandUIRType