private String ValueAsString(object Value, Type Type = null) { if (Type == null) { Type = (Value != null) ? Value.GetType() : typeof(Object); } if (Value == null) { return("null"); } if (Value is bool) { return(Value.ToString().ToLower()); } else if (Value is IntPtr) { return(String.Format("0x{0:X}", ((IntPtr)Value).ToInt64())); } else if (Value is string) { return(String.Format("{0}", AstStringUtils.ToLiteral(Value as string))); } else if (!AstUtils.IsTypeSigned(Type)) { //StringValue = String.Format("0x{0:X8}", ItemValue); if (Convert.ToInt64(Value) > 9) { return(String.Format("0x{0:X}", Value)); } } return(Value.ToString()); }
private static string ValueAsString(object value, Type type = null) { if (type == null) { type = value?.GetType() ?? typeof(object); } if (value == null) { return("null"); } if (value is bool) { return(value.ToString().ToLower()); } if (value is IntPtr) { return($"0x{((IntPtr) value).ToInt64():X}"); } if (value is string) { return($"{AstStringUtils.ToLiteral(value as string)}"); } if (AstUtils.IsTypeSigned(type)) { return(value.ToString()); } if (Convert.ToInt64(value) > 9) { return($"0x{value:X}"); } return(value.ToString()); }
protected virtual AstNode _Optimize(AstNodeExprBinop binary) { //Console.WriteLine("Optimize.AstNodeExprBinop: {0} {1} {2}", Binary.LeftNode, Binary.Operator, Binary.RightNode); var leftImm = binary.LeftNode as AstNodeExprImm; var rightImm = binary.RightNode as AstNodeExprImm; var leftType = binary.LeftNode.Type; var rightType = binary.RightNode.Type; var Operator = binary.Operator; if (leftType == rightType) { if (AstUtils.IsTypeFloat(leftType)) { var type = leftType; if (leftImm != null && rightImm != null) { var leftValue = Convert.ToDouble(leftImm.Value); var rightValue = Convert.ToDouble(rightImm.Value); switch (Operator) { case "+": return(new AstNodeExprImm(AstUtils.CastType(leftValue + rightValue, type))); case "-": return(new AstNodeExprImm(AstUtils.CastType(leftValue - rightValue, type))); case "*": return(new AstNodeExprImm(AstUtils.CastType(leftValue * rightValue, type))); case "/": return(new AstNodeExprImm(AstUtils.CastType(leftValue / rightValue, type))); } } else if (leftImm != null) { var leftValue = Convert.ToInt64(leftImm.Value); switch (Operator) { case "|": if (leftValue == 0) { return(binary.RightNode); } break; case "+": if (leftValue == 0) { return(binary.RightNode); } break; case "-": if (leftValue == 0) { return(new AstNodeExprUnop("-", binary.RightNode)); } break; case "*": //if (LeftValue == 0) return new AstNodeExprImm(AstUtils.CastType(0, Type)); if (leftValue == 1) { return(binary.RightNode); } break; case "/": //if (LeftValue == 0) return new AstNodeExprImm(AstUtils.CastType(0, Type)); break; } } else if (rightImm != null) { var rightValue = Convert.ToInt64(rightImm.Value); switch (Operator) { case "|": if (rightValue == 0) { return(binary.LeftNode); } break; case "+": if (rightValue == 0) { return(binary.LeftNode); } break; case "-": if (rightValue == 0) { return(binary.LeftNode); } break; case "*": if (rightValue == 1) { return(binary.LeftNode); } break; case "/": //if (LeftValue == 0) return new AstNodeExprImm(AstUtils.CastType(0, Type)); break; } } } else { var unop = binary.RightNode as AstNodeExprUnop; if (unop != null) { var rightUnary = unop; if (Operator == "+" || Operator == "-") { if (rightUnary.Operator == "-") { return(new AstNodeExprBinop(binary.LeftNode, Operator == "+" ? "-" : "+", rightUnary.RightNode)); } } } var type = leftType; // Can optimize just literal values. if (leftImm != null && rightImm != null) { if (AstUtils.IsTypeSigned(leftType)) { var leftValue = Convert.ToInt64(leftImm.Value); var rightValue = Convert.ToInt64(rightImm.Value); switch (Operator) { case "+": return(new AstNodeExprImm(AstUtils.CastType(leftValue + rightValue, type))); case "-": return(new AstNodeExprImm(AstUtils.CastType(leftValue - rightValue, type))); case "*": return(new AstNodeExprImm(AstUtils.CastType(leftValue * rightValue, type))); case "/": return(new AstNodeExprImm(AstUtils.CastType(leftValue / rightValue, type))); case "<<": return(new AstNodeExprImm(AstUtils.CastType(leftValue << (int)rightValue, type))); case ">>": return(new AstNodeExprImm(AstUtils.CastType(leftValue >> (int)rightValue, type))); } } else { var leftValue = Convert.ToUInt64(leftImm.Value); var rightValue = Convert.ToUInt64(rightImm.Value); // Optimize adding 0 switch (Operator) { case "+": return(new AstNodeExprImm(AstUtils.CastType(leftValue + rightValue, type))); case "-": return(new AstNodeExprImm(AstUtils.CastType(leftValue - rightValue, type))); case "*": return(new AstNodeExprImm(AstUtils.CastType(leftValue * rightValue, type))); case "/": return(new AstNodeExprImm(AstUtils.CastType(leftValue / rightValue, type))); case "<<": return(new AstNodeExprImm(AstUtils.CastType(leftValue << (int)rightValue, type))); case ">>": return(new AstNodeExprImm(AstUtils.CastType(leftValue >> (int)rightValue, type))); } } } else if (leftImm != null) { var leftValue = Convert.ToInt64(leftImm.Value); switch (Operator) { case "&": if (leftValue == 0) { return(new AstNodeExprImm(0)); } break; case "|": if (leftValue == 0) { return(binary.RightNode); } break; case "+": if (leftValue == 0) { return(binary.RightNode); } break; case "-": if (leftValue == 0) { return(new AstNodeExprUnop("-", binary.RightNode)); } break; case "*": //if (LeftValue == 0) return new AstNodeExprImm(AstUtils.CastType(0, Type)); if (leftValue == 1) { return(binary.RightNode); } break; case "/": //if (LeftValue == 0) return new AstNodeExprImm(AstUtils.CastType(0, Type)); break; } } else if (rightImm != null) { var rightValue = Convert.ToInt64(rightImm.Value); switch (Operator) { case "0": if (rightValue == 0) { return(new AstNodeExprImm(0)); } break; case "|": if (rightValue == 0) { return(binary.LeftNode); } break; case "+": if (rightValue == 0) { return(binary.LeftNode); } if (rightValue < 0) { return(new AstNodeExprBinop(binary.LeftNode, "-", new AstNodeExprImm(AstUtils.Negate(rightImm.Value)))); } break; case "-": if (rightValue == 0) { return(binary.LeftNode); } break; case "*": if (rightValue == 1) { return(binary.LeftNode); } break; case "/": //if (RightValue == 0) throw(new Exception("Can't divide by 0")); if (rightValue == 1) { return(binary.LeftNode); } break; } } } // !AstUtils.IsTypeFloat(LeftType) } // Special optimizations if ((leftType == typeof(uint) || leftType == typeof(int)) && rightType == typeof(int) && rightImm != null) { var rightValue = Convert.ToInt64(rightImm.Value); if (Operator == ">>" && rightValue == 0) { return(binary.LeftNode); } } return(binary); }
protected virtual void _Generate(AstNodeExprBinop item) { var leftType = item.LeftNode.Type; //var rightType = item.RightNode.Type; //if (LeftType != RightType) throw(new Exception(String.Format("BinaryOp Type mismatch ({0}) != ({1})", LeftType, RightType))); //Item.GetType().GenericTypeArguments[0] Generate(item.LeftNode); Generate(item.RightNode); //switch (Item.Operator) //{ // case "||": // case "&&": // if (LeftType != typeof(bool) || RightType != typeof(bool)) // { // throw(new InvalidOperationException(String.Format("Operator '{0}' requires boolean types but found {1}, {2}", Item.Operator, LeftType, RightType))); // } // break; //} switch (item.Operator) { case "+": Emit(OpCodes.Add); break; case "-": Emit(OpCodes.Sub); break; case "*": Emit(OpCodes.Mul); break; case "/": Emit(AstUtils.IsTypeSigned(leftType) ? OpCodes.Div : OpCodes.Div_Un); break; case "%": Emit(AstUtils.IsTypeSigned(leftType) ? OpCodes.Rem : OpCodes.Rem_Un); break; case "==": Emit(OpCodes.Ceq); break; case "!=": Emit(OpCodes.Ceq); Emit(OpCodes.Ldc_I4_0); Emit(OpCodes.Ceq); break; case "<": Emit(AstUtils.IsTypeSigned(leftType) ? OpCodes.Clt : OpCodes.Clt_Un); break; case ">": Emit(AstUtils.IsTypeSigned(leftType) ? OpCodes.Cgt : OpCodes.Cgt_Un); break; case "<=": Emit(AstUtils.IsTypeSigned(leftType) ? OpCodes.Cgt : OpCodes.Cgt_Un); Emit(OpCodes.Ldc_I4_0); Emit(OpCodes.Ceq); break; case ">=": Emit(AstUtils.IsTypeSigned(leftType) ? OpCodes.Clt : OpCodes.Clt_Un); Emit(OpCodes.Ldc_I4_0); Emit(OpCodes.Ceq); break; case "&": case "&&": Emit(OpCodes.And); break; case "|": case "||": Emit(OpCodes.Or); break; case "^": Emit(OpCodes.Xor); break; case "<<": Emit(OpCodes.Shl); break; case ">>": Emit(AstUtils.IsTypeSigned(leftType) ? OpCodes.Shr : OpCodes.Shr_Un); break; default: throw new NotImplementedException($"Not implemented operator '{item.Operator}'"); } }
protected virtual AstNode _Optimize(AstNodeExprBinop Binary) { //Console.WriteLine("Optimize.AstNodeExprBinop: {0} {1} {2}", Binary.LeftNode, Binary.Operator, Binary.RightNode); var LeftImm = (Binary.LeftNode as AstNodeExprImm); var RightImm = (Binary.RightNode as AstNodeExprImm); var LeftType = Binary.LeftNode.Type; var RightType = Binary.RightNode.Type; var Operator = Binary.Operator; if ((LeftType == RightType)) { if (AstUtils.IsTypeFloat(LeftType)) { var Type = LeftType; if ((LeftImm != null) && (RightImm != null)) { var LeftValue = Convert.ToDouble(LeftImm.Value); var RightValue = Convert.ToDouble(RightImm.Value); switch (Operator) { case "+": return(new AstNodeExprImm(AstUtils.CastType(LeftValue + RightValue, Type))); case "-": return(new AstNodeExprImm(AstUtils.CastType(LeftValue - RightValue, Type))); case "*": return(new AstNodeExprImm(AstUtils.CastType(LeftValue * RightValue, Type))); case "/": return(new AstNodeExprImm(AstUtils.CastType(LeftValue / RightValue, Type))); } } else if (LeftImm != null) { var LeftValue = Convert.ToInt64(LeftImm.Value); switch (Operator) { case "|": if (LeftValue == 0) { return(Binary.RightNode); } break; case "+": if (LeftValue == 0) { return(Binary.RightNode); } break; case "-": if (LeftValue == 0) { return(new AstNodeExprUnop("-", Binary.RightNode)); } break; case "*": //if (LeftValue == 0) return new AstNodeExprImm(AstUtils.CastType(0, Type)); if (LeftValue == 1) { return(Binary.RightNode); } break; case "/": //if (LeftValue == 0) return new AstNodeExprImm(AstUtils.CastType(0, Type)); break; } } else if (RightImm != null) { var RightValue = Convert.ToInt64(RightImm.Value); switch (Operator) { case "|": if (RightValue == 0) { return(Binary.LeftNode); } break; case "+": if (RightValue == 0) { return(Binary.LeftNode); } break; case "-": if (RightValue == 0) { return(Binary.LeftNode); } break; case "*": if (RightValue == 1) { return(Binary.LeftNode); } break; case "/": //if (LeftValue == 0) return new AstNodeExprImm(AstUtils.CastType(0, Type)); break; } } } else { if (Binary.RightNode is AstNodeExprUnop) { var RightUnary = Binary.RightNode as AstNodeExprUnop; if (Operator == "+" || Operator == "-") { if (RightUnary.Operator == "-") { return(new AstNodeExprBinop(Binary.LeftNode, (Operator == "+") ? "-" : "+", RightUnary.RightNode)); } } } var Type = LeftType; // Can optimize just literal values. if ((LeftImm != null) && (RightImm != null)) { if (AstUtils.IsTypeSigned(LeftType)) { var LeftValue = Convert.ToInt64(LeftImm.Value); var RightValue = Convert.ToInt64(RightImm.Value); switch (Operator) { case "+": return(new AstNodeExprImm(AstUtils.CastType(LeftValue + RightValue, Type))); case "-": return(new AstNodeExprImm(AstUtils.CastType(LeftValue - RightValue, Type))); case "*": return(new AstNodeExprImm(AstUtils.CastType(LeftValue * RightValue, Type))); case "/": return(new AstNodeExprImm(AstUtils.CastType(LeftValue / RightValue, Type))); case "<<": return(new AstNodeExprImm(AstUtils.CastType(LeftValue << (int)RightValue, Type))); case ">>": return(new AstNodeExprImm(AstUtils.CastType(LeftValue >> (int)RightValue, Type))); } } else { var LeftValue = Convert.ToUInt64(LeftImm.Value); var RightValue = Convert.ToUInt64(RightImm.Value); // Optimize adding 0 switch (Operator) { case "+": return(new AstNodeExprImm(AstUtils.CastType(LeftValue + RightValue, Type))); case "-": return(new AstNodeExprImm(AstUtils.CastType(LeftValue - RightValue, Type))); case "*": return(new AstNodeExprImm(AstUtils.CastType(LeftValue * RightValue, Type))); case "/": return(new AstNodeExprImm(AstUtils.CastType(LeftValue / RightValue, Type))); case "<<": return(new AstNodeExprImm(AstUtils.CastType(LeftValue << (int)RightValue, Type))); case ">>": return(new AstNodeExprImm(AstUtils.CastType(LeftValue >> (int)RightValue, Type))); } } } else if (LeftImm != null) { var LeftValue = Convert.ToInt64(LeftImm.Value); switch (Operator) { case "&": if (LeftValue == 0) { return(new AstNodeExprImm(0)); } break; case "|": if (LeftValue == 0) { return(Binary.RightNode); } break; case "+": if (LeftValue == 0) { return(Binary.RightNode); } break; case "-": if (LeftValue == 0) { return(new AstNodeExprUnop("-", Binary.RightNode)); } break; case "*": //if (LeftValue == 0) return new AstNodeExprImm(AstUtils.CastType(0, Type)); if (LeftValue == 1) { return(Binary.RightNode); } break; case "/": //if (LeftValue == 0) return new AstNodeExprImm(AstUtils.CastType(0, Type)); break; } } else if (RightImm != null) { var RightValue = Convert.ToInt64(RightImm.Value); switch (Operator) { case "0": if (RightValue == 0) { return(new AstNodeExprImm(0)); } break; case "|": if (RightValue == 0) { return(Binary.LeftNode); } break; case "+": if (RightValue == 0) { return(Binary.LeftNode); } if (RightValue < 0) { return(new AstNodeExprBinop(Binary.LeftNode, "-", new AstNodeExprImm(AstUtils.Negate(RightImm.Value)))); } break; case "-": if (RightValue == 0) { return(Binary.LeftNode); } break; case "*": if (RightValue == 1) { return(Binary.LeftNode); } break; case "/": //if (RightValue == 0) throw(new Exception("Can't divide by 0")); if (RightValue == 1) { return(Binary.LeftNode); } break; } } } // !AstUtils.IsTypeFloat(LeftType) } // Special optimizations if ((LeftType == typeof(uint) || LeftType == typeof(int)) && RightType == typeof(int)) { if (RightImm != null) { var RightValue = Convert.ToInt64(RightImm.Value); if (Operator == ">>" && (RightValue == 0)) { return(Binary.LeftNode); } } } return(Binary); }