예제 #1
0
파일: Meta.cs 프로젝트: robotii/Wren.NET
        static bool Eval(WrenVM vm, Obj[] args, int stackStart)
        {
            if (args[stackStart + 1] is ObjString)
            {

                // Eval the code in the module where the calling function was defined.
                Obj callingFn = vm.Fiber.GetFrame().Fn;
                ObjModule module = (callingFn is ObjFn)
                    ? ((ObjFn)callingFn).Module
                    : ((ObjClosure)callingFn).Function.Module;

                // Compile it.
                ObjFn fn = Compiler.Compile(vm, module, "", args[stackStart + 1].ToString(), false);

                if (fn == null)
                {
                    vm.Fiber.Error = Obj.MakeString("Could not compile source code.");
                    return false;
                }

                // TODO: Include the compile errors in the runtime error message.

                // Create a fiber to run the code in.
                ObjFiber evalFiber = new ObjFiber(fn) { Caller = vm.Fiber };

                // Switch to the fiber.
                args[stackStart] = evalFiber;

                return false;
            }

            vm.Fiber.Error = Obj.MakeString("Source code must be a string.");
            return false;
        }
예제 #2
0
        public static void LoadLibrary(WrenVM vm, string libraryName, string typeName)
        {
            Type wrenLibrary = Type.GetType("Wren.Core.Library.LoadLibrary");

            var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            var di = new DirectoryInfo(path);
            foreach (var file in di.GetFiles(libraryName))
            {
                try
                {
                    var nextAssembly = Assembly.LoadFrom(file.FullName);

                    foreach (var type in nextAssembly.GetTypes())
                    {
                        if (type.GetCustomAttributes(wrenLibrary, false).Length > 0)
                        {
                            // This class implements the interface
                            var m = type.GetMethod("LoadLibrary");
                            m.Invoke(null, new object[] {vm});
                        }
                    }
                }
                catch (BadImageFormatException)
                {
                    // Not a .net assembly  - ignore
                }
            }
        }
예제 #3
0
파일: Meta.cs 프로젝트: robotii/Wren.NET
        public static void LoadLibrary(WrenVM vm)
        {
            vm.Interpret("", "", MetaLibSource);

            ObjClass meta = (ObjClass)vm.FindVariable("Meta");
            vm.Primitive(meta.ClassObj, "eval(_)", Eval);
        }
예제 #4
0
 public static void LoadLibrary(WrenVM vm)
 {
     vm.Interpret("scheduler", "scheduler", _schedulerSource);
     ObjClass scheduler = (ObjClass)vm.FindVariable("scheduler", "Scheduler");
     vm.Primitive(scheduler.ClassObj, "captureMethods_()", CaptureMethods);
     vm.Interpret("scheduler", "scheduler", "Scheduler.captureMethods_()");
 }
예제 #5
0
파일: Program.cs 프로젝트: robotii/Wren.NET
        static int RunFile(string path)
        {
            if (!File.Exists(path)) 
                return 66; // File Not Found

            _loadedFile = path;
            string source = File.ReadAllText(path);
            WrenVM vm = new WrenVM { LoadModuleFn = LoadModule };
            LibraryLoader.LoadLibraries(vm);
            return (int)vm.Interpret("main", path, source);
        }
예제 #6
0
파일: Program.cs 프로젝트: minirop/Wren.NET
 static int RunFile(string path)
 {
     if (File.Exists(path))
     {
         loadedFile = path;
         string source = File.ReadAllText(path);
         WrenVM vm = new WrenVM { LoadModuleFn = LoadModule };
         return (int)vm.Interpret(path, source);
     }
     return 66; // File Not Found
 }
예제 #7
0
파일: io.cs 프로젝트: robotii/Wren.NET
        public static void LoadLibrary(WrenVM vm)
        {
            vm.Interpret("io", "io", IoSource);
            ObjClass file = (ObjClass)vm.FindVariable("io", "File");
            vm.Primitive(file.ClassObj, "open_(_,_)", Open);
            vm.Primitive(file.ClassObj, "sizePath_(_,_)", SizePath);

            vm.Primitive(file, "close_(_)", Close);
            vm.Primitive(file, "descriptor", Descriptor);
            vm.Primitive(file, "readBytes_(_,_)", ReadBytes);
            vm.Primitive(file, "size_(_)", Size);
        }
예제 #8
0
파일: Program.cs 프로젝트: minirop/Wren.NET
        static void RunRepl()
        {
            WrenVM vm = new WrenVM();

            Console.WriteLine("-- wren v0.0.0");

            string line = "";

            for (; line != "/exit"; )
            {
                Console.Write("> ");
                line = Console.ReadLine();

                // TODO: Handle failure.
                vm.Interpret("Prompt", line);
            }
        }
예제 #9
0
파일: Program.cs 프로젝트: robotii/Wren.NET
        static void RunRepl()
        {
            WrenVM vm = new WrenVM();
            LibraryLoader.LoadLibraries(vm);

            Console.WriteLine("-- wren v0.0.0");

            string line = "";

            for (; ; )
            {
                Console.Write("> ");
                line += Console.ReadLine() + "\n";

                if(OpenBrackets(line) > 0)
                    continue;

                // TODO: Handle failure.
                vm.Interpret("Prompt","Prompt", line);
                line = "";
            }
        }
예제 #10
0
        static bool prim_map_subscript(WrenVM vm, Obj[] args, int stackStart)
        {
            Obj a = args[stackStart + 1];
            if (ValidateKey(a))
            {
                ObjMap map = args[stackStart] as ObjMap;
                if (map != null)
                {
                    args[stackStart] = map.Get(a);
                    if (args[stackStart] == Obj.Undefined)
                    {
                        args[stackStart] = Obj.Null;
                    }
                }
                else
                {
                    args[stackStart] = Obj.Null;
                }
                return true;
            }

            vm.Fiber.Error = Obj.MakeString("Key must be a value type or fiber.");
            return false;
        }
예제 #11
0
 static bool prim_map_instantiate(WrenVM vm, Obj[] args, int stackStart)
 {
     args[stackStart] = new ObjMap();
     return true;
 }
예제 #12
0
        static bool prim_list_subscriptSetter(WrenVM vm, Obj[] args, int stackStart)
        {
            ObjList list = (ObjList)args[stackStart];
            if (args[stackStart + 1].Type == ObjType.Num)
            {
                int index = (int)args[stackStart + 1].Num;

                if (index == args[stackStart + 1].Num)
                {
                    if (index < 0)
                    {
                        index += list.Count();
                    }

                    if (list != null && index >= 0 && index < list.Count())
                    {
                        list.Set(args[stackStart + 2], index);
                        args[stackStart] = args[stackStart + 2];
                        return true;
                    }

                    vm.Fiber.Error = Obj.MakeString("Subscript out of bounds.");
                    return false;
                }

                vm.Fiber.Error = Obj.MakeString("Subscript must be an integer.");
                return false;
            }
            vm.Fiber.Error = Obj.MakeString("Subscript must be a number.");
            return false;
        }
예제 #13
0
        static bool prim_list_subscript(WrenVM vm, Obj[] args, int stackStart)
        {
            ObjList list = (ObjList)args[stackStart];

            if (args[stackStart + 1].Type == ObjType.Num)
            {
                int index = (int)args[stackStart + 1].Num;
                if (index == args[stackStart + 1].Num)
                {
                    if (index < 0)
                    {
                        index += list.Count();
                    }
                    if (index >= 0 && index < list.Count())
                    {
                        args[stackStart] = list.Get(index);
                        return true;
                    }

                    vm.Fiber.Error = Obj.MakeString("Subscript out of bounds.");
                    return false;
                }
                vm.Fiber.Error = Obj.MakeString("Subscript must be an integer.");
                return false;
            }

            ObjRange r = args[stackStart + 1] as ObjRange;

            if (r == null)
            {
                vm.Fiber.Error = Obj.MakeString("Subscript must be a number or a range.");
                return false;
            }

            // TODO: This is seriously broken and needs a rewrite
            int from = (int)r.From;
            if (from != r.From)
            {
                vm.Fiber.Error = Obj.MakeString("Range start must be an integer.");
                return false;
            }
            int to = (int)r.To;
            if (to != r.To)
            {
                vm.Fiber.Error = Obj.MakeString("Range end must be an integer.");
                return false;
            }

            if (from < 0)
                from += list.Count();
            if (to < 0)
                to += list.Count();

            int step = to < from ? -1 : 1;

            if (step > 0 && r.IsInclusive)
                to += 1;
            if (step < 0 && !r.IsInclusive)
                to += 1;

            // Handle copying an empty list
            if (list.Count() == 0 && to == (r.IsInclusive ? -1 : 0))
            {
                to = 0;
                step = 1;
            }

            int count = (to - from) * step + (step < 0 ? 1 : 0);

            if (to < 0 || from + (count * step) > list.Count())
            {
                vm.Fiber.Error = Obj.MakeString("Range end out of bounds.");
                return false;
            }
            if (from < 0 || (from >= list.Count() && from > 0))
            {
                vm.Fiber.Error = Obj.MakeString("Range start out of bounds.");
                return false;
            }

            ObjList result = new ObjList(count);
            for (int i = 0; i < count; i++)
            {
                result.Add(list.Get(from + (i * step)));
            }

            args[stackStart] = result;
            return true;
        }
예제 #14
0
        static bool prim_fn_new(WrenVM vm, Obj[] args, int stackStart)
        {
            Obj v = args[stackStart + 1];
            if (v != null && (v is ObjFn || v is ObjClosure))
            {
                args[stackStart] = args[stackStart + 1];
                return true;
            }

            // The block argument is already a function, so just return it.
            vm.Fiber.Error = Obj.MakeString("Argument must be a function.");
            return false;
        }
예제 #15
0
        private static bool prim_map_iterate(WrenVM vm, Obj[] args, int stackStart)
        {
            ObjMap map = (ObjMap)args[stackStart];

            if (map.Count() == 0)
            {
                args[stackStart] = Obj.False;
                return true;
            }

            // Start one past the last entry we stopped at.
            if (args[stackStart + 1].Type == ObjType.Num)
            {
                if (args[stackStart + 1].Num < 0)
                {
                    args[stackStart] = Obj.False;
                    return true;
                }
                int index = (int)args[stackStart + 1].Num;

                if (index == args[stackStart + 1].Num)
                {
                    args[stackStart] = index > map.Count() || map.Get(index) == Obj.Undefined ? Obj.False : new Obj(index + 1);
                    return true;
                }

                vm.Fiber.Error = Obj.MakeString("Iterator must be an integer.");
                return false;
            }

            // If we're starting the iteration, start at the first used entry.
            if (args[stackStart + 1] == Obj.Null)
            {
                args[stackStart] = new Obj(1);
                return true;
            }

            vm.Fiber.Error = Obj.MakeString("Iterator must be a number.");
            return false;
        }
예제 #16
0
        static bool prim_map_containsKey(WrenVM vm, Obj[] args, int stackStart)
        {
            ObjMap map = (ObjMap)args[stackStart];

            if (ValidateKey(args[stackStart + 1]))
            {
                Obj v = map.Get(args[stackStart + 1]);

                args[stackStart] = Obj.Bool(v != Obj.Undefined);
                return true;
            }

            vm.Fiber.Error = Obj.MakeString("Key must be a value type or fiber.");
            return false;
        }
예제 #17
0
 static bool prim_list_add(WrenVM vm, Obj[] args, int stackStart)
 {
     ObjList list = args[stackStart] as ObjList;
     if (list == null)
     {
         vm.Fiber.Error = Obj.MakeString("Trying to add to a non-list");
         return false;
     }
     list.Add(args[stackStart + 1]);
     args[stackStart] = args[stackStart + 1];
     return true;
 }
예제 #18
0
파일: WrenVM.cs 프로젝트: robotii/Wren.NET
 // Creates a string containing an appropriate method not found error for a
 // method with [symbol] on [classObj].
 static void MethodNotFound(WrenVM vm, ObjClass classObj, int symbol)
 {
     vm.Fiber.Error = Obj.MakeString(string.Format("{0} does not implement '{1}'.", classObj.Name, vm.MethodNames[symbol]));
 }
예제 #19
0
 static bool prim_list_instantiate(WrenVM vm, Obj[] args, int stackStart)
 {
     args[stackStart] = new ObjList(16);
     return true;
 }
예제 #20
0
 static bool prim_fn_toString(WrenVM vm, Obj[] args, int stackStart)
 {
     args[stackStart] = Obj.MakeString("<fn>");
     return true;
 }
예제 #21
0
 static bool prim_fn_arity(WrenVM vm, Obj[] args, int stackStart)
 {
     ObjFn fn = args[stackStart] as ObjFn;
     args[stackStart] = fn != null ? new Obj(fn.Arity) : new Obj(0.0);
     return true;
 }
예제 #22
0
        static bool prim_map_subscriptSetter(WrenVM vm, Obj[] args, int stackStart)
        {
            if (ValidateKey(args[stackStart + 1]))
            {
                ObjMap map = args[stackStart] as ObjMap;

                if (map != null)
                {
                    map.Set(args[stackStart + 1], args[stackStart + 2]);
                }
                args[stackStart] = args[stackStart + 2];
                return true;
            }

            vm.Fiber.Error = Obj.MakeString("Key must be a value type or fiber.");
            return false;
        }
예제 #23
0
        static bool prim_list_insert(WrenVM vm, Obj[] args, int stackStart)
        {
            ObjList list = (ObjList)args[stackStart];

            if (args[stackStart + 1].Type == ObjType.Num)
            {
                int index = (int)args[stackStart + 1].Num;
                if (args[stackStart + 1].Num == index)
                {
                    if (index < 0)
                        index += list.Count() + 1;
                    if (index >= 0 && index <= list.Count())
                    {
                        list.Insert(args[stackStart + 2], index);
                        args[stackStart] = args[stackStart + 2];
                        return true;
                    }
                    vm.Fiber.Error = Obj.MakeString("Index out of bounds.");
                    return false;
                }

                // count + 1 here so you can "insert" at the very end.
                vm.Fiber.Error = Obj.MakeString("Index must be an integer.");
                return false;
            }

            vm.Fiber.Error = Obj.MakeString("Index must be a number.");
            return false;
        }
예제 #24
0
 static bool prim_map_clear(WrenVM vm, Obj[] args, int stackStart)
 {
     ObjMap m = args[stackStart] as ObjMap;
     if (m != null)
         m.Clear();
     args[stackStart] = Obj.Null;
     return true;
 }
예제 #25
0
        static bool prim_list_iterate(WrenVM vm, Obj[] args, int stackStart)
        {
            ObjList list = (ObjList)args[stackStart];

            // If we're starting the iteration, return the first index.
            if (args[stackStart + 1] == Obj.Null)
            {
                if (list.Count() != 0)
                {
                    args[stackStart] = new Obj(0.0);
                    return true;
                }

                args[stackStart] = Obj.False;
                return true;
            }

            if (args[stackStart + 1].Type == ObjType.Num)
            {
                int index = (int)args[stackStart + 1].Num;
                if (args[stackStart + 1].Num == index)
                {
                    if (!(index < 0) && !(index >= list.Count() - 1))
                    {
                        // Move to the next index.
                        args[stackStart] = new Obj(index + 1);
                        return true;
                    }

                    // Stop if we're out of bounds.
                    args[stackStart] = Obj.False;
                    return true;
                }

                vm.Fiber.Error = Obj.MakeString("Iterator must be an integer.");
                return false;
            }

            vm.Fiber.Error = Obj.MakeString("Iterator must be a number.");
            return false;
        }
예제 #26
0
 static bool prim_map_count(WrenVM vm, Obj[] args, int stackStart)
 {
     ObjMap m = (ObjMap)args[stackStart];
     args[stackStart] = new Obj(m.Count());
     return true;
 }
예제 #27
0
        static bool prim_list_removeAt(WrenVM vm, Obj[] args, int stackStart)
        {
            ObjList list = (ObjList)args[stackStart];

            if (args[stackStart + 1].Type == ObjType.Num)
            {
                int index = (int)args[stackStart + 1].Num;
                if (args[stackStart + 1].Num == index)
                {
                    if (index < 0)
                        index += list.Count();
                    if (index >= 0 && index < list.Count())
                    {
                        args[stackStart] = list.RemoveAt(index);
                        return true;
                    }

                    vm.Fiber.Error = Obj.MakeString("Index out of bounds.");
                    return false;
                }

                vm.Fiber.Error = Obj.MakeString("Index must be an integer.");
                return false;
            }

            vm.Fiber.Error = Obj.MakeString("Index must be a number.");
            return false;
        }
예제 #28
0
        static bool prim_list_clear(WrenVM vm, Obj[] args, int stackStart)
        {
            ObjList list = args[stackStart] as ObjList;
            if (list == null)
            {
                vm.Fiber.Error = Obj.MakeString("Trying to clear a non-list");
                return false;
            }
            list.Clear();

            args[stackStart] = Obj.Null;
            return true;
        }
예제 #29
0
        static bool prim_fiber_yield1(WrenVM vm, Obj[] args, int stackStart)
        {
            // Unhook this fiber from the one that called it.
            ObjFiber caller = vm.Fiber.Caller;
            vm.Fiber.Caller = null;
            vm.Fiber.CallerIsTrying = false;

            // If we don't have any other pending fibers, jump all the way out of the
            // interpreter.
            if (caller == null)
            {
                args[stackStart] = Obj.Null;
            }
            else
            {
                // Make the caller's run method return the argument passed to yield.
                caller.StoreValue(-1, args[stackStart + 1]);

                // When the yielding fiber resumes, we'll store the result of the yield call
                // in its stack. Since Fiber.yield(value) has two arguments (the Fiber class
                // and the value) and we only need one slot for the result, discard the other
                // slot now.
                vm.Fiber.StackTop--;

                // Return the fiber to resume.
                args[stackStart] = caller;
            }

            return false;
        }
예제 #30
0
파일: WrenVM.cs 프로젝트: robotii/Wren.NET
 // Creates a string containing an appropriate method not found error for a
 // method with [symbol] on [classObj].
 static void MethodNotFound(WrenVM vm, ObjClass classObj, int symbol)
 {
     vm.Fiber.Error = Obj.MakeString(string.Format("{0} does not implement '{1}'.", classObj.Name, vm.MethodNames[symbol]));
 }
예제 #31
0
        static bool prim_list_count(WrenVM vm, Obj[] args, int stackStart)
        {
            ObjList list = args[stackStart] as ObjList;
            if (list != null)
            {
                args[stackStart] = new Obj(list.Count());
                return true;
            }

            vm.Fiber.Error = Obj.MakeString("Trying to clear a non-list");
            return false;
        }