From 2cb5839c1133a44378ff277e0bc2d6d340aa2abf Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Oct 2016 12:15:25 +0200 Subject: [PATCH] - count errors in the parser and abort afterward if there were some. - use FScriptPosition's error counter throughout the compiler so that there is only one counter for everything, not two. Parts of the compiler use FScriptPosition, so this is easier to handle than having a separate counter in the compiler class. It also avoids having to pass the compiler object to any function where an error may be output. The TreeNodes contain sufficient data to be converted to an FScriptPosition and using that for error message formatting. --- src/CMakeLists.txt | 1 + src/sc_man.cpp | 2 ++ src/sc_man.h | 2 ++ src/scripting/thingdef.cpp | 1 + src/scripting/zscript/zcc-parse.lemon | 1 + src/scripting/zscript/zcc_compile.cpp | 11 +++++------ src/scripting/zscript/zcc_compile.h | 2 -- src/scripting/zscript/zcc_parser.cpp | 20 ++++++++++++++++++++ 8 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ab9306447..545400b1c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1248,6 +1248,7 @@ set (PCH_SOURCES scripting/thingdef_data.cpp scripting/thingdef_properties.cpp scripting/codegeneration/codegen.cpp + scripting/codegeneration/functioncalls.cpp scripting/decorate/olddecorations.cpp scripting/decorate/thingdef_exp.cpp scripting/decorate/thingdef_parse.cpp diff --git a/src/sc_man.cpp b/src/sc_man.cpp index 97f384f3d..f48d6b461 100644 --- a/src/sc_man.cpp +++ b/src/sc_man.cpp @@ -1006,6 +1006,7 @@ void FScanner::CheckOpen() // //========================================================================== int FScriptPosition::ErrorCounter; +int FScriptPosition::WarnCounter; bool FScriptPosition::StrictErrors; // makes all OPTERRPR messages real errors. FScriptPosition::FScriptPosition(const FScriptPosition &other) @@ -1072,6 +1073,7 @@ void FScriptPosition::Message (int severity, const char *message, ...) const return; case MSG_WARNING: + WarnCounter++; type = "warning"; color = TEXTCOLOR_YELLOW; break; diff --git a/src/sc_man.h b/src/sc_man.h index c319a7a2f..5eeacd892 100644 --- a/src/sc_man.h +++ b/src/sc_man.h @@ -139,6 +139,7 @@ enum struct FScriptPosition { + static int WarnCounter; static int ErrorCounter; static bool StrictErrors; FString FileName; @@ -155,6 +156,7 @@ struct FScriptPosition void Message(int severity, const char *message,...) const; static void ResetErrorCounter() { + WarnCounter = 0; ErrorCounter = 0; } }; diff --git a/src/scripting/thingdef.cpp b/src/scripting/thingdef.cpp index 1ed0ea910..f62997816 100644 --- a/src/scripting/thingdef.cpp +++ b/src/scripting/thingdef.cpp @@ -127,6 +127,7 @@ void LoadActors () InitThingdef(); ParseScripts(); + ParseAllDecorate(); FunctionBuildList.Build(); diff --git a/src/scripting/zscript/zcc-parse.lemon b/src/scripting/zscript/zcc-parse.lemon index cd1cbce14..78a4d29ea 100644 --- a/src/scripting/zscript/zcc-parse.lemon +++ b/src/scripting/zscript/zcc-parse.lemon @@ -99,6 +99,7 @@ static void SetNodeLine(ZCC_TreeNode *name, int line) } } stat->sc->ScriptMessage("%s\n%s\n", unexpected.GetChars(), expecting.GetChars()); + FScriptPosition::ErrorCounter++; } %parse_accept { DPrintf(DMSG_SPAMMY, "Input accepted\n"); } %parse_failure { /**failed = true;*/ } diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index 2016659fa..f2f7b4d4b 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -203,8 +203,9 @@ void ZCCCompiler::ProcessStruct(ZCC_Struct *cnode, PSymbolTreeNode *treenode, ZC //========================================================================== ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols, PSymbolTable &_outsymbols) - : Outer(_outer), GlobalTreeNodes(&_symbols), OutputSymbols(&_outsymbols), AST(ast), ErrorCount(0), WarnCount(0) + : Outer(_outer), GlobalTreeNodes(&_symbols), OutputSymbols(&_outsymbols), AST(ast) { + FScriptPosition::ResetErrorCounter(); // Group top-level nodes by type if (ast.TopNode != NULL) { @@ -320,7 +321,7 @@ void ZCCCompiler::Warn(ZCC_TreeNode *node, const char *msg, ...) MessageV(node, TEXTCOLOR_ORANGE, msg, argptr); va_end(argptr); - WarnCount++; + FScriptPosition::WarnCounter++; } //========================================================================== @@ -338,7 +339,7 @@ void ZCCCompiler::Error(ZCC_TreeNode *node, const char *msg, ...) MessageV(node, TEXTCOLOR_RED, msg, argptr); va_end(argptr); - ErrorCount++; + FScriptPosition::ErrorCounter++; } //========================================================================== @@ -376,7 +377,7 @@ int ZCCCompiler::Compile() InitDefaults(); InitFunctions(); CompileStates(); - return ErrorCount; + return FScriptPosition::ErrorCounter; } //========================================================================== @@ -1678,7 +1679,6 @@ void ZCCCompiler::DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *proper } } // call the handler - FScriptPosition::ErrorCounter = 0; try { prop->Handler(defaults, bag.Info, bag, ¶ms[0]); @@ -1687,7 +1687,6 @@ void ZCCCompiler::DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *proper { Error(property, "%s", error.GetMessage()); } - ErrorCount += FScriptPosition::ErrorCounter; } //========================================================================== diff --git a/src/scripting/zscript/zcc_compile.h b/src/scripting/zscript/zcc_compile.h index 2ca00459a..12e570330 100644 --- a/src/scripting/zscript/zcc_compile.h +++ b/src/scripting/zscript/zcc_compile.h @@ -146,8 +146,6 @@ private: PSymbolTable *GlobalTreeNodes; PSymbolTable *OutputSymbols; ZCC_AST * - int ErrorCount; - int WarnCount; }; void ZCC_InitConversions(); diff --git a/src/scripting/zscript/zcc_parser.cpp b/src/scripting/zscript/zcc_parser.cpp index b803b4158..c3f75b2b0 100644 --- a/src/scripting/zscript/zcc_parser.cpp +++ b/src/scripting/zscript/zcc_parser.cpp @@ -39,6 +39,7 @@ #include "cmdlib.h" #include "m_alloc.h" #include "i_system.h" +#include "v_text.h" #include "zcc_parser.h" #include "zcc_compile.h" @@ -323,6 +324,12 @@ static void DoParse(int lumpnum) ZCCParse(parser, 0, value, &state); ZCCParseFree(parser, free); + // If the parser fails, there is no point starting the compiler, because it'd only flood the output with endless errors. + if (FScriptPosition::ErrorCounter > 0) + { + I_Error("%d errors while parsing %s", FScriptPosition::ErrorCounter, Wads.GetLumpFullPath(lumpnum)); + } + { // Make a dump of the AST before running the compiler for diagnostic purposes. #ifdef _DEBUG @@ -347,11 +354,24 @@ static void DoParse(int lumpnum) symtable.SetName("Global_Node"); ZCCCompiler cc(state, NULL, symtable, GlobalSymbols); cc.Compile(); + + if (FScriptPosition::ErrorCounter > 0) + { + // Abort if the compiler produced any errors. Also do not compile further lumps, because they very likely miss some stuff. + I_Error("%d errors, %d warnings while compiling %s", FScriptPosition::ErrorCounter, FScriptPosition::WarnCounter, Wads.GetLumpFullPath(lumpnum)); + } + else if (FScriptPosition::WarnCounter > 0) + { + // If we got warnings, but no errors, print the information but continue. + Printf(TEXTCOLOR_ORANGE, "%d warnings while compiling %s", FScriptPosition::WarnCounter, Wads.GetLumpFullPath(lumpnum)); + } + } void ParseScripts() { int lump, lastlump = 0; + FScriptPosition::ResetErrorCounter(); while ((lump = Wads.FindLump("ZSCRIPT", &lastlump)) != -1) { DoParse(lump);