Beispiel #1
0
 private void SetupRegexFunctions()
 {
     AddFunction("rmatch", "True if regex matches parameter",
                 (context, arguments) =>
     {
         var regex  = AutoBind.StringArgument(arguments[0]);
         var value  = AutoBind.StringArgument(arguments[1]);
         var result = System.Text.RegularExpressions.Regex.Match(value, regex);
         return(result);
     }, Arguments.Arg("regex"), Arguments.Arg("value"));
 }
Beispiel #2
0
        private void SetupLoopFunctions()
        {
            AddFunction("map", "variable_name list code : Transform one list into another",
                        (context, arguments) =>
            {
                var vName  = ArgumentType <String>(arguments[0]);
                var list   = ArgumentType <System.Collections.IEnumerable>(arguments[1]);
                var code   = ArgumentType <ScriptObject>(arguments[2]);
                var result = new ScriptList();
                context.Scope.PushVariable(vName, null);
                foreach (var item in list)
                {
                    context.Scope.ChangeVariable(vName, item);
                    result.Add(Evaluate(context, code, true));
                    if (context.evaluationState == EvaluationState.UnwindingBreak)
                    {
                        context.Scope.PopVariable(vName);
                        return(context.UnBreak());
                    }
                }
                context.Scope.PopVariable(vName);
                return(result);
            },
                        Arguments.Mutator(Arguments.Lazy("variable-name"), "(@identifier value)"),
                        Arguments.Arg("in"),
                        Arguments.Lazy("code"));

            AddFunction("mapi", "Like map, except the variable will hold the index.",
                        (context, arguments) =>
            {
                var vName  = ArgumentType <String>(arguments[0]);
                var from   = AutoBind.IntArgument(arguments[1]);
                var to     = AutoBind.IntArgument(arguments[2]);
                var code   = ArgumentType <ScriptObject>(arguments[3]);
                var result = new ScriptList();
                context.Scope.PushVariable(vName, null);
                for (int i = from; i < to; ++i)
                {
                    context.Scope.ChangeVariable(vName, i);
                    result.Add(Evaluate(context, code, true));
                    if (context.evaluationState == EvaluationState.UnwindingBreak)
                    {
                        context.Scope.PopVariable(vName);
                        return(context.UnBreak());
                    }
                }
                context.Scope.PopVariable(vName);
                return(result);
            },
                        Arguments.Mutator(Arguments.Lazy("variable-name"), "(@identifier value)"),
                        Arguments.Arg("from"),
                        Arguments.Arg("to"),
                        Arguments.Lazy("code"));


            AddFunction("mapex",
                        "variable_name start code next : Like map, but the next element is the result of 'next'. Stops when next = null.",
                        (context, arguments) =>
            {
                var vName  = ArgumentType <String>(arguments[0]);
                var code   = ArgumentType <ScriptObject>(arguments[2]);
                var next   = ArgumentType <ScriptObject>(arguments[3]);
                var result = new ScriptList();
                var item   = arguments[1];
                context.Scope.PushVariable(vName, null);

                while (item != null)
                {
                    context.Scope.ChangeVariable(vName, item);
                    result.Add(Evaluate(context, code, true));
                    if (context.evaluationState == EvaluationState.UnwindingBreak)
                    {
                        context.Scope.PopVariable(vName);
                        return(context.UnBreak());
                    }
                    item = Evaluate(context, next, true);
                }

                context.Scope.PopVariable(vName);
                return(result);
            },
                        Arguments.Mutator(Arguments.Lazy("variable-name"), "(@identifier value)"),
                        Arguments.Arg("start"),
                        Arguments.Lazy("code"),
                        Arguments.Lazy("next"));

            AddFunction("for",
                        "variable_name list code : Execute code for each item in list. Returns result of last run of code.",
                        (context, arguments) =>
            {
                var vName = ArgumentType <String>(arguments[0]);
                var list  = ArgumentType <System.Collections.IEnumerable>(arguments[1]);
                var func  = ArgumentType <ScriptObject>(arguments[2]);
                context.Scope.PushVariable(vName, null);
                Object result = null;
                foreach (var item in list)
                {
                    context.Scope.ChangeVariable(vName, item);
                    result = Evaluate(context, func, true);
                    if (context.evaluationState == EvaluationState.UnwindingBreak)
                    {
                        context.Scope.PopVariable(vName);
                        return(context.UnBreak());
                    }
                }

                context.Scope.PopVariable(vName);

                return(result);
            },
                        Arguments.Mutator(Arguments.Lazy("variable-name"), "(@identifier value)"),
                        Arguments.Arg("list"),
                        Arguments.Lazy("code"));

            AddFunction("fori",
                        "variable_name list code : Execute code for each item in list. Returns result of last run of code.",
                        (context, arguments) =>
            {
                var vName = ArgumentType <String>(arguments[0]);
                var from  = AutoBind.IntArgument(arguments[1]);
                var to    = AutoBind.IntArgument(arguments[2]);
                var func  = ArgumentType <ScriptObject>(arguments[3]);
                context.Scope.PushVariable(vName, null);
                Object result = null;
                for (int i = from; i < to; ++i)
                {
                    context.Scope.ChangeVariable(vName, i);
                    result = Evaluate(context, func, true);
                    if (context.evaluationState == EvaluationState.UnwindingError)
                    {
                        return(result);
                    }
                    else if (context.evaluationState == EvaluationState.UnwindingBreak)
                    {
                        context.Scope.PopVariable(vName);
                        return(context.UnBreak());
                    }
                }

                context.Scope.PopVariable(vName);

                return(result);
            },
                        Arguments.Mutator(Arguments.Lazy("variable-name"), "(@identifier value)"),
                        Arguments.Arg("from"),
                        Arguments.Arg("to"),
                        Arguments.Lazy("code"));

            AddFunction("while",
                        "condition code : Repeat code while condition evaluates to true.",
                        (context, arguments) =>
            {
                var cond = ArgumentType <ScriptObject>(arguments[0]);
                var code = ArgumentType <ScriptObject>(arguments[1]);

                while (context.evaluationState == EvaluationState.Normal && Evaluate(context, cond, true) != null)
                {
                    if (context.evaluationState == EvaluationState.Normal)
                    {
                        Evaluate(context, code, true);
                    }
                }
                if (context.evaluationState == EvaluationState.UnwindingBreak)
                {
                    return(context.UnBreak());
                }
                return(null);
            },
                        Arguments.Lazy("condition"),
                        Arguments.Lazy("code"));
        }
Beispiel #3
0
        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"));
        }
Beispiel #4
0
        private void SetupVariableFunctions()
        {
            AddFunction("var",
                        "name value : Assign value to a variable named [name].", (context, arguments) =>
            {
                if (specialVariables.ContainsKey(ScriptObject.AsString(arguments[0])))
                {
                    context.RaiseNewError("Can't assign to protected variable name.", context.currentNode);
                }
                else
                {
                    try
                    {
                        context.Scope.ChangeVariable(ScriptObject.AsString(arguments[0]), arguments[1]);
                    }
                    catch (Exception e) { context.RaiseNewError(e.Message, context.currentNode); }
                }
                return(arguments[1]);
            },
                        Arguments.Mutator(Arguments.Lazy("name"), "(@identifier value)"),
                        Arguments.Arg("value"));

            AddFunction("let",
                        "^( ^(\"name\" value ?cleanup-code) ^(...) ) code : Create temporary variables, run code. Optional clean-up code for each variable.",
                        (context, arguments) =>
            {
                var variables = ArgumentType <ScriptObject>(arguments[0]);
                if (!String.IsNullOrEmpty(variables.gsp("@prefix"))) /* Raise warning */ } {
                    var code      = ArgumentType <ScriptObject>(arguments[1]);
                    var cleanUp   = new List <LetVariable>();
                    Object result = null;

                    foreach (var item in variables._children)
                    {
                        var sitem = item as ScriptObject;
                        if (sitem._children.Count <= 1 || sitem._children.Count > 3)
                        {
                            context.RaiseNewError("Bad variable definition in let", context.currentNode);
                            goto RUN_CLEANUP;
                        }

                        var nameObject = sitem._child(0) as ScriptObject;
                        var varName    = "";

                        if (nameObject.gsp("@type") == "token")
                        {
                            varName = nameObject.gsp("@token");
                        }
                        else
                        {
                            varName = AutoBind.StringArgument(Evaluate(context, nameObject, true));
                        }
                        if (context.evaluationState != EvaluationState.Normal)
                        {
                            goto RUN_CLEANUP;
                        }

                        var varValue = Evaluate(context, sitem._child(1), false);
                        if (context.evaluationState != EvaluationState.Normal)
                        {
                            goto RUN_CLEANUP;
                        }

                        context.Scope.PushVariable(varName, varValue);
                        cleanUp.Add(new LetVariable
                    {
                        name        = varName,
                        cleanupCode = sitem._children.Count == 3 ? sitem._child(2) : null
                    });
                    }

                    result = Evaluate(context, code, true);

                    RUN_CLEANUP:
                    var pre_state = context.evaluationState;
                    foreach (var item in cleanUp)
                    {
                        if (item.cleanupCode != null)
                        {
                            context.evaluationState = EvaluationState.Normal;
                            Evaluate(context, item.cleanupCode, true, true);
                        }
                        context.Scope.PopVariable(item.name);
                    }
                    context.evaluationState = pre_state;
                    return(result);
},
Beispiel #5
0
        private void SetupListFunctions()
        {
            AddFunction("length", "list : Returns length of list.",
                        (context, arguments) =>
            {
                var list = arguments[0] as ScriptList;
                return(list == null ? 0 : list.Count);
            }, Arguments.Arg("list"));

            AddFunction("count", "variable_name list code : Returns number of items in list for which code evaluated to true.",
                        (context, arguments) =>
            {
                var vName = ArgumentType <String>(arguments[0]);
                var list  = ArgumentType <ScriptList>(arguments[1]);
                var func  = ArgumentType <ScriptObject>(arguments[2]);

                context.Scope.PushVariable(vName, null);
                var result = (int)list.Count((o) =>
                {
                    context.Scope.ChangeVariable(vName, o);

                    return(Evaluate(context, func, true) != null);
                });
                context.Scope.PopVariable(vName);
                return(result);
            },
                        Arguments.Mutator(Arguments.Lazy("variable-name"), "(@identifier value)"),
                        Arguments.Mutator(Arguments.Arg("in"), "(@list value)"),
                        Arguments.Lazy("code"));

            AddFunction("where", "variable_name list code : Returns new list containing only the items in list for which code evaluated to true.",
                        (context, arguments) =>
            {
                var vName = ArgumentType <String>(arguments[0]);
                var list  = ArgumentType <ScriptList>(arguments[1]);
                var func  = ArgumentType <ScriptObject>(arguments[2]);

                context.Scope.PushVariable(vName, null);
                var result = new ScriptList(list.Where((o) =>
                {
                    context.Scope.ChangeVariable(vName, o);
                    return(Evaluate(context, func, true) != null);
                }));
                context.Scope.PopVariable(vName);
                return(result);
            },
                        Arguments.Mutator(Arguments.Lazy("variable-name"), "(@identifier value)"),
                        Arguments.Mutator(Arguments.Arg("in"), "(@list value)"),
                        Arguments.Lazy("code"));

            AddFunction("cat", "<n> : Combine N lists into one",
                        (context, arguments) =>
            {
                var result = new ScriptList();
                foreach (var arg in arguments[0] as ScriptList)
                {
                    if (arg is ScriptList)
                    {
                        result.AddRange(arg as ScriptList);
                    }
                    else
                    {
                        result.Add(arg);
                    }
                }
                return(result);
            }, Arguments.Repeat(Arguments.Optional("item")));

            AddFunction("last",
                        "list : Returns last item in list.",
                        (context, arguments) =>
            {
                return(ArgumentType <ScriptList>(arguments[0]).LastOrDefault());
            },
                        Arguments.Mutator(Arguments.Arg("list"), "(@list value)"));

            AddFunction("first",
                        "list : Returns first item in list.",
                        (context, arguments) =>
            {
                if (arguments[2] == null)
                {
                    return(ArgumentType <ScriptList>(arguments[0]).FirstOrDefault());
                }
                else
                {
                    var vName = ArgumentType <String>(arguments[1]);
                    var list  = ArgumentType <ScriptList>(arguments[0]);
                    var func  = ArgumentType <ScriptObject>(arguments[2]);

                    context.Scope.PushVariable(vName, null);
                    var result = list.FirstOrDefault((o) => {
                        context.Scope.ChangeVariable(vName, o);
                        return(Evaluate(context, func, true) != null);
                    });
                    context.Scope.PopVariable(vName);
                    return(result);
                }
            },
                        Arguments.Mutator(Arguments.Arg("list"), "(@list value)"),
                        Arguments.Optional(Arguments.Mutator(Arguments.Lazy("variable-name"), "(@identifier value)")),
                        Arguments.Optional(Arguments.Lazy("code")));

            AddFunction("index",
                        "list n : Returns nth element in list.",
                        (context, arguments) =>
            {
                var index = arguments[1] as int?;
                if (index == null || !index.HasValue)
                {
                    return(null);
                }
                if (index.Value < 0)
                {
                    return(null);
                }

                var list = ArgumentType <ScriptList>(arguments[0]);
                if (index.Value >= list.Count)
                {
                    return(null);
                }
                return(list[index.Value]);
            },
                        Arguments.Mutator(Arguments.Arg("list"), "(@list value)"),
                        Arguments.Arg("n"));


            //functions.Add("sub-list", Function.MakeSystemFunction("sub-list",
            //    Arguments.ParseArguments(this, "list list", "integer start", "integer ?length"),
            //    "list start length: Returns a elements in list between start and start+length.",
            //    (context, arguments) =>
            //    {
            //        var list = ArgumentType<ScriptList>(arguments[0]);
            //        var start = arguments[1] as int?;
            //        if (start == null || !start.HasValue) return new ScriptList();
            //        int? length = arguments[2] as int?;
            //        if (length == null || !length.HasValue) length = list.Count;

            //        if (start.Value < 0) { length -= start; start = 0; }
            //        if (start.Value >= list.Count) return new ScriptList();
            //        if (length.Value <= 0) return new ScriptList();
            //        if (length.Value + start.Value >= list.Count) length = list.Count - start.Value;

            //        return new ScriptList(list.GetRange(start.Value, length.Value));
            //    }));

            //functions.Add("sort", Function.MakeSystemFunction("sort",
            //    Arguments.ParseArguments(this, "string variable_name", "list in", "code code"),
            //    "vname list sort_func: Sorts elements according to sort func; sort func returns integer used to order items.",
            //    (context, arguments) =>
            //    {
            //        var vName = ScriptObject.AsString(arguments[0]);
            //        var list = ArgumentType<ScriptList>(arguments[1]);
            //        var sortFunc = ArgumentType<ScriptObject>(arguments[2]);

            //        var comparer = new ListSortComparer(this, vName, sortFunc, context);
            //        list.Sort(comparer);
            //        return list;
            //    }));

            //functions.Add("reverse", Function.MakeSystemFunction("reverse",
            //    Arguments.ParseArguments(this, "list list"),
            //    "list: Reverse the list.",
            //    (context, arguments) =>
            //    {
            //        var list = ArgumentType<ScriptList>(arguments[0]);
            //        list.Reverse();
            //        return list;
            //    }));

            AddFunction("reverse", "Reverse the elements of a list",
                        (context, arguments) =>
            {
                var r = AutoBind.ListArgument(arguments[0]);
                if (r == null)
                {
                    r = new ScriptList();
                }
                r.Reverse();
                return(r);
            }, Arguments.Arg("list"));

            AddFunction("array", "Create a list of items by running code N times",
                        (context, arguments) =>
            {
                var count = arguments[0] as int?;
                if (count == null || !count.HasValue)
                {
                    return(null);
                }
                var result = new ScriptList();
                for (int i = 0; i < count; ++i)
                {
                    result.Add(Evaluate(context, arguments[1], true));
                }
                return(result);
            },
                        Arguments.Arg("count"),
                        Arguments.Lazy("code"));
        }
Beispiel #6
0
        private void SetupFileFunctions()
        {
            var file_functions = new GenericScriptObject();

            file_functions.SetProperty("open", Function.MakeSystemFunction("open",
                                                                           Arguments.Args("file-name", "mode"), "Opens a file",
                                                                           (context, arguments) =>
            {
                var mode = AutoBind.StringArgument(arguments[1]).ToUpperInvariant();
                if (mode == "READ")
                {
                    return(System.IO.File.OpenText(AutoBind.StringArgument(arguments[0])));
                }
                else if (mode == "WRITE")
                {
                    return(System.IO.File.CreateText(AutoBind.StringArgument(arguments[0])));
                }
                else if (mode == "APPEND")
                {
                    return(System.IO.File.AppendText(AutoBind.StringArgument(arguments[0])));
                }
                else
                {
                    context.RaiseNewError("Invalid mode specifier", context.currentNode);
                }
                return(null);
            }));

            file_functions.SetProperty("close", Function.MakeSystemFunction("close",
                                                                            Arguments.Args("file"), "Close a file.",
                                                                            (context, arguments) =>
            {
                if (arguments[0] is System.IO.StreamReader)
                {
                    (arguments[0] as System.IO.StreamReader).Close();
                }
                else if (arguments[0] is System.IO.StreamWriter)
                {
                    (arguments[0] as System.IO.StreamWriter).Close();
                }
                else
                {
                    context.RaiseNewError("Argument is not a file.", context.currentNode);
                }
                return(null);
            }));

            file_functions.SetProperty("read-line", Function.MakeSystemFunction("read-line",
                                                                                Arguments.Args("file"), "Read a line from a file.",
                                                                                (context, arguments) =>
            {
                var file = arguments[0] as System.IO.StreamReader;
                if (file == null)
                {
                    context.RaiseNewError("Argument is not a read file.", context.currentNode);
                    return(null);
                }
                return(file.ReadLine());
            }));

            file_functions.SetProperty("read-all", Function.MakeSystemFunction("read-all",
                                                                               Arguments.Args("file"), "Read all of a file.",
                                                                               (context, arguments) =>
            {
                var file = arguments[0] as System.IO.StreamReader;
                if (file == null)
                {
                    context.RaiseNewError("Argument is not a read file.", context.currentNode);
                    return(null);
                }
                return(file.ReadToEnd());
            }));

            file_functions.SetProperty("write", Function.MakeSystemFunction("write",
                                                                            Arguments.Args("file", "text"), "Write to a file.",
                                                                            (context, arguments) =>
            {
                var file = arguments[0] as System.IO.StreamWriter;
                if (file == null)
                {
                    context.RaiseNewError("Argument is not a write file.", context.currentNode);
                    return(null);
                }
                file.Write(ScriptObject.AsString(arguments[1]));
                return(null);
            }));

            file_functions.SetProperty("more", Function.MakeSystemFunction("more",
                                                                           Arguments.Args("file"), "Is there more to read in this file?",
                                                                           (context, arguments) =>
            {
                var file = arguments[0] as System.IO.StreamReader;
                if (file == null)
                {
                    context.RaiseNewError("Argument is not a read file.", context.currentNode);
                    return(null);
                }
                if (file.EndOfStream)
                {
                    return(null);
                }
                return(true);
            }));

            AddGlobalVariable("file", c => file_functions);
        }
Beispiel #7
0
        private void SetupMathFunctions()
        {
            AddFunction("tochar", "Convert an integer to a character", (context, arguments) =>
            {
                return((char)AutoBind.IntArgument(arguments[0]));
            }, Arguments.Arg("value"));

            AddFunction("toint", "Convert a char to an integet", (context, arguments) =>
            {
                return((int)AutoBind.CharArgument(arguments[0]));
            }, Arguments.Arg("value"));

            AddFunction("round", "Round a value", (context, arguments) =>
            {
                if (arguments[0] is Int32)
                {
                    return(arguments[0]);
                }
                if (arguments[0] is Single)
                {
                    return((int)(Math.Round((arguments[0] as Single?).Value)));
                }
                return(0);
            },
                        Arguments.Arg("value"));

            AddFunction("floor", "", (context, arguments) =>
            {
                if (arguments[0] is Int32)
                {
                    return(arguments[0]);
                }
                if (arguments[0] is Single)
                {
                    return((int)(Math.Floor((arguments[0] as Single?).Value)));
                }
                return(0);
            },
                        Arguments.Arg("value"));

            AddFunction("+", "Add values", (context, arguments) =>
            {
                var values = AutoBind.ListArgument(arguments[0]);
                if (values.Count == 0)
                {
                    return(0);
                }
                if (values.Count == 1)
                {
                    return(values[0]);
                }
                var result = (dynamic)values[0];
                for (int i = 1; i < values.Count; ++i)
                {
                    result += (dynamic)values[i];
                }
                return(result);
            },
                        Arguments.Repeat("value"));

            AddFunction("-", "Subtract values", (context, arguments) =>
            {
                if (arguments[0] == null || arguments[1] == null)
                {
                    return(null);
                }
                return((dynamic)arguments[0] - (dynamic)arguments[1]);
            },
                        Arguments.Arg("A"),
                        Arguments.Arg("B"));

            AddFunction("*", "Add values", (context, arguments) =>
            {
                var values = AutoBind.ListArgument(arguments[0]);
                if (values.Count == 0)
                {
                    return(0);
                }
                if (values.Count == 1)
                {
                    return(values[0]);
                }
                var result = (dynamic)values[0];
                for (int i = 1; i < values.Count; ++i)
                {
                    result *= (dynamic)values[i];
                }
                return(result);
            },
                        Arguments.Repeat("value"));

            AddFunction("/", "Divide values", (context, arguments) =>
            {
                if (arguments[0] == null || arguments[1] == null)
                {
                    return(null);
                }
                return((dynamic)arguments[0] / (dynamic)arguments[1]);
            },
                        Arguments.Arg("A"),
                        Arguments.Arg("B"));

            AddFunction("%", "Modulus values", (context, arguments) =>
            {
                if (arguments[0] == null || arguments[1] == null)
                {
                    return(null);
                }
                return((dynamic)arguments[0] % (dynamic)arguments[1]);
            },
                        Arguments.Arg("A"),
                        Arguments.Arg("B"));


            //functions.Add("random", Function.MakeSystemFunction("random",
            //    Arguments.ParseArguments(this, "integer A", "integer B"),
            //    "A B : return a random value in range (A,B).",
            //    (context, arguments) =>
            //    {
            //        var first = arguments[0] as int?;
            //        var second = arguments[1] as int?;
            //        if (first == null || second == null || !first.HasValue || !second.HasValue) return null;
            //        return random.Next(first.Value, second.Value);
            //    }));
        }
Beispiel #8
0
        private void SetupStringFunctions()
        {
            AddFunction("split", "Split a string into pieces", (context, arguments) =>
            {
                var pieces = AutoBind.StringArgument(arguments[0]).Split(
                    new String[] { AutoBind.StringArgument(arguments[1]) },
                    Int32.MaxValue, StringSplitOptions.RemoveEmptyEntries);
                var r = new ScriptList(pieces);
                return(r);
            }, Arguments.Arg("string"), Arguments.Arg("split-chars"));

            AddFunction("strlen", "string : Returns length of string.",
                        (context, arguments) =>
            {
                return(ScriptObject.AsString(arguments[0]).Length);
            }, Arguments.Arg("string"));

            AddFunction("strind",
                        "string n : Returns nth element in string.",
                        (context, arguments) =>
            {
                var index = arguments[1] as int?;
                if (index == null || !index.HasValue)
                {
                    return(null);
                }
                if (index.Value < 0)
                {
                    return(null);
                }
                var str = ScriptObject.AsString(arguments[0]);
                if (index.Value >= str.Length)
                {
                    return(null);
                }
                return(str[index.Value]);
            },
                        Arguments.Arg("string"),
                        Arguments.Arg("n"));

            AddFunction("substr", "Returns a portion of the input string.",
                        (context, arguments) =>
            {
                var str   = ScriptObject.AsString(arguments[0]);
                var start = AutoBind.IntArgument(arguments[1]);
                if (arguments[2] == null)
                {
                    return(str.Substring(start));
                }
                else
                {
                    return(str.Substring(start, AutoBind.IntArgument(arguments[2])));
                }
            },
                        Arguments.Arg("string"),
                        Arguments.Arg("start"),
                        Arguments.Optional("length"));

            AddFunction("strcat", "Concatenate many strings into one.",
                        (context, arguments) =>
            {
                var r = new StringBuilder();
                foreach (var obj in AutoBind.ListArgument(arguments[0]))
                {
                    r.Append(ScriptObject.AsString(obj));
                }
                return(r.ToString());
            },
                        Arguments.Repeat("item"));

            AddFunction("itoa", "Change a number to the string representation.",
                        (context, arguments) =>
            {
                return(arguments[0].ToString());
            },
                        Arguments.Arg("i"));

            AddFunction("atoi", "",
                        (context, arguments) =>
            {
                return(Convert.ToInt32(arguments[0]));
            },
                        Arguments.Arg("i"));

            AddFunction("unescape", "", (context, arguments) =>
            {
                return(Console.UnescapeString(ScriptObject.AsString(arguments[0])));
            },
                        Arguments.Arg("string"));

            AddFunction("format", "Format a string.",
                        (context, arguments) =>
            {
                return(String.Format(AutoBind.StringArgument(arguments[0]),
                                     AutoBind.ListArgument(arguments[1]).ToArray()));
            },
                        Arguments.Arg("format-string"),
                        Arguments.Optional(Arguments.Repeat("value")));
        }
Beispiel #9
0
        private void SetupObjectFunctions()
        {
            AddFunction("members", "Lists all members of an object",
                        (context, arguments) =>
            {
                var obj = ArgumentType <ScriptObject>(arguments[0]);
                return(obj.ListProperties());
            },
                        Arguments.Arg("object"));

            AddFunction("record", "Create a new record.",
                        (context, arguments) =>
            {
                var obj  = new GenericScriptObject();
                var vars = AutoBind.ListArgument(arguments[0]);
                foreach (var item in vars)
                {
                    var l = ArgumentType <ScriptObject>(item);
                    if (l == null || l._children.Count != 2)
                    {
                        throw new ScriptError("Record expects a list of pairs.", null);
                    }
                    var arg      = l._child(0) as ScriptObject;
                    string mname = "";
                    if (arg != null && arg.gsp("@type") == "token")
                    {
                        mname = arg.gsp("@token");
                    }
                    else
                    {
                        mname = Evaluate(context, arg, true).ToString();
                    }
                    obj.SetProperty(mname, Evaluate(context, l._child(1)));
                }
                return(obj);
            },
                        Arguments.Repeat(Arguments.Lazy("pairs")));

            AddFunction("clone", "Clone a record.",
                        (context, arguments) =>
            {
                var r = new GenericScriptObject(arguments[0] as ScriptObject);
                foreach (var item in arguments[1] as ScriptList)
                {
                    var list = item as ScriptList;
                    if (list == null || list.Count != 2)
                    {
                        throw new ScriptError("Record expects only pairs as arguments.", context.currentNode);
                    }
                    r[ScriptObject.AsString(list[0])] = list[1];
                }
                return(r);
            },
                        Arguments.Arg("object"),
                        Arguments.Mutator(Arguments.Repeat(Arguments.Optional("pairs")), "(@list value)"));

            AddFunction("set", "Set a member on an object.",
                        (context, arguments) =>
            {
                if (arguments[0] == null)
                {
                    return(arguments[2]);
                }
                return(SetObjectProperty(context, arguments[0], ScriptObject.AsString(arguments[1]), arguments[2]));
            },
                        Arguments.Arg("object"),
                        Arguments.Mutator(Arguments.Lazy("name"), "(@identifier-if-token value)"),
                        Arguments.Arg("value"));

            AddFunction("multi-set", "Set multiple members of an object.",
                        (context, arguments) =>
            {
                var obj  = ArgumentType <ScriptObject>(arguments[0]);
                var vars = AutoBind.ListArgument(arguments[1]);
                foreach (var item in vars)
                {
                    var l = ArgumentType <ScriptObject>(item);
                    if (l == null || l._children.Count != 2)
                    {
                        throw new ScriptError("Multi-set expects a list of pairs.", null);
                    }
                    var arg      = l._child(0) as ScriptObject;
                    string mname = "";
                    if (arg != null && arg.gsp("@type") == "token")
                    {
                        mname = arg.gsp("@token");
                    }
                    else
                    {
                        mname = Evaluate(context, arg, true).ToString();
                    }
                    SetObjectProperty(context, obj, mname, Evaluate(context, l._child(1)));
                }
                return(obj);
            },
                        Arguments.Arg("object"),
                        Arguments.Repeat(Arguments.Lazy("pairs")));

            AddFunction("delete", "Deletes a property from an object.",
                        (context, arguments) =>
            {
                var value = (arguments[0] as ScriptObject)[ScriptObject.AsString(arguments[1])];
                if (arguments[0] is Scope)
                {
                    (arguments[0] as Scope).PopVariable(ScriptObject.AsString(arguments[1]));
                }
                else
                {
                    (arguments[0] as ScriptObject).DeleteProperty(ScriptObject.AsString(arguments[1]));
                }
                return(value);
            },
                        Arguments.Arg("object"),
                        Arguments.Arg("property-name"));
        }