| 1515 | } |
| 1516 | |
| 1517 | public static class ConditionalReader extends AFn { |
| 1518 | |
| 1519 | final static private Object READ_STARTED = new Object(); |
| 1520 | final static public Keyword DEFAULT_FEATURE = Keyword.intern(null, "default"); |
| 1521 | final static public IPersistentSet RESERVED_FEATURES = |
| 1522 | RT.set(Keyword.intern(null, "else"), Keyword.intern(null, "none")); |
| 1523 | |
| 1524 | public static boolean hasFeature(Object feature, Object opts) { |
| 1525 | if (! (feature instanceof Keyword)) |
| 1526 | throw Util.runtimeException("Feature should be a keyword: " + feature); |
| 1527 | |
| 1528 | if(DEFAULT_FEATURE.equals(feature)) |
| 1529 | return true; |
| 1530 | |
| 1531 | IPersistentSet custom = (IPersistentSet) ((IPersistentMap)opts).valAt(OPT_FEATURES); |
| 1532 | return custom != null && custom.contains(feature); |
| 1533 | } |
| 1534 | |
| 1535 | public static Object readCondDelimited(PushbackReader r, boolean splicing, Object opts, Object pendingForms) { |
| 1536 | Object result = READ_STARTED; |
| 1537 | Object form; // The most recently ready form |
| 1538 | boolean toplevel = (pendingForms == null); |
| 1539 | pendingForms = ensurePending(pendingForms); |
| 1540 | |
| 1541 | final int firstline = |
| 1542 | (r instanceof LineNumberingPushbackReader) ? |
| 1543 | ((LineNumberingPushbackReader) r).getLineNumber() : -1; |
| 1544 | |
| 1545 | for(; ;) { |
| 1546 | if(result == READ_STARTED) { |
| 1547 | // Read the next feature |
| 1548 | form = read(r, false, READ_EOF, ')', READ_FINISHED, true, opts, pendingForms, null); |
| 1549 | |
| 1550 | if (form == READ_EOF) { |
| 1551 | if (firstline < 0) |
| 1552 | throw Util.runtimeException("EOF while reading"); |
| 1553 | else |
| 1554 | throw Util.runtimeException("EOF while reading, starting at line " + firstline); |
| 1555 | } else if (form == READ_FINISHED) { |
| 1556 | break; // read-cond form is done |
| 1557 | } |
| 1558 | |
| 1559 | if(RESERVED_FEATURES.contains(form)) |
| 1560 | throw Util.runtimeException("Feature name " + form + " is reserved."); |
| 1561 | |
| 1562 | if (hasFeature(form, opts)) { |
| 1563 | |
| 1564 | //Read the form corresponding to the feature, and assign it to result if everything is kosher |
| 1565 | |
| 1566 | form = read(r, false, READ_EOF, ')', READ_FINISHED, true, opts, pendingForms, (Resolver) RT.READER_RESOLVER.deref()); |
| 1567 | |
| 1568 | if (form == READ_EOF) { |
| 1569 | if (firstline < 0) |
| 1570 | throw Util.runtimeException("EOF while reading"); |
| 1571 | else |
| 1572 | throw Util.runtimeException("EOF while reading, starting at line " + firstline); |
| 1573 | } else if (form == READ_FINISHED) { |
| 1574 | if (firstline < 0) |