예제 #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 Parser(Runtime runtime)
        {
            parser_runtime = new Runtime();
            parser_runtime.NativeRegex = true;

            // find compiled code
            var parser_assembly = System.Reflection.Assembly.Load("Language.P.Net.Parser");

            parser_runtime.ModuleLoaders.Insert(0, new AssemblyModuleLoader(parser_assembly));

            // load Language::P frontend
            Builtins.RequireFile(parser_runtime,
                                 Opcode.ContextValues.VOID,
                                 new P5Scalar(parser_runtime, "Language/P.pm"));

            // create generator
            generator = new DynamicGenerator(runtime, parser_runtime);

            // instantiate parser
            P5Array arglist_parser =
                new P5Array(parser_runtime,
                            new P5Scalar(parser_runtime, "Language::P::Parser"),
                            GetInit(runtime));
            parser_template = arglist_parser.CallMethod(parser_runtime, Opcode.ContextValues.SCALAR, "new") as P5Scalar;
        }
예제 #3
0
 public P5VecBody(Runtime runtime, P5Scalar _value,
                  int _offset, int _bits)
 {
     value = _value;
     offset = _offset;
     bits = _bits;
 }
예제 #4
0
        public static P5Scalar Close(Runtime runtime, P5Scalar arg)
        {
            var handle = arg.DereferenceHandle(runtime);
            bool res = handle.Close(runtime);

            return new P5Scalar(runtime, res);
        }
예제 #5
0
 public DynamicGenerator(Runtime _runtime, Runtime _parser_runtime,
                         P5Scalar _intermediate, P5Scalar _transform)
     : this(_runtime)
 {
     parser_runtime = _parser_runtime;
     intermediate = _intermediate;
     transform = _transform;
 }
예제 #6
0
        public bool Readline(Runtime runtime, out P5Scalar result)
        {
            System.Text.StringBuilder builder = null;

            for (;;)
            {
                if (rdbuf_start < rdbuf_end)
                {
                    int newline = System.Array.IndexOf(read_buffer, '\n', rdbuf_start, rdbuf_end - rdbuf_start);

                    if (newline < 0 && rdbuf_end != BUFFER_SIZE)
                        newline = rdbuf_end - 1;

                    if (newline >= 0)
                    {
                        if (builder != null)
                        {
                            builder.Append(read_buffer, rdbuf_start, newline + 1 - rdbuf_start);

                            result = new P5Scalar(runtime, builder.ToString());
                        }
                        else
                            result = new P5Scalar(runtime, new string(read_buffer, rdbuf_start, newline + 1 - rdbuf_start));

                        rdbuf_start = newline + 1;

                        return true;
                    }

                    if (builder == null)
                        builder = new System.Text.StringBuilder(2 * BUFFER_SIZE);

                    builder.Append(read_buffer, rdbuf_start, rdbuf_end - rdbuf_start);
                }

                rdbuf_start = 0;
                rdbuf_end = input.Read(read_buffer, 0, BUFFER_SIZE);

                if (rdbuf_start == rdbuf_end)
                {
                    if (builder != null)
                    {
                        result = new P5Scalar(runtime, builder.ToString());

                        return true;
                    }
                    else
                    {
                        result = new P5Scalar(runtime);

                        return false;
                    }
                }
            }
        }
예제 #7
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;
        }
예제 #8
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));
            }
        }
예제 #9
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;
        }
예제 #10
0
        public DynamicGenerator(Runtime _runtime, Runtime _parser_runtime)
            : this(_runtime)
        {
            parser_runtime = _parser_runtime;

            // load Language::P::Intermediate frontend
            Builtins.RequireFile(parser_runtime,
                                 Opcode.ContextValues.VOID,
                                 new P5Scalar(parser_runtime, "Language/P/Intermediate/Generator.pm"));

            // set the opcode factory
            var assembly_i = parser_runtime.SymbolTable.GetGlob(parser_runtime, "Language::P::Assembly::i", true);
            assembly_i.Code = new P5NativeCode("Language::P::Assembly::i",
                                               new P5Code.Sub(Opcode.WrapCreate));

            // wrap Language::P::Intermediate support classes
            NetGlue.Extend(parser_runtime, "Language::P::Intermediate::Code",
                           "org.mbarbon.p.runtime.Subroutine",
                           "new", false);
            NetGlue.Extend(parser_runtime, "Language::P::Intermediate::BasicBlock",
                           "org.mbarbon.p.runtime.BasicBlock",
                           "new_from_label", false);
            NetGlue.Extend(parser_runtime, "Language::P::Intermediate::Scope",
                           "org.mbarbon.p.runtime.Scope",
                           "new", false);
            NetGlue.Extend(parser_runtime, "Language::P::Intermediate::LexicalState",
                           "org.mbarbon.p.runtime.LexicalState",
                           "new", false);
            NetGlue.Extend(parser_runtime, "Language::P::Intermediate::LexicalInfo",
                           "org.mbarbon.p.runtime.LexicalInfo",
                           "new", false);

            intermediate = CreateIRGenerator();

            // load Language::P::Transform
            Builtins.RequireFile(parser_runtime,
                                 Opcode.ContextValues.VOID,
                                 new P5Scalar(parser_runtime, "Language/P/Intermediate/Transform.pm"));

            transform = CreateTransform();
        }
예제 #11
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");
        }
예제 #12
0
        public IP5Any CallMethod(Runtime runtime, Opcode.ContextValues context,
                                 string method, P5Array args)
        {
            int count = args.GetCount(runtime);
            var arg = new P5Scalar[count - 1];

            for (int i = 1; i < count; ++i)
                arg[i - 1] = args.GetItem(runtime, i) as P5Scalar;

            var type = obj as System.Type;
            if (type != null)
                return NetGlue.CallStaticMethod(runtime, type, method, arg);
            else
                return NetGlue.CallMethod(runtime, obj, method, arg);
        }
예제 #13
0
 public static P5Scalar BitAndAssign(Runtime runtime,
                                     P5Scalar a, P5Scalar b)
 {
     return BitAnd(runtime, a, a, b);
 }
예제 #14
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;
        }
예제 #15
0
        public static P5Scalar Bless(Runtime runtime, P5Scalar reference, IP5Any pack)
        {
            var pack_str = pack.AsString(runtime);
            var stash = runtime.SymbolTable.GetPackage(runtime, pack_str, true);

            reference.BlessReference(runtime, stash);

            return reference;
        }
예제 #16
0
        public virtual IP5ScalarBody Assign(Runtime runtime, IP5ScalarBody other)
        {
            var osb = other as P5TypeglobBody;

            if (osb == null)
                return other.CloneBody(runtime);

            scalar = osb.scalar;
            array = osb.array;
            hash = osb.hash;
            handle = osb.handle;
            code = osb.code;

            return this;
        }
예제 #17
0
        public static bool IsOverloaded(Runtime runtime, P5Scalar scalar,
                                        out Overloads overloads)
        {
            overloads = null;

            if (!scalar.IsReference(runtime))
                return false;

            var stash = scalar.Dereference(runtime).Blessed(runtime);
            if (stash == null)
                return false;

            overloads = stash.Overloads;

            return stash.HasOverloading;
        }
예제 #18
0
        public static P5Scalar RightShiftScalars(Runtime runtime, P5Scalar res, IP5Any left, IP5Any right)
        {
            res.SetInteger(runtime, left.AsInteger(runtime) >> right.AsInteger(runtime));

            return res;
        }
예제 #19
0
 public static P5Scalar RightShiftScalarsAssign(Runtime runtime, P5Scalar left, IP5Any right)
 {
     return RightShiftScalars(runtime, left, left, right);
 }
예제 #20
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));
        }
예제 #21
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));
        }
예제 #22
0
 public static P5Scalar MultiplyScalarsAssign(Runtime runtime, P5Scalar left, IP5Any right)
 {
     return MultiplyScalars(runtime, left, left, right);
 }
예제 #23
0
        public static IP5Any LocalizeHashElement(Runtime runtime, P5Hash hash, IP5Any index, ref SavedValue state)
        {
            string str_index = index.AsString(runtime);
            var saved = hash.LocalizeElement(runtime, str_index);
            var new_value = new P5Scalar(runtime);

            state.container = hash;
            state.str_key = str_index;
            state.value = saved;

            hash.SetItem(runtime, str_index, new_value);

            return new_value;
        }
예제 #24
0
 public static P5Scalar AddScalarsAssign(Runtime runtime, P5Scalar left, IP5Any right)
 {
     return AddScalars(runtime, left, left, right);
 }
예제 #25
0
        public static P5Scalar CallOverloadInverted(Runtime runtime, OverloadOperation op,
                                                    P5Scalar left, IP5Any right)
        {
            Overloads oright;

            if (!IsOverloaded(runtime, right, out oright))
                return null;

            return oright.CallOperation(runtime, op, left, right, true);
        }
예제 #26
0
        public static P5Scalar SubtractScalars(Runtime runtime, P5Scalar res, IP5Any left, IP5Any right)
        {
            // TODO handle integer addition and integer -> float promotion
            res.SetFloat(runtime, left.AsFloat(runtime) - right.AsFloat(runtime));

            return res;
        }
예제 #27
0
        public P5Scalar SpliceSubstring(Runtime runtime, int start,
                                        IP5Any replace)
        {
            var sn = ForceString(runtime);

            AdjustOffsets(sn.stringValue, ref start);

            // TODO handle the various corner cases for start/end
            var part = new P5Scalar(runtime, sn.stringValue.Substring(start, sn.stringValue.Length - start));
            sn.stringValue = sn.stringValue.Substring(0, start)
                + replace.AsString(runtime);

            return part;
        }
예제 #28
0
 public static P5Scalar SubtractScalarsAssign(Runtime runtime, P5Scalar left, IP5Any right)
 {
     return SubtractScalars(runtime, left, left, right);
 }
예제 #29
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));
        }
예제 #30
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);
        }