From 68c3f42a53f9f1ae1678884e0425f57efaf5d7a5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 23 Jan 2017 01:10:40 +0100 Subject: [PATCH] - no more Simplify for global constants as well. --- src/dobjtype.h | 2 +- src/sc_man.cpp | 1 + src/sc_man.h | 2 +- src/scripting/codegeneration/codegen.cpp | 51 ++++++++------ src/scripting/zscript/zcc_compile.cpp | 86 ++++++++++++++++++------ src/scripting/zscript/zcc_compile.h | 9 ++- 6 files changed, 105 insertions(+), 46 deletions(-) diff --git a/src/dobjtype.h b/src/dobjtype.h index d38c42c58..96c1a05e0 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -1043,7 +1043,7 @@ class PSymbolConstString : public PSymbolConst public: FString Str; - PSymbolConstString(FName name, FString &str) : PSymbolConst(name, TypeString), Str(str) {} + PSymbolConstString(FName name, const FString &str) : PSymbolConst(name, TypeString), Str(str) {} PSymbolConstString() {} }; diff --git a/src/sc_man.cpp b/src/sc_man.cpp index b05349d00..5f944735a 100644 --- a/src/sc_man.cpp +++ b/src/sc_man.cpp @@ -1008,6 +1008,7 @@ void FScanner::CheckOpen() int FScriptPosition::ErrorCounter; int FScriptPosition::WarnCounter; bool FScriptPosition::StrictErrors; // makes all OPTERROR messages real errors. +bool FScriptPosition::errorout; // call I_Error instead of printing the error itself. FScriptPosition::FScriptPosition(const FScriptPosition &other) { diff --git a/src/sc_man.h b/src/sc_man.h index ded92b398..3347fe26a 100644 --- a/src/sc_man.h +++ b/src/sc_man.h @@ -144,9 +144,9 @@ struct FScriptPosition static int WarnCounter; static int ErrorCounter; static bool StrictErrors; + static bool errorout; FString FileName; int ScriptLine; - bool errorout = false; FScriptPosition() { diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index e5a0470b0..6065050a9 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -5829,7 +5829,7 @@ FxExpression *FxIdentifier::ResolveMember(FCompileContext &ctx, PStruct *classct return x->Resolve(ctx); } - if ((sym = objtype->Symbols.FindSymbolInTable(Identifier, symtbl)) != nullptr) + if (objtype != nullptr && (sym = objtype->Symbols.FindSymbolInTable(Identifier, symtbl)) != nullptr) { if (sym->IsKindOf(RUNTIME_CLASS(PSymbolConst))) { @@ -7168,7 +7168,6 @@ static bool CheckArgSize(FName fname, FArgumentList &args, int min, int max, FSc FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx) { - ABORT(ctx.Class); bool error = false; for (auto a : ArgList) @@ -7181,27 +7180,30 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx) } } - PFunction *afd = FindClassMemberFunction(ctx.Class, ctx.Class, MethodName, ScriptPosition, &error); - - if (afd != nullptr) + if (ctx.Class != nullptr) { - if (ctx.Function == nullptr) - { - ScriptPosition.Message(MSG_ERROR, "Unable to call function %s from constant declaration", MethodName.GetChars()); - delete this; - return nullptr; - } + PFunction *afd = FindClassMemberFunction(ctx.Class, ctx.Class, MethodName, ScriptPosition, &error); - if (!CheckFunctionCompatiblity(ScriptPosition, ctx.Function, afd)) + if (afd != nullptr) { - delete this; - return nullptr; - } + if (ctx.Function == nullptr) + { + ScriptPosition.Message(MSG_ERROR, "Unable to call function %s from constant declaration", MethodName.GetChars()); + delete this; + return nullptr; + } - auto self = (afd->Variants[0].Flags & VARF_Method)? new FxSelf(ScriptPosition) : nullptr; - auto x = new FxVMFunctionCall(self, afd, ArgList, ScriptPosition, false); - delete this; - return x->Resolve(ctx); + if (!CheckFunctionCompatiblity(ScriptPosition, ctx.Function, afd)) + { + delete this; + return nullptr; + } + + auto self = (afd->Variants[0].Flags & VARF_Method) ? new FxSelf(ScriptPosition) : nullptr; + auto x = new FxVMFunctionCall(self, afd, ArgList, ScriptPosition, false); + delete this; + return x->Resolve(ctx); + } } for (size_t i = 0; i < countof(FxFlops); ++i) @@ -7228,7 +7230,7 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx) if (special != 0 && min >= 0) { int paramcount = ArgList.Size(); - if (ctx.Function == nullptr) + if (ctx.Function == nullptr || ctx.Class == nullptr) { ScriptPosition.Message(MSG_ERROR, "Unable to call action special %s from constant declaration", MethodName.GetChars()); delete this; @@ -7459,13 +7461,20 @@ FxMemberFunctionCall::~FxMemberFunctionCall() FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx) { - ABORT(ctx.Class); PStruct *cls; bool staticonly = false; bool novirtual = false; PStruct *ccls = nullptr; + if (ctx.Class == nullptr) + { + // There's no way that a member function call can resolve to a constant so abort right away. + ScriptPosition.Message(MSG_ERROR, "Expression is not constant."); + delete this; + return nullptr; + } + for (auto a : ArgList) { if (a == nullptr) diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index 365a29abb..83b93cafb 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -48,7 +48,6 @@ #include "p_lnspec.h" #include "i_system.h" #include "gdtoa.h" -#include "codegeneration/codegen.h" #include "vmbuilder.h" #include "version.h" @@ -642,11 +641,11 @@ void ZCCCompiler::CreateClassTypes() // //========================================================================== -void ZCCCompiler::CopyConstants(TArray &dest, TArray &Constants, PSymbolTable *ot) +void ZCCCompiler::CopyConstants(TArray &dest, TArray &Constants, PStruct *cls, PSymbolTable *ot) { for (auto c : Constants) { - dest.Push({ c, ot }); + dest.Push({ c, cls, ot }); } } @@ -665,14 +664,14 @@ void ZCCCompiler::CompileAllConstants() // put all constants in one list to make resolving this easier. TArray constantwork; - CopyConstants(constantwork, Constants, OutputSymbols); + CopyConstants(constantwork, Constants, nullptr, OutputSymbols); for (auto c : Classes) { - CopyConstants(constantwork, c->Constants, &c->Type()->Symbols); + CopyConstants(constantwork, c->Constants, c->Type(), &c->Type()->Symbols); } for (auto s : Structs) { - CopyConstants(constantwork, s->Constants, &s->Type()->Symbols); + CopyConstants(constantwork, s->Constants, s->Type(), &s->Type()->Symbols); } // Before starting to resolve the list, let's create symbols for all already resolved ones first (i.e. all literal constants), to reduce work. @@ -693,7 +692,7 @@ void ZCCCompiler::CompileAllConstants() donesomething = false; for (unsigned i = 0; i < constantwork.Size(); i++) { - if (CompileConstant(constantwork[i].node, constantwork[i].outputtable)) + if (CompileConstant(&constantwork[i])) { AddConstant(constantwork[i]); // Remove the constant from the list @@ -721,6 +720,9 @@ void ZCCCompiler::AddConstant(ZCC_ConstantWork &constant) { auto def = constant.node; auto val = def->Value; + ExpVal &c = constant.constval; + + // This is for literal constants. if (val->NodeType == AST_ExprConstant) { ZCC_ExprConstant *cval = static_cast(val); @@ -747,14 +749,40 @@ void ZCCCompiler::AddConstant(ZCC_ConstantWork &constant) Error(def->Value, "Bad type for constant definiton"); def->Symbol = nullptr; } - - if (def->Symbol == nullptr) - { - // Create a dummy constant so we don't make any undefined value warnings. - def->Symbol = new PSymbolConstNumeric(def->NodeName, TypeError, 0); - } - constant.outputtable->ReplaceSymbol(def->Symbol); } + else + { + if (c.Type == TypeString) + { + def->Symbol = new PSymbolConstString(def->NodeName, c.GetString()); + } + else if (c.Type->IsA(RUNTIME_CLASS(PInt))) + { + // How do we get an Enum type in here without screwing everything up??? + //auto type = def->Type != nullptr ? def->Type : cval->Type; + def->Symbol = new PSymbolConstNumeric(def->NodeName, c.Type, c.GetInt()); + } + else if (c.Type->IsA(RUNTIME_CLASS(PFloat))) + { + if (def->Type != nullptr) + { + Error(def, "Enum members must be integer values"); + } + def->Symbol = new PSymbolConstNumeric(def->NodeName, c.Type, c.GetFloat()); + } + else + { + Error(def->Value, "Bad type for constant definiton"); + def->Symbol = nullptr; + } + } + + if (def->Symbol == nullptr) + { + // Create a dummy constant so we don't make any undefined value warnings. + def->Symbol = new PSymbolConstNumeric(def->NodeName, TypeError, 0); + } + constant.Outputtable->ReplaceSymbol(def->Symbol); } //========================================================================== @@ -766,13 +794,31 @@ void ZCCCompiler::AddConstant(ZCC_ConstantWork &constant) // //========================================================================== -bool ZCCCompiler::CompileConstant(ZCC_ConstantDef *def, PSymbolTable *sym) +bool ZCCCompiler::CompileConstant(ZCC_ConstantWork *work) { - assert(def->Symbol == nullptr); - - ZCC_Expression *val = Simplify(def->Value, sym, true); - def->Value = val; - return (val->NodeType == AST_ExprConstant); + FCompileContext ctx(work->cls, false); + FxExpression *exp = ConvertNode(work->node->Value); + try + { + FScriptPosition::errorout = true; + exp = exp->Resolve(ctx); + if (exp == nullptr) return false; + FScriptPosition::errorout = false; + if (!exp->isConstant()) + { + delete exp; + return false; + } + work->constval = static_cast(exp)->GetValue(); + delete exp; + return true; + } + catch (...) + { + // eat the reported error and treat this as a temorary failure. All unresolved contants will be reported at the end. + FScriptPosition::errorout = false; + return false; + } } diff --git a/src/scripting/zscript/zcc_compile.h b/src/scripting/zscript/zcc_compile.h index 2b9671cdc..d0284263a 100644 --- a/src/scripting/zscript/zcc_compile.h +++ b/src/scripting/zscript/zcc_compile.h @@ -2,6 +2,7 @@ #define ZCC_COMPILE_H #include +#include "codegeneration/codegen.h" struct Baggage; struct FPropertyInfo; @@ -77,7 +78,9 @@ struct ZCC_PropertyWork struct ZCC_ConstantWork { ZCC_ConstantDef *node; - PSymbolTable *outputtable; + PStruct *cls; + PSymbolTable *Outputtable; + ExpVal constval; }; class ZCCCompiler @@ -93,10 +96,10 @@ private: void ProcessStruct(ZCC_Struct *node, PSymbolTreeNode *tnode, ZCC_Class *outer); void CreateStructTypes(); void CreateClassTypes(); - void CopyConstants(TArray &dest, TArray &Constants, PSymbolTable *ot); + void CopyConstants(TArray &dest, TArray &Constants, PStruct *cls, PSymbolTable *ot); void CompileAllConstants(); void AddConstant(ZCC_ConstantWork &constant); - bool CompileConstant(ZCC_ConstantDef *def, PSymbolTable *Symbols); + bool CompileConstant(ZCC_ConstantWork *def); void CompileAllFields(); bool CompileFields(PStruct *type, TArray &Fields, PClass *Outer, PSymbolTable *TreeNodes, bool forstruct, bool hasnativechildren = false);