- allow defining flags in the script declaration of a class and do that for Weapon.
This commit is contained in:
parent
b5c4ab8c47
commit
70d3c31551
14 changed files with 207 additions and 35 deletions
|
|
@ -348,6 +348,17 @@ static void PrintProperty(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintFlagDef(FLispString &out, ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_FlagDef *snode = (ZCC_FlagDef *)node;
|
||||
out.Break();
|
||||
out.Open("flagdef");
|
||||
out.AddName(snode->NodeName);
|
||||
out.AddName(snode->RefName);
|
||||
out.AddInt(snode->BitValue);
|
||||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintStaticArrayState(FLispString &out, ZCC_TreeNode *node)
|
||||
{
|
||||
auto *snode = (ZCC_StaticArrayStatement *)node;
|
||||
|
|
@ -959,6 +970,7 @@ void (* const TreeNodePrinter[NUM_AST_NODE_TYPES])(FLispString &, ZCC_TreeNode *
|
|||
PrintExprClassCast,
|
||||
PrintStaticArrayState,
|
||||
PrintProperty,
|
||||
PrintFlagDef,
|
||||
};
|
||||
|
||||
FString ZCC_PrintAST(ZCC_TreeNode *root)
|
||||
|
|
|
|||
|
|
@ -313,6 +313,7 @@ class_innards(X) ::= . { X = NULL; }
|
|||
class_innards(X) ::= class_innards(X) class_member(B). { SAFE_APPEND(X,B); }
|
||||
|
||||
%type property_def{ZCC_Property *}
|
||||
%type flag_def{ZCC_FlagDef *}
|
||||
%type struct_def{ZCC_Struct *}
|
||||
%type enum_def {ZCC_Enum *}
|
||||
%type states_def {ZCC_States *}
|
||||
|
|
@ -325,6 +326,7 @@ class_member(X) ::= states_def(A). { X = A; /*X-overwrites-A*/ }
|
|||
class_member(X) ::= default_def(A). { X = A; /*X-overwrites-A*/ }
|
||||
class_member(X) ::= const_def(A). { X = A; /*X-overwrites-A*/ }
|
||||
class_member(X) ::= property_def(A). { X = A; /*X-overwrites-A*/ }
|
||||
class_member(X) ::= flag_def(A). { X = A; /*X-overwrites-A*/ }
|
||||
class_member(X) ::= staticarray_statement(A). { X = A; /*X-overwrites-A*/ }
|
||||
|
||||
|
||||
|
|
@ -344,6 +346,16 @@ property_def(X) ::= PROPERTY(T) IDENTIFIER(A) COLON identifier_list(B) SEMICOLON
|
|||
X = def;
|
||||
}
|
||||
|
||||
flag_def(X) ::= FLAGDEF(T) IDENTIFIER(A) COLON IDENTIFIER(B) COMMA INTCONST(C) SEMICOLON.
|
||||
{
|
||||
NEW_AST_NODE(FlagDef,def,T);
|
||||
def->NodeName = A.Name();
|
||||
def->RefName = B.Name();
|
||||
def->BitValue = C.Int;
|
||||
X = def;
|
||||
}
|
||||
|
||||
|
||||
identifier_list(X) ::= IDENTIFIER(A).
|
||||
{
|
||||
NEW_AST_NODE(Identifier,id,A);
|
||||
|
|
|
|||
|
|
@ -175,6 +175,10 @@ void ZCCCompiler::ProcessClass(ZCC_Class *cnode, PSymbolTreeNode *treenode)
|
|||
cls->Properties.Push(static_cast<ZCC_Property *>(node));
|
||||
break;
|
||||
|
||||
case AST_FlagDef:
|
||||
cls->FlagDefs.Push(static_cast<ZCC_FlagDef*>(node));
|
||||
break;
|
||||
|
||||
case AST_VarDeclarator:
|
||||
cls->Fields.Push(static_cast<ZCC_VarDeclarator *>(node));
|
||||
break;
|
||||
|
|
@ -1375,6 +1379,10 @@ void ZCCCompiler::CompileAllProperties()
|
|||
{
|
||||
if (c->Properties.Size() > 0)
|
||||
CompileProperties(c->ClassType(), c->Properties, c->Type()->TypeName);
|
||||
|
||||
if (c->FlagDefs.Size() > 0)
|
||||
CompileFlagDefs(c->ClassType(), c->FlagDefs, c->Type()->TypeName);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1415,20 +1423,83 @@ bool ZCCCompiler::CompileProperties(PClass *type, TArray<ZCC_Property *> &Proper
|
|||
fields.Push(f);
|
||||
id = (ZCC_Identifier*)id->SiblingNext;
|
||||
} while (id != p->Body);
|
||||
|
||||
FString qualifiedname;
|
||||
// Store the full qualified name and prepend some 'garbage' to the name so that no conflicts with other symbol types can happen.
|
||||
// All these will be removed from the symbol table after the compiler finishes to free up the allocated space.
|
||||
FName name = FName(p->NodeName);
|
||||
if (prefix == NAME_None) qualifiedname.Format("@property@%s", name.GetChars());
|
||||
else qualifiedname.Format("@property@%s.%s", prefix.GetChars(), name.GetChars());
|
||||
|
||||
fields.ShrinkToFit();
|
||||
if (!type->VMType->Symbols.AddSymbol(Create<PProperty>(qualifiedname, fields)))
|
||||
{
|
||||
Error(id, "Unable to add property %s to class %s", FName(p->NodeName).GetChars(), type->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FString qualifiedname;
|
||||
// Store the full qualified name and prepend some 'garbage' to the name so that no conflicts with other symbol types can happen.
|
||||
// All these will be removed from the symbol table after the compiler finishes to free up the allocated space.
|
||||
FName name = FName(p->NodeName);
|
||||
if (prefix == NAME_None) qualifiedname.Format("@property@%s", name.GetChars());
|
||||
else qualifiedname.Format("@property@%s.%s", prefix.GetChars(), name.GetChars());
|
||||
//==========================================================================
|
||||
//
|
||||
// ZCCCompiler :: CompileProperties
|
||||
//
|
||||
// builds the internal structure of a single class or struct
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
fields.ShrinkToFit();
|
||||
if (!type->VMType->Symbols.AddSymbol(Create<PProperty>(qualifiedname, fields)))
|
||||
bool ZCCCompiler::CompileFlagDefs(PClass *type, TArray<ZCC_FlagDef *> &Properties, FName prefix)
|
||||
{
|
||||
if (!type->IsDescendantOf(RUNTIME_CLASS(AActor)))
|
||||
{
|
||||
Error(Properties[0], "Flags can only be defined for actors");
|
||||
return false;
|
||||
}
|
||||
for (auto p : Properties)
|
||||
{
|
||||
PField *field;
|
||||
FName referenced = FName(p->RefName);
|
||||
|
||||
if (FName(p->NodeName) == FName("prefix") && Wads.GetLumpFile(Lump) == 0)
|
||||
{
|
||||
Error(id, "Unable to add property %s to class %s", FName(p->NodeName).GetChars(), type->TypeName.GetChars());
|
||||
// only for internal definitions: Allow setting a prefix. This is only for compatiblity with the old DECORATE property parser, but not for general use.
|
||||
prefix = referenced;
|
||||
}
|
||||
else
|
||||
{
|
||||
field = dyn_cast<PField>(type->FindSymbol(referenced, true));
|
||||
if (field == nullptr)
|
||||
{
|
||||
Error(p, "Variable %s not found in %s", referenced.GetChars(), type->TypeName.GetChars());
|
||||
}
|
||||
if (!field->Type->isInt() || field->Type->Size != 4)
|
||||
{
|
||||
Error(p, "Variable %s in %s must have a size of 4 bytes for use as flag storage", referenced.GetChars(), type->TypeName.GetChars());
|
||||
}
|
||||
|
||||
|
||||
FString qualifiedname;
|
||||
// Store the full qualified name and prepend some 'garbage' to the name so that no conflicts with other symbol types can happen.
|
||||
// All these will be removed from the symbol table after the compiler finishes to free up the allocated space.
|
||||
FName name = FName(p->NodeName);
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (i == 0) qualifiedname.Format("@flagdef@%s", name.GetChars());
|
||||
else
|
||||
{
|
||||
if (prefix == NAME_None) continue;
|
||||
qualifiedname.Format("@flagdef@%s.%s", prefix.GetChars(), name.GetChars());
|
||||
}
|
||||
|
||||
if (!type->VMType->Symbols.AddSymbol(Create<PPropFlag>(qualifiedname, field, p->BitValue, i == 0 && prefix != NAME_None)))
|
||||
{
|
||||
Error(p, "Unable to add flag definition %s to class %s", FName(p->NodeName).GetChars(), type->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
|
||||
type->VMType->AddNativeField(FStringf("b%s", name.GetChars()), TypeSInt32, field->Offset, 0, 1 << p->BitValue);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ struct ZCC_ClassWork : public ZCC_StructWork
|
|||
TArray<ZCC_Default *> Defaults;
|
||||
TArray<ZCC_States *> States;
|
||||
TArray<ZCC_Property *> Properties;
|
||||
TArray<ZCC_FlagDef *> FlagDefs;
|
||||
|
||||
ZCC_ClassWork(ZCC_Class * s, PSymbolTreeNode *n)
|
||||
{
|
||||
|
|
@ -110,6 +111,7 @@ private:
|
|||
bool CompileFields(PContainerType *type, TArray<ZCC_VarDeclarator *> &Fields, PClass *Outer, PSymbolTable *TreeNodes, bool forstruct, bool hasnativechildren = false);
|
||||
void CompileAllProperties();
|
||||
bool CompileProperties(PClass *type, TArray<ZCC_Property *> &Properties, FName prefix);
|
||||
bool CompileFlagDefs(PClass *type, TArray<ZCC_FlagDef *> &FlagDefs, FName prefix);
|
||||
FString FlagsToString(uint32_t flags);
|
||||
PType *DetermineType(PType *outertype, ZCC_TreeNode *field, FName name, ZCC_Type *ztype, bool allowarraytypes, bool formember);
|
||||
PType *ResolveArraySize(PType *baseType, ZCC_Expression *arraysize, PContainerType *cls);
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ static void InitTokenMap()
|
|||
TOKENDEF ('}', ZCC_RBRACE);
|
||||
TOKENDEF (TK_Struct, ZCC_STRUCT);
|
||||
TOKENDEF (TK_Property, ZCC_PROPERTY);
|
||||
TOKENDEF (TK_FlagDef, ZCC_FLAGDEF);
|
||||
TOKENDEF (TK_Transient, ZCC_TRANSIENT);
|
||||
TOKENDEF (TK_Enum, ZCC_ENUM);
|
||||
TOKENDEF2(TK_SByte, ZCC_SBYTE, NAME_sByte);
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ enum EZCCTreeNodeType
|
|||
AST_ClassCast,
|
||||
AST_StaticArrayStatement,
|
||||
AST_Property,
|
||||
AST_FlagDef,
|
||||
|
||||
NUM_AST_NODE_TYPES
|
||||
};
|
||||
|
|
@ -226,6 +227,12 @@ struct ZCC_Property : ZCC_NamedNode
|
|||
ZCC_TreeNode *Body;
|
||||
};
|
||||
|
||||
struct ZCC_FlagDef : ZCC_NamedNode
|
||||
{
|
||||
ENamedName RefName;
|
||||
int BitValue;
|
||||
};
|
||||
|
||||
struct ZCC_Class : ZCC_Struct
|
||||
{
|
||||
ZCC_Identifier *ParentName;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue