// -------------------------------------------------------------------------- // 1. goto 9 // 9. goto 21 // 1. goto 21 // 9. goto 21 private void TraceGotoChains() { for (int index = 1; index < m_middleCodeList.Count; ++index) { MiddleCode middleCode = m_middleCodeList[index]; if (middleCode.IsRelationCarryOrGoto()) { ISet <int> sourceSet = new HashSet <int>(); sourceSet.Add(index); int firstTarget = (int)middleCode[0]; int finalTarget = TraceGoto(firstTarget, sourceSet); if (firstTarget != finalTarget) { foreach (int source in sourceSet) { MiddleCode sourceCode = m_middleCodeList[source]; sourceCode[0] = finalTarget; } m_update = true; } } } }
public void ObjectToIntegerAddresses() { IDictionary <MiddleCode, int> addressMap = new Dictionary <MiddleCode, int>(); for (int index = 0; index < m_middleCodeList.Count; ++index) { MiddleCode middleCode = m_middleCodeList[index]; addressMap.Add(middleCode, index); } for (int index = 0; index < m_middleCodeList.Count; ++index) { MiddleCode sourceCode = m_middleCodeList[index]; if (sourceCode.IsGoto() || sourceCode.IsCarry() || sourceCode.IsRelation()) { Debug.Assert(sourceCode[0] is MiddleCode); MiddleCode targetCode = (MiddleCode)sourceCode[0]; Debug.Assert(addressMap.ContainsKey(targetCode)); sourceCode[0] = addressMap[targetCode]; } } }
private int TraceGoto(int target, ISet <int> sourceSet) { MiddleCode objectCode = m_middleCodeList[target]; if (!sourceSet.Contains(target) && objectCode.IsGoto()) { sourceSet.Add(target); int nextTarget = (int)objectCode[0]; return(TraceGoto(nextTarget, sourceSet)); } else { return(target); } }
private void DereferenceToIndex() { for (int index = 0; index < (m_middleCodeList.Count - 1); ++index) { MiddleCode thisCode = m_middleCodeList[index], nextCode = m_middleCodeList[index + 1]; // *(a + 3) <=> a[3] <=> *(3 + a) <=> 3[a] if ((thisCode.Operator == MiddleOperator.Add) && (nextCode.Operator == MiddleOperator.Dereference) && (thisCode[0] == nextCode[1])) { Symbol leftSymbol = (Symbol)thisCode[1], rightSymbol = (Symbol)thisCode[2]; if (leftSymbol.Value is BigInteger) { Symbol resultSymbol = (Symbol)nextCode[0]; resultSymbol.AddressSymbol = rightSymbol; resultSymbol.AddressOffset = ((int)((BigInteger)leftSymbol.Value)); thisCode.Clear(); } else if (rightSymbol.Value is BigInteger) { Symbol resultSymbol = (Symbol)nextCode[0]; resultSymbol.AddressSymbol = leftSymbol; resultSymbol.AddressOffset = ((int)((BigInteger)rightSymbol.Value)); thisCode.Clear(); } } // *(a - 3) <=> a[-3] else if ((thisCode.Operator == MiddleOperator.Subtract) && (nextCode.Operator == MiddleOperator.Dereference) && (thisCode[0] == nextCode[1])) { Symbol leftSymbol = (Symbol)thisCode[1], rightSymbol = (Symbol)thisCode[2]; if (rightSymbol.Value is BigInteger) { Symbol resultSymbol = (Symbol)nextCode[0]; resultSymbol.AddressSymbol = leftSymbol; resultSymbol.AddressOffset = -((int)((BigInteger)rightSymbol.Value)); thisCode.Clear(); } } } }
// Top x + Pop => Pop x // top x // pop // pop x public void MergeTopPopEmptyToPop() { for (int index = 0; index < (m_middleCodeList.Count - 1); ++index) { MiddleCode thisCode = m_middleCodeList[index], nextCode = m_middleCodeList[index + 1]; if ((thisCode.Operator == MiddleOperator.TopFloat) && (nextCode.Operator == MiddleOperator.PopEmpty)) { thisCode.Operator = MiddleOperator.PopFloat; nextCode.Clear(); m_update = true; } } }
// -------------------------------------------------------------------------- private void ClearUnreachableCode() { ISet <MiddleCode> visitedSet = new HashSet <MiddleCode>(); SearchReachableCode(0, visitedSet); for (int index = 0; index < (m_middleCodeList.Count - 1); ++index) { MiddleCode middleCode = m_middleCodeList[index]; if (!visitedSet.Contains(middleCode)) { m_middleCodeList[index].Clear(); m_update = true; } } }
public override bool Equals(Object obj) { if (obj is MiddleCode) { MiddleCode middleCode = (MiddleCode)obj; return((m_middleOperator == middleCode.m_middleOperator) && (((m_operandArray[0] == null) && (middleCode.m_operandArray[0] == null)) || m_operandArray[0].Equals(middleCode.m_operandArray[0])) && (((m_operandArray[1] == null) && (middleCode.m_operandArray[1] == null)) || m_operandArray[1].Equals(middleCode.m_operandArray[1])) && (((m_operandArray[2] == null) && (middleCode.m_operandArray[2] == null)) || m_operandArray[2].Equals(middleCode.m_operandArray[2]))); } return(false); }
// Push x + Pop => empty // push x // pop // empty public void RemovePushPop() { for (int index = 0; index < (m_middleCodeList.Count - 1); ++index) { MiddleCode thisCode = m_middleCodeList[index], nextCode = m_middleCodeList[index + 1]; if ((thisCode.Operator == MiddleOperator.PushFloat) && ((nextCode.Operator == MiddleOperator.PopEmpty) || ((nextCode.Operator == MiddleOperator.PopFloat) && (thisCode[0] == nextCode[0])))) { thisCode.Clear(); nextCode.Clear(); m_update = true; } } }
// t = a // b = t // b = a private void MergeDoubleAssign() { for (int index = 0; index < (m_middleCodeList.Count - 1); ++index) { MiddleCode thisCode = m_middleCodeList[index], nextCode = m_middleCodeList[index + 1]; if ((thisCode.Operator == MiddleOperator.Assign) && (nextCode.Operator == MiddleOperator.Assign) && thisCode[0] == nextCode[1]) { thisCode[0] = nextCode[0]; nextCode.Clear(); m_update = true; } } }
// assign a = b => Pop a // a = b // pop a public void AssignFloat() { for (int index = 0; index < (m_middleCodeList.Count - 1); ++index) { MiddleCode middleCode = m_middleCodeList[index]; if (middleCode.Operator == MiddleOperator.Assign) { Symbol resultSymbol = (Symbol)middleCode[1]; if (resultSymbol.Type.IsFloating()) { middleCode.Operator = MiddleOperator.PopFloat; m_update = true; } } } }
// t = b + c // a = t // a = b + c private void MergeBinary() { for (int index = 0; index < (m_middleCodeList.Count - 1); ++index) { MiddleCode thisCode = m_middleCodeList[index], nextCode = m_middleCodeList[index + 1]; if ((/*thisCode.IsUnary() ||*/ thisCode.IsBinary()) && (nextCode.Operator == MiddleOperator.Assign) && ((Symbol)thisCode[0]).IsTemporary() && (thisCode[0] == nextCode[1])) { thisCode[0] = nextCode[0]; nextCode.Clear(); m_update = true; } } }
// -------------------------------------------------------------------------- // 1. goto 2 // 2. ... private void ClearGotoNextStatements() { for (int index = 0; index < (m_middleCodeList.Count - 1); ++index) { MiddleCode middleCode = m_middleCodeList[index]; if (middleCode.IsRelationCarryOrGoto()) { int target = (int)middleCode[0]; if (target == (index + 1)) { middleCode.Clear(); m_update = true; } } } }
public static Expression Logical(MiddleOperator middleOp, Expression leftExpression, Expression rightExpression) { if (!IsConstant(leftExpression) || !IsConstant(rightExpression)) { return(null); } bool resultValue = false; switch (middleOp) { case MiddleOperator.LogicalAnd: resultValue = IsTrue(leftExpression) && IsTrue(rightExpression); break; case MiddleOperator.LogicalOr: resultValue = IsTrue(leftExpression) || IsTrue(rightExpression); break; } List <MiddleCode> longList = new List <MiddleCode>(); MiddleCode jumpCode = new MiddleCode(MiddleOperator.Jump); longList.Add(jumpCode); ISet <MiddleCode> jumpSet = new HashSet <MiddleCode>(); jumpSet.Add(jumpCode); Symbol resultSymbol = new Symbol(null, null); if (resultValue) { resultSymbol.TrueSet = jumpSet; } else { resultSymbol.FalseSet = jumpSet; } return(new Expression(resultSymbol, null, longList)); }
public void Optimize() { ObjectToIntegerAddresses(); if (SymbolTable.CurrentFunction.Name.Equals("log")) { string name = @"C:\Users\Stefa\Documents\vagrant\homestead\code\code\" + SymbolTable.CurrentFunction.Name + ".middlenumber"; StreamWriter streamWriter = new StreamWriter(name); for (int index = 0; index < m_middleCodeList.Count; ++index) { MiddleCode middleCode = m_middleCodeList[index]; streamWriter.WriteLine(index + ": " + middleCode.ToString()); } streamWriter.Close(); } do { m_update = false; ClearGotoNextStatements(); ClearDoubleRelationStatements(); TraceGotoChains(); ClearUnreachableCode(); RemovePushPop(); //MergePopPushToTop(); MergeTopPopEmptyToPop(); //AssignFloat(); // XXX MergeBinary(); // XXX DereferenceToIndex(); //MergeDoubleAssign(); // XXX SematicOptimization(); //OptimizeRelation(); // XXX OptimizeCommutative(); SwapRelation(); RemoveTrivialAssign(); //OptimizeBinary(); CheckIntegral(); // XXX CheckFloating(); // XXX RemoveClearedCode(); } while (m_update); }
private void SearchReachableCode(int index, ISet <MiddleCode> visitedSet) { for (; index < m_middleCodeList.Count; ++index) { MiddleCode middleCode = m_middleCodeList[index]; if (visitedSet.Contains(middleCode)) { return; } visitedSet.Add(middleCode); if (middleCode.IsRelation() || middleCode.IsCarry()) { int target = (int)middleCode[0]; SearchReachableCode(target, visitedSet); } else if (middleCode.IsGoto()) { int target = (int)middleCode[0]; SearchReachableCode(target, visitedSet); return; } else if (middleCode.Operator == MiddleOperator.Return) { if (m_middleCodeList[index + 1].Operator == MiddleOperator.Exit) { visitedSet.Add(m_middleCodeList[index + 1]); } return; } else if (middleCode.Operator == MiddleOperator.FunctionEnd) { Symbol funcSymbol = (Symbol)middleCode[0]; Error.Check(funcSymbol.Type.ReturnType.IsVoid(), funcSymbol.Name, Message.Reached_the_end_of_a_non__void_function); return; } } }
private void ClearDoubleRelationStatements() { for (int index = 0; index < (m_middleCodeList.Count - 1); ++index) { MiddleCode thisCode = m_middleCodeList[index], nextCode = m_middleCodeList[index + 1]; if ((thisCode.IsRelation() || thisCode.IsCarry()) && nextCode.IsGoto()) { int target1 = (int)thisCode[0], target2 = (int)nextCode[0]; if (target1 == (index + 2)) { MiddleOperator operator1 = thisCode.Operator; thisCode.Operator = m_inverseMap[operator1]; thisCode[0] = target2; nextCode.Clear(); m_update = true; } } } }
private void CheckFloating() { int stackSize = 0; for (int line = 0; line < m_middleCodeList.Count; ++line) { MiddleCode middleCode = m_middleCodeList[line]; object operand0 = middleCode[0], operand1 = middleCode[1], operand2 = middleCode[2]; Symbol symbol0 = (operand0 is Symbol) ? ((Symbol)operand0) : null, symbol1 = (operand1 is Symbol) ? ((Symbol)operand1) : null, symbol2 = (operand2 is Symbol) ? ((Symbol)operand2) : null; switch (middleCode.Operator) { case MiddleOperator.PreCall: middleCode[2] = stackSize; break; case MiddleOperator.PushOne: case MiddleOperator.PushZero: case MiddleOperator.PushFloat: case MiddleOperator.IntegralToFloating: ++stackSize; break; case MiddleOperator.GetReturnValue: if (symbol0.Type.IsFloating()) { ++stackSize; } break; case MiddleOperator.PopFloat: case MiddleOperator.FloatingToIntegral: case MiddleOperator.DecreaseStack: --stackSize; break; case MiddleOperator.Return: stackSize = 0; break; case MiddleOperator.Equal: case MiddleOperator.NotEqual: case MiddleOperator.LessThan: case MiddleOperator.LessThanEqual: case MiddleOperator.GreaterThan: case MiddleOperator.GreaterThanEqual: { if (symbol1.Type.IsFloating()) { stackSize -= 2; } } break; case MiddleOperator.Add: case MiddleOperator.Subtract: case MiddleOperator.Multiply: case MiddleOperator.Divide: if (symbol1.Type.IsFloating()) { --stackSize; } break; case MiddleOperator.Parameter: if (symbol2.Type.IsFloating()) { --stackSize; } break; } } }
private void CheckIntegral() { Stack <ISet <Symbol> > integralSetStack = new Stack <ISet <Symbol> >(); ISet <Symbol> integralSet = new HashSet <Symbol>(); for (int line = 0; line < m_middleCodeList.Count; ++line) { MiddleCode middleCode = m_middleCodeList[line]; object operand0 = middleCode[0], operand1 = middleCode[1], operand2 = middleCode[2]; Symbol symbol0 = (operand0 is Symbol) ? ((Symbol)operand0) : null, symbol1 = (operand1 is Symbol) ? ((Symbol)operand1) : null, symbol2 = (operand2 is Symbol) ? ((Symbol)operand2) : null; switch (middleCode.Operator) { case MiddleOperator.Empty: //Debug.Assert((symbol0 == null) && (symbol1 == null) && (symbol2 == null)); break; case MiddleOperator.PreCall: { middleCode[1] = CloneSet(integralSet); integralSetStack.Push(integralSet); integralSet = new HashSet <Symbol>(); } break; case MiddleOperator.PostCall: integralSet = integralSetStack.Pop(); break; case MiddleOperator.Dereference: { Symbol resultSymbol = (Symbol)middleCode[0]; integralSet.Add(resultSymbol.AddressSymbol); //integralSet.Remove(resultSymbol.AddressSymbol); /* if (resultSymbol.Switch) { * integralSet.Remove(resultSymbol.AddressSymbol); * } * else { * integralSet.Add(resultSymbol.AddressSymbol); * }*/ } break; /*case MiddleOperator.SysCall: { * List<Pair<Register,Symbol>> outParameterList = SystemCode.OutParameterList(); * * foreach (Pair<Register,Symbol> pair in outParameterList) { * Symbol outSymbol = pair.Second; * integralSet.Add(outSymbol); * } * } * break;*/ case MiddleOperator.Case: if (symbol1.AddressSymbol != null) { integralSet.Remove(symbol1.AddressSymbol); } break; case MiddleOperator.CaseEnd: integralSet.Remove(symbol0); break; default: if ((symbol0 != null) && symbol0.IsTemporary() && (symbol0.AddressSymbol == null) && symbol0.Type.IsIntegralPointerOrArray()) { integralSet.Add(symbol0); } if ((symbol1 != null) && symbol1.IsTemporary() && symbol1.Type.IsIntegralPointerOrArray()) { integralSet.Remove(symbol1); } if ((symbol2 != null) && symbol2.IsTemporary() && symbol2.Type.IsIntegralPointerOrArray()) { integralSet.Remove(symbol2); } if ((symbol0 != null) && (symbol0.AddressSymbol != null)) { integralSet.Remove(symbol0.AddressSymbol); } if ((symbol1 != null) && (symbol1.AddressSymbol != null)) { integralSet.Remove(symbol1.AddressSymbol); } if ((symbol2 != null) && (symbol2.AddressSymbol != null)) { integralSet.Remove(symbol2.AddressSymbol); } break; } } }
private void SematicOptimization() { for (int index = 0; index < m_middleCodeList.Count; ++index) { MiddleCode thisCode = m_middleCodeList[index]; if (thisCode.IsBinary()) { Symbol resultSymbol = (Symbol)thisCode[0], leftSymbol = (Symbol)thisCode[1], rightSymbol = (Symbol)thisCode[2], newSymbol = null; if ((leftSymbol.Value is BigInteger) && // t0 = 2 * 3 (rightSymbol.Value is BigInteger)) { newSymbol = ConstantExpression.ArithmeticIntegral(thisCode.Operator, leftSymbol, rightSymbol); } // t0 = 0 + i else if ((thisCode.Operator == MiddleOperator.Add) && (leftSymbol.Value is BigInteger) && (leftSymbol.Value.Equals(BigInteger.Zero))) { newSymbol = rightSymbol; } // t0 = 0 - i; t0 = -i else if ((thisCode.Operator == MiddleOperator.Subtract) && (leftSymbol.Value is BigInteger) && (leftSymbol.Value.Equals(BigInteger.Zero))) { thisCode.Operator = MiddleOperator.Minus; thisCode[0] = thisCode[1]; thisCode[1] = null; } // t0 = i + 0 // t0 = i - 0 else if (((thisCode.Operator == MiddleOperator.Add) || (thisCode.Operator == MiddleOperator.Subtract)) && (rightSymbol.Value is BigInteger) && (rightSymbol.Value.Equals(BigInteger.Zero))) { newSymbol = leftSymbol; } // t0 = 0 * i else if ((thisCode.Operator == MiddleOperator.Multiply) && (leftSymbol.Value is BigInteger) && (leftSymbol.Value.Equals(BigInteger.Zero))) { newSymbol = new Symbol(resultSymbol.Type, BigInteger.Zero); } // t0 = 1 * i else if ((thisCode.Operator == MiddleOperator.Multiply) && (leftSymbol.Value is BigInteger) && (leftSymbol.Value.Equals(BigInteger.One))) { newSymbol = rightSymbol; } // t0 = i * 0 else if ((thisCode.Operator == MiddleOperator.Multiply) && (rightSymbol.Value is BigInteger) && (rightSymbol.Value.Equals(BigInteger.Zero))) { newSymbol = new Symbol(resultSymbol.Type, BigInteger.Zero); } // t0 = -1 * i else if ((thisCode.Operator == MiddleOperator.Multiply) && (leftSymbol.Value is BigInteger) && (leftSymbol.Value.Equals(BigInteger.MinusOne))) { thisCode.Operator = MiddleOperator.Minus; thisCode[0] = thisCode[1]; thisCode[1] = null; } // t0 = i * -1 else if ((thisCode.Operator == MiddleOperator.Multiply) && (rightSymbol.Value is BigInteger) && (rightSymbol.Value.Equals(BigInteger.MinusOne))) { thisCode.Operator = MiddleOperator.Minus; thisCode[1] = null; } // t0 = i * 1 // t0 = i / 1 // t0 = i % 1 else if (((thisCode.Operator == MiddleOperator.Multiply) || (thisCode.Operator == MiddleOperator.Divide) || (thisCode.Operator == MiddleOperator.Modulo)) && (rightSymbol.Value is BigInteger) && (rightSymbol.Value.Equals(BigInteger.One))) { newSymbol = leftSymbol; } if (newSymbol != null) { if (resultSymbol.IsTemporary()) { thisCode.Operator = MiddleOperator.Empty; if (newSymbol.IsTemporary()) { int index2; for (index2 = (index - 1); index2 >= 0; --index2) { MiddleCode previousCode = m_middleCodeList[index2]; if (previousCode[0] == resultSymbol) { previousCode[0] = newSymbol; break; } } } { int index2; for (index2 = index + 1; index2 < m_middleCodeList.Count; ++index2) { MiddleCode nextCode = m_middleCodeList[index2]; if (nextCode[0] == resultSymbol) { nextCode[0] = newSymbol; } if (nextCode[1] == resultSymbol) { nextCode[1] = newSymbol; } if (nextCode[2] == resultSymbol) { nextCode[2] = newSymbol; } } } } else { thisCode.Operator = MiddleOperator.Assign; // i = 0 + j; thisCode[1] = newSymbol; // i = j; thisCode[2] = null; } m_update = true; } } } }
public static Expression ConstantCast(Expression sourceExpression, Type targetType) { if (!IsConstant(sourceExpression)) { return(null); } Symbol sourceSymbol = sourceExpression.Symbol, targetSymbol; Type sourceType = sourceSymbol.Type; object sourceValue = sourceSymbol.Value; List <MiddleCode> longList = new List <MiddleCode>(); if (sourceType.IsIntegralOrPointer() && targetType.IsFloating()) { decimal targetValue = ((decimal)((BigInteger)sourceValue)); targetSymbol = new Symbol(targetType, targetValue); } else if (sourceType.IsFloating() && targetType.IsIntegralOrPointer()) { BigInteger targetValue = ((BigInteger)((decimal)sourceValue)); targetSymbol = new Symbol(targetType, targetValue); } else if (sourceType.IsLogical() && targetType.IsArithmeticOrPointer()) { bool isTrue = (sourceSymbol.TrueSet.Count > 0); object targetValue; if (targetType.IsIntegralOrPointer()) { targetValue = isTrue ? BigInteger.One : BigInteger.Zero; } else { targetValue = isTrue ? decimal.One : decimal.Zero; } targetSymbol = new Symbol(targetType, targetValue); } else if (sourceType.IsArithmeticOrPointer() && targetType.IsLogical()) { bool isTrue = !sourceValue.Equals(BigInteger.Zero) && !sourceValue.Equals(decimal.Zero); MiddleCode gotoCode = new MiddleCode(MiddleOperator.Jump); longList.Add(gotoCode); ISet <MiddleCode> trueSet = new HashSet <MiddleCode>(), falseSet = new HashSet <MiddleCode>(); if (isTrue) { trueSet.Add(gotoCode); } else { falseSet.Add(gotoCode); } targetSymbol = new Symbol(trueSet, falseSet); } else { targetSymbol = new Symbol(targetType, sourceValue); } if (targetType.IsFloating()) { longList.Add(new MiddleCode(MiddleOperator.PushFloat, targetSymbol)); } return(new Expression(targetSymbol, null, longList)); }
public static Expression Relation(MiddleOperator middleOp, Expression leftExpression, Expression rightExpression) { if (!IsConstant(leftExpression) || !IsConstant(rightExpression)) { return(null); } leftExpression = LogicalToIntegral(leftExpression); rightExpression = LogicalToIntegral(rightExpression); Type leftType = leftExpression.Symbol.Type, rightType = rightExpression.Symbol.Type; object leftValue = leftExpression.Symbol.Value, rightValue = rightExpression.Symbol.Value; int compareTo = 0; if (leftType.IsFloating() || rightType.IsFloating()) { decimal leftDecimal, rightDecimal; if (leftValue is BigInteger) { leftDecimal = (decimal)((BigInteger)leftValue); rightDecimal = (decimal)rightValue; } else if (rightValue is BigInteger) { leftDecimal = (decimal)leftValue; rightDecimal = (decimal)((BigInteger)rightValue); } else { leftDecimal = (decimal)leftValue; rightDecimal = (decimal)rightValue; } compareTo = leftDecimal.CompareTo(rightDecimal); } else { BigInteger leftBigInteger = (BigInteger)leftExpression.Symbol.Value, rightBigInteger = (BigInteger)rightExpression.Symbol.Value; compareTo = leftBigInteger.CompareTo(rightBigInteger); } bool resultValue = false; switch (middleOp) { case MiddleOperator.Equal: resultValue = (compareTo == 0); break; case MiddleOperator.NotEqual: resultValue = (compareTo != 0); break; case MiddleOperator.LessThan: resultValue = (compareTo < 0); break; case MiddleOperator.LessThanEqual: resultValue = (compareTo <= 0); break; case MiddleOperator.GreaterThan: resultValue = (compareTo > 0); break; case MiddleOperator.GreaterThanEqual: resultValue = (compareTo >= 0); break; } List <MiddleCode> longList = new List <MiddleCode>(); MiddleCode jumpCode = new MiddleCode(MiddleOperator.Jump); longList.Add(jumpCode); ISet <MiddleCode> jumpSet = new HashSet <MiddleCode>(); jumpSet.Add(jumpCode); Symbol resultSymbol = new Symbol(null, null); if (resultValue) { resultSymbol.TrueSet = jumpSet; } else { resultSymbol.FalseSet = jumpSet; } return(new Expression(resultSymbol, null, longList)); }
public static Expression ExplicitCast(Expression sourceExpression, Type targetType) { Expression constantExpression = ConstantExpression.ConstantCast(sourceExpression, targetType); if (constantExpression != null) { return(constantExpression); } Symbol sourceSymbol = sourceExpression.Symbol, targetSymbol = null; Type sourceType = sourceSymbol.Type; List <MiddleCode> shortList = sourceExpression.ShortList, longList = sourceExpression.LongList; if (targetType.IsVoid()) { targetSymbol = new Symbol(targetType); } else if (sourceType.IsStructOrUnion() && targetType.IsStructOrUnion()) { Assert.Error(sourceType.Equals(targetType), sourceType + " to " + targetType, Message.Invalid_type_cast); targetSymbol = new Symbol(targetType); } else if (sourceType.IsLogical() && targetType.IsIntegralPointerOrArray()) { targetSymbol = new Symbol(targetType); Symbol oneSymbol = new Symbol(targetType, BigInteger.One); MiddleCode trueCode = new MiddleCode(MiddleOperator.Assign, targetSymbol, oneSymbol); MiddleCodeGenerator.Backpatch(sourceSymbol.TrueSet, trueCode); longList.Add(trueCode); MiddleCode targetCode = new MiddleCode(MiddleOperator.Empty); longList.Add(new MiddleCode(MiddleOperator.Jump, targetCode)); Symbol zeroSymbol = new Symbol(targetType, BigInteger.Zero); MiddleCode falseCode = new MiddleCode(MiddleOperator.Assign, targetSymbol, zeroSymbol); MiddleCodeGenerator.Backpatch(sourceSymbol.FalseSet, falseCode); longList.Add(falseCode); longList.Add(targetCode); } else if (sourceType.IsLogical() && targetType.IsFloating()) { targetSymbol = new Symbol(targetType); MiddleCode trueCode = new MiddleCode(MiddleOperator.PushOne); MiddleCodeGenerator.Backpatch(sourceSymbol.TrueSet, trueCode); longList.Add(trueCode); MiddleCode targetCode = new MiddleCode(MiddleOperator.Empty); longList.Add(new MiddleCode(MiddleOperator.Jump, targetCode)); MiddleCode falseCode = new MiddleCode(MiddleOperator.PushZero); MiddleCodeGenerator.Backpatch(sourceSymbol.FalseSet, falseCode); longList.Add(falseCode); longList.Add(targetCode); } else if ((sourceType.IsArithmetic() || sourceType.IsPointerArrayStringOrFunction()) && targetType.IsLogical()) { object zeroValue = sourceType.IsLogical() ? ((object)decimal.Zero) : ((object)BigInteger.Zero); Symbol zeroSymbol = new Symbol(targetType, zeroValue); MiddleCode testCode = new MiddleCode(MiddleOperator.NotEqual, null, sourceSymbol, zeroSymbol); ISet <MiddleCode> trueSet = new HashSet <MiddleCode>(); trueSet.Add(testCode); longList.Add(testCode); MiddleCode gotoCode = new MiddleCode(MiddleOperator.Jump); ISet <MiddleCode> falseSet = new HashSet <MiddleCode>(); falseSet.Add(gotoCode); longList.Add(gotoCode); targetSymbol = new Symbol(trueSet, falseSet); } else if (sourceType.IsFloating() && targetType.IsFloating()) { targetSymbol = new Symbol(targetType); } else if (sourceType.IsFloating() && targetType.IsIntegralPointerOrArray()) { targetSymbol = new Symbol(targetType); if (targetType.Size() == 1) { Type tempType = sourceType.IsSigned() ? Type.SignedIntegerType : Type.UnsignedIntegerType; Symbol tempSymbol = new Symbol(tempType); MiddleCode tempCode = new MiddleCode(MiddleOperator.FloatingToIntegral, tempSymbol, sourceSymbol); longList.Add(tempCode); MiddleCode resultCode = new MiddleCode(MiddleOperator.IntegralToIntegral, targetSymbol, tempSymbol); longList.Add(resultCode); } else { MiddleCode resultCode = new MiddleCode(MiddleOperator.FloatingToIntegral, targetSymbol, sourceSymbol); longList.Add(resultCode); } } else if (sourceType.IsIntegralPointerArrayStringOrFunction() && targetType.IsFloating()) { targetSymbol = new Symbol(targetType); if (sourceType.Size() == 1) { Type tempType = sourceType.IsSigned() ? Type.SignedIntegerType : Type.UnsignedIntegerType; Symbol tempSymbol = new Symbol(tempType); MiddleCodeGenerator. AddMiddleCode(longList, MiddleOperator.IntegralToIntegral, tempSymbol, sourceSymbol); MiddleCodeGenerator. AddMiddleCode(longList, MiddleOperator.IntegralToFloating, targetSymbol, tempSymbol); } else { MiddleCodeGenerator. AddMiddleCode(longList, MiddleOperator.IntegralToFloating, targetSymbol, sourceSymbol); } } else if (sourceType.IsIntegralPointerArrayStringOrFunction() && targetType.IsIntegralPointerOrArray()) { targetSymbol = new Symbol(targetType); MiddleCodeGenerator. AddMiddleCode(longList, MiddleOperator.IntegralToIntegral, targetSymbol, sourceSymbol); } Assert.Error(targetSymbol != null, sourceType + " to " + targetType, Message.Invalid_type_cast); return(new Expression(targetSymbol, shortList, longList)); }