Skip to content

Commit 5e96dbc

Browse files
RicardoLuis0coelckers
authored andcommitted
Add final and sealed as class options
1 parent 42df409 commit 5e96dbc

File tree

7 files changed

+55
-9
lines changed

7 files changed

+55
-9
lines changed

src/common/engine/sc_man_scanner.re

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ std2:
204204
'stop' { RET(TK_Stop); }
205205
'null' { RET(TK_Null); }
206206
'nullptr' { RET(ParseVersion >= MakeVersion(4, 9, 0)? TK_Null : TK_Identifier); }
207+
'sealed' { RET(ParseVersion >= MakeVersion(4, 12, 0)? TK_Sealed : TK_Identifier); }
207208

208209
'is' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Is : TK_Identifier); }
209210
'replaces' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Replaces : TK_Identifier); }

src/common/engine/sc_man_tokens.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ xx(TK_Null, "'null'")
122122
xx(TK_Global, "'global'")
123123
xx(TK_Stop, "'stop'")
124124
xx(TK_Include, "'include'")
125+
xx(TK_Sealed, "'sealed'")
125126

126127
xx(TK_Is, "'is'")
127128
xx(TK_Replaces, "'replaces'")

src/common/objects/dobjtype.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,14 @@ class PClass
6666
bool bRuntimeClass = false; // class was defined at run-time, not compile-time
6767
bool bDecorateClass = false; // may be subject to some idiosyncracies due to DECORATE backwards compatibility
6868
bool bAbstract = false;
69+
bool bSealed = false;
70+
bool bFinal = false;
6971
bool bOptional = false;
7072
TArray<VMFunction*> Virtuals; // virtual function table
7173
TArray<FTypeAndOffset> MetaInits;
7274
TArray<FTypeAndOffset> SpecialInits;
7375
TArray<PField *> Fields;
76+
TArray<FName> SealedRestriction;
7477
PClassType *VMType = nullptr;
7578

7679
void (*ConstructNative)(void *);

src/common/scripting/frontend/zcc-parse.lemon

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ static void SetNodeLine(ZCC_TreeNode *name, int line)
7878
struct ClassFlagsBlock {
7979
VM_UWORD Flags;
8080
ZCC_Identifier *Replaces;
81+
ZCC_Identifier *Sealed;
8182
VersionInfo Version;
8283
};
8384

@@ -242,6 +243,7 @@ class_head(X) ::= CLASS(T) IDENTIFIER(A) class_ancestry(B) class_flags(C).
242243
head->ParentName = B;
243244
head->Flags = C.Flags;
244245
head->Replaces = C.Replaces;
246+
head->Sealed = C.Sealed;
245247
head->Version = C.Version;
246248
head->Type = nullptr;
247249
head->Symbol = nullptr;
@@ -253,13 +255,15 @@ class_ancestry(X) ::= . { X = NULL; }
253255
class_ancestry(X) ::= COLON dottable_id(A). { X = A; /*X-overwrites-A*/ }
254256

255257
%type class_flags{ClassFlagsBlock}
256-
class_flags(X) ::= . { X.Flags = 0; X.Replaces = NULL; X.Version = {0,0}; }
257-
class_flags(X) ::= class_flags(A) ABSTRACT. { X.Flags = A.Flags | ZCC_Abstract; X.Replaces = A.Replaces; }
258-
class_flags(X) ::= class_flags(A) NATIVE. { X.Flags = A.Flags | ZCC_Native; X.Replaces = A.Replaces; }
259-
class_flags(X) ::= class_flags(A) UI. { X.Flags = A.Flags | ZCC_UIFlag; X.Replaces = A.Replaces; }
260-
class_flags(X) ::= class_flags(A) PLAY. { X.Flags = A.Flags | ZCC_Play; X.Replaces = A.Replaces; }
261-
class_flags(X) ::= class_flags(A) REPLACES dottable_id(B). { X.Flags = A.Flags; X.Replaces = B; }
262-
class_flags(X) ::= class_flags(A) VERSION LPAREN STRCONST(C) RPAREN. { X.Flags = A.Flags | ZCC_Version; X.Replaces = A.Replaces; X.Version = C.String->GetChars(); }
258+
class_flags(X) ::= . { X.Flags = 0; X.Replaces = NULL; X.Version = {0,0}; X.Sealed = NULL; }
259+
class_flags(X) ::= class_flags(A) ABSTRACT. { X.Flags = A.Flags | ZCC_Abstract; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; }
260+
class_flags(X) ::= class_flags(A) FINAL. { X.Flags = A.Flags | ZCC_Final; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed;}
261+
class_flags(X) ::= class_flags(A) NATIVE. { X.Flags = A.Flags | ZCC_Native; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; }
262+
class_flags(X) ::= class_flags(A) UI. { X.Flags = A.Flags | ZCC_UIFlag; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; }
263+
class_flags(X) ::= class_flags(A) PLAY. { X.Flags = A.Flags | ZCC_Play; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; }
264+
class_flags(X) ::= class_flags(A) REPLACES dottable_id(B). { X.Flags = A.Flags; X.Replaces = B; X.Version = A.Version; X.Sealed = A.Sealed; }
265+
class_flags(X) ::= class_flags(A) VERSION LPAREN STRCONST(C) RPAREN. { X.Flags = A.Flags | ZCC_Version; X.Replaces = A.Replaces; X.Version = C.String->GetChars(); X.Sealed = A.Sealed; }
266+
class_flags(X) ::= class_flags(A) SEALED LPAREN states_opt(B) RPAREN. { X.Flags = A.Flags | ZCC_Sealed; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = B; }
263267

264268
/*----- Dottable Identifier -----*/
265269
// This can be either a single identifier or two identifiers connected by a .

src/common/scripting/frontend/zcc_compile.cpp

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -792,8 +792,14 @@ void ZCCCompiler::CreateClassTypes()
792792
PClass *parent;
793793
auto ParentName = c->cls->ParentName;
794794

795-
if (ParentName != nullptr && ParentName->SiblingNext == ParentName) parent = PClass::FindClass(ParentName->Id);
796-
else if (ParentName == nullptr) parent = RUNTIME_CLASS(DObject);
795+
if (ParentName != nullptr && ParentName->SiblingNext == ParentName)
796+
{
797+
parent = PClass::FindClass(ParentName->Id);
798+
}
799+
else if (ParentName == nullptr)
800+
{
801+
parent = RUNTIME_CLASS(DObject);
802+
}
797803
else
798804
{
799805
// The parent is a dotted name which the type system currently does not handle.
@@ -813,6 +819,15 @@ void ZCCCompiler::CreateClassTypes()
813819

814820
if (parent != nullptr && (parent->VMType != nullptr || c->NodeName() == NAME_Object))
815821
{
822+
if(parent->bFinal)
823+
{
824+
Error(c->cls, "Class '%s' cannot extend final class '%s'", FName(c->NodeName()).GetChars(), parent->TypeName.GetChars());
825+
}
826+
else if(parent->bSealed && !parent->SealedRestriction.Contains(c->NodeName()))
827+
{
828+
Error(c->cls, "Class '%s' cannot extend sealed class '%s'", FName(c->NodeName()).GetChars(), parent->TypeName.GetChars());
829+
}
830+
816831
// The parent exists, we may create a type for this class
817832
if (c->cls->Flags & ZCC_Native)
818833
{
@@ -874,6 +889,25 @@ void ZCCCompiler::CreateClassTypes()
874889
{
875890
c->Type()->mVersion = c->cls->Version;
876891
}
892+
893+
894+
if (c->cls->Flags & ZCC_Final)
895+
{
896+
c->ClassType()->bFinal = true;
897+
}
898+
899+
if (c->cls->Flags & ZCC_Sealed)
900+
{
901+
PClass * ccls = c->ClassType();
902+
ccls->bSealed = true;
903+
ZCC_Identifier * it = c->cls->Sealed;
904+
if(it) do
905+
{
906+
ccls->SealedRestriction.Push(FName(it->Id));
907+
it = (ZCC_Identifier*) it->SiblingNext;
908+
}
909+
while(it != c->cls->Sealed);
910+
}
877911
//
878912
if (mVersion >= MakeVersion(2, 4, 0))
879913
{

src/common/scripting/frontend/zcc_parser.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ static void InitTokenMap()
232232
TOKENDEF (TK_Out, ZCC_OUT);
233233
TOKENDEF (TK_Super, ZCC_SUPER);
234234
TOKENDEF (TK_Null, ZCC_NULLPTR);
235+
TOKENDEF (TK_Sealed, ZCC_SEALED);
235236
TOKENDEF ('~', ZCC_TILDE);
236237
TOKENDEF ('!', ZCC_BANG);
237238
TOKENDEF (TK_SizeOf, ZCC_SIZEOF);

src/common/scripting/frontend/zcc_parser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ enum
6464
ZCC_VirtualScope = 1 << 20,
6565
ZCC_Version = 1 << 21,
6666
ZCC_Internal = 1 << 22,
67+
ZCC_Sealed = 1 << 23,
6768
};
6869

6970
// Function parameter modifiers
@@ -251,6 +252,7 @@ struct ZCC_Class : ZCC_Struct
251252
{
252253
ZCC_Identifier *ParentName;
253254
ZCC_Identifier *Replaces;
255+
ZCC_Identifier *Sealed;
254256

255257
PClass *CType() { return static_cast<PClassType *>(Type)->Descriptor; }
256258
};

0 commit comments

Comments
 (0)