internal static ConversionSymbol VarArgumentConversion(Arg arg, TypeSymbol type, BindOptions options) { if (arg == null || arg.Expr is EmptyExpr) { return(ConversionSymbol.Create(Constant.CreateDefault(type))); } var conv = Conversion(arg.Expr, type, options); return(conv); }
internal static ConversionSymbol ArgumentConversion(Arg arg, ParameterInfo param, BindOptions options) { if (arg == null || arg.Expr is EmptyExpr) { var type = FindType(param.ParameterType); if (param.HasDefaultValue && type.NativeType != NativeType.Unknown) { return(ConversionSymbol.Create(Constant.Create(param.DefaultValue, type.NativeType))); } else if (param.HasDefaultValue || param.IsOptional) { return(ConversionSymbol.Create(Constant.CreateDefault(type))); } else { var defValAttr = Compilation.Get(WellKnownTypes.DefaultParameterValueAttribute); foreach (var attr in param.CustomAttributes) { if (attr.AttributeType == defValAttr.Type) { int desc = attr.ConstructorArguments[1].Value as int? ?? -1; var val = attr.ConstructorArguments[0]; switch (desc) { case 0: // normal .Net Object // return value or null if (val.ArgumentType != null && val.Value != null) { var valType = FindType(val.ArgumentType); if (valType.NativeType == NativeType.Unknown) { // Enum type? can be casted to Int32 return(ConversionSymbol.Create(Constant.Create(val.Value, NativeType.Int32))); } else { return(ConversionSymbol.Create(Constant.Create(val.Value, valType.NativeType))); } } else { return(ConversionSymbol.Create(Constant.Null)); } case 1: // NIL return(ConversionSymbol.Create(Constant.Nil)); case 2: // Date, value should be long of ticks. Return DateTime DateTime dt = new DateTime((long)val.Value); return(ConversionSymbol.Create(Constant.Create(dt))); case 3: // Symbol, value should be a string literal or null if (val.Value == null) { return(ConversionSymbol.Create(Constant.Null)); } else { return(ConversionSymbol.Create(Constant.Create((string)val.Value))); } case 4: // Psz, value should be a string or null if (val.Value == null) { return(ConversionSymbol.Create(Constant.Null)); } else { return(ConversionSymbol.Create(Constant.Create((string)val.Value))); } case 5: // IntPtr, return value as IntPtr if (val.Value == null) { return(ConversionSymbol.Create(Constant.Null)); } else { int i = val.Value as int? ?? 0; IntPtr p = new IntPtr(i); return(ConversionSymbol.Create(Constant.Create(p))); } default: return(ConversionSymbol.Create(Constant.Null)); } } } } return(ConversionSymbol.Create(ConversionKind.NoConversion)); } var conv = Conversion(arg.Expr, FindType(param.ParameterType), options); return(conv); }
internal Constant CreateLiteral(LiteralExpr expr, string Value) { switch (expr.Kind) { case TokenType.TRUE_CONST: return(Constant.Create(true)); case TokenType.FALSE_CONST: return(Constant.Create(false)); case TokenType.CHAR_CONST: return(Constant.Create(Literals.CharValue(Value))); case TokenType.STRING_CONST: return(Constant.Create(Literals.StringValue(Value))); case TokenType.ESCAPED_STRING_CONST: return(Constant.Create(Literals.EscapedStringValue(Value))); case TokenType.INTERPOLATED_STRING_CONST: return(Constant.Create(Literals.StringValue(Value))); case TokenType.SYMBOL_CONST: return(Constant.CreateSymbol(Value.StartsWith("#") ? Value.Substring(1).ToUpperInvariant() : Value.ToUpperInvariant())); case TokenType.BINARY_CONST: return(Constant.CreateBinary(Literals.BinaryValue(Value))); case TokenType.HEX_CONST: switch (Value.Last()) { case 'U': case 'u': if (Value.Length > 8 + 3) { return(Constant.Create(unchecked ((ulong)Literals.HexValue(Value.Substring(2))))); } else { return(Constant.Create(unchecked ((uint)Literals.HexValue(Value.Substring(2))))); } case 'L': case 'l': if (Value.Length > 8 + 3) { return(Constant.Create(Literals.HexValue(Value.Substring(2)))); } else { return(Constant.Create(unchecked ((int)Literals.HexValue(Value.Substring(2))))); } default: { long l = Literals.HexValue(Value.Substring(2)); if (l < 0) { return(Constant.Create(unchecked ((ulong)l))); } else if (l > uint.MaxValue) { return(Constant.Create(l)); } else if (l > int.MaxValue) { return(Constant.Create(unchecked ((uint)l))); } else { return(Constant.Create(unchecked ((int)l))); } } } case TokenType.BIN_CONST: switch (Value.Last()) { case 'U': case 'u': if (Value.Length > 32 + 3) { return(Constant.Create(unchecked ((ulong)Literals.BinValue(Value.Substring(2))))); } else { return(Constant.Create(unchecked ((uint)Literals.BinValue(Value.Substring(2))))); } case 'L': case 'l': if (Value.Length > 32 + 3) { return(Constant.Create(Literals.BinValue(Value.Substring(2)))); } else { return(Constant.Create(unchecked ((int)Literals.BinValue(Value.Substring(2))))); } default: { long l = Literals.BinValue(Value.Substring(2)); if (l < 0) { return(Constant.Create(unchecked ((ulong)l))); } else if (l > uint.MaxValue) { return(Constant.Create(l)); } else if (l > int.MaxValue) { return(Constant.Create(unchecked ((uint)l))); } else { return(Constant.Create(unchecked ((int)l))); } } } case TokenType.REAL_CONST: char spec = Value.First() == '$' ? '$' : Value.Last(); switch (spec) { case 'M': case 'm': try { return(Constant.Create(decimal.Parse(Value.Substring(0, Value.Length - 1), System.Globalization.CultureInfo.InvariantCulture))); } catch (OverflowException) { throw expr.Error(ErrorCode.LiteralFloatOverflow); } case 'S': case 's': try { return(Constant.Create(float.Parse(Value.Substring(0, Value.Length - 1), System.Globalization.CultureInfo.InvariantCulture))); } catch (OverflowException) { throw expr.Error(ErrorCode.LiteralFloatOverflow); } case 'D': case 'd': try { return(Constant.Create(double.Parse(Value.Substring(0, Value.Length - 1), System.Globalization.CultureInfo.InvariantCulture))); } catch (OverflowException) { throw expr.Error(ErrorCode.LiteralFloatOverflow); } case '$': try { return(Constant.CreateCurrency(decimal.Parse(Value.Substring(1, Value.Length - 1), System.Globalization.CultureInfo.InvariantCulture))); } catch (OverflowException) { throw expr.Error(ErrorCode.LiteralFloatOverflow); } default: try { if (Options.VOFloatConstants) { var args = Value.Split('.'); if (args.Length == 2) { int dec = 0; while (args[1].Length > dec && Char.IsDigit(args[1][dec])) { dec++; } return(Constant.Create(double.Parse(Value, System.Globalization.CultureInfo.InvariantCulture), 0, dec)); } return(Constant.Create(double.Parse(Value, System.Globalization.CultureInfo.InvariantCulture))); } else { return(Constant.Create(double.Parse(Value, System.Globalization.CultureInfo.InvariantCulture))); } } catch (OverflowException) { throw expr.Error(ErrorCode.LiteralFloatOverflow); } } case TokenType.INT_CONST: switch (Value.Last()) { case 'U': case 'u': try { ulong ul = ulong.Parse(Value.Substring(0, Value.Length - 1), System.Globalization.CultureInfo.InvariantCulture); if (ul > uint.MaxValue) { return(Constant.Create(ul)); } else { return(Constant.Create(unchecked ((uint)ul))); } } catch (OverflowException) { throw expr.Error(ErrorCode.LiteralIntegerOverflow); } case 'L': case 'l': try { long l = long.Parse(Value.Substring(0, Value.Length - 1), System.Globalization.CultureInfo.InvariantCulture); if (l > int.MaxValue) { return(Constant.Create(l)); } else { return(Constant.Create(unchecked ((int)l))); } } catch (OverflowException) { throw expr.Error(ErrorCode.LiteralIntegerOverflow); } default: try { ulong un = 0; long n = 0; if (Value.First() != '-') { un = ulong.Parse(Value, System.Globalization.CultureInfo.InvariantCulture); if (un <= long.MaxValue) { n = unchecked ((long)un); } } else { n = long.Parse(Value, System.Globalization.CultureInfo.InvariantCulture); } if (un > long.MaxValue) { return(Constant.Create(un)); } else if (n > uint.MaxValue) { return(Constant.Create(n)); } else if (n > int.MaxValue) { return(Constant.Create(unchecked ((uint)n))); } else { return(Constant.Create(unchecked ((int)n))); } } catch (OverflowException) { throw expr.Error(ErrorCode.LiteralIntegerOverflow); } } case TokenType.NULL: return(Constant.Create((object)null)); case TokenType.NIL: return(Constant.CreateDefault(Compilation.Get(NativeType.Usual))); case TokenType.DATE_CONST: { var args = Value.Split('.'); if (args.Length == 3) { int year, month, day; if (Int32.TryParse(args[0], out year) && Int32.TryParse(args[1], out month) && Int32.TryParse(args[2], out day)) { if (year == 0 || month == 0 || day == 0) { return(Constant.CreateDefault(Compilation.Get(NativeType.VODate))); } if (Options.VODateConstants) { return(Constant.CreateVODate(year, month, day)); } else { return(Constant.Create(new DateTime(year, month, day))); } } } throw new InternalError(); } case TokenType.DATETIME_CONST: { // when we get here then the value is "{^.....}" Value = Value.Trim(); if (Value.Length < 6) { throw new InternalError(); } Value = Value.Substring(2, Value.Length - 3).Trim(); // replace possible duplicate spaces inside the string var numbers = new int[6]; int current = 0; int value = 0; bool hasAmPm = false; bool isPm = false; bool valid = true; char last = '\0'; numbers[0] = numbers[1] = numbers[2] = numbers[3] = numbers[4] = numbers[5] = 0; foreach (var c in Value) { switch (c) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '0': if (hasAmPm) // no numbers after Am or Pm { valid = false; } else { value = value * 10 + (c - '0'); numbers[current] = value; } break; case ':': case '.': case ' ': case '-': // separators if (char.IsNumber(last)) { // prevent duplicate spaces or other separators from confusing us if (current < 5) { current += 1; value = 0; } } break; case 'a': case 'A': case 'p': case 'P': if (current == 5) { hasAmPm = true; isPm = (c == 'P' || c == 'p'); } else { valid = false; } break; case 'm': case 'M': if (!hasAmPm) { valid = false; } break; default: valid = false; break; } last = c; if (!valid) { throw new InternalError(); } } var year = numbers[0]; var month = numbers[1]; var day = numbers[2]; var hour = numbers[3]; var minute = numbers[4]; var second = numbers[5]; if (isPm) { hour += 12; } return(Constant.CreateDateTime(year, month, day, hour, minute, second)); } case TokenType.NULL_ARRAY: return(Constant.CreateDefault(Compilation.Get(NativeType.Array))); case TokenType.NULL_CODEBLOCK: return(Constant.CreateDefault(Compilation.Get(NativeType.Codeblock))); case TokenType.NULL_DATE: return(Constant.CreateDefault(Compilation.Get(NativeType.VODate))); case TokenType.NULL_OBJECT: return(Constant.CreateDefault(Compilation.Get(NativeType.Object))); case TokenType.NULL_PSZ: return(Constant.CreateDefault(Compilation.Get(NativeType.Psz))); case TokenType.NULL_PTR: return(Constant.CreateDefault(Compilation.Get(NativeType.Ptr))); case TokenType.NULL_STRING: return(Constant.CreateDefault(Compilation.Get(NativeType.String))); case TokenType.NULL_SYMBOL: return(Constant.CreateDefault(Compilation.Get(NativeType.Symbol))); default: throw new InternalError(); } }
internal Constant CreateLiteral(LiteralExpr expr, string Value) { switch (expr.Kind) { case TokenType.TRUE_CONST: return(Constant.Create(true)); case TokenType.FALSE_CONST: return(Constant.Create(false)); case TokenType.CHAR_CONST: return(Constant.Create(Literals.CharValue(Value))); case TokenType.STRING_CONST: return(Constant.Create(Literals.StringValue(Value))); case TokenType.ESCAPED_STRING_CONST: return(Constant.Create(Literals.EscapedStringValue(Value))); case TokenType.INTERPOLATED_STRING_CONST: return(Constant.Create(Literals.StringValue(Value))); case TokenType.SYMBOL_CONST: return(Constant.CreateSymbol(Value.StartsWith("#") ? Value.Substring(1).ToUpperInvariant() : Value.ToUpperInvariant())); case TokenType.HEX_CONST: switch (Value.Last()) { case 'U': case 'u': if (Value.Length > 8 + 3) { return(Constant.Create(unchecked ((ulong)Literals.HexValue(Value.Substring(2))))); } else { return(Constant.Create(unchecked ((uint)Literals.HexValue(Value.Substring(2))))); } case 'L': case 'l': if (Value.Length > 8 + 3) { return(Constant.Create(Literals.HexValue(Value.Substring(2)))); } else { return(Constant.Create(unchecked ((int)Literals.HexValue(Value.Substring(2))))); } default: { long l = Literals.HexValue(Value.Substring(2)); if (l < 0) { return(Constant.Create(unchecked ((ulong)l))); } else if (l > uint.MaxValue) { return(Constant.Create(l)); } else if (l > int.MaxValue) { return(Constant.Create(unchecked ((uint)l))); } else { return(Constant.Create(unchecked ((int)l))); } } } case TokenType.BIN_CONST: switch (Value.Last()) { case 'U': case 'u': if (Value.Length > 32 + 3) { return(Constant.Create(unchecked ((ulong)Literals.BinValue(Value.Substring(2))))); } else { return(Constant.Create(unchecked ((uint)Literals.BinValue(Value.Substring(2))))); } case 'L': case 'l': if (Value.Length > 32 + 3) { return(Constant.Create(Literals.BinValue(Value.Substring(2)))); } else { return(Constant.Create(unchecked ((int)Literals.BinValue(Value.Substring(2))))); } default: { long l = Literals.BinValue(Value.Substring(2)); if (l < 0) { return(Constant.Create(unchecked ((ulong)l))); } else if (l > uint.MaxValue) { return(Constant.Create(l)); } else if (l > int.MaxValue) { return(Constant.Create(unchecked ((uint)l))); } else { return(Constant.Create(unchecked ((int)l))); } } } case TokenType.REAL_CONST: switch (Value.Last()) { case 'M': case 'm': try { return(Constant.Create(decimal.Parse(Value.Substring(0, Value.Length - 1), System.Globalization.CultureInfo.InvariantCulture))); } catch (OverflowException) { throw expr.Error(ErrorCode.LiteralFloatOverflow); } case 'S': case 's': try { return(Constant.Create(float.Parse(Value.Substring(0, Value.Length - 1), System.Globalization.CultureInfo.InvariantCulture))); } catch (OverflowException) { throw expr.Error(ErrorCode.LiteralFloatOverflow); } case 'D': case 'd': try { return(Constant.Create(double.Parse(Value.Substring(0, Value.Length - 1), System.Globalization.CultureInfo.InvariantCulture))); } catch (OverflowException) { throw expr.Error(ErrorCode.LiteralFloatOverflow); } default: try { if (Options.VOFloatConstants) { var args = Value.Split('.'); if (args.Length == 2) { int dec = 0; while (args[1].Length > dec && Char.IsDigit(args[1][dec])) { dec++; } return(Constant.Create(double.Parse(Value, System.Globalization.CultureInfo.InvariantCulture), 0, dec)); } return(Constant.Create(double.Parse(Value, System.Globalization.CultureInfo.InvariantCulture))); } else { return(Constant.Create(double.Parse(Value, System.Globalization.CultureInfo.InvariantCulture))); } } catch (OverflowException) { throw expr.Error(ErrorCode.LiteralFloatOverflow); } } case TokenType.INT_CONST: switch (Value.Last()) { case 'U': case 'u': try { ulong ul = ulong.Parse(Value.Substring(0, Value.Length - 1), System.Globalization.CultureInfo.InvariantCulture); if (ul > uint.MaxValue) { return(Constant.Create(ul)); } else { return(Constant.Create(unchecked ((uint)ul))); } } catch (OverflowException) { throw expr.Error(ErrorCode.LiteralIntegerOverflow); } case 'L': case 'l': try { long l = long.Parse(Value.Substring(0, Value.Length - 1), System.Globalization.CultureInfo.InvariantCulture); if (l > int.MaxValue) { return(Constant.Create(l)); } else { return(Constant.Create(unchecked ((int)l))); } } catch (OverflowException) { throw expr.Error(ErrorCode.LiteralIntegerOverflow); } default: try { ulong un = 0; long n = 0; if (Value.First() != '-') { un = ulong.Parse(Value, System.Globalization.CultureInfo.InvariantCulture); if (un <= long.MaxValue) { n = unchecked ((long)un); } } else { n = long.Parse(Value, System.Globalization.CultureInfo.InvariantCulture); } if (un > long.MaxValue) { return(Constant.Create(un)); } else if (n > uint.MaxValue) { return(Constant.Create(n)); } else if (n > int.MaxValue) { return(Constant.Create(unchecked ((uint)n))); } else { return(Constant.Create(unchecked ((int)n))); } } catch (OverflowException) { throw expr.Error(ErrorCode.LiteralIntegerOverflow); } } case TokenType.NULL: return(Constant.Create((object)null)); case TokenType.NIL: return(Constant.CreateDefault(Compilation.Get(NativeType.Usual))); case TokenType.DATE_CONST: { var args = Value.Split('.'); if (args.Length == 3) { int year, month, day; if (Int32.TryParse(args[0], out year) && Int32.TryParse(args[1], out month) && Int32.TryParse(args[2], out day)) { if (Options.VODateConstants) { return(Constant.CreateVODate(year, month, day)); } else { return(Constant.Create(new DateTime(year, month, day))); } } } throw new InternalError(); } case TokenType.NULL_ARRAY: return(Constant.CreateDefault(Compilation.Get(NativeType.Array))); case TokenType.NULL_CODEBLOCK: return(Constant.CreateDefault(Compilation.Get(NativeType.Codeblock))); case TokenType.NULL_DATE: return(Constant.CreateDefault(Compilation.Get(NativeType.VODate))); case TokenType.NULL_OBJECT: return(Constant.CreateDefault(Compilation.Get(NativeType.Object))); case TokenType.NULL_PSZ: return(Constant.CreateDefault(Compilation.Get(NativeType.Psz))); case TokenType.NULL_PTR: return(Constant.CreateDefault(Compilation.Get(NativeType.Ptr))); case TokenType.NULL_STRING: return(Constant.CreateDefault(Compilation.Get(NativeType.String))); case TokenType.NULL_SYMBOL: return(Constant.CreateDefault(Compilation.Get(NativeType.Symbol))); default: throw new InternalError(); } }