From 16fc9be41124d8207e121aeaa4ad10145750c52e Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 30 Oct 2013 20:53:02 -0500 Subject: [PATCH] Interpret function calls to type refs as type casts --- src/zscript/zcc_compile.cpp | 80 ++++++++++++++++++++++++++++++++----- src/zscript/zcc_compile.h | 1 + src/zscript/zcc_errors.h | 2 + src/zscript/zcc_parser.h | 8 ++++ 4 files changed, 81 insertions(+), 10 deletions(-) diff --git a/src/zscript/zcc_compile.cpp b/src/zscript/zcc_compile.cpp index b6ff67a47e..b95bc33b7f 100644 --- a/src/zscript/zcc_compile.cpp +++ b/src/zscript/zcc_compile.cpp @@ -226,7 +226,15 @@ PSymbolConst *ZCCCompiler::CompileConstant(ZCC_ConstantDef *def) ZCC_Expression *ZCCCompiler::Simplify(ZCC_Expression *root) { - if (root->Operation == PEX_ID) + if (IsUnaryOp(root->Operation)) + { + return SimplifyUnary(static_cast(root)); + } + else if (IsBinaryOp(root->Operation)) + { + return SimplifyBinary(static_cast(root)); + } + else if (root->Operation == PEX_ID) { return IdentifyIdentifier(static_cast(root)); } @@ -234,13 +242,9 @@ ZCC_Expression *ZCCCompiler::Simplify(ZCC_Expression *root) { return SimplifyMemberAccess(static_cast(root)); } - else if (IsUnaryOp(root->Operation)) + else if (root->Operation == PEX_FuncCall) { - return SimplifyUnary(static_cast(root)); - } - else if (IsBinaryOp(root->Operation)) - { - return SimplifyBinary(static_cast(root)); + return SimplifyFunctionCall(static_cast(root)); } return root; } @@ -324,6 +328,64 @@ ZCC_Expression *ZCCCompiler::SimplifyMemberAccess(ZCC_ExprMemberAccess *dotop) return dotop; } +//========================================================================== +// +// ZCCCompiler :: SimplifyFunctionCall +// +// This may replace a function call with cast(s), since they look like the +// same thing to the parser. +// +//========================================================================== + +ZCC_Expression *ZCCCompiler::SimplifyFunctionCall(ZCC_ExprFuncCall *callop) +{ + ZCC_FuncParm *parm; + int parmcount = 0; + + callop->Function = Simplify(callop->Function); + parm = callop->Parameters; + if (parm != NULL) + { + do + { + parmcount++; + assert(parm->NodeType == AST_FuncParm); + parm->Value = Simplify(parm->Value); + parm = static_cast(parm->SiblingNext); + } + while (parm != callop->Parameters); + } + // If the left side is a type ref, then this is actually a cast + // and not a function call. + if (callop->Function->Operation == PEX_TypeRef) + { + if (parmcount != 1) + { + Message(callop, ERR_cast_needs_1_parm, "Type cast requires one parameter"); + callop->ToErrorNode(); + } + else + { + PType *dest = static_cast(callop->Function)->RefType; + const PType::Conversion *route[CONVERSION_ROUTE_SIZE]; + int routelen = parm->Value->Type->FindConversion(dest, route, countof(route)); + if (routelen < 0) + { + // FIXME: Need real type names + Message(callop, ERR_cast_not_possible, "Cannot convert type 1 to type 2"); + callop->ToErrorNode(); + } + else + { + ZCC_Expression *val = ApplyConversion(parm->Value, route, routelen); + assert(val->Type == dest); + return val; + } + } + } + return callop; +} + //========================================================================== // // ZCCCompiler :: PromoteUnary @@ -456,9 +518,7 @@ ZCC_Expression *ZCCCompiler::IdentifyIdentifier(ZCC_ExprID *idnode) } } // Identifier didn't refer to anything good, so type error it. - idnode->Type = TypeError; - idnode->Operation = PEX_Nil; - idnode->NodeType = AST_Expression; + idnode->ToErrorNode(); return idnode; } diff --git a/src/zscript/zcc_compile.h b/src/zscript/zcc_compile.h index a5029ad93c..c8933ff5fe 100644 --- a/src/zscript/zcc_compile.h +++ b/src/zscript/zcc_compile.h @@ -24,6 +24,7 @@ private: ZCC_Expression *SimplifyUnary(ZCC_ExprUnary *unary); ZCC_Expression *SimplifyBinary(ZCC_ExprBinary *binary); ZCC_Expression *SimplifyMemberAccess(ZCC_ExprMemberAccess *dotop); + ZCC_Expression *SimplifyFunctionCall(ZCC_ExprFuncCall *callop); ZCC_OpProto *PromoteUnary(EZCCExprType op, ZCC_Expression *&expr); ZCC_OpProto *PromoteBinary(EZCCExprType op, ZCC_Expression *&left, ZCC_Expression *&right); diff --git a/src/zscript/zcc_errors.h b/src/zscript/zcc_errors.h index 7deb5737ec..cb38a00d58 100644 --- a/src/zscript/zcc_errors.h +++ b/src/zscript/zcc_errors.h @@ -9,4 +9,6 @@ enum EZCCError ERR_recursive_definition = 20004 | ZCCERR_ERROR, ERR_not_a_member = 20005 | ZCCERR_ERROR, ERR_bad_symbol = 20006 | ZCCERR_ERROR, + ERR_cast_needs_1_parm = 20007 | ZCCERR_ERROR, + ERR_cast_not_possible = 20008 | ZCCERR_ERROR, }; diff --git a/src/zscript/zcc_parser.h b/src/zscript/zcc_parser.h index 47213b549e..5dae12e780 100644 --- a/src/zscript/zcc_parser.h +++ b/src/zscript/zcc_parser.h @@ -234,6 +234,14 @@ struct ZCC_Expression : ZCC_TreeNode { EZCCExprType Operation; PType *Type; + + // Repurposes this node as an error node + void ToErrorNode() + { + Type = TypeError; + Operation = PEX_Nil; + NodeType = AST_Expression; + } }; struct ZCC_StateGoto : ZCC_StatePart