ljr/wcmtools/s2/danga/s2/NodeFormals.java

149 lines
3.7 KiB
Java
Executable File

package danga.s2;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Hashtable;
public class NodeFormals extends Node
{
public LinkedList listFormals = new LinkedList(); // NodeNamedType
public NodeFormals () { }
public NodeFormals (LinkedList formals) {
listFormals = formals;
}
public static Node parse (Tokenizer toker) throws Exception
{
NodeFormals n = new NodeFormals();
int count = 0;
n.requireToken(toker, TokenPunct.LPAREN);
while (toker.peek() != null && ! toker.peek().equals(TokenPunct.RPAREN)) {
if (count > 0) {
n.requireToken(toker, TokenPunct.COMMA);
}
n.skipWhite(toker);
NodeNamedType nf = (NodeNamedType) NodeNamedType.parse(toker);
n.listFormals.add(nf);
n.tokenlist.add(nf);
n.skipWhite(toker);
count++;
}
n.requireToken(toker, TokenPunct.RPAREN);
return n;
}
public void check (Layer l, Checker ck) throws Exception
{
Hashtable h = new Hashtable();
ListIterator li = listFormals.listIterator();
while (li.hasNext()) {
NodeNamedType nt = (NodeNamedType) li.next();
String name = nt.getName();
if (h.get(name) != null)
throw new Exception("Duplicate argument named '" + name + "' at "+
nt.getFilePos());
h.put(name, name);
Type t = nt.getType();
if (! ck.isValidType(t))
throw new Exception("Unknown type '" + t + "' at "+nt.getFilePos());
}
}
public void asS2 (Indenter o) {
if (listFormals.size() == 0) return; // no empty parens necessary in S2
o.write(toString());
}
public String toString () {
StringBuffer sb = new StringBuffer("(");
ListIterator li = listFormals.listIterator();
boolean first = true;
while (li.hasNext()) {
NodeNamedType nf = (NodeNamedType) li.next();
if (! first) {
sb.append(", ");
}
first = false;
sb.append(nf.toString());
}
sb.append(")");
return sb.toString();
}
// returns a ListIterator returning variations of this NodeFormal
// object using derived classes as well.
public static ListIterator variationIterator (NodeFormals nf, Checker ck)
{
LinkedList l = new LinkedList();
if (nf == null) {
l.add(new NodeFormals(new LinkedList()));
} else {
nf.getVariations(ck, l, new LinkedList(), 0);
}
return l.listIterator();
}
private void getVariations (Checker ck,
LinkedList vars,
LinkedList temp,
int col)
{
if (col == listFormals.size()) {
vars.add(new NodeFormals(temp));
return;
}
NodeNamedType nt = (NodeNamedType) listFormals.get(col);
Type t = nt.getType();
for (ListIterator li = t.subTypesIter(ck); li.hasNext(); ) {
t = (Type) li.next();
LinkedList newtemp = (LinkedList) temp.clone();
newtemp.add(new NodeNamedType(nt.getName(), t));
getVariations(ck, vars, newtemp, col+1);
}
}
public String typeList ()
{
StringBuffer sb = new StringBuffer(50);
if (listFormals.size() == 0) return sb.toString();
ListIterator li = listFormals.listIterator();
boolean first = true;
while (li.hasNext()) {
NodeNamedType nt = (NodeNamedType) li.next();
if (! first) sb.append(",");
first = false;
sb.append(nt.getType().toString());
}
return sb.toString();
}
// adds all these variables to the stmtblock's symbol table
public void populateScope (NodeStmtBlock nb)
{
if (listFormals.size() == 0) return;
ListIterator li = listFormals.listIterator();
while (li.hasNext()) {
NodeNamedType nt = (NodeNamedType) li.next();
nb.addLocalVar(nt.getName(), nt.getType());
}
}
public ListIterator iterator() {
return listFormals.listIterator();
}
};