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")); }
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")); }
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")); }
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); },
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")); }
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); }
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); // })); }
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"))); }
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")); }