예제 #1
0
        public static P5Scalar Open(Runtime runtime, P5Array args)
        {
            if (args.GetCount(runtime) == 3)
                return Open3Args(runtime,
                                 args.GetItem(runtime, 0) as P5Scalar,
                                 args.GetItem(runtime, 1).AsString(runtime),
                                 args.GetItem(runtime, 2) as P5Scalar);

            throw new System.Exception("Unhandled arg count in open");
        }
예제 #2
0
        public static void AddOverload(Runtime runtime, string pack_name,
                                       P5Array args)
        {
            var overloads = new Overloads();
            var pack = runtime.SymbolTable.GetPackage(runtime, pack_name, true);

            for (int i = 0; i < args.GetCount(runtime); i += 2)
            {
                string key = args.GetItem(runtime, i).AsString(runtime);
                var value = args.GetItem(runtime, i + 1);

                overloads.AddOperation(runtime, key, value);
            }

            pack.SetOverloads(overloads);
        }
예제 #3
0
        public static P5Exception Die(Runtime runtime, P5Array args)
        {
            int argc = args.GetCount(runtime);

            if (argc == 1)
            {
                var s = args.GetItem(runtime, 0) as P5Scalar;

                if (s.IsReference(runtime))
                    return new P5Exception(runtime, s);
            }

            string message;
            if (argc == 0)
            {
                var exc = runtime.SymbolTable.GetStashScalar(runtime, "@", true);

                if (exc.IsDefined(runtime))
                    message = exc.AsString(runtime) + "\t...propagated";
                else
                    message = "Died";
            }
            else
            {
                var t = new System.Text.StringBuilder();
                foreach (var e in args)
                    t.Append(e.AsString(runtime));
                message = t.ToString();
            }

            return new P5Exception(runtime, message);
        }
예제 #4
0
        private static IP5Any WrapSpecializeType(Runtime runtime, Opcode.ContextValues context,
                                                 P5ScratchPad pad, P5Array args)
        {
            var type = Glue.UnwrapValue<System.Type>(runtime, args.GetItem(runtime, 0));
            var tyargs = new System.Type[args.GetCount(runtime) - 1];

            for (int i = args.GetCount(runtime) - 1; i > 0; --i)
                tyargs[i - 1] = Glue.UnwrapValue<System.Type>(runtime, args.GetItem(runtime, i));

            return new P5Scalar(new P5NetWrapper(type.MakeGenericType(tyargs)));
        }
예제 #5
0
        private static IP5Any WrapSetProperty(Runtime runtime, Opcode.ContextValues context,
                                              P5ScratchPad pad, P5Array args)
        {
            var obj = args.GetItem(runtime, 0) as P5Scalar;
            var name = args.GetItem(runtime, 1);
            var value = args.GetItem(runtime, 2);

            Glue.SetProperty(runtime, obj, name.AsString(runtime), value);

            return new P5Scalar(runtime);
        }
예제 #6
0
        private static IP5Any WrapIsa(Runtime runtime, Opcode.ContextValues context,
                                      P5ScratchPad pad, P5Array args)
        {
            var value = args.GetItem(runtime, 0) as P5Scalar;
            var parent = args.GetItem(runtime, 1);
            bool is_derived = Builtins.IsDerivedFrom(runtime, value, parent);

            return new P5Scalar(runtime, is_derived);
        }
예제 #7
0
        private static IP5Any WrapGetClass(Runtime runtime, Opcode.ContextValues context,
                                           P5ScratchPad pad, P5Array args)
        {
            var name = args.GetItem(runtime, 0);

            return Glue.GetClass(runtime, name.AsString(runtime));
        }
예제 #8
0
        private static IP5Any WrapCreate(Runtime runtime, Opcode.ContextValues context,
                                         P5ScratchPad pad, P5Array args)
        {
            var cls = args.GetItem(runtime, 0) as P5Scalar;
            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;

            return Glue.CallConstructor(runtime, cls, arg);
        }
예제 #9
0
        private static IP5Any WrapCallStatic(Runtime runtime, Opcode.ContextValues context,
                                             P5ScratchPad pad, P5Array args)
        {
            var type = Glue.UnwrapValue<System.Type>(runtime, args.GetItem(runtime, 0));
            var name = args.GetItem(runtime, 1).AsString(runtime);
            int count = args.GetCount(runtime);
            var arg = new P5Scalar[count - 2];

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

            return Glue.CallStaticMethod(runtime, type, name, arg);
        }
예제 #10
0
        private static IP5Any WrapCompileAssembly(Runtime runtime, Opcode.ContextValues context,
                                                  P5ScratchPad pad, P5Array args)
        {
            var asm_path = args.GetItem(runtime, 0).AsString(runtime);
            var generator = new Generator(runtime, asm_path);

            for (int i = 1; i < args.GetCount(runtime); ++i)
            {
                var arg = args.GetItem(runtime, i).AsString(runtime);
                string path, file;

                path = Builtins.SearchFile(runtime, arg);

                if (path != null)
                    file = arg;
                else
                {
                    file = arg.Replace("::", "/") + ".pm";
                    path = Builtins.SearchFile(runtime, file);
                }

                if (path == null)
                    throw new System.Exception(string.Format("File not found for '{0:S}'", arg));

                var cu = Serializer.ReadCompilationUnit(runtime, path);
                cu.FileName = file;

                generator.Generate(cu);
            }

            generator.Assembly.Save(new System.IO.FileInfo(asm_path + ".dll").Name);

            return new P5Scalar(runtime);
        }
예제 #11
0
        private static IP5Any WrapCallMethod(Runtime runtime, Opcode.ContextValues context,
                                             P5ScratchPad pad, P5Array args)
        {
            var obj = args.GetItem(runtime, 0) as P5Scalar;
            var name = args.GetItem(runtime, 1).AsString(runtime);
            int count = args.GetCount(runtime);
            var arg = new P5Scalar[count - 2];

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

            return Glue.CallMethod(runtime, obj, name, arg);
        }
예제 #12
0
        private static IP5Any WrapAddOverload(Runtime runtime, Opcode.ContextValues context,
                                              P5ScratchPad pad, P5Array args)
        {
            var pack = args.GetItem(runtime, 0) as P5Scalar;
            var opref = args.GetItem(runtime, 1) as P5Scalar;
            var ops = opref.DereferenceArray(runtime) as P5Array;

            Builtins.AddOverload(runtime, pack.AsString(runtime), ops);

            return null;
        }
예제 #13
0
        public static P5Scalar Print(Runtime runtime, P5Handle handle, P5Array args)
        {
            // wrong but works well enough for now
            for (int i = 0, m = args.GetCount(runtime); i < m; ++i)
            {
                handle.Write(runtime, args.GetItem(runtime, i), 0, -1);
            }

            return new P5Scalar(runtime, 1);
        }
예제 #14
0
        public static IP5Any Reverse(Runtime runtime, Opcode.ContextValues context,
                                     P5Array args)
        {
            if (context == Opcode.ContextValues.LIST)
                return args.Reversed(runtime);

            int count = args.GetCount(runtime);
            char[] value;

            if (count == 0)
                value = runtime.SymbolTable.GetStashScalar(runtime, "_", true).AsString(runtime).ToCharArray();
            else if (count == 1)
                value = args.GetItem(runtime, 0).AsString(runtime).ToCharArray();
            else
            {
                var t = new System.Text.StringBuilder();

                foreach (var i in args)
                    t.Append(i.AsString(runtime));

                value = t.ToString().ToCharArray();
            }

            // TODO does not handle UCS-4
            System.Array.Reverse(value);

            return new P5Scalar(runtime, new string(value));
        }
예제 #15
0
        private static IP5Any WrapExtend(Runtime runtime, Opcode.ContextValues context,
                                         P5ScratchPad pad, P5Array args)
        {
            var pack = args.GetItem(runtime, 0);
            var cls = args.GetItem(runtime, 1);

            return Glue.Extend(runtime, pack.AsString(runtime),
                               cls.AsString(runtime), "new", true);
        }
예제 #16
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);
        }
예제 #17
0
        public static P5Scalar Sprintf(Runtime runtime, P5Array args)
        {
            string format = args.GetItem(runtime, 0).AsString(runtime);
            var result = new System.Text.StringBuilder();
            int index = 1, last_pos = 0;

            for (var match = specifier.Match(format); match.Success;
                 match = specifier.Match(format, last_pos))
            {
                // append text between two format placeholders
                result.Append(format, last_pos, match.Index - last_pos);
                last_pos = match.Index + match.Length;

                char format_char = format[match.Groups[FORMAT].Index];
                bool has_width = match.Groups[WIDTH].Success;
                bool has_precision = match.Groups[PRECISION].Success;
                bool zero_pad = false;
                int width = -1, precision = -1;

                if (has_width)
                    width = System.Int32.Parse(match.Groups[WIDTH].Value);

                if (has_precision)
                    precision = System.Int32.Parse(match.Groups[PRECISION].Value);

                if (match.Groups[FLAGS].Success)
                {
                    foreach (char c in match.Groups[FLAGS].Value)
                    {
                        switch (c)
                        {
                        case '0':
                            zero_pad = true;
                            break;
                        }
                    }
                }

                switch (format_char)
                {
                case 'd':
                {
                    var value = args.GetItem(runtime, index++).AsInteger(runtime);

                    if (!has_width && !zero_pad)
                        result.Append(value);
                    else
                        result.AppendFormat(MakeIntFormat('d', width, zero_pad), value);
                    break;
                }
                case 'x':
                {
                    var value = args.GetItem(runtime, index++).AsInteger(runtime);

                    if (!has_width && !zero_pad)
                        result.AppendFormat("{0:x}", value);
                    else
                        result.AppendFormat(MakeIntFormat('x', width, zero_pad), value);
                    break;
                }
                case 's':
                {
                    var value = args.GetItem(runtime, index++).AsString(runtime);

                    if (!has_width && !zero_pad)
                        result.Append(value);
                    else
                        result.AppendFormat(MakeIntFormat('S', width, zero_pad), value);
                    break;
                }
                case 'f':
                {
                    var value = args.GetItem(runtime, index++).AsFloat(runtime);

                    if (!has_width && !zero_pad && !has_precision)
                        result.Append(value);
                    else if (!zero_pad)
                        result.AppendFormat(MakeFloatFormat('f', width, precision), value);
                    else
                    {
                        var num = string.Format(MakeFloatFormat('F', -1, precision), value);

                        result.Append('0', width - num.Length);
                        result.Append(num);
                    }

                    break;
                }
                case '%':
                    result.Append('%');
                    break;
                default:
                    throw new System.Exception(string.Format("Unhandled format character '{0:C}' in sprintf", format_char));
                }
            }

            // append trailing text
            result.Append(format, last_pos, format.Length - last_pos);

            return new P5Scalar(runtime, result.ToString());
        }