From 4c93e2baa3df3eca38ee697d152902bb22e69a95 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 22 Jan 2017 22:19:32 +0100 Subject: [PATCH] - use the expression evaluation capabilities of the compiler backend to resolve constants in actor defaults. This is the first step to get rid of Simplify and all the baggage it depends on. --- src/scripting/zscript/zcc_compile.cpp | 53 ++++++++++++++++++++------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index ddf08fbc4..03bc15e45 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -1765,6 +1765,27 @@ const char *ZCCCompiler::GetString(ZCC_Expression *expr, bool silent) } } +static int GetIntConst(FxExpression *ex, FCompileContext &ctx) +{ + ex = new FxIntCast(ex, false); + ex = ex->Resolve(ctx); + return ex ? static_cast(ex)->GetValue().GetInt() : 0; +} + +static double GetFloatConst(FxExpression *ex, FCompileContext &ctx) +{ + ex = new FxFloatCast(ex); + ex = ex->Resolve(ctx); + return ex ? static_cast(ex)->GetValue().GetFloat() : 0; +} + +static FString GetStringConst(FxExpression *ex, FCompileContext &ctx) +{ + ex = new FxStringCast(ex); + ex = ex->Resolve(ctx); + return static_cast(ex)->GetValue().GetString(); +} + //========================================================================== // // Parses an actor property's parameters and calls the handler @@ -1787,16 +1808,22 @@ void ZCCCompiler::DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *proper Error(property, "%s: arguments missing", prop->name); return; } - property->Values = Simplify(property->Values, &bag.Info->Symbols, true); // need to do this before the loop so that we can find the head node again. const char * p = prop->params; auto exp = property->Values; + FCompileContext ctx(bag.Info, false); while (true) { FPropParam conv; FPropParam pref; - if (exp->NodeType != AST_ExprConstant) + FxExpression *ex = ConvertNode(exp); + ex = ex->Resolve(ctx); + if (ex == nullptr) + { + return; + } + else if (!ex->isConstant()) { // If we get TypeError, there has already been a message from deeper down so do not print another one. if (exp->Type != TypeError) Error(exp, "%s: non-constant parameter", prop->name); @@ -1809,7 +1836,7 @@ void ZCCCompiler::DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *proper { case 'X': // Expression in parentheses or number. We only support the constant here. The function will have to be handled by a separate property to get past the parser. - conv.i = GetInt(exp); + conv.i = GetIntConst(ex, ctx); params.Push(conv); conv.exp = nullptr; break; @@ -1817,15 +1844,15 @@ void ZCCCompiler::DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *proper case 'I': case 'M': // special case for morph styles in DECORATE . This expression-aware parser will not need this. case 'N': // special case for thing activations in DECORATE. This expression-aware parser will not need this. - conv.i = GetInt(exp); + conv.i = GetIntConst(ex, ctx); break; case 'F': - conv.d = GetDouble(exp); + conv.d = GetFloatConst(ex, ctx); break; case 'Z': // an optional string. Does not allow any numeric value. - if (!GetString(exp, true)) + if (ex->ValueType != TypeString) { // apply this expression to the next argument on the list. params.Push(conv); @@ -1833,21 +1860,21 @@ void ZCCCompiler::DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *proper p++; continue; } - conv.s = GetString(exp); + conv.s = GetStringConst(ex, ctx); break; case 'C': // this parser accepts colors only in string form. pref.i = 1; case 'S': case 'T': // a filtered string (ZScript only parses filtered strings so there's nothing to do here.) - conv.s = GetString(exp); + conv.s = GetStringConst(ex, ctx); break; case 'L': // Either a number or a list of strings - if (!GetString(exp, true)) + if (ex->ValueType != TypeString) { pref.i = 0; - conv.i = GetInt(exp); + conv.i = GetIntConst(ex, ctx); } else { @@ -1857,13 +1884,13 @@ void ZCCCompiler::DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *proper do { - conv.s = GetString(exp); + conv.s = GetStringConst(ex, ctx); if (conv.s != nullptr) { params.Push(conv); params[0].i++; } - exp = Simplify(static_cast(exp->SiblingNext), &bag.Info->Symbols, true); + exp = static_cast(exp->SiblingNext); } while (exp != property->Values); goto endofparm; } @@ -1881,7 +1908,7 @@ void ZCCCompiler::DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *proper } params.Push(conv); params[0].i++; - exp = Simplify(static_cast(exp->SiblingNext), &bag.Info->Symbols, true); + exp = static_cast(exp->SiblingNext); endofparm: p++; // Skip the DECORATE 'no comma' marker