コード例 #1
0
        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));
        }
コード例 #2
0
        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);
            }
        }
コード例 #3
0
        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());
        }
コード例 #4
0
        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);
            }
        }
コード例 #5
0
        private LispList remove(LispDataType target, LispList list)
        {
            LispList result = list.Evaluate(this).Copy();

            result.Data.RemoveAll(d => eqlBoolean(target, d));
            return(result);
        }
コード例 #6
0
        private LispList makeList(LispDataType data)
        {
            LispList result = new LispList();

            result.Data.Add(data);
            result.SetLiteral(true);
            return(result);
        }
コード例 #7
0
 private LispDataType symbolp(LispDataType d)
 {
     if (d is LispSymbolicAtom || (d is LispList && d.IsAtom))
     {
         return(new LispSymbolicAtom("T"));
     }
     else
     {
         return(new LispList());
     }
 }
コード例 #8
0
 private LispDataType numberp(LispDataType d)
 {
     if (d is LispNumericAtom)
     {
         return(new LispSymbolicAtom("T"));
     }
     else
     {
         return(new LispList());
     }
 }
コード例 #9
0
 private LispDataType not(LispDataType d)
 {
     if (!d.Evaluate(this))
     {
         return(new LispSymbolicAtom("T"));
     }
     else
     {
         return(new LispList());
     }
 }
コード例 #10
0
 private LispDataType isAtom(LispDataType data)
 {
     if (data.Evaluate(this).IsAtom)
     {
         return(new LispSymbolicAtom("T"));
     }
     else
     {
         return(new LispList());
     }
 }
コード例 #11
0
 private LispDataType isNull(LispDataType data)
 {
     if (data.Evaluate(this).ToString() == "NIL")
     {
         return(new LispSymbolicAtom("T"));
     }
     else
     {
         return(new LispList());
     }
 }
コード例 #12
0
 private LispDataType equal(LispDataType d1, LispDataType d2)
 {
     if (d1.Evaluate(this).ToString() == d2.Evaluate(this).ToString())
     {
         return(new LispSymbolicAtom("T"));
     }
     else
     {
         return(new LispList());
     }
 }
コード例 #13
0
 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());
 }
コード例 #14
0
 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());
     }
 }
コード例 #15
0
        // 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);
        }
コード例 #16
0
            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));
                    }
                }
            }
コード例 #17
0
        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);
        }
コード例 #18
0
        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);
        }
コード例 #19
0
        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());
            }
        }
コード例 #20
0
 public LispUserFunction(string name, List <LispSymbolicAtom> arguments, LispDataType function)
 {
     args      = arguments;
     func      = function;
     this.name = name;
 }
コード例 #21
0
 public ResultTree Add(LispDataType type, object obj)
 {
     return(Add(new ResultTree(type, obj)));
 }
コード例 #22
0
 public void Set(LispDataType type)
 {
     _typedValue = new TypedValue((int)type);
 }
コード例 #23
0
 public void Set(LispDataType type, object obj)
 {
     _typedValue = new TypedValue((int)type, obj);
 }
コード例 #24
0
 public ResultTree(LispDataType type, object obj)
     : this(new TypedValue((int)type, obj))
 {
 }
コード例 #25
0
ファイル: ResultList.cs プロジェクト: cxfwolfkings/EIM
 public void Add(LispDataType type, object obj)
 {
     base.Add(new TypedValue((int)type, obj));
 }
コード例 #26
0
 private LispDataType quote(LispDataType input)
 {
     input.SetLiteral(true);
     return(input);
 }
コード例 #27
0
 private LispList cons(LispDataType d1, LispDataType d2)
 {
     return(append(makeList(d1), new List <LispDataType> {
         d2
     }));
 }
コード例 #28
0
 private LispDataType set(LispSymbolicAtom symbol, LispDataType value)
 {
     LispGlobals[symbol.Value] = value.Evaluate(this);
     return(value);
 }
コード例 #29
0
        // 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));
            }
        }