import java.util.*;
import Jakarta.util.FixDosOutputStream;
import java.io.*;
// note: default action for lists is that lists of base and extension
// MUST have the same number of elements!!
public abstract class AstList {
public void compose( AstNode etree ) {
AstNode.override( "AstList.compose", this );
AstNode l, ll;
if ( arg[0]==null )
return;
for ( l = arg[0], ll = etree.arg[0]; l!=null;
l = l.right, ll = ll.right ) {
if ( l.arg[0] == null )
continue;
l.arg[0].compose( ll.arg[0] );
}
}
public void setSource( String s ) {
AstNode l;
if( _source == null )
_source = s;
if ( arg[0]==null )
return;
for ( l = arg[0]; l!=null; l = l.right ) {
if ( l.arg[0] == null )
continue;
l.arg[0].setSource( s );
}
}
// typeSort algorithm -- arrange nodes of a list in type
// order. Consider the following list, where letters denote
// types and numbers are instance numbers.
// A1 - B1 - B2 - A2 - C2 - B3 - A4 - C3
// The typeSort of this list is:
// A1 - A2 - A4 - B1 - B2 - B3 - C2 - C3
// That is, all instances of A are listed after the first A (i.e., A1)
// all instances of B are listed after the first B (i.e., B1)
// and all instances of C are listed after the first C (i.e., C2)
// typeSort is introduced to make the result of composing
// type declarations easier to read... This is a linear algorithm
public void typeSort( AstList listMaker ) {
AstCursor c = new AstCursor();
Hashtable h = new Hashtable();
AstCursor k;
String nodeType;
// since we got to this point by manipulating lists
// let's normalize the entire structure
this.normalize();
for ( c.FirstElement( this ); c.MoreElement(); c.NextElement() ) {
// Step 1: get name of node type
nodeType = c.node.getClass().getName();
// Step 2: now see if we've registered this type before.
// if so, all instances of this type line up after
// this instance
k = ( AstCursor ) h.get( nodeType );
if ( k == null ) {
// Step 2.1: remember first instance (henceforth "anchor")
// by cloning a copy of c and its pointers
h.put( nodeType, c.copy() );
}
else {
// Step 2.2: remove the current node, but remember it
AstNode n = c.node;
c.Delete(); // detach node and have cursor point to next
// element on list
// Step 2.3: create list of length 1 and place the
// previously detached node on this list
AstList l = listMaker.makeList( n );
// Step 2.4: add this list after the anchor point, and
// advance the anchor point
k.AddAfter( l );
k.NextElement();
}
}
}
public AstList makeList( AstNode n ) {
AstNode.override( "AstList.makeList", this );
return null;
}
}