public static bool TryParse(this ILValue node, out int value) { ILValue valueNode = node as ILValue; if (valueNode != null && (valueNode.Type == GM_Type.Short || valueNode.Type == GM_Type.Int)) { value = (int)valueNode; return(true); } value = 0; return(false); }
void WriteOperand(ITextOutput output, bool escapeString = true) { if (Operand == null) { output.Write("%NULL_OPERAND%"); } else if (Operand is ILLabel) { output.Write((Operand as ILLabel).Name); } else if (escapeString) { if (Operand is string) { output.Write(GMCodeUtil.EscapeString((string)Operand)); } else if (Operand is ILValue) { ILValue val = Operand as ILValue; if (escapeString && val.Type == GM_Type.String) { output.Write(val.ValueText); } else { output.Write(val.ToString()); } } else { output.Write(Operand.ToString()); } } else { output.Write(Operand.ToString()); } }
// This is before the expression is processed, so ILValue's and constants havn't been assigned public bool SimplifyTernaryOperator(List <ILNode> body, ILBasicBlock head, int pos) { Debug.Assert(body.Contains(head)); // Debug.Assert((head.Body[0] as ILLabel).Name != "Block_54"); // Debug.Assert((head.Body[0] as ILLabel).Name != "L1257"); ILExpression condExpr; ILLabel trueLabel; ILLabel falseLabel; ILExpression trueExpr; ILLabel trueFall; ILExpression falseExpr; ILLabel falseFall; ILExpression finalFall; ILLabel finalFalseFall; ILLabel finalTrueFall; if ((head.MatchLastAndBr(GMCode.Bt, out trueLabel, out condExpr, out falseLabel) || head.MatchLastAndBr(GMCode.Bf, out falseLabel, out condExpr, out trueLabel)) && labelGlobalRefCount[trueLabel] == 1 && labelGlobalRefCount[falseLabel] == 1 && labelToBasicBlock[trueLabel].MatchSingleAndBr(GMCode.Push, out trueExpr, out trueFall) && labelToBasicBlock[falseLabel].MatchSingleAndBr(GMCode.Push, out falseExpr, out falseFall) && trueFall == falseFall && body.Contains(labelToBasicBlock[trueLabel]) && labelToBasicBlock[trueFall].MatchLastAndBr(GMCode.Bf, out finalFalseFall, out finalFall, out finalTrueFall) && finalFall.Code == GMCode.Pop ) // (finalFall == null || finalFall.Code == GMCode.Pop) { Debug.Assert(finalFall.Arguments.Count != 2); ILValue falseLocVar = falseExpr.Code == GMCode.Constant ? falseExpr.Operand as ILValue : null; ILValue trueLocVar = trueExpr.Code == GMCode.Constant ? trueExpr.Operand as ILValue : null; Debug.Assert(falseLocVar != null || trueLocVar != null); ILExpression newExpr = null; // a ? true : b is equivalent to a || b // a ? b : true is equivalent to !a || b // a ? b : false is equivalent to a && b // a ? false : b is equivalent to !a && b if (trueLocVar != null && trueLocVar.Type == GM_Type.Short && (trueLocVar == 0 || trueLocVar == 1)) { // It can be expressed as logical expression if (trueLocVar != 0) { newExpr = MakeLeftAssociativeShortCircuit(GMCode.LogicOr, condExpr, falseExpr); } else { newExpr = MakeLeftAssociativeShortCircuit(GMCode.LogicAnd, new ILExpression(GMCode.Not, null, condExpr), falseExpr); } } else if (falseLocVar != null && falseLocVar.Type == GM_Type.Short && (falseLocVar == 0 || falseLocVar == 1)) { // It can be expressed as logical expression if (falseLocVar != 0) { newExpr = MakeLeftAssociativeShortCircuit(GMCode.LogicOr, new ILExpression(GMCode.Not, null, condExpr), trueExpr); } else { newExpr = MakeLeftAssociativeShortCircuit(GMCode.LogicAnd, condExpr, trueExpr); } } Debug.Assert(newExpr != null); // head.Body.RemoveTail(ILCode.Brtrue, ILCode.Br); head.Body.RemoveRange(head.Body.Count - 2, 2); head.Body.Add(new ILExpression(GMCode.Bf, finalFalseFall, newExpr)); head.Body.Add(new ILExpression(GMCode.B, finalTrueFall)); // Remove the inlined branch from scope // body.RemoveOrThrow(nextBasicBlock); // Remove the old basic blocks body.RemoveOrThrow(labelToBasicBlock[trueLabel]); body.RemoveOrThrow(labelToBasicBlock[falseLabel]); body.RemoveOrThrow(labelToBasicBlock[trueFall]); return(true); } return(false); }