示例#1
0
        public static P5Scalar BitAnd(Runtime runtime, P5Scalar res,
                                      P5Scalar a, P5Scalar b)
        {
            if (a.IsString(runtime) && b.IsString(runtime))
            {
                string sa = a.AsString(runtime), sb = b.AsString(runtime);
                System.Text.StringBuilder t;

                if (sa.Length > sb.Length)
                {
                    t = new System.Text.StringBuilder(sa);

                    for (int i = 0; i < sb.Length; ++i)
                        t[i] &= sb[i];
                }
                else
                {
                    t = new System.Text.StringBuilder(sb);

                    for (int i = 0; i < sa.Length; ++i)
                        t[i] &= sa[i];
                }

                res.SetString(runtime, t.ToString());
            }
            else
            {
                // TODO take into account signed/unsigned?
                res.SetInteger(runtime, a.AsInteger(runtime) & b.AsInteger(runtime));
            }

            return res;
        }
示例#2
0
        public static IP5Any DoFile(Runtime runtime,
                                    Opcode.ContextValues context,
                                    P5Scalar file)
        {
            var file_s = file.AsString(runtime);

            var ret = LoadFile(runtime, context, file_s);
            if (ret == null)
                return new P5Scalar(runtime);

            return ret;
        }
示例#3
0
        public static P5Scalar BitNot(Runtime runtime, P5Scalar value)
        {
            if (value.IsString(runtime))
            {
                string svalue = value.AsString(runtime);
                var t = new System.Text.StringBuilder(svalue);;

                for (int i = 0; i < svalue.Length; ++i)
                    t[i] = (char)(~t[i] & 0xff); // only ASCII for now

                return new P5Scalar(runtime, t.ToString());
            }
            else
            {
                // TODO take into account signed/unsigned?
                return new P5Scalar(runtime, ~value.AsInteger(runtime));
            }
        }
示例#4
0
        public static IP5Any RequireFile(Runtime runtime,
                                         Opcode.ContextValues context,
                                         P5Scalar file)
        {
            if (file.IsInteger(runtime) || file.IsFloat(runtime))
            {
                var value = file.AsFloat(runtime);
                var version = runtime.SymbolTable.GetScalar(runtime, "]", false);
                var version_f = version.AsFloat(runtime);

                if (version_f >= value)
                    return new P5Scalar(runtime, true);

                var msg = string.Format("Perl {0:F} required--this is only {1:F} stopped.", value, version_f);

                throw new P5Exception(runtime, msg);
            }

            var file_s = file.AsString(runtime);
            var inc = runtime.SymbolTable.GetHash(runtime, "INC", true);

            if (inc.ExistsKey(runtime, file_s))
                return new P5Scalar(runtime, 1);

            var ret = LoadFile(runtime, context, file_s);
            if (ret == null)
            {
                var message = new System.Text.StringBuilder();
                var inc_a = runtime.SymbolTable.GetArray(runtime, "INC", true);

                message.Append(string.Format("Can't locate {0:S} in @INC (@INC contains:", file_s));
                foreach (var dir in inc_a)
                {
                    message.Append(" ");
                    message.Append(dir.AsString(runtime));
                }
                message.Append(")");

                throw new P5Exception(runtime, message.ToString());
            }

            return ret;
        }
示例#5
0
        public static int Transliterate(Runtime runtime, P5Scalar scalar,
                                        string match, string replacement,
                                        int flags)
        {
            bool complement = (flags & Opcode.FLAG_RX_COMPLEMENT) != 0;
            bool delete = (flags & Opcode.FLAG_RX_DELETE) != 0;
            bool squeeze = (flags & Opcode.FLAG_RX_SQUEEZE) != 0;
            var s = scalar.AsString(runtime);
            int count = 0, last_r = -1;
            var new_str = new System.Text.StringBuilder();

            for (int i = 0; i < s.Length; ++i)
            {
                int idx = match.IndexOf(s[i]);
                int replace = s[i];

                if (idx == -1 && complement)
                {
                    if (delete)
                        replace = -1;
                    else if (replacement.Length > 0)
                        replace = replacement[replacement.Length - 1];

                    if (last_r == replace && squeeze)
                        replace = -1;
                    else
                        last_r = replace;

                    count += 1;
                }
                else if (idx != -1 && !complement)
                {
                    if (idx >= replacement.Length && delete)
                        replace = -1;
                    else if (idx >= replacement.Length)
                        replace = replacement[replacement.Length - 1];
                    else if (idx < replacement.Length)
                        replace = replacement[idx];

                    if (last_r == replace && squeeze)
                        replace = -1;
                    else
                        last_r = replace;

                    count += 1;
                }
                else
                    last_r = -1;

                if (replace != -1)
                    new_str.Append((char)replace);
            }

            scalar.SetString(runtime, new_str.ToString());

            return count;
        }
示例#6
0
        public static P5Scalar Oct(Runtime runtime, P5Scalar value)
        {
            var str = value.AsString(runtime);
            int start;

            for (start = 0; start < str.Length; ++start)
                if (!char.IsWhiteSpace(str[start]))
                    break;

            // TODO warn about invalid octal digit
            return new P5Scalar(runtime, ParseBaseInteger(str, start, 8));
        }
示例#7
0
        public static P5Scalar Negate(Runtime runtime, P5Scalar value)
        {
            if (value.IsString(runtime))
            {
                string str = value.AsString(runtime);
                bool word = true;

                foreach (var c in str)
                {
                    if (!(c == '_' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
                    {
                        word = false;
                        break;
                    }
                }

                if (word)
                    return new P5Scalar(runtime, "-" + str);
            }

            if (value.IsFloat(runtime))
                return new P5Scalar(runtime, -value.AsFloat(runtime));

            return new P5Scalar(runtime, -value.AsInteger(runtime));
        }
示例#8
0
        public static bool IsDerivedFrom(Runtime runtime, P5Scalar value, IP5Any pack)
        {
            P5SymbolTable stash = value.BlessedReferenceStash(runtime);

            if (stash == null)
                stash = runtime.SymbolTable.GetPackage(runtime, value.AsString(runtime), false);

            string pack_name = pack.AsString(runtime);
            P5SymbolTable parent = runtime.SymbolTable.GetPackage(runtime, pack_name, false);

            if (parent == null || stash == null)
                return false;

            return stash.IsDerivedFrom(runtime, parent);
        }
示例#9
0
        public static P5Scalar Hex(Runtime runtime, P5Scalar value)
        {
            var str = value.AsString(runtime);

            // TODO warn about invalid hexadecimal digits
            return new P5Scalar(runtime, ParseBaseInteger(str, 0, 16));
        }
示例#10
0
        public static IP5Regex CompileRegex(Runtime runtime, P5Scalar value, int flags)
        {
            if (value.IsReference(runtime))
            {
                var rx = value.DereferenceRegex(runtime);

                if (rx != null)
                    return rx;
            }

            if (runtime.NativeRegex)
                return new NetRegex(value.AsString(runtime));
            else
                throw new System.Exception("P5: Needs compiler to recompile string expression");
        }
示例#11
0
        public static P5Scalar Open3Args(Runtime runtime, P5Scalar target, string open_mode, P5Scalar value)
        {
            FileMode mode;
            FileAccess access;
            bool is_read = false, is_write = false, truncate = false;

            switch (open_mode)
            {
            case ">":
                mode = FileMode.OpenOrCreate;
                access = FileAccess.Write;
                is_write = truncate = true;
                break;
            case "<":
                mode = FileMode.Open;
                access = FileAccess.Read;
                is_read = true;
                break;
            case ">>":
                mode = FileMode.Append;
                access = FileAccess.Write;
                is_write = true;
                break;
            case "+>":
                mode = FileMode.OpenOrCreate;
                access = FileAccess.ReadWrite;
                is_read = is_write = truncate = true;
                break;
            case "+<":
                mode = FileMode.OpenOrCreate;
                access = FileAccess.ReadWrite;
                is_read = is_write = true;
                break;
            default:
                throw new P5Exception(runtime, string.Format("Unknown open() mode '{0}'", open_mode));
            }

            FileStream filestream;

            try
            {
                filestream = new FileStream(value.AsString(runtime), mode, access);
                if (truncate)
                    filestream.SetLength(0);
            }
            catch (IOException)
            {
                // TODO set $!
                return new P5Scalar(runtime, false);
            }

            // TODO handle encoding
            var handle = new P5Handle(
                runtime,
                is_read ? new StreamReader(filestream) : null,
                is_write ? new StreamWriter(filestream) : null);

            target.SetHandle(runtime, handle);

            return new P5Scalar(runtime, true);
        }