Changeset 12646


Ignore:
Timestamp:
05/01/10 21:43:28 (11 years ago)
Author:
ehuelsmann
Message:

Re #93: Instead of fixing just readList and readDelimitedList,
document the protocol for processChar and fix that. Also, remove
a pattern from LispReader?.java (return null) which can't be used
by Lisp functions.

This commit fixes a much broader range of cases of the symptom
reported in #93.

Location:
trunk/abcl/src/org/armedbear/lisp
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/abcl/src/org/armedbear/lisp/LispReader.java

    r12604 r12646  
    4747
    4848        {
    49           try 
     49          try
    5050            {
    5151              while (true) {
    5252                int n = stream._readChar();
    5353                if (n < 0)
    54                   return null;
     54                  return LispThread.currentThread().setValues();
    5555                if (n == '\n')
    56                   return null;
     56                  return LispThread.currentThread().setValues();
    5757              }
    5858            }
    5959          catch (java.io.IOException e)
    6060            {
    61               return null;
     61                return LispThread.currentThread().setValues();
    6262            }
    6363        }
     
    329329        {
    330330            stream.skipBalancedComment();
    331             return null;
     331            return LispThread.currentThread().setValues();
    332332        }
    333333    };
  • trunk/abcl/src/org/armedbear/lisp/Stream.java

    r12645 r12646  
    482482                if (rt.isWhitespace(c))
    483483                    continue;
    484                 LispObject result = processChar(c, rt);
     484                LispObject result = processChar(thread, c, rt);
    485485                if (result != null)
    486486                    return result;
     
    498498    }
    499499
    500     private final LispObject processChar(char c, Readtable rt)
    501 
     500    /** Dispatch macro function if 'c' has one associated,
     501     * read a token otherwise.
     502     *
     503     * When the macro function returns zero values, this function
     504     * returns null or the token or returned value otherwise.
     505     */
     506    private final LispObject processChar(LispThread thread,
     507                                         char c, Readtable rt)
    502508    {
    503509        final LispObject handler = rt.getReaderMacroFunction(c);
    504         if (handler instanceof ReaderMacroFunction)
    505             return ((ReaderMacroFunction)handler).execute(this, c);
    506         if (handler != null && handler != NIL)
    507             return handler.execute(this, LispCharacter.getInstance(c));
    508         return readToken(c, rt);
     510        LispObject value;
     511
     512        if (handler instanceof ReaderMacroFunction) {
     513            thread._values = null;
     514            value = ((ReaderMacroFunction)handler).execute(this, c);
     515        }
     516        else if (handler != null && handler != NIL) {
     517            thread._values = null;
     518            value = handler.execute(this, LispCharacter.getInstance(c));
     519        }
     520        else
     521            return readToken(c, rt);
     522
     523        // If we're looking at zero return values, set 'value' to null
     524        if (value == NIL) {
     525            LispObject[] values = thread._values;
     526            if (values != null && values.length == 0)
     527                value = null;
     528        }
     529        return value;
    509530    }
    510531
     
    659680                }
    660681
    661                 thread._values = null;
    662                 LispObject obj = processChar(c, rt);
    663                 if (obj == null) {
    664                     // A comment.
     682                LispObject obj = processChar(thread, c, rt);
     683                if (obj == null)
    665684                    continue;
    666                 }
    667 
    668                 if (! (obj == NIL && thread._values != null
    669                        && thread._values.length == 0)) {
    670                     // Don't add the return value NIL to the list
    671                     // if the _values array indicates no values have been returned
    672                     if (first == null) {
    673                         first = new Cons(obj);
    674                         last = first;
    675                     } else {
    676                         Cons newCons = new Cons(obj);
    677                         last.cdr = newCons;
    678                         last = newCons;
    679                     }
     685
     686
     687                if (first == null) {
     688                    first = new Cons(obj);
     689                    last = first;
     690                } else {
     691                    Cons newCons = new Cons(obj);
     692                    last.cdr = newCons;
     693                    last = newCons;
    680694                }
    681695            }
     
    14491463                break;
    14501464
    1451             thread._values = null;
    1452             LispObject obj = processChar(c, rt);
    1453             if (obj != null &&
    1454                 ! (obj == NIL && thread._values != null
    1455                    && thread._values.length == 0))
    1456                 // Don't add 'obj' to the list, if _values indicates
    1457                 // no values have been returned
     1465            LispObject obj = processChar(thread, c, rt);
     1466            if (obj != null)
    14581467                result = new Cons(obj, result);
    14591468        }
Note: See TracChangeset for help on using the changeset viewer.