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 LispList subst(LispDataType newData, LispDataType oldData, LispList list) { Dictionary <string, LispDataType> subs = new Dictionary <string, LispDataType>(); subs[oldData.Evaluate(this).ToString()] = newData.Evaluate(this); return(list.Replace(subs)); }
private LispList parseList(StreamReader reader) { reader.Read(); skipWhitespaces(reader); var list = new LispList(); while (!reader.EndOfStream) { char c = (char)reader.Peek(); if (c == ')') { reader.Read(); return(list); } else { dynamic expression = parseExpression(reader); list.Add(expression); } skipWhitespaces(reader); } throw new NotImplementedException("Missing closing brace!"); }
private LispList reverse(LispList list) { LispList result = new LispList(list); result.Data.Reverse(); return(result); }
public LispFunction(LispList parameters, LispElement body, LispEnvironment funcEnv, LispSymbol funcName) { this.parameters = parameters; this.body = body; this.funcName = funcName; this.funcEnv = (LispEnvironment)funcEnv.Clone(); }
private LispList append(LispList list, List <LispDataType> values) { if (values.Count == 0) { return(new LispList(list)); } if (list.IsDotted) { throw new LispException(string.Format(ERR_INVALID_LIST_ENDING, list.Last())); } List <LispDataType> evaluatedData = new List <LispDataType>(values); LispList result = new LispList(list); if (values.First().Evaluate(this) is LispList) { // TODO: ADDRANGE AND VALUES NOT BEING COPIED? result.Data.AddRange(((LispList)values.First().Evaluate(this)).Data); result.IsDotted = list.IsDotted; } else { result.Data.Add(values.First().Evaluate(this)); result.IsDotted = true; } result.SetLiteral(true); return(append(result, values.GetRange(1, values.Count - 1))); }
private LispList remove(LispDataType target, LispList list) { LispList result = list.Evaluate(this).Copy(); result.Data.RemoveAll(d => eqlBoolean(target, d)); return(result); }
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 LispNumericAtom listlength(LispList list) { if (list.IsDotted) { throw new LispException(string.Format(ERR_INVALID_LIST_ENDING, list.Last())); } return(new LispNumericAtom(list.Count)); }
private LispList makeList(LispDataType data) { LispList result = new LispList(); result.Data.Add(data); result.SetLiteral(true); return(result); }
private LispDataType car(LispList list) { if (list.IsAtom) { return(list); } return(list.First()); }
private LispDataType last(LispList list) { LispList result = new LispList(list); result.Data.RemoveRange(0, result.Data.Count - 1); result.SetLiteral(true); result.IsDotted = list.IsDotted; return(result); }
private LispList parseQuote(StreamReader reader) { reader.Read(); var list = new LispList(); list.Add(new LispSymbol("quote")); list.Add(parseExpression(reader)); return(list); }
private LispDataType cdr(LispList list) { if (list.IsAtom) { return(list); } if (list.Count == 2 && list.IsDotted) { return(list.Last()); } return(list.GetRange(1, list.Count - 1)); }
private LispList member(LispDataType target, LispList list) { target = target.Evaluate(this); for (int i = 0; i < list.Count; ++i) { if (eql(list[i], target)) { return(list.GetRange(i, list.Count - i)); } } return(new LispList()); }
// Return a copy of the list made of the given range. public LispList GetRange(int index, int count) { LispList result = Copy(); result.Data = Data.GetRange(index, count); if (result.Count == 1 && result.IsDotted) { throw new LispException(string.Format(ERR_INVALID_LIST_ENDING, result.Last())); } if (result.Count == 0) { result.IsAtom = true; } return(result); }
// Creates Lisp datatypes out of the command buffer and executes them. // Incomplete lists will be preserved in the buffer. public string Eval() { string outputString = string.Empty; try { // Parse the list. foreach (LispDataType data in ProcessInputBuffer(ref buffer)) { CommandQueue.Enqueue(data); } } catch (LispException e) { outputString += e.Message; buffer = string.Empty; } try { while (CommandQueue.Count > 0) { LispDataType command = CommandQueue.Dequeue(); // Exit command. if (command is LispList) { LispList cmd = (LispList)command; if (cmd.Count >= 1 && cmd.First().ToString() == "EXIT") { exit = true; return(outputString); } } // Evaluate the command. outputString += command.Evaluate(this); if (CommandQueue.Count > 0) { outputString += '\n'; } } } catch (LispException e) { outputString += e.Message; CommandQueue.Clear(); } return(outputString); }
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); }
// Replaces matching atoms with corresponding Lisp datatypes. public LispList Replace(Dictionary <string, LispDataType> replacements, bool replaceLiterals = true) { List <LispDataType> newData = new List <LispDataType>(); foreach (LispDataType data in Data) { if (data is LispList) { if ((!replaceLiterals && data.IsLiteral) || (((LispList)data).First() is LispSymbolicAtom && ((LispSymbolicAtom)((LispList)data).First()).Value == "QUOTE")) { newData.Add(data.Copy()); } else { newData.Add(data.Copy().Replace(replacements, replaceLiterals)); } } else if (data is LispSymbolicAtom) { // Check if this symbol is one we need to replace. if (replacements.ContainsKey(((LispSymbolicAtom)data).ToString()) && (replaceLiterals || (!replaceLiterals && !data.IsLiteral))) { LispDataType replacement = replacements[((LispSymbolicAtom)data).ToString()].Copy(); newData.Add(replacement); } else { newData.Add(data.Copy()); } } else { newData.Add(data); } } LispList result = Copy(); result.Data = newData; return(result); }
private LispDataType dolist(LispList args, LispDataType body) { if (args.Count != 2 && args.Count != 3) { throw new LispException(string.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS, "DOLIST")); } if (!(args.First() is LispSymbolicAtom)) { throw new LispException(string.Format(ERR_NOT_A_SYMBOL, args.First())); } LispDataType list = args[1].Evaluate(this); if (!(list is LispList)) { throw new LispException(string.Format(ERR_NOT_A_LIST, list)); } List <LispSymbolicAtom> varList = new List <LispSymbolicAtom> { (LispSymbolicAtom)args.First() }; foreach (LispDataType data in (LispList)list) { setq(varList, new List <LispDataType> { data }); body.Evaluate(this); } if (args.Count == 3) { return(args[2].Evaluate(this)); } else { return(new LispList()); } }
public LispMacro(LispList parameters, LispElement body, LispEnvironment funcEnv) { throw new NotImplementedException(); }
public LispFunction(LispList parameters, LispElement body, LispEnvironment funcEnv) : this(parameters, body, funcEnv, null) { }
public bool Equals(LispList other) { return(ToString() == other.ToString()); }
public LispList(LispList list) : base(list.IsAtom, list.IsList) { Data = new List <LispDataType>(list.Data); IsDotted = list.IsDotted; IsLiteral = list.IsLiteral; }