Interpret function calls to type refs as type casts

This commit is contained in:
Randy Heit 2013-10-30 20:53:02 -05:00
parent 2adf5782b9
commit 16fc9be411
4 changed files with 81 additions and 10 deletions

View file

@ -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;
} }

View file

@ -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);

View file

@ -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,
}; };

View file

@ -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