public virtual object Invoke(DictionaryBonsaiFunction localVariables = null) { var newScope = new DictionaryBonsaiFunction(Scope); if (localVariables != null) foreach (var key in localVariables.Dict.Keys) newScope.Dict[key] = localVariables.Dict[key]; return Function(newScope); }
public static object Fun(object[] args) { Debug.Assert(args.Length >= 2, "A call to defun should have at least one parameter: its block"); Debug.Assert(args[0] is DictionaryBonsaiFunction); Debug.Assert(args[args.Length - 1] is BlockBonsaiFunction, "The last arguments should be a block"); var parameters = new SymbolId[args.Length - 2]; for (int i = 1; i < args.Length - 1; i++) parameters[i - 1] = (SymbolId)args[i]; var block = (BlockBonsaiFunction)args[args.Length - 1]; return new DelegateBonsaiFunction(callArgs => { Debug.Assert(callArgs.Length - 1 == parameters.Length, "The number of arguments should equal the number of parameters"); var blockLocalVariables = new DictionaryBonsaiFunction(); for (int i = 0; i < parameters.Length; i++) { blockLocalVariables[parameters[i]] = callArgs[i + 1]; } return block.Invoke(blockLocalVariables); }); }
public override object Call(object[] arguments) { foreach (var @case in Cases) { if (@case.Item1.Count == arguments.Length - 1) { bool ismatch = true; for (int i = 0; i < arguments.Length - 1; i++) { var arg = arguments[i + 1]; var pat = @case.Item1[i]; if (!pat.Test(arg)) { ismatch = false; break; } } if (ismatch) { var blockLocalVariables = new DictionaryBonsaiFunction(); for (int i = 0; i < @case.Item1.Count; i++) { blockLocalVariables[@case.Item1[i].ParameterName] = arguments[i + 1]; } return @case.Item2.Invoke(blockLocalVariables); } } } throw new NoMatchException(); }
public object Foreach(object[] args) { Debug.Assert(args.Length == 4); Debug.Assert(args[1] is SymbolId); Debug.Assert(args[2] is System.Collections.IEnumerable); Debug.Assert(args[3] is BlockBonsaiFunction); var scope = (DictionaryBonsaiFunction)args[0]; var varName = (SymbolId)args[1]; var enumerable = (System.Collections.IEnumerable)args[2]; var block = (BlockBonsaiFunction)args[3]; object result = null; foreach (var e in enumerable) { var locals = new DictionaryBonsaiFunction(); locals[varName] = e; result = block.Invoke(locals); } return result; }
public static object Method(object[] args) { Debug.Assert(args.Length >= 3, "A call to «method» should have at least two parameters: the name of the method and its block"); Debug.Assert(args[0] is DictionaryBonsaiFunction); for (int i = 1; i < args.Length - 1; i++) Debug.Assert(args[i] is SymbolId, "Argument " + i + " should be a SymbolId"); Debug.Assert(args[args.Length - 1] is BlockBonsaiFunction, "The last arguments should be a block"); var scope = (DictionaryBonsaiFunction)args[0]; var name = (SymbolId)args[1]; var block = (BlockBonsaiFunction)args[args.Length - 1]; var self = (BonsaiPrototypeFunction)scope["self"]; var parameters = new SymbolId[args.Length - 3]; for (int i = 2; i < args.Length - 1; i++) parameters[i - 2] = (SymbolId)args[i]; self[name] = new DelegateBonsaiFunction(callArgs => { Debug.Assert(callArgs.Length - 1 == parameters.Length, "The number of arguments should equal the number of parameters"); var blockLocalVariables = new DictionaryBonsaiFunction(); for (int i = 0; i < parameters.Length; i++) { blockLocalVariables[parameters[i]] = callArgs[i + 1]; } var callSelf = ((DictionaryBonsaiFunction)callArgs[0])["self"]; blockLocalVariables["self"] = callSelf; return block.Invoke(blockLocalVariables); }); return self[name]; }
public override object Call(object[] arguments) { var newArgs = new object[arguments.Length]; Array.Copy(arguments, newArgs, arguments.Length); var newScope = new DictionaryBonsaiFunction((BonsaiFunction)arguments[0]); newScope["self"] = this; newArgs[0] = newScope; return base.Call(newArgs); }
public BlockBonsaiFunction(Func<DictionaryBonsaiFunction, object> function, DictionaryBonsaiFunction scope) { this.Function = function; this.Scope = scope; }