public static object Equal(FunctionInvocation call) { object[] values = call.EvalArgs().ToArray(); if (values[0] != null) { object right = Convert.ChangeType(values[1], values[0].GetType()); return(values[0].Equals(right)); } else { if (values[1] == null) { return(true); } else { return(false); } } }
public static object Div(FunctionInvocation call) { List <object> args = call.EvalArgs(); object firstArg = args[0]; if (firstArg is double) { return(Operation <double>(args, (a, b) => a / b)); } if (firstArg is int) { return(Operation <int>(args, (a, b) => a / b)); } if (firstArg is BigInteger) { return(Operation <BigInteger>(args, (a, b) => a / b)); } return(null); }
public static object LogicalOr(FunctionInvocation call) { List <object> args = call.EvalArgs(); return(Operation <bool>(args, (a, b) => a || b)); }
public static object Concat(FunctionInvocation call) { return (call.EvalArgs().Select(item => item == null ? "" : item.ToString()).Aggregate( (left, right) => left + right)); }
public static object Arr(FunctionInvocation call) { object[] res = call.EvalArgs().ToArray(); return(res); }
public static object List(FunctionInvocation call) { List <object> res = call.EvalArgs().ToList(); return(res); }
public static void SetupArgs(ConsNode definedArgs, FunctionInvocation call, Scope newScope) { int i = 1; //todo: verify arg list, only identifiers allowed //setup local args for (int argIndex = 0; argIndex < definedArgs.Args.Count; argIndex++) { var arg = definedArgs.Args[argIndex] as SymbolNode; string argName = arg.Name; if (argName == "&optional") { } else if (argName == "&rest") { argIndex++; var restArg = definedArgs.Args[argIndex] as SymbolNode; string restName = restArg.Name; ConsNode restCons = NewCons(call.StackFrame.Root); restCons.Args = call.EvalArgs(i); newScope.PushSymbol(restName).Value = restCons; } else if (argName[0] == '*') { //ref symbol var argId = call.Args[i] as SymbolNode; argName = argName.Substring(1); if (argId == null) { throw new Exception( string.Format("Argument '{0}' is defined as a pointer, but passed as a value", argName)); } Symbol sourceVar = argId.GetSymbol(call.StackFrame); newScope.DeclareRef(argName, sourceVar); } else if (argName[0] == '!') { argName = argName.Substring(1); newScope.PushSymbol(argName); var bodyArg = call.Args[i] as ValueNode; newScope.SetSymbolValue(argName, bodyCall => bodyArg.Eval(call.StackFrame)); } else if (argName[0] == '#') { argName = argName.Substring(1); Symbol symbol = newScope.PushSymbol(argName); object bodyArg = call.Args[i]; symbol.Value = bodyArg; } else if (argName[0] == ':') { var argId = call.Args[i] as SymbolNode; argName = argName.Substring(1); if (argId == null) { throw new Exception( string.Format("Argument '{0}' is defined as a verbatim, but passed as a value", argName)); } if (argId.Name != argName) { throw new Exception(string.Format("Argument '{0}' is defined as a verbatim, but passed as {1}", argName, argId.Name)); } } else if (argName[0] == '@') { var argId = call.Args[i] as SymbolNode; object argValue = argId.Name; argName = argName.Substring(1); newScope.PushSymbol(argName).Value = argValue; } else { //normal var object argValue = Eval(call.StackFrame, call.Args[i]); newScope.PushSymbol(argName).Value = argValue; } i++; } //for (int j = i; j < call.Args.Count; j++) //{ // ValueNode node = call.Args[j]; // string argName = string.Format("arg{0}", j); // object argValue = node.GetValue(stack); // stack.PushSymbol(argName); // stack.Scope.SetSymbolValue(argName, argValue); //} }