public object Cons(object pObject) { var deepCopy = new SharpList(); deepCopy.Add (pObject); foreach (var item in this) { deepCopy.Add (item); } return deepCopy; }
public object Rest() { if (this.Count == 0) { return null; } else { if (Count <= 1) { return null; } var deepCopy = new SharpList (); for(int i = 1; i < Count; i++) { deepCopy.Add (this[i]); } return deepCopy; } }
SharpList ReadList() { var list = new SharpList (); _indent++; while (CurrentToken().type != TokenType.RIGHT_PAREN) { object child = Read (); list.Add (child); //Console.WriteLine (GetIndentSpaces() + "Added " + child.ToString() + " to list"); } Step (); // skip the right parenthesis _indent--; return list; }
private object Let(SharpList pList, Scope pCurrentScope) { SharpVector bindingsVector = pList [1] as SharpVector; if(bindingsVector == null) { Error ("The first argument to let is not a bindings vector", pList); } Scope letScope = new Scope ("Let" + _letScopeCounter++, pCurrentScope); #if LOG_SCOPES Console.WriteLine ("Created new let scope: " + letScope.name); #endif for (int i = 0; i < bindingsVector.Count; i += 2) { SymbolToken symbolToken = bindingsVector [i] as SymbolToken; if(symbolToken == null) { Error("Argument " + (i).ToString() + " in let binding is not a symbol", pList); } letScope.SetVar (symbolToken.value, Eval (bindingsVector[i + 1], pCurrentScope)); } SharpList copy = new SharpList (); for (int i = 2; i < pList.Count; i++) { copy.Add(pList[i]); } object lastResult = null; foreach(var item in copy) { //Console.WriteLine("Time to eval " + item); lastResult = Eval (item, letScope); } return lastResult; }
private object Fn(SharpList pList, Scope pCurrentScope) { SharpVector argBindings = pList [1] as SharpVector; if(argBindings == null) { Error ("The first argument to fn is not a vector of args", pList); } SharpVector argBindingsDeepCopy = new SharpVector (); foreach(var argBinding in argBindings) { argBindingsDeepCopy.Add (argBinding); } SharpList body = new SharpList (); for (int i = 2; i < pList.Count; i++) { body.Add(pList[i]); } Scope closure = new Scope ("Closure" + _closureCounter++, pCurrentScope); #if LOG_SCOPES Console.WriteLine ("Created new closure: " + closure.name); #endif string functionName = "Fn" + _functionCounter++; return new SharpFunction(args => { Scope functionCallScope = new Scope ("FunctionCallScope" + _functionCallScopeCounter++, closure); #if LOG_SCOPES Console.WriteLine ("Created new function call scope: " + functionCallScope.name); #endif int argPos = 0; for(int argBindingPos = 0; argBindingPos < argBindingsDeepCopy.Count; argBindingPos++) { var argBinding = argBindingsDeepCopy[argBindingPos]; if(argBinding is ReservedToken && (argBinding as ReservedToken).type == TokenType.AMPERSAND) { argBindingPos++; SymbolToken finalSymbol = argBindingsDeepCopy[argBindingPos] as SymbolToken; if(finalSymbol == null) { Error ("Final arg binding after ampersand is not a symbol: " + argBindingsDeepCopy[argBindingPos], pList); } var restOfArgs = new SharpList (); while (argPos < args.Length) { restOfArgs.Add(args[argPos++]); } functionCallScope.SetVar(finalSymbol.value, restOfArgs); break; } SymbolToken symbol = argBinding as SymbolToken; if(symbol == null) { Error("Arg binding is not a symbol: " + symbol, pList); } functionCallScope.SetVar(symbol.value, args[argPos++]); } // Console.WriteLine(functionName + " was called with " + args.Length + " arguments:"); // foreach(var arg in args) { // if(arg == null) { // Console.WriteLine("null"); // } else { // Console.WriteLine(arg.ToString()); // } // } object lastResult = null; foreach(var item in body) { //Console.WriteLine("Time to eval " + item); lastResult = Eval (item, functionCallScope); } return lastResult; }, functionName); }
private object CallMacro(SharpList pMacroForm, SharpList pInvokingList, Scope pCurrentScope) { SymbolToken macroNameSymbol = pMacroForm [1] as SymbolToken; if (macroNameSymbol == null) { Error("The first argument to macro is not a string", pInvokingList); } //Console.WriteLine ("Calling macro " + macroNameSymbol.value); var argBindings = pMacroForm [2] as SharpVector; if (argBindings == null) { Error("The second argument to macro is not a vector of args", pInvokingList); } List<object> args = new List<object> (); for (int i = 1; i < pInvokingList.Count; i++) { args.Add (pInvokingList[i]); } int argPos = 0; Scope macroScope = new Scope ("Macro scope " + _macroScopeCounter++, pCurrentScope); for(int argBindingPos = 0; argBindingPos < argBindings.Count; argBindingPos++) { var argBinding = argBindings [argBindingPos]; if(argBinding is ReservedToken && (argBinding as ReservedToken).type == TokenType.AMPERSAND) { argBindingPos++; SymbolToken finalSymbol = argBindings[argBindingPos] as SymbolToken; if(finalSymbol == null) { Error("Final arg binding after ampersand is not a symbol: " + argBindings[argBindingPos], pInvokingList); } var restOfArgs = new SharpList (); while (argPos < args.Count) { restOfArgs.Add(args[argPos++]); } macroScope.SetVar(finalSymbol.value, restOfArgs); break; } SymbolToken symbol = argBinding as SymbolToken; if (symbol == null) { Error ("One of the bindings to the macro is not a symbol", pInvokingList); } macroScope.SetVar(symbol.value, args[argPos]); #if MACRODEBUG Console.WriteLine ("Setting " + symbol.value + " to " + args[argPos] + " at arg pos " + argPos); #endif argPos++; } List<object> compiledForms = new List<object> (); for(int i = 3; i < pMacroForm.Count; i++) { object compiledBody = CompileMacro(pMacroForm [i], macroScope); compiledForms.Add (compiledBody); } #if MACRODEBUG Console.WriteLine("Compiled macro " + macroNameSymbol.value + " to the following forms: "); foreach(var form in compiledForms) { if(form != null) { Console.WriteLine(form.ToString ()); } else { Console.WriteLine("null"); } } #endif object lastResult = null; foreach(var form in compiledForms) { //Console.WriteLine ("Eval form " + form.ToString()); lastResult = Eval (form, pCurrentScope); } return lastResult; }