internal override void EmitGet(ILGenerator ilg) { ilg.Emit(OpCodes.Ldc_R8, Double.Value); EmitConstant_I4(ilg, Length); EmitConstant_I4(ilg, Decimals); ilg.Emit(OpCodes.Newobj, (Compilation.Get(WellKnownMembers.XSharp___Float_ctor) as ConstructorSymbol).Constructor); }
internal static TypeSymbol ConvertResult(ref Expr e1, ref Expr e2, BindOptions options) { var conv1 = Conversion(e1, e2.Datatype, options); var conv2 = Conversion(e2, e1.Datatype, options); if (!conv1.Exists && conv2.Exists) { Convert(ref e2, e1.Datatype, conv2); return(e1.Datatype); } if (conv1.Exists && !conv2.Exists) { Convert(ref e1, e2.Datatype, conv1); return(e2.Datatype); } if (conv1.Exists && conv2.Exists) { int cost1 = conv1.Cost; int cost2 = conv2.Cost; if (cost1 <= cost2 && e1.Datatype.NativeType != NativeType.Usual) { Convert(ref e1, e2.Datatype, conv1); return(e2.Datatype); } else { Convert(ref e2, e1.Datatype, conv2); return(e1.Datatype); } } Convert(ref e1, Compilation.Get(NativeType.Usual), options); Convert(ref e2, Compilation.Get(NativeType.Usual), options); return(Compilation.Get(NativeType.Usual)); }
internal override void EmitGet(ILGenerator ilg) { var m = Compilation.Get(WellKnownMembers.XSharp_RT_Functions_IVarGet) as MethodSymbol; Name.Emit(ilg); ilg.Emit(OpCodes.Call, m.Method); }
internal override void EmitGet(ILGenerator ilg) { EmitConstant_I4(ilg, DateTime.Value.Year); EmitConstant_I4(ilg, DateTime.Value.Month); EmitConstant_I4(ilg, DateTime.Value.Day); ilg.Emit(OpCodes.Newobj, (Compilation.Get(WellKnownMembers.XSharp___Date_ctor) as ConstructorSymbol).Constructor); }
static BinaryOperatorSymbol DynamicBinaryOperator(BinaryOperatorKind kind, ref Expr left, ref Expr right, BindOptions options) { var l = left; var r = right; if (l.Datatype.NativeType == NativeType.Object) { Convert(ref l, Compilation.Get(NativeType.Usual), options); } if (r.Datatype.NativeType == NativeType.Object) { Convert(ref r, Compilation.Get(NativeType.Usual), options); } var op = UserDefinedBinaryOperator(kind, ref l, ref r, options); if (op != null) { left = l; right = r; } return(op); }
internal static BinaryOperatorSymbol SymbolAndStringBinaryOperator(BinaryOperatorKind kind, ref Expr left, ref Expr right, BindOptions options) { if (kind == BinaryOperatorKind.Addition) { var l = left; var r = right; if (left.Datatype.NativeType == NativeType.Symbol) { Convert(ref l, Compilation.Get(NativeType.String), options); } if (right.Datatype.NativeType == NativeType.Symbol) { Convert(ref r, Compilation.Get(NativeType.String), options); } var sym = BinaryOperatorEasyOut.ClassifyOperation(kind, l.Datatype, r.Datatype); if (sym != null) { left = l; right = r; Convert(ref left, sym.TypeOfOp, options); Convert(ref right, sym.TypeOfOp, options); return(sym); } } return(null); }
bool HasMostDerivedArgs(OverloadResult other) { bool preferthis = false; for (int i = 0; i < Parameters.Parameters.Length; i++) { var pt = Binder.FindType(Parameters.Parameters[i].ParameterType); var po = Binder.FindType(other.Parameters.Parameters[i].ParameterType); if (pt.IsSubclassOf(po)) { return(true); } // when the rest of the arguments do not make a difference // then prefer Int32 over UInt32 if (pt == Compilation.Get(WellKnownTypes.System_Int32) && po == Compilation.Get(WellKnownTypes.System_UInt32)) { preferthis = true; } // when no preference then choose the one with a usual argument // over the one without usual. else if (pt == Compilation.Get(WellKnownTypes.XSharp___Usual) && po != Compilation.Get(WellKnownTypes.XSharp___Usual) && !preferthis) { preferthis = true; } } return(preferthis); }
internal override void EmitGet(ILGenerator ilg) { ilg.Emit(OpCodes.Ldstr, Name); MethodSymbol m = Compilation.Get(WellKnownMembers.XSharp_RT_Functions___MemVarGet) as MethodSymbol; ilg.Emit(OpCodes.Call, m.Method); }
internal static void EmitGetElemSafe(ILGenerator ilg, Symbol array, TypeSymbol elemType) { LocalSymbol ls = new LocalSymbol(null, Compilation.Get(NativeType.Int32)); ls.Declare(ilg); ls.EmitSet(ilg); var notExist = ilg.DefineLabel(); var exist = ilg.DefineLabel(); array.EmitGet(ilg); ilg.Emit(OpCodes.Ldlen); ilg.Emit(OpCodes.Conv_U4); ls.EmitGet(ilg); ilg.Emit(OpCodes.Cgt_Un); ilg.Emit(OpCodes.Brfalse_S, notExist); array.EmitGet(ilg); ls.EmitGet(ilg); ilg.Emit(OpCodes.Ldelem_Ref); ilg.Emit(OpCodes.Br_S, exist); ilg.MarkLabel(notExist); EmitDefault(ilg, elemType); ilg.MarkLabel(exist); }
internal override void EmitSet(ILGenerator ilg) { var v = ilg.DeclareLocal(Compilation.Get(NativeType.Usual).Type); ilg.Emit(OpCodes.Stloc, v.LocalIndex); ilg.Emit(OpCodes.Ldstr, Name); ilg.Emit(OpCodes.Ldloc, v.LocalIndex); MethodSymbol m = Compilation.Get(WellKnownMembers.XSharp_RT_Functions___MemVarPut) as MethodSymbol; ilg.Emit(OpCodes.Call, m.Method); ilg.Emit(OpCodes.Pop); }
internal void ConvertArrayBase(ArgList args) { if (!Options.ArrayZero) { for (int i = 0; i < args.Args.Count; i++) { args.Args[i].Expr = BinaryExpr.Bound(args.Args[i].Expr, args.Args[i].Expr.Token, LiteralExpr.Bound(Constant.Create(1)), BinaryOperatorKind.Subtraction, Options.Binding); var expr = args.Args[i].Expr; Binder.Convert(ref expr, Compilation.Get(NativeType.Int32), BindOptions.Default); args.Args[i].Expr = expr; } } }
internal override void EmitGet(ILGenerator ilg) { if (WorkArea != null) { ilg.Emit(OpCodes.Ldstr, WorkArea); } ilg.Emit(OpCodes.Ldstr, Name); MethodSymbol m = WorkArea != null? Compilation.Get(WellKnownMembers.XSharp_RT_Functions___FieldGetWa) as MethodSymbol : Compilation.Get(WellKnownMembers.XSharp_RT_Functions___FieldGet) as MethodSymbol; ilg.Emit(OpCodes.Call, m.Method); }
internal static ConversionSymbol ResolveDynamicConversion(Expr expr, TypeSymbol type, BindOptions options) { if (expr.Datatype.NativeType == NativeType.Object) { var inner = Conversion(expr, Compilation.Get(NativeType.Usual), options); var outer = Conversion(TypeConversion.Bound(expr, Compilation.Get(NativeType.Usual), inner), type, options); if (outer.Exists) { return(ConversionSymbol.Create(outer, inner)); } } return(null); }
internal static ConversionSymbol ResolveUsualConversion(Expr expr, TypeSymbol type, BindOptions options) { if (expr.Datatype.NativeType == NativeType.Usual) { if (type.NativeType == NativeType.Object) { if (options.HasFlag(BindOptions.BoxUsual)) { return(ConversionSymbol.Create(ConversionKind.Boxing)); } else { MethodSymbol converter = null; ResolveConversionMethod(expr, type, Compilation.Get(NativeType.Usual).Lookup(XSharpFunctionNames.ToObject), ref converter, options); if (converter != null) { return(ConversionSymbol.Create(ConversionKind.ImplicitUserDefined, converter)); } } } else { MethodSymbol converter = null; ResolveConversionMethod(expr, Compilation.Get(NativeType.Object), Compilation.Get(NativeType.Usual).Lookup(XSharpFunctionNames.ToObject), ref converter, options); if (converter != null) { var inner = ConversionSymbol.Create(ConversionKind.ImplicitUserDefined, converter); var outer = type.IsReferenceType ? ConversionSymbol.Create(ConversionKind.ExplicitReference) : type.IsValueType ? ConversionSymbol.Create(ConversionKind.Unboxing) : ConversionSymbol.Create(ConversionKind.NoConversion); if (outer.Exists) { return(ConversionSymbol.Create(outer, inner)); } } } } else if (type.NativeType == NativeType.Usual && expr.Datatype.IsReferenceType) { var inner = Conversion(expr, Compilation.Get(NativeType.Object), options | BindOptions.Explicit); if (inner.Exists) { var outer = Conversion(TypeConversion.Bound(expr, Compilation.Get(NativeType.Object), inner), type, options); if (outer.Exists) { return(ConversionSymbol.Create(outer, inner)); } } } return(null); }
internal override void EmitSet(ILGenerator ilg) { var m = Compilation.Get(WellKnownMembers.XSharp_RT_Functions_IVarPut) as MethodSymbol; var lo = ilg.DeclareLocal(Compilation.Get(NativeType.Object).Type); var lv = ilg.DeclareLocal(Type.Type); ilg.Emit(OpCodes.Stloc, lo.LocalIndex); ilg.Emit(OpCodes.Stloc, lv.LocalIndex); ilg.Emit(OpCodes.Ldloc, lo.LocalIndex); Name.Emit(ilg); ilg.Emit(OpCodes.Ldloc, lv.LocalIndex); ilg.Emit(OpCodes.Call, m.Method); ilg.Emit(OpCodes.Pop); }
internal static void EmitDefault(ILGenerator ilg, TypeSymbol t) { if (t.Type.IsValueType) { switch (t.NativeType) { case NativeType.Boolean: case NativeType.Byte: case NativeType.Char: case NativeType.Int16: case NativeType.Int32: case NativeType.SByte: case NativeType.UInt16: case NativeType.UInt32: ilg.Emit(OpCodes.Ldc_I4_0); break; case NativeType.UInt64: case NativeType.Int64: ilg.Emit(OpCodes.Ldc_I8, 0); break; case NativeType.Double: ilg.Emit(OpCodes.Ldc_R8, 0); break; case NativeType.Single: ilg.Emit(OpCodes.Ldc_R4, 0); break; case NativeType.Decimal: ilg.Emit(OpCodes.Ldsfld, (FieldInfo)Compilation.Get(WellKnownMembers.System_Decimal_Zero).Member); break; default: { var l = ilg.DeclareLocal(t.Type); ilg.Emit(l.LocalIndex < 256 ? OpCodes.Ldloca_S : OpCodes.Ldloca, l); ilg.Emit(OpCodes.Initobj, t.Type); ilg.Emit(l.LocalIndex < 256 ? OpCodes.Ldloc_S : OpCodes.Ldloc, l); } break; } } else { ilg.Emit(OpCodes.Ldnull); } }
internal static UnaryOperatorSymbol BindUnaryOperation(UnaryExpr expr, UnaryOperatorKind kind, BindOptions options) { if (options.HasFlag(BindOptions.Logic)) { Convert(ref expr.Expr, Compilation.Get(NativeType.Boolean), options); } var res = UnaryOperation(kind, ref expr.Expr, options); if (res != null) { return(res); } throw UnaryOperationError(expr, kind, options); }
Arg ApplyUsualConversions(ArgList args, out Expr writeBack) { writeBack = null; bool hasRefArgs = false; for (int i = 0; i < args.Args.Count; i++) { var e = args.Args[i].Expr; Convert(ref e, Compilation.Get(NativeType.Usual)); if (args.Args[i].RefKind != RefKind.None) { hasRefArgs = true; } } var arguments = new Arg(LiteralArray.Bound(args.Args)); if (hasRefArgs) { var conv = ConversionSymbol.Create(ConversionSymbol.Create(ConversionKind.Identity), new ConversionToTemp(arguments.Expr.Datatype)); Convert(ref arguments.Expr, arguments.Expr.Datatype, conv); for (int i = 0; i < args.Args.Count; i++) { if (args.Args[i].RefKind != RefKind.None) { HandleVarArgWriteBack(conv, args.Args[i].Expr, i, ref writeBack); } } } return(arguments); void HandleVarArgWriteBack(ConversionSymbol conv, Expr e, int i, ref Expr wb) { if (e.Symbol?.HasSetAccess == true || e is AutoVarExpr || e is AliasExpr) { // Handle writeBack Expr t = IdExpr.Bound(conv.IndirectRefConversionTempLocal()); t = ArrayAccessExpr.Bound(t, ArgList.Bound(LiteralExpr.Bound(Constant.Create(i + 1))), this); var wc = Conversion(t, e.Datatype, BindOptions.Default); if (wc.Exists) { Convert(ref t, e.Datatype, wc); SymbolExtensions.AddExpr(ref wb, AssignExpr.Bound(e, t, BindOptions.Default)); } } } }
internal override void EmitSet(ILGenerator ilg) { var v = ilg.DeclareLocal(Compilation.Get(NativeType.Usual).Type); ilg.Emit(OpCodes.Stloc, v.LocalIndex); if (WorkArea != null) { ilg.Emit(OpCodes.Ldstr, WorkArea); } ilg.Emit(OpCodes.Ldstr, Name); ilg.Emit(OpCodes.Ldloc, v.LocalIndex); MethodSymbol m = WorkArea != null? Compilation.Get(WellKnownMembers.XSharp_RT_Functions___FieldSetWa) as MethodSymbol : Compilation.Get(WellKnownMembers.XSharp_RT_Functions___FieldSet) as MethodSymbol; ilg.Emit(OpCodes.Call, m.Method); ilg.Emit(OpCodes.Pop); }
static UnaryOperatorSymbol DynamicUnaryOperator(UnaryOperatorKind kind, ref Expr expr, BindOptions options) { var e = expr; if (e.Datatype.NativeType == NativeType.Object) { Convert(ref e, Compilation.Get(NativeType.Usual), options); } var op = UserDefinedUnaryOperator(kind, ref e, options); if (op != null) { expr = e; } return(op); }
internal Symbol BindMemberAccess(ref Expr expr, ref Expr member, BindAffinity affinity) { if (member is NameExpr MemberName) { if (affinity == BindAffinity.Invoke) { Symbol s = null; if (!expr.Datatype.IsUsualOrObject()) { s = Lookup(expr.Datatype, MemberName.LookupName); } if (s == null) { if (Options.Binding.HasFlag(BindOptions.AllowDynamic) && expr.Datatype.IsUsualOrObject()) { Convert(ref expr, Compilation.Get(NativeType.Usual) ?? Compilation.Get(NativeType.Object)); return(new DynamicSymbol(MemberName.LookupName)); } else { throw Binder.LookupError(expr, MemberName); } } return(s); } else { Convert(ref expr, Compilation.Get(NativeType.Object)); return(new DynamicSymbol(MemberName.LookupName)); } } else if (member is RuntimeIdExpr) { Bind(ref member, BindAffinity.Member); return(new DynamicExprSymbol(member)); } else { throw member.Error(ErrorCode.NameExpected); } }
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); }
static internal void BuildIndex() { if (Global != null && Usings != null && TypeCache != null) { return; } var global = new NamespaceSymbol(); var usings = new List <ContainerSymbol>(); var rtFuncs = new List <ContainerSymbol>(); var typeCache = new Dictionary <Type, TypeSymbol>(); var usedSymbols = new HashSet <ContainerSymbol>(); foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) { if (a.IsDynamic) { continue; } var most_visible = a == System.Reflection.Assembly.GetEntryAssembly(); try { var types = most_visible ? a.GetTypes() : a.GetExportedTypes(); // Build type lookup dictionary foreach (var t in types.Where(t => !t.IsNested && !string.IsNullOrEmpty(t?.Name))) { var n = global; var nss = t.Namespace?.Split('.'); if (nss != null) { foreach (var ns in nss) { if (!string.IsNullOrEmpty(ns)) { Symbol nn; if (!n.Members.TryGetValue(ns, out nn) || (!(nn is NamespaceSymbol) && most_visible)) { nn = new NamespaceSymbol(ns, n); n.Members[ns] = nn; } if (!(nn is NamespaceSymbol)) { continue; } n = nn as NamespaceSymbol; } } } Func <ContainerSymbol, Type, TypeSymbol> add_type = null; add_type = (ct, ty) => { if (ty.IsNested) { ct = add_type(ct, ty.DeclaringType); if (ct == null) { return(null); } } Symbol tv; if (ct.Members.TryGetValue(ty.Name, out tv)) { if ((tv as TypeSymbol)?.Type == ty) { return((TypeSymbol)tv); } if (!most_visible && tv is TypeSymbol) { return(null); } } var r = new TypeSymbol(ty); ct.Members[ty.Name] = r; typeCache[ty] = r; return(r); }; var ts = add_type(n, t); /*if (!t.IsNested && t.Name.Equals(XSharpSpecialNames.FunctionsClass, StringComparison.OrdinalIgnoreCase)) * { * if (ts != null && !usedSymbols.Contains(ts)) * { * usedSymbols.Add(ts); * usings.Add(ts); * } * }*/ } } catch (Exception e) { System.Diagnostics.Debug.WriteLine("Error loading types from " + a.CodeBase + "\r" + e.Message); } } global = System.Threading.Interlocked.CompareExchange(ref Global, global, null); typeCache = System.Threading.Interlocked.CompareExchange(ref TypeCache, typeCache, null); Compilation.InitializeNativeTypes(); Compilation.InitializeWellKnownTypes(); Compilation.InitializeWellKnownMembers(); foreach (var ns in new string[] { OurNameSpaces.System, OurNameSpaces.XSharp, OurNameSpaces.Vulcan }) { var s = LookupFullName(ns) as NamespaceSymbol; if (s != null && !usedSymbols.Contains(s)) { usedSymbols.Add(s); usings.Add(s); } } var cla = Compilation.Get(WellKnownTypes.XSharp_Internal_ClassLibraryAttribute); var ina = Compilation.Get(WellKnownTypes.ImplicitNamespaceAttribute); if (cla != null && ina != null) { foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) { if (a.IsDynamic) { continue; } bool isXsRuntime = a.IsInXSharpRuntime(); var most_visible = a == System.Reflection.Assembly.GetEntryAssembly(); if (a.CustomAttributes != null) { foreach (var attr in a.CustomAttributes) { if (attr.AttributeType == ina.Type) { var args = attr.ConstructorArguments; if (args != null && args.Count == 1) { // first element is the default namespace var ns = args[0].Value.ToString(); if (!string.IsNullOrEmpty(ns)) { var s = LookupFullName(ns) as NamespaceSymbol; if (s != null && !usedSymbols.Contains(s)) { usedSymbols.Add(s); usings.Add(s); } } } } else if (attr.AttributeType == cla.Type) { var args = attr.ConstructorArguments; if (args != null && args.Count == 2) { // first element is the Functions class var cls = args[0].Value.ToString(); if (!string.IsNullOrEmpty(cls)) { var s = LookupFullName(cls) as TypeSymbol; if (s != null) { if (isXsRuntime) { rtFuncs.Add(s); } else if (!usedSymbols.Contains(s)) { usedSymbols.Add(s); usings.Add(s); } } } // second element is the default namespace var ns = args[1].Value.ToString(); if (!string.IsNullOrEmpty(ns)) { var s = LookupFullName(ns) as NamespaceSymbol; if (s != null && !usedSymbols.Contains(s)) { usedSymbols.Add(s); usings.Add(s); } } } } } } } } usings = System.Threading.Interlocked.CompareExchange(ref Usings, usings, null); rtFuncs = System.Threading.Interlocked.CompareExchange(ref RuntimeFunctions, rtFuncs, null); }
internal int AddNestedCodeblock(out Symbol argSym) { if (NestedCodeblocks == null) { NestedCodeblocks = new List <_Codeblock>(); argSym = AddParam(XSharpSpecialNames.NestedCodeblockArgs, ArrayOf(Compilation.Get(WellKnownTypes.XSharp_Codeblock)), true); } else { argSym = Args[0]; } NestedCodeblocks.Add(null); return(NestedCodeblocks.Count - 1); }
internal override void EmitGet(ILGenerator ilg) { EmitLiteral(ilg, this, Compilation.Get(NativeType.Decimal)); ilg.Emit(OpCodes.Newobj, (Compilation.Get(WellKnownMembers.XSharp___Currency_ctor) as ConstructorSymbol).Constructor); }
internal static MemberSymbol TryBindCall(Expr expr, Symbol symbol, ArgList args, out Expr self, ref OverloadResult ovRes, BindOptions options) { self = (expr as MemberAccessExpr)?.Expr; bool isStatic = self == null; if ((symbol as MethodSymbol)?.Method.IsStatic == isStatic || symbol is ConstructorSymbol) { CheckArguments(symbol as MemberSymbol, ((MethodBaseSymbol)symbol).Parameters, args, ref ovRes, options); } else if ((symbol as SymbolList)?.HasMethodBase == true) { var methods = symbol as SymbolList; for (int i = 0; i < methods.Symbols.Count; i++) { var m = methods.Symbols[i]; if ((m as MethodSymbol)?.Method.IsStatic == isStatic || m is ConstructorSymbol) { CheckArguments(m as MemberSymbol, ((MethodBaseSymbol)m).Parameters, args, ref ovRes, options); if (ovRes?.Exact == true) { break; } } } } if (ovRes?.Unique == true) { ApplyConversions(args, ovRes); return(ovRes.Symbol); } if (options.HasFlag(BindOptions.AllowDynamic) && expr != null && ovRes?.Valid != true) { if (symbol is DynamicExprSymbol symbolExpr) { expr = self; self = null; Convert(ref expr, Compilation.Get(NativeType.Usual), options); var obj = new Arg(expr ?? LiteralExpr.Bound(Constant.Create(null))); var name = new Arg(symbolExpr.Name); var arguments = new Arg(LiteralArray.Bound(args.Args)); args.Args.Clear(); args.Args.Add(obj); args.Args.Add(name); args.Args.Add(arguments); return(Compilation.Get(WellKnownMembers.XSharp_RT_Functions___InternalSend)); } else if (symbol is DynamicSymbol symbolDynamic) { expr = self; self = null; Convert(ref expr, Compilation.Get(NativeType.Usual), options); var obj = new Arg(expr ?? LiteralExpr.Bound(Constant.Create(null))); var name = new Arg(LiteralExpr.Bound(Constant.Create(symbolDynamic.Name))); var arguments = new Arg(LiteralArray.Bound(args.Args)); args.Args.Clear(); args.Args.Add(obj); args.Args.Add(name); args.Args.Add(arguments); return(Compilation.Get(WellKnownMembers.XSharp_RT_Functions___InternalSend)); } else if (symbol.Type()?.IsUsualOrObject() == true) { self = null; Convert(ref expr, Compilation.Get(NativeType.Usual), options); var obj = new Arg(expr); var name = new Arg(LiteralExpr.Bound(Constant.Create(SystemNames.DelegateInvokeName))); var arguments = new Arg(LiteralArray.Bound(args.Args)); args.Args.Clear(); args.Args.Add(obj); args.Args.Add(name); args.Args.Add(arguments); return(Compilation.Get(WellKnownMembers.XSharp_RT_Functions___InternalSend)); } } return(null); }
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 ConstantWithValue(T value, NativeType nt) { Value = value; Type = Compilation.Get(nt); }
internal override void EmitGet(ILGenerator ilg) { ilg.Emit(OpCodes.Ldstr, String); ilg.Emit(OpCodes.Newobj, (Compilation.Get(WellKnownMembers.XSharp___Symbol_ctor) as ConstructorSymbol).Constructor); }
internal override void EmitGet(ILGenerator ilg) { EmitLiteral(ilg, this, Compilation.Get(NativeType.Binary)); }