From 6926875b213569482a9f2c3c85fb89ccd478091a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 14 Mar 2017 20:22:37 +0100 Subject: [PATCH] - 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. --- src/memarena.cpp | 17 +++++++++++++++++ src/memarena.h | 1 + src/namedef.h | 2 ++ src/scripting/zscript/zcc-parse.lemon | 6 ++++-- src/scripting/zscript/zcc_compile.cpp | 8 ++++++++ src/scripting/zscript/zcc_compile.h | 1 + src/scripting/zscript/zcc_parser.cpp | 19 +++++++++++++++++++ 7 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/memarena.cpp b/src/memarena.cpp index 88b2c8c4c..0a90d9e16 100644 --- a/src/memarena.cpp +++ b/src/memarena.cpp @@ -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 diff --git a/src/memarena.h b/src/memarena.h index 14b735eda..7b3b34be4 100644 --- a/src/memarena.h +++ b/src/memarena.h @@ -47,6 +47,7 @@ public: void FreeAll(); void FreeAllBlocks(); void DumpInfo(); + void DumpData(FILE *f); protected: struct Block; diff --git a/src/namedef.h b/src/namedef.h index 28e2ff8c4..f4d123a58 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -643,6 +643,8 @@ xx(floorglowheight) xx(ceilingglowcolor) xx(ceilingglowheight) xx(fogdensity) +xx(Static) +xx(Staticconst) // USDF keywords xx(Amount) diff --git a/src/scripting/zscript/zcc-parse.lemon b/src/scripting/zscript/zcc-parse.lemon index 8fe863dea..aa618fa94 100644 --- a/src/scripting/zscript/zcc-parse.lemon +++ b/src/scripting/zscript/zcc-parse.lemon @@ -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; diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index 11157a85b..6783ba86b 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -197,6 +197,10 @@ void ZCCCompiler::ProcessClass(ZCC_Class *cnode, PSymbolTreeNode *treenode) cls->Defaults.Push(static_cast(node)); break; + case AST_StaticArrayStatement: + cls->Arrays.Push(static_cast(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(node)); + break; + default: assert(0 && "Unhandled AST node type"); break; diff --git a/src/scripting/zscript/zcc_compile.h b/src/scripting/zscript/zcc_compile.h index 8fe4ca36f..5566eec64 100644 --- a/src/scripting/zscript/zcc_compile.h +++ b/src/scripting/zscript/zcc_compile.h @@ -22,6 +22,7 @@ struct ZCC_StructWork TArray Constants; TArray Fields; TArray Functions; + TArray Arrays; ZCC_StructWork() { diff --git a/src/scripting/zscript/zcc_parser.cpp b/src/scripting/zscript/zcc_parser.cpp index 1f0cb0242..e843b70de 100644 --- a/src/scripting/zscript/zcc_parser.cpp +++ b/src/scripting/zscript/zcc_parser.cpp @@ -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)