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));
        }
Пример #3
0
        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);
        }
Пример #5
0
 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);
        }
Пример #13
0
        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);
            }
Пример #17
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);
        }
        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());
            }
        }
Пример #21
0
 public LispMacro(LispList parameters, LispElement body, LispEnvironment funcEnv)
 {
     throw new NotImplementedException();
 }
Пример #22
0
 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;
 }