Exemple #1
0
        // Read a JKLSequence, 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 JKLSeqBase read_list(TokenQueue TQ, JKLSeqBase sequence, char start, char end)
        {
            // Check that we are in fact at the start of a list.
            string token = TQ.Next();

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

            // Use read_form to get the list's contents, accumulating them into the list.
            while (true)
            {
                token = TQ.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.
                        TQ.Next();
                        // And we are done.
                        break;
                    }
                    // Mutually recurse to read the next list element.
                    JKLVal newVal = read_form(TQ);
                    sequence.Add(newVal);
                }
                else
                {
                    // The input has finished but the list hasn't. Try to get more input.
                    TQ.LoadMoreTokens(start, end);
                }
            }

            return(sequence);
        }
Exemple #2
0
            // Support the built-in '=' function. False until explicitly proven otherwise.
            // Should be used in preference to == for internal JKLVal equality checks.
            public static JKLVal EQ(JKLVal a, JKLVal b)
            {
                if (a.GetType() != b.GetType())
                {
                    // TODO - allow equality comparisons between ints and floats.
                    // TODO - allow equality comparisons between empty lists and vectors.
                    return(jklFalse);
                }
                // If here, they are of the same Mal type. Do they have the same value?
                switch ((object)a)
                {
                case JKLSym aSym:
                    if (aSym.getName() == ((JKLSym)b).getName())
                    {
                        return(jklTrue);
                    }
                    break;

                case JKLNum aNumk:
                    if (aNumk.Unbox() == ((JKLNum)b).Unbox())
                    {
                        return(jklTrue);
                    }
                    break;

                case JKLString aString:
                    if (aString.unbox() == ((JKLString)b).unbox())
                    {
                        return(jklTrue);
                    }
                    break;

                case JKLKeyword aKeyWord:
                    if (aKeyWord.unbox() == ((JKLKeyword)b).unbox())
                    {
                        return(jklTrue);
                    }
                    break;

                case JKLNil aNil:
                    if (aNil == ((JKLNil)b))
                    {
                        return(jklTrue);
                    }
                    break;

                case JKLTrue aTrue:
                    if (aTrue == ((JKLTrue)b))
                    {
                        return(jklTrue);
                    }
                    break;

                case JKLFalse aFalse:
                    if (aFalse == ((JKLFalse)b))
                    {
                        return(jklTrue);
                    }
                    break;

                case JKLHashMap ahashMap:
                    if (_innerHashMapEQ(ahashMap, (JKLHashMap)b))
                    {
                        return(jklTrue);
                    }
                    else
                    {
                        return(jklFalse);
                    }

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

                case JKLAtom 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 == ((JKLAtom)b))
                    {
                        return(jklTrue);
                    }
                    break;

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