private static Expression ArithmeticFloating(MiddleOperator middleOp, Expression leftExpression, Expression rightExpression) { leftExpression = TypeCast.LogicalToFloating(leftExpression); rightExpression = TypeCast.LogicalToFloating(rightExpression); Type maxType = TypeCast.MaxType(leftExpression.Symbol.Type, rightExpression.Symbol.Type); leftExpression = ConstantCast(leftExpression, maxType); rightExpression = ConstantCast(rightExpression, maxType); decimal leftDecimal = (decimal)leftExpression.Symbol.Value, rightDecimal = (decimal)rightExpression.Symbol.Value, resultDecimal = 0; switch (middleOp) { case MiddleOperator.Add: resultDecimal = leftDecimal + rightDecimal; break; case MiddleOperator.Subtract: resultDecimal = leftDecimal - rightDecimal; break; case MiddleOperator.Multiply: resultDecimal = leftDecimal * rightDecimal; break; case MiddleOperator.Divide: resultDecimal = leftDecimal / rightDecimal; break; } Symbol resultSymbol = new Symbol(maxType, resultDecimal); List <MiddleCode> longList = new List <MiddleCode>(); MiddleCodeGenerator.AddMiddleCode(longList, MiddleOperator.PushFloat, resultSymbol); return(new Expression(resultSymbol, null, longList)); }
private static Expression ArithmeticFloating(MiddleOperator middleOp, Expression expression) { expression = LogicalToFloating(expression); decimal value = (decimal)expression.Symbol.Value; Symbol resultSymbol = null; switch (middleOp) { case MiddleOperator.Plus: resultSymbol = new Symbol(expression.Symbol.Type, value); break; case MiddleOperator.Minus: resultSymbol = new Symbol(expression.Symbol.Type, -value); break; } List <MiddleCode> longList = new List <MiddleCode>(); MiddleCodeGenerator.AddMiddleCode(longList, MiddleOperator.PushFloat, resultSymbol); 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)); }
public static void GenerateAuto(List <MiddleCode> codeList, Symbol toSymbol, object fromInit) { Type toType = toSymbol.Type; if (toType.IsArray() && toType.ArrayType.IsChar() && (fromInit is Expression) && ((Expression)fromInit).Symbol().Type.IsString()) { fromInit = TextToCharList((string)((Expression)fromInit).Symbol().Value); } if (fromInit is Expression) { Expression initExpr = (Expression)fromInit; codeList.AddRange(initExpr.LongList()); Symbol initSymbol = TypeCast.ImplicitCast(codeList, initExpr.Symbol(), toType); if (toType.IsFloating()) { MiddleCodeGenerator.AddMiddleCode(codeList, MiddleOperator.PopFloat, toSymbol); } else { MiddleCodeGenerator.AddMiddleCode(codeList, MiddleOperator.Assign, toSymbol, initSymbol); } } else { List <object> fromList = (List <object>)fromInit; switch (toType.Sort) { case Sort.Array: { if (toType.ArraySize == 0) { toType.ArraySize = fromList.Count; } Assert.Error(fromList.Count <= toType.ArraySize, toType, Message.Too_many_initializers); //Assert.Warning(fromList.Count == toType.ArraySize, toType, Message.Too_few_initializers); Type arrayType = toType.ArrayType; for (int index = 0; index < fromList.Count; ++index) { Symbol subSymbol = new Symbol(arrayType, false); subSymbol.Offset = toSymbol.Offset + (index * arrayType.Size()); subSymbol.Name = toSymbol.Name + "[" + index + "]"; GenerateAuto(codeList, subSymbol, fromList[index]); } } break; case Sort.Struct: { IDictionary <string, Symbol> memberMap = toType.MemberMap; Assert.Error(fromList.Count <= memberMap.Count, toType, Message.Too_many_initializers); /*Assert.Warning(fromList.Count == memberMap.Count, * toType, Message.Too_few_initializers);*/ KeyValuePair <string, Symbol>[] memberArray = new KeyValuePair <string, Symbol> [memberMap.Count]; memberMap.CopyTo(memberArray, 0); for (int index = 0; index < fromList.Count; ++index) { Symbol memberSymbol = memberArray[index].Value; Symbol subSymbol = new Symbol(memberSymbol.Type, false); subSymbol.Name = toSymbol.Name + Symbol.SeparatorId + memberSymbol.Name; subSymbol.Offset = toSymbol.Offset + memberSymbol.Offset; GenerateAuto(codeList, subSymbol, fromList[index]); } } break; case Sort.Union: { Assert.Error(fromList.Count == 1, toType, Message.A_union_can_be_initalized_by_one_value_only); IDictionary <string, Symbol> memberMap = toType.MemberMap; Symbol firstSymbol = memberMap.Values.GetEnumerator().Current; Symbol subSymbol = new Symbol(firstSymbol.Type); subSymbol.Name = toSymbol.Name + Symbol.SeparatorId + firstSymbol.Name; subSymbol.Offset = toSymbol.Offset; GenerateAuto(codeList, subSymbol, fromList[0]); } break; } } }