コード例 #1
0
        static void ScriptMain(TextReader input, string fileName)
        {
            var state = new MondState();

            Functions.Register(state);

            string source;

            try
            {
                source = input.ReadToEnd();
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to read '{0}':", fileName);
                Console.WriteLine(e);
                return;
            }

            try
            {
                var program = MondProgram.Compile(Functions.Definitions + source, Path.GetFileName(fileName));
                var result  = state.Load(program);

                if (result != MondValue.Undefined)
                {
                    result.Serialize(Console.Out);
                    Console.WriteLine();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
コード例 #2
0
 public ReturnAddress(MondProgram program, int address, Frame arguments, int evalDepth)
 {
     Program   = program;
     Address   = address;
     Arguments = arguments;
     EvalDepth = evalDepth;
 }
コード例 #3
0
        public static MondValue Run(string source)
        {
            var state   = new MondState();
            var program = MondProgram.Compile(source);

            return(state.Load(program));
        }
コード例 #4
0
        private static CallStackEntry GenerateCallStackEntry(MondProgram program, int address)
        {
            var debugInfo = program.DebugInfo;

            if (debugInfo == null)
                return new CallStackEntry(address, program.GetHashCode().ToString("X8"), address.ToString("X8"), 0, -1);

            var fileName = program.DebugInfo.FileName;
            string function = null;
            var lineNumber = 0;
            var columnNumber = -1;

            var func = program.DebugInfo.FindFunction(address);
            if (func.HasValue)
                function = program.Strings[func.Value.Name];

            var position = program.DebugInfo.FindPosition(address);
            if (position.HasValue)
            {
                lineNumber = position.Value.LineNumber;
                columnNumber = position.Value.ColumnNumber;
            }

            if (fileName == null)
                fileName = program.GetHashCode().ToString("X8");

            if (function == null)
                function = address.ToString("X8");

            return new CallStackEntry(address, fileName, function, lineNumber, columnNumber);
        }
コード例 #5
0
        public MondValue Load(MondProgram program)
        {
            if (program == null)
                throw new ArgumentNullException("program");

            var function = new MondValue(new Closure(program, 0, null, null));
            return Call(function);
        }
コード例 #6
0
        private static void InteractiveRun(MondState state, MondProgram program)
        {
            var result = state.Load(program);

            // get rid of leading whitespace
            while (_input.Count > 0 && char.IsWhiteSpace(_input.Peek()))
            {
                _input.Dequeue();
            }

            if (_input.Count != 0)
            {
                return;
            }

            _first = true;

            // ignore undefined return value, it's almost always useless
            if (result == MondValue.Undefined)
            {
                return;
            }

            if (result["moveNext"].Type == MondValueType.Function && result.IsEnumerable)
            {
                Console.WriteLine();

                foreach (var value in result.Enumerate(state).Take(25))
                {
                    value.Serialize(Console.Out);
                    Console.WriteLine();
                }

                if (state.Call(result["moveNext"]))
                {
                    Console.WriteLine("...");
                }

                Console.WriteLine();
            }
            else
            {
                var resultStr = result.Serialize();
                var multiline = resultStr.Contains("\n");

                if (multiline)
                {
                    Console.WriteLine();
                    Console.WriteLine(resultStr);
                    Console.WriteLine();
                }
                else
                {
                    var lineNumberLen = Math.Max(_line.ToString("G").Length, 3);
                    Console.WriteLine("{0}> {1}", new string('=', lineNumberLen), resultStr);
                }
            }
        }
コード例 #7
0
ファイル: Closure.cs プロジェクト: xserve98/Mond
        public Closure(MondProgram program, int address, Frame arguments, Frame locals)
        {
            Type = ClosureType.Mond;

            Program   = program;
            Address   = address;
            Arguments = arguments;
            Locals    = locals;
        }
コード例 #8
0
        public ProgramInfo(MondProgram program)
        {
            _breakpoints = new List <int>(16);

            Program   = program;
            DebugInfo = program.DebugInfo;

            FileName = DebugInfo?.FileName ?? Program.GetHashCode().ToString("X8");
        }
コード例 #9
0
        public Closure(MondProgram program, int address, Frame arguments, Frame locals)
        {
            Type = ClosureType.Mond;

            Program = program;
            Address = address;
            Arguments = arguments;
            Locals = locals;
        }
コード例 #10
0
ファイル: Machine.cs プロジェクト: krixalis/Mond
        public MondValue Load(MondProgram program)
        {
            if (program == null)
                throw new ArgumentNullException("program");

            var programId = _programs.Count;
            _programs.Add(program);

            var closure = new MondValue(new Closure(programId, 0, null, null));
            return Call(closure);
        }
コード例 #11
0
ファイル: Machine.cs プロジェクト: foobit/Mond
        public MondValue Load(MondProgram program)
        {
            if (program == null)
            {
                throw new ArgumentNullException(nameof(program));
            }

            var function = new MondValue(new Closure(program, 0, null, null));

            return(Call(function));
        }
コード例 #12
0
ファイル: MondDebugger.cs プロジェクト: xserve98/Mond
        /// <summary>
        /// Removes a breakpoint from the given program.
        /// </summary>
        /// <param name="program"></param>
        /// <param name="address"></param>
        protected void RemoveBreakpoint(MondProgram program, int address)
        {
            lock (_sync)
            {
                if (!_programBreakpoints.TryGetValue(program, out var breakpoints))
                {
                    return;
                }

                breakpoints.Remove(address);
            }
        }
コード例 #13
0
        public static MondState Load(params string[] sources)
        {
            var state = new MondState();

            foreach (var source in sources)
            {
                var program = MondProgram.Compile(source);
                state.Load(program);
            }

            return(state);
        }
コード例 #14
0
        public void NativeFunction()
        {
            var state = new MondState();

            state["function"] = new MondFunction((_, args) => args[0]);

            var program = MondProgram.Compile(@"
                return global.function('arg');
            ");

            var result = state.Load(program);

            Assert.True(result == "arg");
        }
コード例 #15
0
ファイル: MondDebugContext.cs プロジェクト: foobit/Mond
 internal CallStackEntry(
     MondProgram program,
     int address,
     string fileName,
     string function,
     int lineNumber,
     int columnNumber)
 {
     Program      = program;
     Address      = address;
     FileName     = fileName;
     Function     = function;
     LineNumber   = lineNumber;
     ColumnNumber = columnNumber;
 }
コード例 #16
0
ファイル: MondDebugContext.cs プロジェクト: foobit/Mond
        internal MondDebugContext(
            MondState state, MondProgram program, int address,
            Frame locals, Frame args,
            ReturnAddress[] callStack, int callStackTop, int callStackBottom)
        {
            _state   = state;
            _address = address;
            _locals  = locals;
            _args    = args;

            Program   = program;
            CallStack = GenerateCallStack(address, callStack, callStackTop, callStackBottom).AsReadOnly();

            _localObject = CreateLocalObject();
        }
コード例 #17
0
        public void NativeInstanceFunction()
        {
            var state = new MondState();

            state["value"]    = 123;
            state["function"] = new MondInstanceFunction((_, instance, arguments) => instance[arguments[0]]);

            var program = MondProgram.Compile(@"
                return global.function('value');
            ");

            var result = state.Load(program);

            Assert.True(result == 123);
        }
コード例 #18
0
        private static MondValue Require(MondState state, params MondValue[] arguments)
        {
            if (arguments.Length < 1)
            {
                throw new MondRuntimeException("require: must be called with 1 argument");
            }

            if (arguments[0].Type != MondValueType.String)
            {
                throw new MondRuntimeException("require: argument 1 must be of type String");
            }

            var fileName = (string)arguments[0];
            var program  = MondProgram.Compile(Definitions + File.ReadAllText(fileName), fileName);

            return(state.Load(program));
        }
コード例 #19
0
        internal MondDebugContext(
            MondState state, MondProgram program, int address,
            Frame locals, Frame args,
            ReturnAddress[] callStack,  int callStackTop, int callStackBottom)
        {
            _state = state;
            _address = address;
            _locals = locals;
            _args = args;

            Program = program;
            DebugInfo = program.DebugInfo;

            CallStack = GenerateCallStack(address, callStack, callStackTop, callStackBottom).AsReadOnly();

            _localObject = CreateLocalObject();
        }
コード例 #20
0
        internal bool ShouldBreak(MondProgram program, int address)
        {
            lock (_sync)
            {
                if (IsBreakRequested)
                {
                    IsBreakRequested = false;
                    return true;
                }

                List<int> breakpoints;
                if (!_programBreakpoints.TryGetValue(program, out breakpoints))
                    return false;

                return breakpoints.Contains(address);
            }
        }
コード例 #21
0
ファイル: MondDebugger.cs プロジェクト: xserve98/Mond
        /// <summary>
        /// Adds a breakpoint to the given program.
        /// </summary>
        /// <param name="program"></param>
        /// <param name="address"></param>
        protected void AddBreakpoint(MondProgram program, int address)
        {
            lock (_sync)
            {
                if (!_programBreakpoints.TryGetValue(program, out var breakpoints))
                {
                    breakpoints = new List <int>();
                    _programBreakpoints.Add(program, breakpoints);
                }

                if (breakpoints.Contains(address))
                {
                    return;
                }

                breakpoints.Add(address);
            }
        }
コード例 #22
0
ファイル: MondDebugger.cs プロジェクト: xserve98/Mond
        internal bool ShouldBreak(MondProgram program, int address)
        {
            lock (_sync)
            {
                if (IsBreakRequested)
                {
                    IsBreakRequested = false;
                    return(true);
                }

                if (!_programBreakpoints.TryGetValue(program, out var breakpoints))
                {
                    return(false);
                }

                return(breakpoints.Contains(address));
            }
        }
コード例 #23
0
ファイル: MondDebugContext.cs プロジェクト: foobit/Mond
        private static CallStackEntry GenerateCallStackEntry(MondProgram program, int address)
        {
            var debugInfo = program.DebugInfo;

            if (debugInfo == null)
            {
                return(new CallStackEntry(
                           program, address, program.GetHashCode().ToString("X8"), address.ToString("X8"), 0, -1));
            }

            var    fileName     = program.DebugInfo.FileName;
            string function     = null;
            var    lineNumber   = 0;
            var    columnNumber = -1;

            var func = program.DebugInfo.FindFunction(address);

            if (func.HasValue)
            {
                function = program.Strings[func.Value.Name];
            }

            var position = program.DebugInfo.FindPosition(address);

            if (position.HasValue)
            {
                lineNumber   = position.Value.LineNumber;
                columnNumber = position.Value.ColumnNumber;
            }

            if (fileName == null)
            {
                fileName = program.GetHashCode().ToString("X8");
            }

            if (function == null)
            {
                function = address.ToString("X8");
            }

            return(new CallStackEntry(
                       program, address, fileName, function, lineNumber, columnNumber));
        }
コード例 #24
0
ファイル: MondDebugContext.cs プロジェクト: SirTony/Mond
 internal CallStackEntry(
     MondProgram program,
     int address,
     string fileName,
     string function,
     int startLineNumber,
     int startColumnNumber,
     int?endLineNumber   = null,
     int?endColumnNumber = null)
 {
     Program           = program;
     Address           = address;
     FileName          = fileName;
     Function          = function;
     StartLineNumber   = startLineNumber;
     StartColumnNumber = startColumnNumber;
     EndLineNumber     = endLineNumber;
     EndColumnNumber   = endColumnNumber;
 }
コード例 #25
0
ファイル: MondRemoteDebugger.cs プロジェクト: xserve98/Mond
        private void VisitProgram(MondProgram program)
        {
            var debugInfo = program.DebugInfo;

            if (IsMissingDebugInfo(debugInfo))
            {
                return;
            }

            int         id;
            ProgramInfo programInfo;

            lock (_sync)
            {
                if (_seenPrograms.Contains(program))
                {
                    return;
                }

                _seenPrograms.Add(program);

                id          = _programs.Count;
                programInfo = new ProgramInfo(program);

                _programs.Add(programInfo);
            }

            var message = new MondValue(MondValueType.Object);

            message["Type"]        = "NewProgram";
            message["Id"]          = id;
            message["FileName"]    = programInfo.FileName;
            message["SourceCode"]  = debugInfo.SourceCode;
            message["FirstLine"]   = Utility.FirstLineNumber(debugInfo);
            message["Breakpoints"] = new MondValue(programInfo.Breakpoints.Select(e => new MondValue(e)));

            Broadcast(message);
        }
コード例 #26
0
        private static void InteractiveMain()
        {
            var useColoredInput = !HasFlag("--no-color");

            if (useColoredInput)
            {
                _readLine = () => Highlighted.ReadLine(ref _highlighter);

                Console.CancelKeyPress += (sender, eventArgs) => Console.ResetColor();
            }
            else
            {
                _readLine = Console.ReadLine;
            }

            _input = new Queue <char>();
            _first = true;

            var state = CreateState(true, out var options);

            while (true)
            {
                try
                {
                    options.FirstLineNumber = _line + 1;

                    foreach (var program in MondProgram.CompileStatements(ConsoleInput(), "stdin", options))
                    {
                        InteractiveRun(state, program);
                    }
                }
                catch (Exception e)
                {
                    PrintException(e);
                }
            }
        }
コード例 #27
0
ファイル: Machine.cs プロジェクト: DatZach/Mond
        private static string GetAddressDebugInfo(MondProgram program, int address)
        {
            if (program.DebugInfo != null)
            {
                var func = program.DebugInfo.FindFunction(address);
                var line = program.DebugInfo.FindLine(address);

                if (func.HasValue && line.HasValue)
                {
                    var prefix   = "";
                    var funcName = program.Strings[func.Value.Name];
                    var fileName = program.Strings[line.Value.FileName];

                    if (!string.IsNullOrEmpty(funcName))
                    {
                        prefix = string.Format("at {0} ", funcName);
                    }

                    return(string.Format("{0}in {1}: line {2}", prefix, fileName, line.Value.LineNumber));
                }
            }

            return(address.ToString("X8"));
        }
コード例 #28
0
ファイル: MondRemoteDebugger.cs プロジェクト: xserve98/Mond
 internal int FindProgramIndex(MondProgram p) =>
 _programs.FindIndex(t => ReferenceEquals(t.Program, p));
コード例 #29
0
        static void InteractiveMain()
        {
            _input = new Queue <char>();

            var state   = new MondState();
            var options = new MondCompilerOptions
            {
                GenerateDebugInfo          = true,
                MakeRootDeclarationsGlobal = true,
                UseImplicitGlobals         = true
            };

            Functions.Register(state);

            var line = 1;

            while (true)
            {
                try
                {
                    MondValue result;

                    do
                    {
                        var program = MondProgram.CompileStatement(ConsoleInput(), string.Format("stdin_{0:D}", line), options);
                        result = state.Load(program);

                        // get rid of leading whitespace
                        while (_input.Count > 0 && char.IsWhiteSpace(_input.Peek()))
                        {
                            _input.Dequeue();
                        }
                    } while (_input.Count > 0); // we only want the result of the last statement

                    line++;

                    // ignore undefined return value, it's almost always useless
                    if (result == MondValue.Undefined)
                    {
                        continue;
                    }

                    if (result["moveNext"] && result.IsEnumerable)
                    {
                        foreach (var value in result.Enumerate(state))
                        {
                            value.Serialize(Console.Out);
                            Console.WriteLine();
                        }
                    }
                    else
                    {
                        result.Serialize(Console.Out);
                        Console.WriteLine();
                    }

                    Console.WriteLine();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    Console.WriteLine();

                    _input.Clear();
                }
            }
        }
コード例 #30
0
        static void InteractiveRun(MondState state, MondProgram program)
        {
            var result = state.Load(program);

            // get rid of leading whitespace
            while (_input.Count > 0 && char.IsWhiteSpace(_input.Peek()))
            {
                _input.Dequeue();
            }

            if (_input.Count != 0)
                return;

            _first = true;

            // ignore undefined return value, it's almost always useless
            if (result == MondValue.Undefined)
                return;

            if (result["moveNext"].Type == MondValueType.Function && result.IsEnumerable)
            {
                Console.WriteLine();

                foreach (var value in result.Enumerate(state).Take(25))
                {
                    value.Serialize(Console.Out);
                    Console.WriteLine();
                }

                if (state.Call(result["moveNext"]))
                    Console.WriteLine("...");

                Console.WriteLine();
            }
            else
            {
                var resultStr = result.Serialize();
                var multiline = resultStr.Contains("\n");

                if (multiline)
                {
                    Console.WriteLine();
                    Console.WriteLine(resultStr);
                    Console.WriteLine();
                }
                else
                {
                    var lineNumberLen = Math.Max(_line.ToString("G").Length, 3);
                    Console.WriteLine("{0}> {1}", new string('=', lineNumberLen), resultStr);
                }
            }
        }
コード例 #31
0
        private void DebuggerBreak(MondProgram program, Frame locals, Frame args, int address, int initialCallDepth)
        {
            var context = new MondDebugContext(
                _state, program, address, locals, args, _callStack, _callStackSize, initialCallDepth);

            _debugAction = Debugger.Break(context, address);
            _debugAlign = false;
            _debugDepth = 0;
        }
コード例 #32
0
        /// <summary>
        /// Adds a breakpoint to the given program.
        /// </summary>
        /// <param name="program"></param>
        /// <param name="address"></param>
        protected void AddBreakpoint(MondProgram program, int address)
        {
            lock (_sync)
            {
                List<int> breakpoints;
                if (!_programBreakpoints.TryGetValue(program, out breakpoints))
                {
                    breakpoints = new List<int>();
                    _programBreakpoints.Add(program, breakpoints);
                }

                if (breakpoints.Contains(address))
                    return;

                breakpoints.Add(address);
            }
        }
コード例 #33
0
        private static string GetAddressDebugInfo(MondProgram program, int address)
        {
            if (program.DebugInfo != null)
            {
                var func = program.DebugInfo.FindFunction(address);
                var position = program.DebugInfo.FindPosition(address);

                if (func.HasValue && position.HasValue)
                {
                    var prefix = "";
                    var funcName = program.Strings[func.Value.Name];
                    var fileName = program.DebugInfo.FileName ?? program.GetHashCode().ToString("X8");

                    if (!string.IsNullOrEmpty(funcName))
                        prefix = string.Format("at {0} ", funcName);

                    return string.Format("{0}in {1}: line {2}:{3}", prefix, fileName, position.Value.LineNumber, position.Value.ColumnNumber);
                }
            }

            return address.ToString("X8");
        }
コード例 #34
0
        /// <summary>
        /// Removes a breakpoint from the given program.
        /// </summary>
        /// <param name="program"></param>
        /// <param name="address"></param>
        protected void RemoveBreakpoint(MondProgram program, int address)
        {
            lock (_sync)
            {
                List<int> breakpoints;
                if (!_programBreakpoints.TryGetValue(program, out breakpoints))
                    return;

                breakpoints.Remove(address);
            }
        }
コード例 #35
0
        public MondValue Require(MondState state, string fileName)
        {
            if (_require.Loader == null)
            {
                throw new MondRuntimeException("require: module loader is not set");
            }

            const string cacheObjectName = "__modules";

            MondValue cacheObject;

            // make sure we have somewhere to cache modules
            if (state[cacheObjectName].Type != MondValueType.Object)
            {
                cacheObject            = new MondValue(state);
                cacheObject.Prototype  = MondValue.Null;
                state[cacheObjectName] = cacheObject;
            }
            else
            {
                cacheObject = state[cacheObjectName];
            }

            // return cached module if it exists
            var cachedExports = cacheObject[fileName];

            if (cachedExports.Type == MondValueType.Object)
            {
                return(cachedExports);
            }

            // create a new object to store the exports
            var exports = new MondValue(state);

            exports.Prototype = MondValue.Null;

            // instantly cache it so we can have circular dependencies
            cacheObject[fileName] = exports;

            try
            {
                IEnumerable <string> searchDirectories =
                    _require.SearchDirectories ?? Array.Empty <string>();

                if (_require.SearchBesideScript)
                {
                    var currentDir = Path.GetDirectoryName(state.CurrentScript);
                    searchDirectories = Enumerable.Repeat(currentDir, 1)
                                        .Concat(searchDirectories);
                }

                var moduleSource = _require.Loader(fileName, searchDirectories);

                // wrap the module script in a function so we can pass out exports object to it
                var source = _require.Definitions + "return fun (exports) {\n" + moduleSource + " return exports; };";

                var options = new MondCompilerOptions
                {
                    FirstLineNumber = -1
                };

                var requireOptions = _require.Options;
                if (requireOptions != null)
                {
                    options.DebugInfo = requireOptions.DebugInfo;
                    options.MakeRootDeclarationsGlobal = requireOptions.MakeRootDeclarationsGlobal;
                    options.UseImplicitGlobals         = requireOptions.UseImplicitGlobals;
                }

                var program     = MondProgram.Compile(source, fileName, options);
                var initializer = state.Load(program);

                var result = state.Call(initializer, exports);

                if (result.Type != MondValueType.Object)
                {
                    throw new MondRuntimeException("require: module must return an object (`{0}`)", fileName);
                }

                if (!ReferenceEquals(exports, result))
                {
                    // module returned a different object, merge with ours
                    foreach (var kv in result.Object)
                    {
                        var key   = kv.Key;
                        var value = kv.Value;

                        exports[key] = value;
                    }

                    exports.Prototype = result.Prototype;

                    if (result.IsLocked)
                    {
                        exports.Lock();
                    }
                }
            }
            catch
            {
                // if something goes wrong, remove the entry from the cache
                cacheObject[fileName] = MondValue.Undefined;
                throw;
            }

            return(exports);
        }
コード例 #36
0
ファイル: ReturnAddress.cs プロジェクト: DatZach/Mond
 public ReturnAddress(MondProgram program, int address, Frame arguments)
 {
     Program   = program;
     Address   = address;
     Arguments = arguments;
 }