예제 #1
0
파일: InputModule.cs 프로젝트: hvp/Gemgine
        public void BindScript(Engine scriptEngine)
        {
            scriptEngine.AddFunction("clear-click-events", "Clear all click events.",
                (context, arguments) =>
                {
                    clickBindings.Clear();
                    return null;
                });

            scriptEngine.AddFunction("on-click", "Create an on-click event handler for an entity.",
                (context, arguments) =>
                    {
                        var objectID = AutoBind.UIntArgument(arguments[0]);
                        var body = arguments[1];
                        var lambda = Function.MakeFunction("on-click lambda", new ScriptList(), "",
                            body as ScriptObject, context.Scope, true);
                        clickBindings.Upsert(objectID, lambda);
                        return true;
                    },
                Arguments.Arg("object-id", "id of the clicked object."),
                Arguments.Lazy("code"));
        }
예제 #2
0
파일: Console.cs 프로젝트: Blecki/misp
        private void SetupEnvironmentFunctions(Engine mispEngine)
        {
            mispEngine.AddFunction("save-environment", "", (context, arguments) =>
            {
                Engine.ReportSerializationError = (str) => Write(str + "\n");
                var file = new System.IO.StreamWriter(arguments[0].ToString());
                mispEngine.SerializeEnvironment(file, context.Scope);
                file.Close();
                return true;
            }, Arguments.Arg("file"));

            mispEngine.AddFunction("load-environment", "", (context, arguments) =>
            {
                var newContext = new Context();
                var newEngine = new Engine();

                PrepareEnvironment(newEngine);

                if (arguments[2] != null)
                {
                    newEngine.Evaluate(newContext, arguments[2], true, true);
                    if (newContext.evaluationState == EvaluationState.UnwindingError)
                    {
                        Write("Prime error:\n");
                        Write(MISP.Console.PrettyPrint2(newContext.errorObject, 0));
                        return false;
                    }
                }

                var result = newEngine.EvaluateString(newContext,
                    System.IO.File.ReadAllText(arguments[0].ToString()), arguments[0].ToString()) as ScriptObject;

                if (newContext.evaluationState != EvaluationState.UnwindingError)
                {
                    var environment = AddEnvironment(arguments[1].ToString(), newEngine, newContext);
                    if (environment.name == this.environment.name)
                        this.environment = environment;
                    SetupEnvironmentFunctions(newEngine);
                    var scope = new Scope();
                    foreach (var prop in result.ListProperties())
                        scope.PushVariable(prop as String, result.GetLocalProperty(prop as String));
                    newContext.ReplaceScope(scope);

                    Write("Loaded.\n");
                    return true;
                }
                else
                {
                    Write("Error:\n");
                    Write(MISP.Console.PrettyPrint2(newContext.errorObject, 0));
                    return false;
                }
            }, Arguments.Arg("file"), Arguments.Arg("name"), Arguments.Optional(Arguments.Lazy("prime")));
        }
예제 #3
0
파일: Console.cs 프로젝트: Blecki/misp
        public void SetupStandardConsoleFunctions(Engine mispEngine)
        {
            mispEngine.AddFunction("print", "Print something.",
                (context, arguments) =>
                {
                    noEcho = true;
                    foreach (var item in arguments[0] as ScriptList)
                        Write(UnescapeString(MISP.Console.PrettyPrint2(item, 0)));
                    return null;
                }, Arguments.Optional(Arguments.Repeat("value")));

            mispEngine.AddFunction("printf", "Print a string with formatting.",
                (context, arguments) =>
                {
                    noEcho = true;
                    var s = String.Format(AutoBind.StringArgument(arguments[0]),
                        AutoBind.ListArgument(arguments[1]).ToArray());
                    Write(UnescapeString(s));
                    return null;
                },
                Arguments.Arg("format-string"),
                Arguments.Optional(Arguments.Repeat("value")));

            mispEngine.AddFunction("emitfl", "Emit a list of functions",
                (context, arguments) =>
                {
                    noEcho = true;
                    if (arguments[0] == null) foreach (var item in mispEngine.functions) EmitFunctionListItem(item.Value);
                    else if (arguments[0] is String)
                    {
                        var regex = new System.Text.RegularExpressions.Regex(arguments[0] as String);
                        foreach (var item in mispEngine.functions)
                            if (regex.IsMatch(item.Value.gsp("@name"))) EmitFunctionListItem(item.Value);
                    }
                    else
                    {
                        foreach (var item in AutoBind.ListArgument(arguments[0]))
                            if (item is ScriptObject) EmitFunctionListItem(item as ScriptObject);
                    }
                    return null;
                }, Arguments.Optional("list"));

            mispEngine.AddFunction("module", "Load a module from disc",
                (context, arguments) =>
                {
                    return NetModule.LoadModule(mispEngine, AutoBind.StringArgument(arguments[0]),
                        AutoBind.StringArgument(arguments[1]));
                }, Arguments.Arg("file"), Arguments.Arg("module"));
        }
예제 #4
0
파일: Console.cs 프로젝트: Blecki/misp
 public void SetupNewEnvironment(String name)
 {
     var mispEngine = new Engine();
     var mispContext = new Context();
     PrepareEnvironment(mispEngine);
     var environment = AddEnvironment(name, mispEngine, mispContext);
     mispContext.limitExecutionTime = false;
 }
예제 #5
0
파일: Console.cs 프로젝트: Blecki/misp
 public void PrepareEnvironment(Engine engine)
 {
     SetupStandardConsoleFunctions(engine);
     if (SetupHost != null) SetupHost(engine);
     engine.AddFunction("run-file", "Load and run a file.",
         (_context, arguments) =>
         {
             var text = System.IO.File.ReadAllText(ScriptObject.AsString(arguments[0]));
             return engine.EvaluateString(_context, text, ScriptObject.AsString(arguments[0]), false);
         },
         Arguments.Arg("name"));
 }
예제 #6
0
파일: Console.cs 프로젝트: Blecki/misp
 public Environment AddEnvironment(String name, Engine engine, Context context)
 {
     environments.Upsert(name, new Environment { engine = engine, context = context, name = name });
     return environments[name];
 }
예제 #7
0
파일: Function.cs 프로젝트: hvp/Gemgine
        public static Object Invoke(ScriptObject func, Engine engine, Context context, ScriptList arguments)
        {
            var name = func.gsp("@name");
            var argumentInfo = func["@arguments"] as ScriptList;

            if (context.trace != null)
            {
                context.trace(new String('.', context.traceDepth) + "Entering " + name +"\n");
                context.traceDepth += 1;
            }

            var newArguments = new ScriptList();
            //Check argument types
            if (argumentInfo.Count == 0 && arguments.Count != 0)
            {
                context.RaiseNewError("Function expects no arguments.", context.currentNode);
                return null;
            }

                int argumentIndex = 0;
                for (int i = 0; i < argumentInfo.Count; ++i)
                {
                    var info = argumentInfo[i] as ScriptObject;
                    if (info == null)
                        throw new ScriptError("Invalid argument descriptor on function object", context.currentNode);
                    if (info["@repeat"] != null)
                    {
                        var list = new ScriptList();
                        while (argumentIndex < arguments.Count) //Handy side effect: If no argument is passed for an optional repeat
                        {                                       //argument, it will get an empty list.
                            list.Add(MutateArgument(arguments[argumentIndex], info, engine, context));
                            //list.Add((info["@type"] as Type).ProcessArgument(context, arguments[argumentIndex]));
                            if (context.evaluationState != EvaluationState.Normal) return null;
                            ++argumentIndex;
                        }
                        newArguments.Add(list);
                    }
                    else
                    {
                        if (argumentIndex < arguments.Count)
                        {
                            newArguments.Add(MutateArgument(arguments[argumentIndex], info, engine, context));
                            //newArguments.Add((info["@type"] as Type).ProcessArgument(context, arguments[argumentIndex]));
                            if (context.evaluationState == EvaluationState.UnwindingError) return null;
                        }
                        else if (info["@optional"] != null)
                            newArguments.Add(MutateArgument(null, info, engine, context));
                        else
                        {
                            context.RaiseNewError("Not enough arguments to " + name, context.currentNode);
                            return null;
                        }
                        ++argumentIndex;
                    }
                }
                if (argumentIndex < arguments.Count)
                {
                    context.RaiseNewError("Too many arguments to " + name, context.currentNode);
                    return null;
                }

            Object r = null;

            if (func["@function-body"] is ScriptObject)
            {
                var declarationScope = func["@declaration-scope"];
                if (declarationScope is GenericScriptObject)
                {
                    var newScope = new Scope();
                    foreach (var valueName in (declarationScope as GenericScriptObject).properties)
                        newScope.PushVariable(valueName.Key, valueName.Value);
                    func["@declaration-scope"] = newScope;
                }

                context.PushScope(func["@declaration-scope"] as Scope);

                for (int i = 0; i < argumentInfo.Count; ++i)
                    context.Scope.PushVariable((argumentInfo[i] as ScriptObject).gsp("@name"), newArguments[i]);

                r = engine.Evaluate(context, func["@function-body"], true);

                for (int i = 0; i < argumentInfo.Count; ++i)
                    context.Scope.PopVariable((argumentInfo[i] as ScriptObject).gsp("@name"));

                context.PopScope();
            }
            else
            {
                try
                {
                    r = (func["@function-body"] as Func<Context, ScriptList, Object>)(context, newArguments);
                }
                catch (Exception e)
                {
                    context.RaiseNewError("System Exception: " + e.Message, context.currentNode);
                    return null;
                }
            }

            if (context.trace != null)
            {
                context.traceDepth -= 1;
                context.trace(new String('.', context.traceDepth) + "Leaving " + name +
                    (context.evaluationState == EvaluationState.UnwindingError ?
                    (" -Error: " + context.errorObject.GetLocalProperty("message").ToString()) :
                    "") +
                    (context.evaluationState == EvaluationState.UnwindingBreak ? " -Breaking" : "") +
                    "\n");
            }

            return r;
        }
예제 #8
0
파일: Function.cs 프로젝트: hvp/Gemgine
 private static Object MutateArgument(Object argument, ScriptObject argumentDescripter, Engine engine, Context context)
 {
     var mutator = argumentDescripter["@mutator"];
     if (mutator == null) return argument;
     context.Scope.PushVariable("value", argument);
     var result = engine.Evaluate(context, mutator, true);
     context.Scope.PopVariable("value");
     return result;
 }
예제 #9
0
파일: InputModule.cs 프로젝트: hvp/Gemgine
        void IModule.BindScript(Engine scriptEngine)
        {
            scriptEngine.AddFunction("bind-key", "Bind an event handler to a key.", (context, arguments) =>
                {
                    var keyNames = AutoBind.StringArgument(arguments[0]);
                    var bindingType = AutoBind.StringArgument(arguments[1]).ToUpperInvariant();
                    var body = arguments[2];
                    var lambda = Function.MakeFunction("key-binding lambda", new ScriptList(), "",
                        body as ScriptObject, context.Scope, true);
                    BindingType parsedBindType;
                    if (!Enum.TryParse(bindingType, out parsedBindType))
                    {
                        context.RaiseNewError("Unknown binding type", context.currentNode);
                        return null;
                    }
                    foreach (var c in keyNames.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        Keys key;
                        if (Enum.TryParse(c, out key))
                        {
                            if (parsedBindType == BindingType.HELD)
                                keysWithHeldEvent.Add(key);
                            if (!eventBindings.ContainsKey(key))
                                eventBindings.Add(key, new List<Tuple<BindingType, ScriptObject>>());
                            eventBindings[key].Add(new Tuple<BindingType, ScriptObject>(parsedBindType, lambda));
                        }
                    }
                    return true;
                },
                Arguments.Arg("key-names", "A string containing key-names separated by spaces."),
                Arguments.Arg("binding-type", "Any of DOWN, UP, or HELD."),
                Arguments.Lazy("code"));

            scriptEngine.AddFunction("unbind-key", "Clear event handlers associated with a key/event combo",
                (context, arguments) =>
                {
                    var keyNames = AutoBind.StringArgument(arguments[0]);
                    var bindingType = AutoBind.StringArgument(arguments[1]).ToUpperInvariant();
                    BindingType parsedBindType;
                    if (!Enum.TryParse(bindingType, out parsedBindType))
                    {
                        context.RaiseNewError("Unknown binding type", context.currentNode);
                        return null;
                    }
                    foreach (var c in keyNames.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        Keys key;
                        if (Enum.TryParse(c, out key))
                        {
                            if (parsedBindType == BindingType.HELD)
                                keysWithHeldEvent.Remove(key);
                            if (eventBindings.ContainsKey(key))
                                eventBindings[key].RemoveAll(p => p.Item1 != parsedBindType);
                        }
                    }
                    return true;
                },
                Arguments.Arg("key-names", "A string containing key-names separated by spaces."),
                Arguments.Arg("binding-type", "Any of DOWN, UP, or HELD."));

            scriptEngine.AddFunction("on-click", "Create an on-click event handler for an entity.",
                (context, arguments) =>
                    {
                        var objectID = AutoBind.UIntArgument(arguments[0]);
                        var body = arguments[1];
                        if (!(body is ScriptObject)) return null;
                        clickBindings.Upsert(objectID, body as ScriptObject);
                        return true;
                    },
                Arguments.Arg("object-id", "id of the clicked object."),
                Arguments.Arg("lambda"));
        }