예제 #1
0
파일: Program.cs 프로젝트: xserve98/Mond
        private static MondState CreateState(bool isInteractive, out MondCompilerOptions options)
        {
            options = new MondCompilerOptions();

            if (isInteractive)
            {
                options.MakeRootDeclarationsGlobal = true;
                options.UseImplicitGlobals         = true;
            }

            var isDebug = HasFlag("--debug");

            if (isDebug)
            {
                options.DebugInfo = MondDebugInfoLevel.Full;
            }

            var state = new MondState
            {
                Options = options
            };

            if (isDebug)
            {
                state.Debugger = new MondRemoteDebugger(1597);
            }

            return(state);
        }
예제 #2
0
        public MondValue Evaluate(string expression)
        {
            var options = new MondCompilerOptions();

            var lexer  = new Lexer("return " + expression, "debug", options);
            var parser = new Parser(lexer);

            var expr = parser.ParseStatement(false);

            var rewriter = new DebugExpressionRewriter(LocalObjectName);

            expr = expr.Accept(rewriter).Simplify();
            expr.SetParent(null);

            var oldLocal = _state[LocalObjectName];

            _state[LocalObjectName] = _localObject;

            var program = new ExpressionCompiler(options).Compile(expr);
            var result  = _state.Load(program);

            _state[LocalObjectName] = oldLocal;

            return(result);
        }
예제 #3
0
        private static MondState CreateState(bool isInteractive, out MondCompilerOptions options)
        {
            options = new MondCompilerOptions();

            if (isInteractive)
            {
                options.MakeRootDeclarationsGlobal = true;
                options.UseImplicitGlobals         = true;
            }

            var isDebug = HasFlag("--debug");

            if (isDebug)
            {
                options.DebugInfo = MondDebugInfoLevel.Full;
            }

            var state = new MondState
            {
                Options = options
            };

            if (isDebug)
            {
                var debugger = new MondRemoteDebugger(new IPEndPoint(IPAddress.Loopback, 1597));
                state.Debugger = debugger;

                if (HasFlag("--wait"))
                {
                    debugger.RequestBreak();
                }
            }

            return(state);
        }
예제 #4
0
        public MondState()
        {
            _machine = new Machine(this);
            _librariesLoaded = false;

            Options = new MondCompilerOptions();

            Libraries = new MondLibraryManager
            {
                new StandardLibraries()
            };
        }
예제 #5
0
        public ExpressionCompiler(MondCompilerOptions options)
        {
            _contexts   = new List <FunctionContext>();
            _scope      = new Scope(0, null);
            _labelIndex = 0;

            Options = options;

            NumberPool = new ConstantPool <double>();
            StringPool = new ConstantPool <string>();

            LambdaId = 0;
        }
예제 #6
0
        static void InteractiveMain(string[] args)
        {
            var useColoredInput = args.Any(s => s == "-c");

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

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

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

            var libraries = new MondLibraryManager
            {
                new StandardLibraries()
            };

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

            libraries.Load(state);

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

                    foreach (var program in MondProgram.CompileStatements(ConsoleInput(), "stdin", options))
                    {
                        InteractiveRun(state, program);
                    }
                }
                catch (Exception e)
                {
                    PrintException(e);
                }
            }
        }
예제 #7
0
        public Lexer(
            IEnumerable <char> source,
            string fileName             = null,
            MondCompilerOptions options = null,
            bool buildSourceString      = false)
        {
            _options          = options;
            _fileName         = fileName;
            _sourceEnumerable = source;
            _positions        = new Stack <Position>();

            if (buildSourceString)
            {
                _sourceCode = new StringBuilder(4096);
            }
        }
예제 #8
0
        public MondValue Evaluate(string expression)
        {
            var options = new MondCompilerOptions();

            var lexer = new Lexer("return " + expression, "debug", options);
            var parser = new Parser(lexer);

            var expr = parser.ParseStatement(false);

            var rewriter = new DebugExpressionRewriter(LocalObjectName);
            expr = expr.Accept(rewriter).Simplify();
            expr.SetParent(null);

            var oldLocal = _state[LocalObjectName];
            _state[LocalObjectName] = _localObject;

            var program = new ExpressionCompiler(options).Compile(expr);
            var result = _state.Load(program);

            _state[LocalObjectName] = oldLocal;

            return result;
        }
예제 #9
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);
        }
예제 #10
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
            {
                var searchDirectories = new[] { Path.GetDirectoryName(state.CurrentScript), "" };
                var moduleSource = _require.Loader(fileName, searchDirectories.AsReadOnly());

                // 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;
        }
예제 #11
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();
                }
            }
        }