public static Expr GetResourceString(ICall call) {
     var ctx = call.Ctx;
     var expr = new ExprLiteral(ctx, "<GetRuntimeResourceString>", ctx.String);
     return expr;
 }
 public static Expr GetResourceFromDefault(ICall call) {
     var ctx = call.Ctx;
     var pre = new ExprLiteral(ctx, "GetResourceFromDefault_", ctx.String);
     var expr = new ExprBinary(ctx, BinaryOp.Add, ctx.String, pre, call.Args.First());
     return expr;
 }
        public static Expr InitializeArray(ICall call) {
            var ctx = call.Ctx;
            var array = (ExprVar)call.Args.ElementAt(0);
            var initExpr = (ExprRuntimeHandle)call.Args.ElementAt(1);
            var initData = ((FieldDefinition)initExpr.Member).InitialValue;
            var arrayElType = ((ArrayType)array.Type).ElementType;

            int inc;
            Func<int, object> getValue;
            switch (arrayElType.MetadataType) {
            case MetadataType.Boolean:
                inc = 1;
                getValue = i => initData[i] != 0;
                break;
            case MetadataType.Byte:
                inc = 1;
                getValue = i => initData[i];
                break;
            case MetadataType.SByte:
                inc = 1;
                getValue = i => (sbyte)initData[i];
                break;
            case MetadataType.Int16:
                inc = 2;
                getValue = i => BitConverter.ToInt16(initData, i);
                break;
            case MetadataType.Int32:
                inc = 4;
                getValue = i => BitConverter.ToInt32(initData, i);
                break;
            case MetadataType.Int64:
                inc = 8;
                getValue = i => BitConverter.ToInt64(initData, i);
                break;
            case MetadataType.UInt16:
                inc = 2;
                getValue = i => BitConverter.ToUInt16(initData, i);
                break;
            case MetadataType.UInt32:
                inc = 4;
                getValue = i => BitConverter.ToUInt32(initData, i);
                break;
            case MetadataType.UInt64:
                inc = 8;
                getValue = i => BitConverter.ToUInt64(initData, i);
                break;
            case MetadataType.Single:
                inc = 4;
                getValue = i => BitConverter.ToSingle(initData, i);
                break;
            case MetadataType.Double:
                inc = 8;
                getValue = i => BitConverter.ToDouble(initData, i);
                break;
            case MetadataType.Char:
                inc = 2;
                getValue = i => (char)BitConverter.ToUInt16(initData, i);
                break;
            default:
                throw new NotImplementedException("Cannot handle: " + arrayElType.MetadataType);
            }
            var values = new List<NamedExpr>();
            for (int i = 0; i < initData.Length; i += inc) {
                var value = new ExprLiteral(ctx, getValue(i), arrayElType);
                values.Add(value.Named("v" + i));
            }
            var vStr = string.Join(",", values.Select(x => x.Name));
            var arrayTypeName = new ExprJsTypeVarName(call.Ctx, array.Type).Named("typeName");
            var js = "a = [" + vStr + "]; a._ = typeName";
            return new ExprJsExplicit(call.Ctx, js, array.Type, values.Concat(array.Named("a")).Concat(arrayTypeName));
        }
 protected override ICode VisitLiteral(ExprLiteral e) {
     if (e.Value == null) {
         this.js.Append("null");
     } else {
         object value;
         var mdt = e.Type.MetadataType;
         switch (mdt) {
         case MetadataType.String:
             var s = (string)e.Value;
             var sb = new StringBuilder(s.Length + 2);
             sb.Append("\"");
             for (int i = 0; i < s.Length; i++) {
                 var c = s[i];
                 if ((int)c >= 32 && c <= 126 && c != '\\' && c != '\'' && c != '"') {
                     sb.Append(c);
                 } else {
                     if ((int)c <= 255) {
                         sb.AppendFormat("\\x{0:x2}", (int)c);
                     } else {
                         sb.AppendFormat("\\u{0:x4}", (int)c);
                     }
                 }
             }
             sb.Append("\"");
             value = sb.ToString();
             break;
         case MetadataType.Char:
             value = (int)(char)e.Value;
             break;
         case MetadataType.Boolean:
             value = (bool)e.Value ? "true" : "false";
             break;
         case MetadataType.Int64:
             var i64 = (UInt64)(Int64)e.Value;
             value = string.Format("[{0}, {1}]", (i64 >> 32) & 0xffffffffUL, i64 & 0xffffffffUL);
             break;
         case MetadataType.UInt64:
             var u64 = (UInt64)e.Value;
             value = string.Format("[{0}, {1}]", (u64 >> 32) & 0xffffffffUL, u64 & 0xffffffffUL);
             break;
         case MetadataType.Single:
             var f = (Single)e.Value;
             if (Single.IsNegativeInfinity(f)) {
                 value = "Number.NEGATIVE_INFINITY";
             } else if (Single.IsPositiveInfinity(f)) {
                 value = "Number.POSITIVE_INFINITY";
             } else {
                 value = f;
             }
             break;
         case MetadataType.Double:
             var d = (Double)e.Value;
             if (Double.IsNegativeInfinity(d)) {
                 value = "Number.NEGATIVE_INFINITY";
             } else if (Double.IsPositiveInfinity(d)) {
                 value = "Number.POSITIVE_INFINITY";
             } else {
                 value = d;
             }
             break;
         default:
             value = e.Value;
             break;
         }
         this.js.Append(value);
     }
     return e;
 }
 protected override ICode VisitLiteral(ExprLiteral e) {
     if (e.Value == null) {
         this.code.Append("null");
     } else if (e.Type.IsString()) {
         this.code.Append("\"" + e.Value + "\"");
     } else if (e.Type.IsChar()) {
         this.code.Append("'" + e.Value + "'");
     } else {
         this.code.Append(e.Value);
     }
     return e;
 }