public static MondValue Run(string source) { var state = new MondState(); var program = MondProgram.Compile(source); return(state.Load(program)); }
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); } }
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); }
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"); }
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); }
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)); }
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); }