Allow `if {} else if {}` with DECORATE

This is as opposed to `if {} else { if {} }`, which is what was required
previously to express the same construct.
This commit is contained in:
Randy Heit 2016-02-29 21:40:10 -06:00
parent f23c0121c5
commit cb1d9597f2
1 changed files with 40 additions and 26 deletions

View File

@ -441,6 +441,45 @@ static PPrototype *ReturnCheck(PPrototype *proto1, PPrototype *proto2, FScanner
// //
//========================================================================== //==========================================================================
static FxExpression *ParseIf(FScanner &sc, FState state, FString statestring, Baggage &bag,
PPrototype *&retproto, bool &lastwasret)
{
FxExpression *add, *cond;
FxExpression *true_part, *false_part = NULL;
PPrototype *true_proto, *false_proto = NULL;
bool true_ret, false_ret = false;
sc.MustGetStringName("(");
cond = ParseExpression(sc, bag.Info);
sc.MustGetStringName(")");
sc.MustGetStringName("{"); // braces are mandatory
true_part = ParseActions(sc, state, statestring, bag, true_proto, true_ret);
sc.MustGetString();
if (sc.Compare("else"))
{
if (sc.CheckString("if"))
{
false_part = ParseIf(sc, state, statestring, bag, false_proto, false_ret);
}
else
{
sc.MustGetStringName("{"); // braces are still mandatory
false_part = ParseActions(sc, state, statestring, bag, false_proto, false_ret);
sc.MustGetString();
}
}
add = new FxIfStatement(cond, true_part, false_part, sc);
retproto = ReturnCheck(retproto, true_proto, sc);
retproto = ReturnCheck(retproto, false_proto, sc);
// If one side does not end with a return, we don't consider the if statement
// to end with a return. If the else case is missing, it can never be considered
// as ending with a return.
if (true_ret && false_ret)
{
lastwasret = true;
}
return add;
}
FxExpression *ParseActions(FScanner &sc, FState state, FString statestring, Baggage &bag, FxExpression *ParseActions(FScanner &sc, FState state, FString statestring, Baggage &bag,
PPrototype *&retproto, bool &endswithret) PPrototype *&retproto, bool &endswithret)
{ {
@ -467,32 +506,7 @@ FxExpression *ParseActions(FScanner &sc, FState state, FString statestring, Bagg
lastwasret = false; lastwasret = false;
if (sc.Compare("if")) if (sc.Compare("if"))
{ // Hangle an if statement { // Hangle an if statement
FxExpression *cond; add = ParseIf(sc, state, statestring, bag, proto, lastwasret);
FxExpression *true_part, *false_part = NULL;
PPrototype *true_proto, *false_proto = NULL;
bool true_ret, false_ret = false;
sc.MustGetStringName("(");
cond = ParseExpression(sc, bag.Info);
sc.MustGetStringName(")");
sc.MustGetStringName("{"); // braces are mandatory
true_part = ParseActions(sc, state, statestring, bag, true_proto, true_ret);
sc.MustGetString();
if (sc.Compare("else"))
{
sc.MustGetStringName("{"); // braces are still mandatory
false_part = ParseActions(sc, state, statestring, bag, false_proto, false_ret);
sc.MustGetString();
}
add = new FxIfStatement(cond, true_part, false_part, sc);
proto = ReturnCheck(proto, true_proto, sc);
proto = ReturnCheck(proto, false_proto, sc);
// If one side does not end with a return, we don't consider the if statement
// to end with a return. If the else case is missing, it can never be considered
// as ending with a return.
if (true_ret && false_ret)
{
lastwasret = true;
}
} }
else if (sc.Compare("return")) else if (sc.Compare("return"))
{ // Handle a return statement { // Handle a return statement