Esempio n. 1
0
        public static object?Sub(MyArgs args)
        {
            var that  = args.That;
            var start = MyNumber.TryConvertFrom(args[0]);
            var len   = MyNumber.TryConvertFrom(args[1]);

            if (that is string str && start is not null)
            {
                if (str.Length == 0)
                {
                    return("");
                }
                int s = (int)start;
                s = (s % str.Length + str.Length) % str.Length;
                if (len is null)
                {
                    return(str.Substring(s));
                }
                else
                {
                    return(str.Substring(s, (int)len));
                }
            }
            return(null);
        }
Esempio n. 2
0
        public static object?ConvertFromMSToCS(object?obj, Type target_type)
        {
            if (obj is null)
            {
                return(null);// 注意值类型的情况
            }

            if (target_type.IsInstanceOfType(obj))
            {
                return(obj);
            }

            // @om 一些特殊处理
            // Enum
            if (target_type.IsEnum)
            {
                if (obj is string str)
                {
                    return(Enum.Parse(target_type, str));// will three exception
                }
                var n = MyNumber.TryConvertFrom(obj);
                if (n is not null && n.IsInt64)
                {
                    long d = (long)n;// 经过阅读源码,这个是内部最终也会转换过来的版本
                    return(Enum.ToObject(target_type, d));
                }
                else
                {
                    return(null);
                }
            }
Esempio n. 3
0
        public object?Get(object key)
        {
            MyNumber?num = MyNumber.TryConvertFrom(key);

            if (num is not null)
            {
                if (num.IsInt32)
                {
                    return(this[(int)num]);
                }
            }
            throw new NotImplementedException();
        }
Esempio n. 4
0
        /// <summary>
        /// MyScript内部使用的比较函数,可以用于支持 a <> b。
        /// 1. 字符串,按UTF-16二进制方式比较
        /// 2. 数字,正常比较,不过最小的是NaN。
        /// 3. 其他的就有些随意了
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static int Compare(object?a, object?b)
        {
            if (a == b)
            {
                return(0);
            }
            if (a == null)
            {
                return(-1);
            }
            if (b == null)
            {
                return(1);
            }

            if (a is string sa && b is string sb)
            {
                return(string.Compare(sa, sb, StringComparison.Ordinal));
            }

            // 需要对数字类型的特殊处理下
            var fa = MyNumber.TryConvertFrom(a);
            var fb = MyNumber.TryConvertFrom(b);

            if (fa is not null && fb is not null)
            {
                return(fa.CompareTo(fb));
            }

            if (a.Equals(b))
            {
                return(0);            // 相等比较特殊处理下吧
            }
            // 不能使用直接使用 IComparable。大部分实现,遇到类型不一样,会抛异常。
            var ta = a.GetType();
            var tb = b.GetType();

            if (ta == tb)
            {
                if (a is IComparable ia)
                {
                    return(ia.CompareTo(b));
                }
            }
            // 没办法了,随便比较下啦。选择HashCode,速度可能快些。用FullName也许会更稳定些。
            // @om C# 的HashCode的实现方法还为找到确定位置,疑似发现一个,太复杂了点。
            return(ta.GetHashCode().CompareTo(tb.GetHashCode()));
        }
Esempio n. 5
0
        /// <summary>
        /// 等性比较,非常重要。和Compare不一样,Compare == 0, 不一定相等。
        /// 1. 数字类型特殊处理
        /// </summary>
        public static bool CheckEquals(object?a, object?b)
        {
            if (a == b)
            {
                return(true);
            }
            if (a == null || b == null)
            {
                return(false);
            }

            // 需要对数字类型的特殊处理下
            var fa = MyNumber.TryConvertFrom(a);
            var fb = MyNumber.TryConvertFrom(b);

            if (fa is not null && fb is not null)
            {
                return(fa.Equals(fb));
            }
Esempio n. 6
0
        public static object?Get(string str, object key)
        {
            if (key is string ss)
            {
                if (s_func_map.TryGetValue(ss, out ICall? func))
                {
                    return(func);
                }
                switch (ss)
                {
                case "size":
                    return(ss.Length);
                }
                return(null);
            }
            var num = MyNumber.TryConvertFrom(key);

            if (num is not null && num.IsInt32)
            {
                return(str.GetByIdx((int)num));
            }
            return(null);
        }
Esempio n. 7
0
        public MyNumber GetNumber(Frame frame)
        {
            var x = GetResult(frame);

            return(MyNumber.ForceConvertFrom(x));
        }
Esempio n. 8
0
        protected override object?_GetResults(Frame frame)
        {
            object?ret = null;

            if (op.Match(Keyword.AND))
            {
                ret = left.GetBool(frame) && right.GetBool(frame);
            }
            else if (op.Match(Keyword.OR))
            {
                ret = left.GetBool(frame) || right.GetBool(frame);
            }
            else if (op.Match('+'))
            {
                ret = left.GetNumber(frame) + right.GetNumber(frame);
            }
            else if (op.Match('-'))
            {
                ret = left.GetNumber(frame) - right.GetNumber(frame);
            }
            else if (op.Match('*'))
            {
                ret = left.GetNumber(frame) * right.GetNumber(frame);
            }
            else if (op.Match('/'))
            {
                ret = left.GetNumber(frame) / right.GetNumber(frame);
            }
            else if (op.Match('%'))
            {
                ret = left.GetNumber(frame) % right.GetNumber(frame);
            }
            else if (op.Match(TokenType.DIVIDE))
            {
                ret = MyNumber.IntegerDivide(left.GetNumber(frame), right.GetNumber(frame));
            }
            else if (op.Match('^'))
            {
                ret = MyNumber.Pow(left.GetNumber(frame), right.GetNumber(frame));
            }
            else if (op.Match('<'))
            {
                ret = Utils.Compare(left.GetResult(frame), right.GetResult(frame)) < 0;
            }
            else if (op.Match('>'))
            {
                ret = Utils.Compare(left.GetResult(frame), right.GetResult(frame)) > 0;
            }
            else if (op.Match(TokenType.LE))
            {
                ret = Utils.Compare(left.GetResult(frame), right.GetResult(frame)) <= 0;
            }
            else if (op.Match(TokenType.GE))
            {
                ret = Utils.Compare(left.GetResult(frame), right.GetResult(frame)) >= 0;
            }
            else if (op.Match(TokenType.EQ))
            {
                ret = Utils.CheckEquals(left.GetResult(frame), right.GetResult(frame));
            }
            else if (op.Match(TokenType.NE))
            {
                ret = !Utils.CheckEquals(left.GetResult(frame), right.GetResult(frame));
            }
            else if (op.Match(TokenType.THREE_CMP))
            {
                ret = Utils.Compare(left.GetResult(frame), right.GetResult(frame));
            }
            else if (op.Match(TokenType.CONCAT))
            {
                ret = left.GetString(frame) + right.GetString(frame);
            }
            else
            {
                Debug.Assert(false);
            }

            return(ret);
        }