blob: 86f65ca0689ce651d467ebfe5bcec833f81d214e [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.mrql.gen;
import java.util.Iterator;
import java.io.*;
final class TreeIterator implements Iterator<Tree> {
Trees trees;
TreeIterator ( Trees trees ) { this.trees = trees; }
public boolean hasNext () { return trees.tail != null; }
public Tree next () {
Tree res = trees.head;
trees = trees.tail;
return res;
}
public void remove () { trees = trees.tail; }
}
final public class Trees implements Iterable<Tree>, Serializable {
private final static int screen_size = 100;
public Tree head;
public Trees tail;
public Trees ( Tree head, Trees tail ) {
if (tail == null)
throw new Error("Gen: an empty list of nodes must be nil, not null");
this.head = head;
this.tail = tail;
}
public Trees () {
head = null;
tail = null;
}
public final static Trees nil = new Trees();
public Trees ( Tree head ) {
this.head = head;
tail = nil;
}
public Tree head () {
if (tail == null)
throw new Error("Gen: tried to retrieve the head of an empty list of nodes");
return head;
}
public Trees tail () {
if (tail == null)
throw new Error("Gen: tried to retrieve the tail of an empty list of nodes");
return tail;
}
public boolean is_empty () {
return (tail == null);
}
/* number of nodes */
public int length () {
int n = 0;
for (Trees r = this; !r.is_empty(); r = r.tail)
n += 1;
return n;
}
/* put an Tree e at the beginning of the nodes */
public Trees cons ( Tree e ) {
return new Trees(e,this);
}
/* put an Tree e at the end of the nodes */
public Trees append ( Tree e ) {
if (is_empty())
return new Trees(e);
else {
Trees temp = new Trees(e,new Trees(e));
Trees res = temp;
for (Trees r = this; !r.is_empty(); r = r.tail) {
temp.tail = temp.tail.cons(r.head);
temp = temp.tail;
};
return res.tail;
}
}
/* append two lists of nodes */
public Trees append ( Trees s ) {
if (is_empty())
return s;
else if (s.is_empty())
return this;
else {
Trees temp = s.cons(s.head);
Trees res = temp;
for (Trees r = this; !r.is_empty(); r = r.tail)
{ temp.tail = temp.tail.cons(r.head);
temp = temp.tail;
}
return res.tail;
}
}
/* reverse the order of nodes */
public Trees reverse () {
Trees res = nil;
for (Trees r = this; !r.is_empty(); r = r.tail)
res = res.cons(r.head);
return res;
}
/* is e one of the nodes? */
public boolean member ( Tree e ) {
for (Trees r = this; !r.is_empty(); r = r.tail)
if (r.head.equals(e))
return true;
return false;
}
/* return the nth node */
public Tree nth ( int n ) {
Trees r = this;
for (int i = 0; !r.is_empty() && i < n; r = r.tail(), i++)
;
if (r.is_empty())
throw new Error("Gen: tried to retrieve a nonexistent nth element from a list of nodes");
else return r.head;
}
/* deep equality */
public boolean equals ( Trees s ) {
Trees n = this;
Trees m = s;
for(; n.tail != null && m.tail != null; n = n.tail, m = m.tail )
if (!n.head.equals(m.head))
return false;
return (m.tail == null) && (n.tail == null);
}
protected int size () {
int n = 1;
for (Trees r = this; !r.is_empty(); r = r.tail)
n += r.head.size()+1;
return n;
}
public Iterator<Tree> iterator () { return new TreeIterator(this); }
/* print the nodes */
public String toString () {
if (is_empty())
return "()";
String s = "(" + head;
for (Trees r = tail; !r.is_empty(); r = r.tail)
s = s + "," + r.head;
return s + ")";
}
/* pretty-print the nodes */
public String pretty ( int position ) {
if (is_empty() || (position+size() <= screen_size))
return toString();
String s = "(" + head.pretty(position+1);
for (Trees r=tail; !r.is_empty(); r=r.tail) {
s = s + ",\n";
for (int i=0; i<position+1; i++)
s = s + " ";
s = s + r.head.pretty(position+1);
};
return s + ")";
}
}