mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-18 10:21:42 +00:00
Interpret function calls to type refs as type casts
This commit is contained in:
parent
2adf5782b9
commit
16fc9be411
4 changed files with 81 additions and 10 deletions
|
@ -226,7 +226,15 @@ PSymbolConst *ZCCCompiler::CompileConstant(ZCC_ConstantDef *def)
|
||||||
|
|
||||||
ZCC_Expression *ZCCCompiler::Simplify(ZCC_Expression *root)
|
ZCC_Expression *ZCCCompiler::Simplify(ZCC_Expression *root)
|
||||||
{
|
{
|
||||||
if (root->Operation == PEX_ID)
|
if (IsUnaryOp(root->Operation))
|
||||||
|
{
|
||||||
|
return SimplifyUnary(static_cast<ZCC_ExprUnary *>(root));
|
||||||
|
}
|
||||||
|
else if (IsBinaryOp(root->Operation))
|
||||||
|
{
|
||||||
|
return SimplifyBinary(static_cast<ZCC_ExprBinary *>(root));
|
||||||
|
}
|
||||||
|
else if (root->Operation == PEX_ID)
|
||||||
{
|
{
|
||||||
return IdentifyIdentifier(static_cast<ZCC_ExprID *>(root));
|
return IdentifyIdentifier(static_cast<ZCC_ExprID *>(root));
|
||||||
}
|
}
|
||||||
|
@ -234,13 +242,9 @@ ZCC_Expression *ZCCCompiler::Simplify(ZCC_Expression *root)
|
||||||
{
|
{
|
||||||
return SimplifyMemberAccess(static_cast<ZCC_ExprMemberAccess *>(root));
|
return SimplifyMemberAccess(static_cast<ZCC_ExprMemberAccess *>(root));
|
||||||
}
|
}
|
||||||
else if (IsUnaryOp(root->Operation))
|
else if (root->Operation == PEX_FuncCall)
|
||||||
{
|
{
|
||||||
return SimplifyUnary(static_cast<ZCC_ExprUnary *>(root));
|
return SimplifyFunctionCall(static_cast<ZCC_ExprFuncCall *>(root));
|
||||||
}
|
|
||||||
else if (IsBinaryOp(root->Operation))
|
|
||||||
{
|
|
||||||
return SimplifyBinary(static_cast<ZCC_ExprBinary *>(root));
|
|
||||||
}
|
}
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
@ -324,6 +328,64 @@ ZCC_Expression *ZCCCompiler::SimplifyMemberAccess(ZCC_ExprMemberAccess *dotop)
|
||||||
return 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<ZCC_FuncParm *>(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<ZCC_ExprTypeRef *>(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
|
// ZCCCompiler :: PromoteUnary
|
||||||
|
@ -456,9 +518,7 @@ ZCC_Expression *ZCCCompiler::IdentifyIdentifier(ZCC_ExprID *idnode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Identifier didn't refer to anything good, so type error it.
|
// Identifier didn't refer to anything good, so type error it.
|
||||||
idnode->Type = TypeError;
|
idnode->ToErrorNode();
|
||||||
idnode->Operation = PEX_Nil;
|
|
||||||
idnode->NodeType = AST_Expression;
|
|
||||||
return idnode;
|
return idnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ private:
|
||||||
ZCC_Expression *SimplifyUnary(ZCC_ExprUnary *unary);
|
ZCC_Expression *SimplifyUnary(ZCC_ExprUnary *unary);
|
||||||
ZCC_Expression *SimplifyBinary(ZCC_ExprBinary *binary);
|
ZCC_Expression *SimplifyBinary(ZCC_ExprBinary *binary);
|
||||||
ZCC_Expression *SimplifyMemberAccess(ZCC_ExprMemberAccess *dotop);
|
ZCC_Expression *SimplifyMemberAccess(ZCC_ExprMemberAccess *dotop);
|
||||||
|
ZCC_Expression *SimplifyFunctionCall(ZCC_ExprFuncCall *callop);
|
||||||
ZCC_OpProto *PromoteUnary(EZCCExprType op, ZCC_Expression *&expr);
|
ZCC_OpProto *PromoteUnary(EZCCExprType op, ZCC_Expression *&expr);
|
||||||
ZCC_OpProto *PromoteBinary(EZCCExprType op, ZCC_Expression *&left, ZCC_Expression *&right);
|
ZCC_OpProto *PromoteBinary(EZCCExprType op, ZCC_Expression *&left, ZCC_Expression *&right);
|
||||||
|
|
||||||
|
|
|
@ -9,4 +9,6 @@ enum EZCCError
|
||||||
ERR_recursive_definition = 20004 | ZCCERR_ERROR,
|
ERR_recursive_definition = 20004 | ZCCERR_ERROR,
|
||||||
ERR_not_a_member = 20005 | ZCCERR_ERROR,
|
ERR_not_a_member = 20005 | ZCCERR_ERROR,
|
||||||
ERR_bad_symbol = 20006 | ZCCERR_ERROR,
|
ERR_bad_symbol = 20006 | ZCCERR_ERROR,
|
||||||
|
ERR_cast_needs_1_parm = 20007 | ZCCERR_ERROR,
|
||||||
|
ERR_cast_not_possible = 20008 | ZCCERR_ERROR,
|
||||||
};
|
};
|
||||||
|
|
|
@ -234,6 +234,14 @@ struct ZCC_Expression : ZCC_TreeNode
|
||||||
{
|
{
|
||||||
EZCCExprType Operation;
|
EZCCExprType Operation;
|
||||||
PType *Type;
|
PType *Type;
|
||||||
|
|
||||||
|
// Repurposes this node as an error node
|
||||||
|
void ToErrorNode()
|
||||||
|
{
|
||||||
|
Type = TypeError;
|
||||||
|
Operation = PEX_Nil;
|
||||||
|
NodeType = AST_Expression;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZCC_StateGoto : ZCC_StatePart
|
struct ZCC_StateGoto : ZCC_StatePart
|
||||||
|
|
Loading…
Reference in a new issue