internal DynamicModuleGenerator(Runtime _runtime)
 {
     runtime = _runtime;
     subroutines = new Dictionary<Subroutine, P5Code>();
     regexes = new Dictionary<Subroutine, IP5Regex>();
     main_pad = new P5ScratchPad();
 }
예제 #2
0
 public P5Code(string _name, int[] _proto,
               System.Type _class, string _method, bool main)
 {
     subref = (Sub)System.Delegate.CreateDelegate(typeof(Sub), _class, _method);
     scratchpad = null;
     is_main = main;
     name = _name;
     proto = _proto;
 }
예제 #3
0
 public P5Code(string _name, int[] _proto,
               System.Delegate code, bool main)
 {
     subref = (Sub)code;
     scratchpad = null;
     is_main = main;
     name = _name;
     proto = _proto;
 }
예제 #4
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);
        }
예제 #5
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);
        }
예제 #6
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));
        }
예제 #7
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);
        }
예제 #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 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);
        }
예제 #10
0
 public void NewScope(Runtime runtime)
 {
     if (scratchpad != null)
         scratchpad = scratchpad.NewScope(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 void Assign(Runtime runtime, P5Code other)
 {
     subref = other.subref;
     proto = other.proto;
     scratchpad = other.scratchpad;
     const_value = other.const_value;
     const_flags = other.const_flags;
 }
예제 #14
0
        private IP5Any UndefinedSub(Runtime runtime,
                                    Opcode.ContextValues context,
                                    P5ScratchPad pad, P5Array args)
        {
            var msg = string.Format("Undefined subroutine &{0:S} called",
                                    Name);

            throw new P5Exception(runtime, msg);
        }
예제 #15
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)));
        }
예제 #16
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);
        }
예제 #17
0
        public virtual P5Scalar MakeClosure(Runtime runtime, P5ScratchPad outer)
        {
            P5Code closure = new P5Code(name, proto, subref, is_main);
            if (scratchpad != null)
                closure.scratchpad = scratchpad.CloseOver(runtime, outer);

            if (const_flags == 0)
                return new P5Scalar(runtime, closure);

            // constant sub optimization
            var value = closure.scratchpad.GetScalar(runtime, 0) as P5Scalar;
            if (value == null)
                return new P5Scalar(runtime, closure);

            var body = value.Body as P5StringNumber;
            if (body == null)
                return new P5Scalar(runtime, closure);

            int constant_flags = 0;
            object constant_value = null;

            if (body.IsString(runtime))
            {
                constant_value = body.AsString(runtime);
                constant_flags = 1; // CONST_STRING
            }
            else if (body.IsInteger(runtime))
            {
                constant_value = body.AsInteger(runtime);
                constant_flags = 10; // CONST_NUMBER|NUM_INTEGER
            }
            else if (body.IsFloat(runtime))
            {
                constant_value = body.AsFloat(runtime);
                constant_flags = 18; // CONST_NUMBER|NUM_FLOAT
            }

            if (constant_flags != 0)
            {
                var const_sub = new P5Code(null, subref,
                                           constant_value, constant_flags);
                const_sub.scratchpad = closure.scratchpad;

                closure = const_sub;
            }

            return new P5Scalar(runtime, closure);
        }