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); }
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); }
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); }
public MondState() { _machine = new Machine(this); _librariesLoaded = false; Options = new MondCompilerOptions(); Libraries = new MondLibraryManager { new StandardLibraries() }; }
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; }
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); } } }
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); } }
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; }
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); }
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; }
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(); } } }