Ejemplo n.º 1
0
        // Read a MalSequence, checking that it starts and terminates correctly.
        // Named read_list to follow the ref, but has been genericized to handle vectors as well.
        static public MalSeq read_list(Reader reader, MalSeq sequence, char start, char end)
        {
            // Check that we are in fact at the start of a list.
            string token = reader.Next();

            if (token[0] != start)
            {
                // Parse error - probably internal if the list code is correct.
                throw new MalInternalError("Sequence expected '" + start + "' but got: " + token);
            }

            // Use read_form to get the list's contents, accumulating them into the list.
            while (true)
            {
                token = reader.Peek();

                if (token != null)
                {
                    // We are in the list or at the end.
                    if (token[0] == end)
                    {
                        // Reached valid end of list. Consume the end char.
                        reader.Next();
                        // And we are done.
                        break;
                    }
                    // Mutually recurse to read the next list element.
                    MalVal newVal = read_form(reader);
                    sequence.Add(newVal);
                }
                else
                {
                    // The input has finished but the list hasn't. Try to get more input.
                    reader.LoadMoreTokens(start, end);
                }
            }

            return(sequence);
        }
Ejemplo n.º 2
0
            // Support the built-in '=' function. False until explicitly proven otherwise.
            public static MalVal EQ(MalVal a, MalVal b)
            {
                if (a.GetType() != b.GetType())
                {
                    // TODO - allow equality comparisons between ints and floats.
                    return(malFalse);
                }
                // If here, they are of the same Mal type. Do they have the same value?
                switch ((object)a)
                {
                case MalSym aSym:
                    if (aSym.getName() == ((MalSym)b).getName())
                    {
                        return(malTrue);
                    }
                    break;

                case MalNum aNumk:
                    if (aNumk == ((MalNum)b))
                    {
                        return(malTrue);
                    }
                    break;

                case MalString aString:
                    if (aString.ToString() == ((MalString)b).ToString())
                    {
                        return(malTrue);
                    }
                    break;

                case MalKeyword aKeyWord:
                    if (aKeyWord.ToString() == ((MalKeyword)b).ToString())
                    {
                        return(malTrue);
                    }
                    break;

                case MalSeq aSeq:
                    // Sequences must be the same length, and each element must be the same.
                    MalSeq bSeq = (MalSeq)b;
                    if (aSeq.Count() != bSeq.Count())
                    {
                        // They are not of equal length.
                        return(malFalse);
                    }
                    for (var i = 0; i < aSeq.Count(); i++)
                    {
                        // At least one of the elements is not equal.
                        if (EQ(aSeq[i], bSeq[i]) == malFalse)
                        {
                            return(malFalse);
                        }
                    }
                    return(malTrue);

                case MalAtom aAtom:
                    // The atoms must be the same object. Two atoms containing the same value are not equal.
                    // TODO check whether this should be true if dereferencing them should be used instead. This isn't specified in the tests.
                    if (aAtom == ((MalAtom)b))
                    {
                        return(malTrue);
                    }
                    break;

                default:
                    throw new MalInternalError("Can't yet compare '" + a.GetType() + "' with '" + b.GetType() + "'");
                }
                return(malFalse);
            }