repetition.beh.html
Program{
(@ Dictionary repdict; @)
private void convertRepetition()via RepetitionClass bypassing-> *, nonempty, *to{ PlainSyntax, PrintIndent, PrintUnindent, PrintSkip, PrintSpace, ClassName }{
(@
Hashtable repdict = new Hashtable();
ClassName classname;
String container, linknode, linknodename;
boolean inRepeatedPart;
@)
before ClassDef (@
classname = host.get_classname();
container = null;
@)
before RepetitionClass (@
container = "= ";
linknodename = RepetitionClass.makeLinknodeName(classname);
@)
before Syntax (@
if (inRepeatedPart)
linknode += host + " ";
else
container += host + " ";
@)
before RepeatedPart (@
String first = "<first> " + linknodename;
if (host.get_nonempty() == null) {
// The repetition is possibly empty; make the link node optional.
first = "[ " + first + " ] ";
}
container += first;
inRepeatedPart = true;
linknode = "[ ";
LocalLookahead l = host.get_locallookahead();
if (l != null) linknode += l + " ";
@)
before ClassName (@
repdict.put(classname, host);
linknode = "= <it> " + host + " " + linknode
+ "<next> " + linknodename + " ";
@)
after RepeatedPart (@
linknode += "].";
inRepeatedPart = false;
@)
after RepetitionClass (@
container += ".";
@)
after ClassDef (@
if (container != null) {
// Replace the repetition class with the new container class.
host.set_classparts(ConstructionClass.parse(container));
// Add the class definition for the new link node class.
ClassDef linknodedef = host.deepCopy();
linknodedef.set_paramclassname(ParamClassName.parse(linknodename));
linknodedef.set_classparts(ConstructionClass.parse(linknode));
Program.prog.addClassDef(linknodedef);
}
@)
after Program (@ host.repdict = repdict; @)
}
}
RepetitionClass{
static String makeLinknodeName(ClassName classname)(@
return "Nonempty_" + classname;
@)
}
ClassName{
boolean isOrWasRepetitionClass()(@
ClassDef def;
return wasRepetitionClass()
|| ((def = Program.prog.findClassDef(this)) != null
&& def.isRepetitionClass());
@)
boolean wasRepetitionClass()(@
return Program.prog.repdict.get(this) != null;
@)
}
Program{
public void addEnumerationStuff()=allClassDefs{
before ClassDef (@
ClassName cn = host.get_classname();
if (!cn.isOrWasRepetitionClass()) return;
// if we get to here, host is (was) a repetition class.
// add some methods
ClassName ecn = (ClassName) Program.prog.repdict.get(cn);
String ln = RepetitionClass.makeLinknodeName(cn);
host.addBehavior(ClassMethods.parse(
"{"+Text.begin+"\n"
+" private " + ln + " tail;\n"
+" public void addElement(" + ecn + " e) { \n"
+" checktail(); \n"
+" if (tail == null) {\n"
+" first = new " + ln + "(e,null); tail = first;\n"
+" } else {\n"
+" tail.set_next(new " + ln + "(e,null)); tail = tail.get_next();\n"
+" }\n"
+" }\n\n"
+" public void push(" + ecn + " e) { first = new " + ln + "(e,first); }\n\n"
+" public java.util.Enumeration elements() { return new "+cn+"(first); } \n\n"
+" public int size() {\n"
+" int i= 0;\n"
+" for (java.util.Enumeration e=elements(); e.hasMoreElements(); i++)\n"
+" e.nextElement();\n"
+" return i;\n"
+" }\n"
+" public boolean isEmpty() { return (first == null); }\n\n"
+" public boolean hasMoreElements() { return (first != null); }\n\n"
+" public Object nextElement() {\n"
+" " + ecn + " car = first.get_it();\n"
+" first = first.get_next();\n"
+" return (Object) car;\n"
+" }\n\n"
+" private void checktail() {\n"
+" if (tail == null && first != null) {\n"
+" tail = first;\n"
+" while (tail.get_next() != null) tail = tail.get_next();\n"
+" }\n"
+" }\n"
+" public boolean contains("+ecn+" e) {\n"
+" java.util.Enumeration en = this.elements();\n"
+" while (en.hasMoreElements())\n"
+" if (e.equals(("+ecn+") en.nextElement())) return true;\n"
+" return false;\n"
+" }\n"
+Text.end+"}"));
host.addInterface(Interface.parse("java.util.Enumeration."));
@)
}
}
ClassDef{
void addInterface(Interface i)to Interface_Commalist{
before ClassParents (@
if (host.get_interfaces() == null)
host.set_interfaces(new Interface_Commalist());
@)
before Interface_Commalist (@
host.addElement(i);
@)
}
}