- 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);
}
//==========================================================================
//
// 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

View File

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

View File

@ -643,6 +643,8 @@ xx(floorglowheight)
xx(ceilingglowcolor)
xx(ceilingglowheight)
xx(fogdensity)
xx(Static)
xx(Staticconst)
// USDF keywords
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) ::= const_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 -----*/
/* 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 *}
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);
stmt->Type = A;
@ -1701,7 +1703,7 @@ staticarray_statement(X) ::= STATIC CONST type(A) IDENTIFIER(B) LBRACKET RBRACKE
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);
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));
break;
case AST_StaticArrayStatement:
cls->Arrays.Push(static_cast<ZCC_StaticArrayStatement *>(node));
break;
default:
assert(0 && "Unhandled AST node type");
break;
@ -260,6 +264,10 @@ void ZCCCompiler::ProcessStruct(ZCC_Struct *cnode, PSymbolTreeNode *treenode, ZC
enumType = nullptr;
break;
case AST_StaticArrayStatement:
cls->Arrays.Push(static_cast<ZCC_StaticArrayStatement *>(node));
break;
default:
assert(0 && "Unhandled AST node type");
break;

View File

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

View File

@ -305,6 +305,25 @@ static void ParseSingleFile(FScanner *pSC, const char *filename, int lump, void
tokentype = ZCC_NWS;
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:
TokenMapEntry *zcctoken = TokenMap.CheckKey(sc.TokenType);
if (zcctoken != nullptr)