package com.babel17.syntaxtree; import java.util.*; public class NodeList implements Iterable<Node> { private NodeList next; private Node node; private static class Iter implements Iterator<Node> { NodeList list; Iter(NodeList list) { this.list = list; } public boolean hasNext() { return !list.empty(); } public Node next() { if (list.empty()) throw new NoSuchElementException(); Node n = list.head(); list = list.tail(); return n; } public void remove() { throw new UnsupportedOperationException(); } } public NodeList() { next = null; node = null; } public Node head() { if (node == null) throw new RuntimeException("empty list has no head"); return node; } public int length() { if (next == null) return 0; else return next.length()+1; } public Node get(int index) { if (index <= 0) { if (node != null) return node; else throw new RuntimeException("index is out of bounds"); } else return next.get(index-1); } public NodeList tail() { if (node == null) throw new RuntimeException("empty list has no tail"); return next; } public boolean empty() { return node == null; } public NodeList cons(Node node) { if (node == null) throw new IllegalArgumentException(); NodeList l = new NodeList(); l.node = node; l.next = this; return l; } public NodeList append(NodeList l) { for (Node n : this.reverse()) { l = l.cons(n); } return l; } public NodeList reverse() { NodeList l = new NodeList(); for (Node n : this) l = l.cons(n); return l; } public Iterator<Node> iterator() { return new Iter(this); } public Location location() { if (empty()) return null; Location l = head().location(); for (Node n : this) { l = Location.merge(l, n.location()); } return l; } public boolean hasErrors() { for (Node i : this) if (i instanceof ParseErrorNode) return true; return false; } public NodeList suppressErrors() { if (hasErrors()) return new NodeList(); else return this; } public String toString() { String s = ""; for (Node n : this) { s = s + n; s = s + ","; } return "NodeList("+s+")"; } }