- allow struct extensions in zscript.

This is mainly for splitting the Doom specific content off the main definitions for easier reuse.
This commit is contained in:
Christoph Oelckers 2020-10-05 19:15:08 +02:00
parent 3a81c07ecf
commit f99ac8b28b
6 changed files with 70 additions and 25 deletions

View file

@ -234,6 +234,7 @@ class_head(X) ::= EXTEND CLASS(T) IDENTIFIER(A).
X = head; X = head;
} }
class_head(X) ::= CLASS(T) IDENTIFIER(A) class_ancestry(B) class_flags(C). class_head(X) ::= CLASS(T) IDENTIFIER(A) class_ancestry(B) class_flags(C).
{ {
NEW_AST_NODE(Class,head,T); NEW_AST_NODE(Class,head,T);
@ -394,6 +395,17 @@ struct_def(X) ::= STRUCT(T) IDENTIFIER(A) struct_flags(S) LBRACE opt_struct_body
X = def; X = def;
} }
struct_def(X) ::= EXTEND STRUCT(T) IDENTIFIER(A) LBRACE opt_struct_body(B) RBRACE opt_semicolon.
{
NEW_AST_NODE(Struct,def,T);
def->NodeName = A.Name();
def->Body = B;
def->Type = nullptr;
def->Symbol = nullptr;
def->Flags = ZCC_Extension;
X = def;
}
%type struct_flags{ClassFlagsBlock} %type struct_flags{ClassFlagsBlock}
struct_flags(X) ::= . { X.Flags = 0; X.Version = {0, 0}; } struct_flags(X) ::= . { X.Flags = 0; X.Version = {0, 0}; }
struct_flags(X) ::= struct_flags(A) UI. { X.Flags = A.Flags | ZCC_UIFlag; } struct_flags(X) ::= struct_flags(A) UI. { X.Flags = A.Flags | ZCC_UIFlag; }

View file

@ -377,8 +377,30 @@ void ZCCCompiler::ProcessMixin(ZCC_MixinDef *cnode, PSymbolTreeNode *treenode)
void ZCCCompiler::ProcessStruct(ZCC_Struct *cnode, PSymbolTreeNode *treenode, ZCC_Class *outer) void ZCCCompiler::ProcessStruct(ZCC_Struct *cnode, PSymbolTreeNode *treenode, ZCC_Class *outer)
{ {
Structs.Push(new ZCC_StructWork(static_cast<ZCC_Struct *>(cnode), treenode, outer)); ZCC_StructWork* cls = nullptr;
ZCC_StructWork *cls = Structs.Last();
// If this is a struct extension, put the new node directly into the existing class.
if (cnode->Flags == ZCC_Extension)
{
for (auto strct : Structs)
{
if (strct->NodeName() == cnode->NodeName)
{
cls = strct;
break;
}
}
if (cls == nullptr)
{
Error(cnode, "Struct %s cannot be found in the current translation unit.", FName(cnode->NodeName).GetChars());
return;
}
}
else
{
Structs.Push(new ZCC_StructWork(static_cast<ZCC_Struct*>(cnode), treenode, outer));
cls = Structs.Last();
}
auto node = cnode->Body; auto node = cnode->Body;
PSymbolTreeNode *childnode; PSymbolTreeNode *childnode;
@ -494,7 +516,15 @@ ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols,
ProcessClass(static_cast<ZCC_Class *>(node), tnode); ProcessClass(static_cast<ZCC_Class *>(node), tnode);
break; break;
} }
goto common;
case AST_Struct: case AST_Struct:
if (static_cast<ZCC_Class*>(node)->Flags == ZCC_Extension)
{
ProcessStruct(static_cast<ZCC_Struct*>(node), tnode, nullptr);
break;
}
common:
case AST_ConstantDef: case AST_ConstantDef:
case AST_Enum: case AST_Enum:
if ((tnode = AddTreeNode(static_cast<ZCC_NamedNode *>(node)->NodeName, node, GlobalTreeNodes))) if ((tnode = AddTreeNode(static_cast<ZCC_NamedNode *>(node)->NodeName, node, GlobalTreeNodes)))

View file

@ -1,5 +1,6 @@
version "4.5" version "4.5"
#include "zscript/base.zs" #include "zscript/base.zs"
#include "zscript/doombase.zs"
#include "zscript/sounddata.zs" #include "zscript/sounddata.zs"
#include "zscript/mapdata.zs" #include "zscript/mapdata.zs"
#include "zscript/dynarrays.zs" #include "zscript/dynarrays.zs"

View file

@ -2,22 +2,13 @@
struct _ native // These are the global variables, the struct is only here to avoid extending the parser for this. struct _ native // These are the global variables, the struct is only here to avoid extending the parser for this.
{ {
native readonly Array<class> AllClasses; native readonly Array<class> AllClasses;
native readonly Array<class<Actor> > AllActorClasses;
native readonly Array<@PlayerClass> PlayerClasses;
native readonly Array<@PlayerSkin> PlayerSkins;
native readonly Array<@Team> Teams;
native int validcount;
native readonly bool multiplayer; native readonly bool multiplayer;
native @KeyBindings Bindings; native @KeyBindings Bindings;
native @KeyBindings AutomapBindings; native @KeyBindings AutomapBindings;
native play @DehInfo deh;
native readonly @GameInfoStruct gameinfo; native readonly @GameInfoStruct gameinfo;
native readonly ui bool netgame; native readonly ui bool netgame;
native readonly bool automapactive;
native readonly uint gameaction; native readonly uint gameaction;
native readonly int gamestate; native readonly int gamestate;
native readonly TextureID skyflatnum;
native readonly Font smallfont; native readonly Font smallfont;
native readonly Font smallfont2; native readonly Font smallfont2;
native readonly Font bigfont; native readonly Font bigfont;
@ -38,27 +29,14 @@ struct _ native // These are the global variables, the struct is only here to av
native readonly int CleanHeight_1; native readonly int CleanHeight_1;
native ui int menuactive; native ui int menuactive;
native readonly @FOptionMenuSettings OptionMenuSettings; native readonly @FOptionMenuSettings OptionMenuSettings;
native readonly int gametic;
native readonly bool demoplayback; native readonly bool demoplayback;
native ui int BackbuttonTime; native ui int BackbuttonTime;
native ui float BackbuttonAlpha; native ui float BackbuttonAlpha;
native readonly int Net_Arbitrator;
native ui BaseStatusBar StatusBar;
native readonly Weapon WP_NOCHANGE;
deprecated("3.8", "Use Actor.isFrozen() or Level.isFrozen() instead") native readonly bool globalfreeze;
native int LocalViewPitch;
native readonly @MusPlayingInfo musplaying; native readonly @MusPlayingInfo musplaying;
native readonly bool generic_ui; native readonly bool generic_ui;
native readonly int GameTicRate; native readonly int GameTicRate;
native MenuCustomize menuCustomizer; native MenuCustomize menuCustomizer;
// sandbox state in multi-level setups:
native play @PlayerInfo players[MAXPLAYERS];
native readonly bool playeringame[MAXPLAYERS];
native readonly int consoleplayer; native readonly int consoleplayer;
native play LevelLocals Level;
} }
struct MusPlayingInfo native struct MusPlayingInfo native

View file

@ -0,0 +1,24 @@
extend struct _
{
native readonly Array<class<Actor> > AllActorClasses;
native readonly Array<@PlayerClass> PlayerClasses;
native readonly Array<@PlayerSkin> PlayerSkins;
native readonly Array<@Team> Teams;
native int validcount;
native play @DehInfo deh;
native readonly bool automapactive;
native readonly TextureID skyflatnum;
native readonly int gametic;
native readonly int Net_Arbitrator;
native ui BaseStatusBar StatusBar;
native readonly Weapon WP_NOCHANGE;
deprecated("3.8", "Use Actor.isFrozen() or Level.isFrozen() instead") native readonly bool globalfreeze;
native int LocalViewPitch;
// sandbox state in multi-level setups:
native play @PlayerInfo players[MAXPLAYERS];
native readonly bool playeringame[MAXPLAYERS];
native play LevelLocals Level;
}