Files
exercise06/MicroJava Tests/tests/ssw/mj/test/support/SymTabDumper.java
2025-11-18 17:31:44 +01:00

120 lines
3.4 KiB
Java

package ssw.mj.test.support;
import ssw.mj.impl.Tab;
import ssw.mj.symtab.Obj;
import ssw.mj.symtab.Scope;
import ssw.mj.symtab.Struct;
import java.util.Collection;
public class SymTabDumper {
public static String dump(Tab tab) {
StringBuilder sb = new StringBuilder();
if (tab.curScope != null) {
dump(tab.curScope, sb);
}
return sb.toString();
}
private static void dump(Scope scope, StringBuilder sb) {
sb.append("-- begin scope (").append(scope.nVars()).append(" variables) --\n");
if (!scope.locals().isEmpty()) {
dump(scope.locals().values(), sb, "");
}
if (scope.outer() != null) {
sb.append("\n");
dump(scope.outer(), sb);
}
}
private static void dump(Collection<Obj> objects, StringBuilder sb, String indent) {
for (Obj obj : objects) {
dump(obj, sb, indent);
}
}
private static void dump(Obj obj, StringBuilder sb, String indent) {
sb.append(indent);
switch (obj.kind) {
case Con -> dumpCon(obj, sb, indent);
case Var -> dumpVar(obj, sb, indent);
case Type -> dumpType(obj, sb, indent);
case Meth -> dumpMethod(obj, sb, indent);
case Prog -> dumpProgram(obj, sb);
}
if (obj.locals != null) {
sb.append("\n");
dump(obj.locals.values(), sb, indent + " ");
}
sb.append("\n");
}
private static void dumpCon(Obj obj, StringBuilder sb, String indent) {
sb.append("Constant: ");
if (obj.type != null) {
dump(obj.type, sb, indent, false);
}
sb.append(" ").append(obj.name).append(" = ");
if (obj.type == Tab.charType) {
sb.append("'").append((char) obj.val).append("'");
} else {
sb.append(obj.val);
}
}
private static void dumpVar(Obj obj, StringBuilder sb, String indent) {
if (obj.level == 0) {
sb.append("Global Variable ");
} else {
sb.append("Local Variable ");
}
sb.append(obj.adr).append(": ");
if (obj.type != null) {
dump(obj.type, sb, indent, false);
}
sb.append(" ").append(obj.name);
}
private static void dumpType(Obj type, StringBuilder sb, String indent) {
sb.append("Type ").append(type.name).append(": ");
if (type.type != null) {
dump(type.type, sb, indent + " ", true);
}
}
private static void dumpMethod(Obj meth, StringBuilder sb, String indent) {
sb.append("Method: ");
if (meth.type != null) {
dump(meth.type, sb, indent, false);
}
sb.append(" ").append(meth.name).append(" (").append(meth.locals.size()).append(" locals, ").append(meth.nPars).append(" parameters").append(")");
}
private static void dumpProgram(Obj obj, StringBuilder sb) {
sb.append("Program ").append(obj.name).append(":");
}
private static void dump(Struct struct, StringBuilder sb, String indent, boolean dumpFields) {
switch (struct.kind) {
case None -> sb.append("void");
case Int -> sb.append("int");
case Char -> sb.append("char");
case Arr -> {
if (struct.elemType != null) {
dump(struct.elemType, sb, indent, dumpFields);
}
sb.append("[]");
}
case Class -> {
sb.append("class (").append(struct.nrFields()).append(" fields)");
if (dumpFields && struct.fields != null) {
sb.append("\n");
dump(struct.fields.values(), sb, indent);
}
}
}
}
}