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