- allow parsing of static constant arrays in class scope.

This is only the parsing part, the arrays are not yet getting evaluated.
This required quite a hacky workaround because the gramma couldn't be made to accept the rule. The scanner will check if a 'static' token is immediately followed by a 'const' token and will combine both to a new 'staticconst' token that does not create conflicts with other rules.
This commit is contained in:
Christoph Oelckers 2017-03-14 20:22:37 +01:00
parent 539af96b8e
commit 6926875b21
7 changed files with 52 additions and 2 deletions

View file

@ -166,6 +166,23 @@ void FMemArena::DumpInfo()
Printf("%zu bytes allocated, %zu bytes in use\n", allocated, used); Printf("%zu bytes allocated, %zu bytes in use\n", allocated, used);
} }
//==========================================================================
//
// FMemArena :: DumpInfo
//
// Dumps the arena to a file (for debugging)
//
//==========================================================================
void FMemArena::DumpData(FILE *f)
{
for (auto block = TopBlock; block != NULL; block = block->NextBlock)
{
auto used = BlockSize - ((char*)block->Limit - (char*)block->Avail);
fwrite(block, 1, used, f);
}
}
//========================================================================== //==========================================================================
// //
// FMemArena :: FreeBlockChain // FMemArena :: FreeBlockChain

View file

@ -47,6 +47,7 @@ public:
void FreeAll(); void FreeAll();
void FreeAllBlocks(); void FreeAllBlocks();
void DumpInfo(); void DumpInfo();
void DumpData(FILE *f);
protected: protected:
struct Block; struct Block;

View file

@ -643,6 +643,8 @@ xx(floorglowheight)
xx(ceilingglowcolor) xx(ceilingglowcolor)
xx(ceilingglowheight) xx(ceilingglowheight)
xx(fogdensity) xx(fogdensity)
xx(Static)
xx(Staticconst)
// USDF keywords // USDF keywords
xx(Amount) xx(Amount)

View file

@ -287,6 +287,8 @@ 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) ::= default_def(A). { X = A; /*X-overwrites-A*/ }
class_member(X) ::= const_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) ::= property_def(A). { X = A; /*X-overwrites-A*/ }
class_member(X) ::= staticarray_statement(A). { X = A; /*X-overwrites-A*/ }
/*----- Struct Definition -----*/ /*----- Struct Definition -----*/
/* Structs can define variables and enums. */ /* Structs can define variables and enums. */
@ -1692,7 +1694,7 @@ statement(X) ::= staticarray_statement(A). { X = A; /*X-overwrites-A*/ }
%type staticarray_statement{ZCC_StaticArrayStatement *} %type staticarray_statement{ZCC_StaticArrayStatement *}
staticarray_statement(X) ::= STATIC CONST type(A) IDENTIFIER(B) LBRACKET RBRACKET EQ LBRACE expr_list(C) RBRACE. staticarray_statement(X) ::= STATICCONST type(A) IDENTIFIER(B) LBRACKET RBRACKET EQ LBRACE expr_list(C) RBRACE SEMICOLON.
{ {
NEW_AST_NODE(StaticArrayStatement, stmt, A); NEW_AST_NODE(StaticArrayStatement, stmt, A);
stmt->Type = A; stmt->Type = A;
@ -1701,7 +1703,7 @@ staticarray_statement(X) ::= STATIC CONST type(A) IDENTIFIER(B) LBRACKET RBRACKE
X = stmt; X = stmt;
} }
staticarray_statement(X) ::= STATIC CONST type(A) LBRACKET RBRACKET IDENTIFIER(B) EQ LBRACE expr_list(C) RBRACE. staticarray_statement(X) ::= STATICCONST type(A) LBRACKET RBRACKET IDENTIFIER(B) EQ LBRACE expr_list(C) RBRACE SEMICOLON.
{ {
NEW_AST_NODE(StaticArrayStatement, stmt, A); NEW_AST_NODE(StaticArrayStatement, stmt, A);
stmt->Type = A; stmt->Type = A;

View file

@ -197,6 +197,10 @@ void ZCCCompiler::ProcessClass(ZCC_Class *cnode, PSymbolTreeNode *treenode)
cls->Defaults.Push(static_cast<ZCC_Default *>(node)); cls->Defaults.Push(static_cast<ZCC_Default *>(node));
break; break;
case AST_StaticArrayStatement:
cls->Arrays.Push(static_cast<ZCC_StaticArrayStatement *>(node));
break;
default: default:
assert(0 && "Unhandled AST node type"); assert(0 && "Unhandled AST node type");
break; break;
@ -260,6 +264,10 @@ void ZCCCompiler::ProcessStruct(ZCC_Struct *cnode, PSymbolTreeNode *treenode, ZC
enumType = nullptr; enumType = nullptr;
break; break;
case AST_StaticArrayStatement:
cls->Arrays.Push(static_cast<ZCC_StaticArrayStatement *>(node));
break;
default: default:
assert(0 && "Unhandled AST node type"); assert(0 && "Unhandled AST node type");
break; break;

View file

@ -22,6 +22,7 @@ struct ZCC_StructWork
TArray<ZCC_ConstantDef *> Constants; TArray<ZCC_ConstantDef *> Constants;
TArray<ZCC_VarDeclarator *> Fields; TArray<ZCC_VarDeclarator *> Fields;
TArray<ZCC_FuncDeclarator *> Functions; TArray<ZCC_FuncDeclarator *> Functions;
TArray<ZCC_StaticArrayStatement *> Arrays;
ZCC_StructWork() ZCC_StructWork()
{ {

View file

@ -305,6 +305,25 @@ static void ParseSingleFile(FScanner *pSC, const char *filename, int lump, void
tokentype = ZCC_NWS; tokentype = ZCC_NWS;
break; break;
case TK_Static:
sc.MustGetAnyToken();
// The oh so wonderful grammar has problems with the 'const' token thanks to the overly broad rule for constants,
// which effectively prevents use of this token nearly anywhere else. So in order to get 'static const' through
// on the class/struct level we have to muck around with the token type here so that both words get combined into
// a single token that doesn't make the grammar throw a fit.
if (sc.TokenType == TK_Const)
{
tokentype = ZCC_STATICCONST;
value.Int = NAME_Staticconst;
}
else
{
tokentype = ZCC_STATIC;
value.Int = NAME_Static;
sc.UnGet();
}
break;
default: default:
TokenMapEntry *zcctoken = TokenMap.CheckKey(sc.TokenType); TokenMapEntry *zcctoken = TokenMap.CheckKey(sc.TokenType);
if (zcctoken != nullptr) if (zcctoken != nullptr)