Skip to content

Commit 7980d55

Browse files
committed
Implement sumtypes and matching
1 parent d4c5f7a commit 7980d55

38 files changed

Lines changed: 6997 additions & 5 deletions

compiler/include/dmd/aggregate.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include "dsymbol.h"
1414
#include "objc.h"
1515

16+
class TypeSumType;
17+
1618
class AliasThis;
1719
class Identifier;
1820
class Type;
@@ -162,6 +164,7 @@ class StructDeclaration : public AggregateDeclaration
162164
// ABI-specific type(s) if the struct can be passed in registers
163165
TypeTuple *argTypes;
164166

167+
TypeSumType *sumtype; // if non-null, this struct is the lowered form of a __sumtype
165168
structalign_t alignment; // alignment applied outside of the struct
166169
ThreeState ispod; // if struct is POD
167170
private:

compiler/include/dmd/expression.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,7 @@ class DotVarExp final : public UnaExp
706706
public:
707707
Declaration *var;
708708
d_bool hasOverloads;
709+
d_bool compilerOverlappedAccess;
709710

710711
void accept(Visitor *v) override { v->visit(this); }
711712
};
@@ -1256,6 +1257,30 @@ class GenericExp final : Expression
12561257

12571258
/****************************************************************/
12581259

1260+
struct SumTypeMatchArmInfo
1261+
{
1262+
VarDeclaration *vd;
1263+
Expression *guard;
1264+
int variantIndex;
1265+
int originalIndex;
1266+
};
1267+
1268+
class MatchExp final : Expression
1269+
{
1270+
public:
1271+
Expression *arg;
1272+
Array<SumTypeMatchArmInfo> *armInfos;
1273+
Type *resultType;
1274+
StructDeclaration *loweredStruct;
1275+
TypeSumType *sumtypeType;
1276+
1277+
MatchExp *syntaxCopy() override;
1278+
1279+
void accept(Visitor *v) override { v->visit(this); }
1280+
};
1281+
1282+
/****************************************************************/
1283+
12591284
class DefaultInitExp : public Expression
12601285
{
12611286
public:

compiler/include/dmd/module.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ class Module final : public Package
113113
size_t nameoffset; // offset of module name from start of ModuleInfo
114114
size_t namelen; // length of module name in characters
115115

116+
void* sumtypeCollations; // AA: collation table for sumtype declarations (SumTypeKey -> StructDeclaration)
117+
116118
static Module* create(const char *arg, Identifier *ident, int doDocComment, int doHdrGen);
117119
static Module *load(Loc loc, Identifiers *packages, Identifier *ident);
118120

compiler/include/dmd/mtype.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ enum class TY : uint8_t
106106
Ttraits,
107107
Tmixin,
108108
Tnoreturn,
109+
Ttag,
110+
Tsumtype,
109111
TMAX
110112
};
111113

@@ -284,6 +286,7 @@ class Type : public ASTNode
284286
TypeTraits *isTypeTraits();
285287
TypeNoreturn *isTypeNoreturn();
286288
TypeTag *isTypeTag();
289+
TypeSumType *isTypeSumType();
287290

288291
void accept(Visitor *v) override { v->visit(this); }
289292
};
@@ -713,6 +716,30 @@ class TypeTag final : public Type
713716

714717
/**************************************************************/
715718

719+
struct SumTypeVariantInfo
720+
{
721+
Type *type;
722+
Identifier *name;
723+
Expressions *udas;
724+
const char *comment;
725+
};
726+
727+
typedef Array<SumTypeVariantInfo> SumTypeVariantInfos;
728+
729+
class TypeSumType final : public Type
730+
{
731+
public:
732+
SumTypeVariantInfos *variantInfos;
733+
StructDeclaration *loweredStruct;
734+
size_t defaultVariantIdx;
735+
736+
TypeSumType *syntaxCopy() override;
737+
738+
void accept(Visitor *v) override { v->visit(this); }
739+
};
740+
741+
/**************************************************************/
742+
716743
namespace dmd
717744
{
718745
// If the type is a class or struct, returns the symbol for it, else null.

compiler/include/dmd/tokens.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ enum class TOK : unsigned char
259259
whitespace,
260260
rvalue,
261261

262+
sumtype_,
263+
262264
// C only keywords
263265
inline_,
264266
register_,
@@ -430,6 +432,10 @@ enum class EXP : unsigned char
430432
_Generic_,
431433
interval,
432434

435+
loweredAssignExp,
436+
rvalue,
437+
matchExp,
438+
433439
MAX
434440
};
435441

compiler/include/dmd/visitor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class TypeNoreturn;
8686
class TypeTraits;
8787
class TypeMixin;
8888
class TypeTag;
89+
class TypeSumType;
8990

9091
class Dsymbol;
9192

@@ -298,6 +299,7 @@ class ClassReferenceExp;
298299
class VoidInitExp;
299300
class ThrownExceptionExp;
300301
class GenericExp;
302+
class MatchExp;
301303

302304
class TemplateParameter;
303305
class TemplateTypeParameter;
@@ -450,6 +452,7 @@ class ParseTimeVisitor
450452
virtual void visit(TypeTraits *t) { visit((Type *)t); }
451453
virtual void visit(TypeMixin *t) { visit((Type *)t); }
452454
virtual void visit(TypeTag *t) { visit((Type *)t); }
455+
virtual void visit(TypeSumType *t) { visit((Type *)t); }
453456

454457
// TypeNext
455458
virtual void visit(TypeReference *t) { visit((TypeNext *)t); }
@@ -499,6 +502,7 @@ class ParseTimeVisitor
499502
virtual void visit(TupleExp *e) { visit((Expression *)e); }
500503
virtual void visit(ThisExp *e) { visit((Expression *)e); }
501504
virtual void visit(GenericExp *e) { visit((Expression *)e); }
505+
virtual void visit(MatchExp *e) { visit((Expression *)e); }
502506

503507
// Miscellaneous
504508
virtual void visit(VarExp *e) { visit((SymbolExp *)e); }

compiler/src/dmd/arraytypes.d

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,5 @@ alias TemplateInstances = Array!(TemplateInstance);
5555
alias Ensures = Array!(Ensure);
5656
alias Designators = Array!(Designator);
5757
alias DesigInits = Array!(DesigInit);
58+
alias SumTypeVariantInfos = Array!(SumTypeVariantInfo);
59+
alias SumTypeMatchArmInfos = Array!(SumTypeMatchArmInfo);

compiler/src/dmd/astbase.d

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2702,6 +2702,7 @@ struct ASTBase
27022702
sizeTy[Tmixin] = __traits(classInstanceSize, TypeMixin);
27032703
sizeTy[Tnoreturn] = __traits(classInstanceSize, TypeNoreturn);
27042704
sizeTy[Ttag] = __traits(classInstanceSize, TypeTag);
2705+
sizeTy[Tsumtype] = __traits(classInstanceSize, TypeSumType);
27052706
return sizeTy;
27062707
}();
27072708

@@ -3784,6 +3785,39 @@ struct ASTBase
37843785
}
37853786
}
37863787

3788+
struct SumTypeVariantInfo
3789+
{
3790+
Type type;
3791+
Identifier name;
3792+
Expressions* udas;
3793+
const(char)* comment;
3794+
}
3795+
3796+
alias SumTypeVariantInfos = Array!(SumTypeVariantInfo);
3797+
3798+
extern (C++) final class TypeSumType : Type
3799+
{
3800+
SumTypeVariantInfos* variantInfos;
3801+
StructDeclaration loweredStruct;
3802+
size_t defaultVariantIdx;
3803+
3804+
extern (D) this(SumTypeVariantInfos* variantInfos = null)
3805+
{
3806+
super(Tsumtype);
3807+
this.variantInfos = variantInfos;
3808+
}
3809+
3810+
override TypeSumType syntaxCopy()
3811+
{
3812+
return this;
3813+
}
3814+
3815+
override void accept(Visitor v)
3816+
{
3817+
v.visit(this);
3818+
}
3819+
}
3820+
37873821
extern (C++) final class TypeReference : TypeNext
37883822
{
37893823
extern (D) this(Type t)
@@ -6270,6 +6304,35 @@ struct ASTBase
62706304
}
62716305
}
62726306

6307+
struct SumTypeMatchArmInfo
6308+
{
6309+
VarDeclaration vd;
6310+
Expression guard;
6311+
int variantIndex;
6312+
int originalIndex;
6313+
}
6314+
6315+
alias SumTypeMatchArmInfos = Array!(SumTypeMatchArmInfo);
6316+
6317+
extern (C++) final class MatchExp : Expression
6318+
{
6319+
Expression arg;
6320+
SumTypeMatchArmInfos* armInfos;
6321+
Type resultType;
6322+
6323+
extern (D) this(Loc loc, Expression arg, SumTypeMatchArmInfos* armInfos)
6324+
{
6325+
super(loc, EXP.matchExp, __traits(classInstanceSize, MatchExp));
6326+
this.arg = arg;
6327+
this.armInfos = armInfos;
6328+
}
6329+
6330+
override void accept(Visitor v)
6331+
{
6332+
v.visit(this);
6333+
}
6334+
}
6335+
62736336
extern (C++) final class ErrorExp : Expression
62746337
{
62756338
extern (D) this()

compiler/src/dmd/astcodegen.d

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ struct ASTCodegen
7474
alias Tvoid = dmd.mtype.Tvoid;
7575
alias Twchar = dmd.mtype.Twchar;
7676
alias Tnoreturn = dmd.mtype.Tnoreturn;
77+
alias Tsumtype = dmd.mtype.Tsumtype;
7778

7879
alias Timaginary32 = dmd.mtype.Timaginary32;
7980
alias Timaginary64 = dmd.mtype.Timaginary64;

compiler/src/dmd/astenums.d

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ enum TY : ubyte
228228
Tmixin,
229229
Tnoreturn,
230230
Ttag,
231+
Tsumtype,
231232
}
232233
enum TMAX = TY.max + 1;
233234

@@ -279,6 +280,7 @@ alias Ttraits = TY.Ttraits;
279280
alias Tmixin = TY.Tmixin;
280281
alias Tnoreturn = TY.Tnoreturn;
281282
alias Ttag = TY.Ttag;
283+
alias Tsumtype = TY.Tsumtype;
282284

283285
enum TFlags
284286
{

0 commit comments

Comments
 (0)