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 bool eqlBoolean(LispDataType d1, LispDataType d2) { 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(true); } else { return(false); } } else if (d1.ToString() == d2.ToString()) { return(true); } else { return(false); } }
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 LispList remove(LispDataType target, LispList list) { LispList result = list.Evaluate(this).Copy(); result.Data.RemoveAll(d => eqlBoolean(target, d)); return(result); }
private LispList makeList(LispDataType data) { LispList result = new LispList(); result.Data.Add(data); result.SetLiteral(true); return(result); }
private LispDataType symbolp(LispDataType d) { if (d is LispSymbolicAtom || (d is LispList && d.IsAtom)) { return(new LispSymbolicAtom("T")); } else { return(new LispList()); } }
private LispDataType numberp(LispDataType d) { if (d is LispNumericAtom) { return(new LispSymbolicAtom("T")); } else { return(new LispList()); } }
private LispDataType not(LispDataType d) { if (!d.Evaluate(this)) { return(new LispSymbolicAtom("T")); } else { return(new LispList()); } }
private LispDataType isAtom(LispDataType data) { if (data.Evaluate(this).IsAtom) { return(new LispSymbolicAtom("T")); } else { return(new LispList()); } }
private LispDataType isNull(LispDataType data) { if (data.Evaluate(this).ToString() == "NIL") { return(new LispSymbolicAtom("T")); } else { return(new LispList()); } }
private LispDataType equal(LispDataType d1, LispDataType d2) { if (d1.Evaluate(this).ToString() == d2.Evaluate(this).ToString()) { return(new LispSymbolicAtom("T")); } else { return(new LispList()); } }
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()); }
private LispDataType lispIf(LispDataType pred1, LispDataType result, LispDataType elseResult = null) { if (pred1.Evaluate(this)) { return(result.Evaluate(this)); } else if (elseResult != null) { return(elseResult.Evaluate(this)); } else { return(new LispList()); } }
// 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); }
public LispDataType Evaluate(List <LispDataType> arguments, LispInterpreter context) { // replace function arguments if (arguments.Count != args.Count) { throw new LispException(String.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS, name)); } if (func is LispNumericAtom) { return(func.Evaluate(context)); } else if (func is LispList) { // Create the argument replacement map. Dictionary <string, LispDataType> argReplacements = new Dictionary <string, LispDataType>(); for (int i = 0; i < args.Count; ++i) { LispDataType d = arguments[i].Evaluate(context); if (d is LispList) { argReplacements[args[i].Value] = d.Copy(); } else { argReplacements[args[i].Value] = d; } } // Replace the arguments and evaluate. return(((LispList)func).Replace(argReplacements, false).Evaluate(context)); } else { if (args.Count >= 1 && args[0].Value == ((LispSymbolicAtom)func).Value) { return(arguments[0].Evaluate(context)); } else { return(func.Evaluate(context)); } } }
private LispDataType eval(LispDataType value) { bool lit = value.IsLiteral; dynamic temp = value.Copy(); if (temp is LispList) { ((LispList)temp).SetLiteral(false, false); } else { temp.SetLiteral(false); } temp = temp.Evaluate(this); temp.SetLiteral(false, false); //LispDataType result = temp.Evaluate(this); //result.SetLiteral(lit); return(temp); }
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); }
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 LispUserFunction(string name, List <LispSymbolicAtom> arguments, LispDataType function) { args = arguments; func = function; this.name = name; }
public ResultTree Add(LispDataType type, object obj) { return(Add(new ResultTree(type, obj))); }
public void Set(LispDataType type) { _typedValue = new TypedValue((int)type); }
public void Set(LispDataType type, object obj) { _typedValue = new TypedValue((int)type, obj); }
public ResultTree(LispDataType type, object obj) : this(new TypedValue((int)type, obj)) { }
public void Add(LispDataType type, object obj) { base.Add(new TypedValue((int)type, obj)); }
private LispDataType quote(LispDataType input) { input.SetLiteral(true); return(input); }
private LispList cons(LispDataType d1, LispDataType d2) { return(append(makeList(d1), new List <LispDataType> { d2 })); }
private LispDataType set(LispSymbolicAtom symbol, LispDataType value) { LispGlobals[symbol.Value] = value.Evaluate(this); return(value); }
// Given the contents of a list, ExecuteLispFunction will execute the corresponding function. private LispDataType ExecuteLispFunction(List <LispDataType> list) { if (list.Count == 0) { return(new LispList()); } int argCount = list.Count - 1; List <LispDataType> args = list.GetRange(1, list.Count - 1); List <LispDataType> verifiedArgs; List <LispDataType> argList = list.GetRange(1, argCount); string fname = list.First().ToString(); // Lisp functions are called here. The name in the case is the name that the user will use to call the function. switch (fname) { case "+": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom), typeof(LispNumericAtom) }, argList); return(add((LispNumericAtom)verifiedArgs[0], (LispNumericAtom)verifiedArgs[1])); case "-": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom), typeof(LispNumericAtom) }, argList); return(subtract((LispNumericAtom)verifiedArgs[0], (LispNumericAtom)verifiedArgs[1])); case "*": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom), typeof(LispNumericAtom) }, argList); return(multiply((LispNumericAtom)verifiedArgs[0], (LispNumericAtom)verifiedArgs[1])); case "/": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom), typeof(LispNumericAtom) }, argList); return(divide((LispNumericAtom)verifiedArgs[0], (LispNumericAtom)verifiedArgs[1])); case "1+": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom) }, argList); return((LispNumericAtom)verifiedArgs[0] + 1); case "1-": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom) }, argList); return((LispNumericAtom)verifiedArgs[0] - 1); case "DEFUN": if (argCount != 3) { throw new LispException(string.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS, fname)); } if (argList[0] is LispSymbolicAtom && argList[1] is LispList) { return(defun((LispSymbolicAtom)argList[0], (LispList)argList[1], argList[2], this)); } else { if (argList[0] is LispSymbolicAtom) { throw new LispException(string.Format(ERR_NOT_A_LIST, argList[1])); } else { throw new LispException(string.Format(ERR_NOT_A_SYMBOL, argList[0].ToString())); } } case "FIRST": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispList) }, argList); return(car((LispList)verifiedArgs[0])); case "LAST": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispList) }, argList); return(last((LispList)verifiedArgs[0])); case "REST": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispList) }, argList); return(cdr((LispList)verifiedArgs[0])); case "QUOTE": if (argCount != 1) { throw new LispException(String.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS, fname)); } return(quote(args[0])); case "SET": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispSymbolicAtom), typeof(LispDataType) }, argList); return(set((LispSymbolicAtom)verifiedArgs[0], verifiedArgs[1])); case "EVAL": if (argCount != 1) { throw new LispException(string.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS, fname)); } return(eval(args[0])); case "SETQ": List <LispSymbolicAtom> variables = new List <LispSymbolicAtom>(); List <LispDataType> values = new List <LispDataType>(); for (int i = 0; i < args.Count; ++i) { if (i % 2 == 0) { if (args[i] is LispSymbolicAtom) { variables.Add((LispSymbolicAtom)args[i]); } else { throw new LispException(string.Format(ERR_NOT_A_SYMBOL, args[i].ToString())); } } else { values.Add(args[i]); } } return(setq(variables, values)); case "NULL": case "ENDP": if (argCount != 1) { throw new LispException(string.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS, fname)); } return(isNull(args[0])); case "ATOM": if (argCount != 1) { throw new LispException(string.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS, fname)); } return(isAtom(args[0])); case "LISTP": if (argCount != 1) { throw new LispException(string.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS, fname)); } return(isList(args[0])); case "LIST": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispDataType) }, argList); return(makeList(verifiedArgs[0])); case "APPEND": if (argCount == 0) { return(new LispList()); } if (argCount == 1) { return(args[0]); } if (!(args[0].Evaluate(this) is LispList)) { throw new LispException(string.Format(ERR_NOT_A_LIST, args[0])); } return(append((LispList)args[0].Evaluate(this), args.GetRange(1, args.Count - 1))); case "COND": List <LispList> cases = new List <LispList>(); foreach (LispDataType data in args) { if (data is LispList) { cases.Add((LispList)data); } else { throw new LispException(string.Format(ERR_NOT_A_LIST, data)); } } return(cond(cases)); case "IF": if (argCount == 2) { return(lispIf(args[0], args[1])); } else if (argCount == 3) { return(lispIf(args[0], args[1], args[2])); } else { throw new LispException(string.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS, fname)); } case "EQ": case "EQL": if (argCount != 2) { throw new LispException(string.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS)); } return(eql(args[0], args[1])); case "EQUAL": if (argCount != 2) { throw new LispException(string.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS)); } return(equal(args[0], args[1])); case "NOT": if (argCount != 1) { throw new LispException(string.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS)); } return(not(args[0])); case "AND": return(and(args)); case "OR": return(or(args)); case "CONS": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispDataType), typeof(LispDataType) }, argList); return(cons(verifiedArgs[0], verifiedArgs[1])); case "SYMBOLP": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispDataType) }, argList); return(symbolp(verifiedArgs[0])); case "NUMBERP": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispDataType) }, argList); return(numberp(verifiedArgs[0])); case "MINUSP": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom) }, argList); return(minusp((LispNumericAtom)verifiedArgs[0])); case "PLUSP": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom) }, argList); return(plusp((LispNumericAtom)verifiedArgs[0])); case "ZEROP": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom) }, argList); return(zerop((LispNumericAtom)verifiedArgs[0])); case "LIST-LENGTH": case "LENGTH": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispList) }, argList); return(listlength((LispList)verifiedArgs[0])); case "BOUNDP": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispSymbolicAtom) }, argList); return(boundp((LispSymbolicAtom)verifiedArgs[0])); case "MAKUNBOUND": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispSymbolicAtom) }, argList); return(makunbound((LispSymbolicAtom)verifiedArgs[0])); case "REVERSE": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispList) }, argList); return(reverse((LispList)verifiedArgs[0])); case "MEMBER": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispDataType), typeof(LispList) }, argList); return(member(verifiedArgs[0], (LispList)verifiedArgs[1])); case "REMOVE": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispDataType), typeof(LispList) }, argList); return(remove(verifiedArgs[0], (LispList)verifiedArgs[1])); case "SUBST": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispDataType), typeof(LispDataType), typeof(LispList) }, argList); return(subst(verifiedArgs[0], verifiedArgs[1], (LispList)verifiedArgs[2])); case "=": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom), typeof(LispNumericAtom) }, argList); return(equals((LispNumericAtom)verifiedArgs[0], (LispNumericAtom)verifiedArgs[1])); case "/=": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom), typeof(LispNumericAtom) }, argList); return(notequals((LispNumericAtom)verifiedArgs[0], (LispNumericAtom)verifiedArgs[1])); case ">=": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom), typeof(LispNumericAtom) }, argList); return(morethanequals((LispNumericAtom)verifiedArgs[0], (LispNumericAtom)verifiedArgs[1])); case "<=": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom), typeof(LispNumericAtom) }, argList); return(lessthanequals((LispNumericAtom)verifiedArgs[0], (LispNumericAtom)verifiedArgs[1])); case "<": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom), typeof(LispNumericAtom) }, argList); return(lessthan((LispNumericAtom)verifiedArgs[0], (LispNumericAtom)verifiedArgs[1])); case ">": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom), typeof(LispNumericAtom) }, argList); return(morethan((LispNumericAtom)verifiedArgs[0], (LispNumericAtom)verifiedArgs[1])); case "DOLIST": if (argCount != 2) { throw new LispException(string.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS, fname)); } if (!(args[0] is LispList)) { throw new LispException(string.Format(ERR_NOT_A_LIST, args[0])); } return(dolist((LispList)args[0], args[1])); case "DOTIMES": if (argCount != 2) { throw new LispException(string.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS, fname)); } if (!(args[0] is LispList)) { throw new LispException(string.Format(ERR_NOT_A_LIST, args[0])); } return(dotimes((LispList)args[0], args[1])); case "MIN": case "MAX": case "GCD": if (argCount < 1) { throw new LispException(string.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS, fname)); } List <LispNumericAtom> arguments = new List <LispNumericAtom>(); foreach (LispDataType data in args) { if (data.Evaluate(this) is LispNumericAtom) { arguments.Add((LispNumericAtom)data.Evaluate(this)); } else { throw new LispException(string.Format(ERR_NOT_A_NUMBER, data)); } } if (fname == "MIN") { return(min(arguments)); } else if (fname == "MAX") { return(max(arguments)); } else { return(gcd(arguments)); } case "SQRT": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom) }, argList); return(sqrt((LispNumericAtom)verifiedArgs[0])); case "SIN": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom) }, argList); return(sin((LispNumericAtom)verifiedArgs[0])); case "COS": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom) }, argList); return(cos((LispNumericAtom)verifiedArgs[0])); case "TAN": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom) }, argList); return(tan((LispNumericAtom)verifiedArgs[0])); case "ASIN": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom) }, argList); return(asin((LispNumericAtom)verifiedArgs[0])); case "ACOS": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom) }, argList); return(acos((LispNumericAtom)verifiedArgs[0])); case "ATAN": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom) }, argList); return(atan((LispNumericAtom)verifiedArgs[0])); case "MOD": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom), typeof(LispNumericAtom) }, argList); return(mod((LispNumericAtom)verifiedArgs[0], (LispNumericAtom)verifiedArgs[1])); case "ABS": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom) }, argList); return(abs((LispNumericAtom)verifiedArgs[0])); case "ROUND": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom) }, argList); return(round((LispNumericAtom)verifiedArgs[0])); case "RANDOM": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom) }, argList); return(random((LispNumericAtom)verifiedArgs[0])); case "EXP": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom) }, argList); return(exp((LispNumericAtom)verifiedArgs[0])); case "EXPT": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispNumericAtom), typeof(LispNumericAtom) }, argList); return(expt((LispNumericAtom)verifiedArgs[0], (LispNumericAtom)verifiedArgs[1])); case "LOG": if (argCount == 1) { if (args[0].Evaluate(this) is LispNumericAtom) { return(log((LispNumericAtom)args[0])); } throw new LispException(string.Format(ERR_NOT_A_NUMBER, args[0])); } else if (argCount == 2) { if (args[0].Evaluate(this) is LispNumericAtom && args[1].Evaluate(this) is LispNumericAtom) { return(log((LispNumericAtom)args[0].Evaluate(this), (LispNumericAtom)args[1].Evaluate(this))); } if (args[1].Evaluate(this) is LispNumericAtom) { throw new LispException(string.Format(ERR_NOT_A_NUMBER, args[0])); } throw new LispException(string.Format(ERR_NOT_A_NUMBER, args[1])); } else { throw new LispException(string.Format(ERR_INVALID_NUMBER_OF_ARGUMENTS, fname)); } case "LOAD": verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispSymbolicAtom) }, argList); return(load((LispSymbolicAtom)verifiedArgs[0])); default: // CAR/CDR MatchCollection crMatches = crRegex.Matches(fname); if (crMatches.Count != 0) { verifiedArgs = CheckLispArguments(fname, new List <Type> { typeof(LispList) }, argList); LispDataType result = verifiedArgs[0]; string operations = crMatches[0].Groups[1].Value; for (int i = 0; i < operations.Count(); ++i) { char operation = operations[operations.Count() - 1 - i]; if (result is LispList) { if (operation == 'A') { result = car((LispList)result); } else { result = cdr((LispList)result); } } else { throw new LispException(string.Format(ERR_NOT_A_LIST, result)); } } result.SetLiteral(true); return(result); } // User-defined functions. if (LispUserFunctions.ContainsKey(fname)) { return(LispUserFunctions[fname].Evaluate(args, this)); } throw new LispException(String.Format(ERR_UNDEFINED_FUNCTION, fname)); } }