public LispList(List <LispDataType> list) : base(false, true) { Data = list; // Handle dotted list input. LispSymbolicAtom dot = new LispSymbolicAtom("."); int dotCount = Data.Count(sym => sym is LispSymbolicAtom && (LispSymbolicAtom)sym == dot); if (dotCount > 1) { throw new LispException(string.Format(ERR_INVALID_LIST_ENDING, Data.Last())); } else if (dotCount == 1) { if (Data.FindIndex(sym => sym is LispSymbolicAtom && (LispSymbolicAtom)sym == dot) != Data.Count - 2) { throw new LispException(string.Format(ERR_INVALID_LIST_ENDING, Data.Last())); } else { Data.RemoveAt(Data.Count - 2); IsDotted = true; } } if (list.Count == 0) { IsAtom = true; IsLiteral = true; } }
public LispList(string input) : base(false, true) { // Omit the beginning and the ending parenthesis, we just want the items inside the list. input = input.Substring(1, input.Length - 2).ToUpper(); Data = ProcessInputBuffer(ref input); // Handle dotted list input. LispSymbolicAtom dot = new LispSymbolicAtom("."); int dotCount = Data.Count(sym => sym is LispSymbolicAtom && (LispSymbolicAtom)sym == dot); if (dotCount > 1) { throw new LispException(string.Format(ERR_INVALID_LIST_ENDING, Data.Last())); } else if (dotCount == 1) { if (Data.FindIndex(sym => sym is LispSymbolicAtom && (LispSymbolicAtom)sym == dot) != Data.Count - 2) { throw new LispException(string.Format(ERR_INVALID_LIST_ENDING, Data.Last())); } else { Data.RemoveAt(Data.Count - 2); IsDotted = true; } } // List is both an atom and a list when empty (nil). if (Data.Count == 0) { IsAtom = true; } }
private LispDataType dotimes(LispList args, LispDataType body) { if (args.Count != 2 && args.Count != 3) { throw new LispException(string.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS, "DOTIMES")); } if (!(args[0] is LispSymbolicAtom)) { throw new LispException(string.Format(ERR_NOT_A_SYMBOL, args[0])); } LispSymbolicAtom counterVar = (LispSymbolicAtom)args[0]; LispSymbolicAtom[] symbolArray = new LispSymbolicAtom[] { counterVar }; setq(symbolArray, new LispNumericAtom[] { new LispNumericAtom((LispNumericAtom)args[1].Evaluate(this)) - 1 }); while ((LispNumericAtom)counterVar.Evaluate(this) >= 0) { body.Evaluate(this); setq(symbolArray, new LispNumericAtom[] { new LispNumericAtom((LispNumericAtom)counterVar.Evaluate(this)) - 1 }); } if (args.Count == 3) { return(args[2].Evaluate(this)); } return(new LispList()); }
private LispDataType eql(LispDataType d1, LispDataType d2) { LispSymbolicAtom t = new LispSymbolicAtom("T"); LispList nil = new LispList();; d1 = d1.Evaluate(this); d2 = d2.Evaluate(this); if (d1 is LispList && d2 is LispList) { if (((LispList)d1).Count == 0 && ((LispList)d2).Count == 0) { return(t); } else { return(nil); } } else if (d1.ToString() == d2.ToString()) { return(t); } else { return(nil); } }
private LispDataType boundp(LispSymbolicAtom a) { if (LispGlobals.ContainsKey(((LispSymbolicAtom)a.Evaluate(this)).Value)) { return(new LispSymbolicAtom("T")); } else { return(new LispList()); } }
private LispSymbolicAtom defun(LispSymbolicAtom name, LispList arguments, LispDataType function, LispInterpreter context) { List <LispSymbolicAtom> argList = new List <LispSymbolicAtom>(); foreach (LispDataType arg in arguments) { if (arg is LispSymbolicAtom) { argList.Add((LispSymbolicAtom)arg); } else { throw new LispException(string.Format(ERR_NOT_A_SYMBOL, arg.ToString())); } } LispUserFunctions[name.Value] = new LispUserFunction(name.Value, argList, function); LispSymbolicAtom result = new LispSymbolicAtom(name); result.SetLiteral(true); return(result); }
// Definitions of all the C# implementations of built-in Lisp functions. private LispDataType load(LispSymbolicAtom sPath) { string path = sPath.Evaluate(this).ToString(); int fileExtension = path.LastIndexOf('.'); if (fileExtension == -1) { path += ".lsp"; } if (File.Exists(path)) { StreamReader fin = new StreamReader(path); string line; while ((line = fin.ReadLine()) != null) { int comment = line.IndexOf(';'); // No comment found, push onto the command buffer. if (comment == -1) { Read(' ' + line + ' '); } // Ignore the comment by pushing everything before onto the command buffer. else { Read(' ' + line.Substring(0, comment) + ' '); } } fin.Close(); Eval(); return(new LispSymbolicAtom("T")); } else { return(new LispList()); } }
private LispSymbolicAtom makunbound(LispSymbolicAtom a) { LispGlobals.Remove(((LispSymbolicAtom)a.Evaluate(this)).Value); return(a); }
private LispDataType set(LispSymbolicAtom symbol, LispDataType value) { LispGlobals[symbol.Value] = value.Evaluate(this); return(value); }