Homework 1

This commit is contained in:
Carlos Galindo 2020-01-15 22:18:07 +01:00
commit 12f678a924
Signed by: kauron
GPG key ID: 83E68706DEE119A3
43 changed files with 3703 additions and 0 deletions

121
src/cd/util/FileUtil.java Normal file
View file

@ -0,0 +1,121 @@
package cd.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
public class FileUtil {
public static String readAll(Reader ubReader) throws IOException {
try (BufferedReader bReader = new BufferedReader(ubReader)) {
StringBuilder sb = new StringBuilder();
while (true) {
int ch = bReader.read();
if (ch == -1)
break;
sb.append((char) ch);
}
return sb.toString();
}
}
public static String read(File file) throws IOException {
return readAll(new FileReader(file));
}
public static void write(File file, String text) throws IOException {
try (FileWriter writer = new FileWriter(file)) {
writer.write(text);
}
}
public static String runCommand(File dir, String[] command,
String[] substs, String input, boolean detectError)
throws IOException {
// Substitute the substitution strings $0, $1, etc
String newCommand[] = new String[command.length];
for (int i = 0; i < command.length; i++) {
String newItem = command[i];
for (int j = 0; j < substs.length; j++)
newItem = newItem.replace("$" + j, substs[j]);
newCommand[i] = newItem;
}
// Run the command in the specified directory
ProcessBuilder pb = new ProcessBuilder(newCommand);
pb.directory(dir);
pb.redirectErrorStream(true);
final Process p = pb.start();
if (input != null && !input.equals("")) {
try (OutputStreamWriter osw = new OutputStreamWriter(p.getOutputStream())) {
osw.write(input);
}
}
try {
final StringBuffer result = new StringBuffer();
// thread to read stdout from child so that p.waitFor() is interruptible
// by JUnit's timeout mechanism. Otherwise it would block in readAll()
Thread t = new Thread () {
public void run() {
try {
result.append(readAll(new InputStreamReader(p.getInputStream())));
} catch (IOException e) {
}
}
};
t.start();
if (detectError) {
int err = p.waitFor();
// hack: same as ReferenceServer returns when
// a dynamic error occurs running the interpreter
if (err != 0)
return "Error: " + err + "\n";
}
t.join();
return result.toString();
} catch (InterruptedException e) {
return "Error: execution of " + command[0] + " got interrupted (probably timed out)\n";
} finally {
// in case child is still running, destroy
p.destroy();
}
}
/**
* Finds all .javali under directory {@code testDir}, adding File objects
* into {@code result} for each one.
*/
public static void findJavaliFiles(File testDir, List<Object[]> result) {
for (File testFile : testDir.listFiles()) {
if (testFile.getName().endsWith(".javali"))
result.add(new Object[] { testFile });
else if (testFile.isDirectory())
findJavaliFiles(testFile, result);
}
}
/** Finds all .javali under directory {@code testDir} and returns them. */
public static List<File> findJavaliFiles(File testDir) {
List<File> result = new ArrayList<File>();
for (File testFile : testDir.listFiles()) {
if (testFile.getName().endsWith(".javali"))
result.add(testFile);
else if (testFile.isDirectory())
result.addAll(findJavaliFiles(testFile));
}
return result;
}
}

53
src/cd/util/Pair.java Normal file
View file

@ -0,0 +1,53 @@
package cd.util;
import java.util.ArrayList;
import java.util.List;
/** Simple class for joining two objects of the same type */
public class Pair<T> {
public T a;
public T b;
public Pair(T a, T b) {
this.a = a;
this.b = b;
}
public static <T> List<Pair<T>> zip(List<T> listA, List<T> listB) {
List<Pair<T>> res = new ArrayList<Pair<T>>();
for (int i = 0; i < Math.min(listA.size(), listB.size()); i++) {
res.add(new Pair<T>(listA.get(i), listB.get(i)));
}
return res;
}
public static <T> List<T> unzipA(List<Pair<T>> list) {
List<T> res = new ArrayList<T>();
for (Pair<T> p : list)
res.add(p.a);
return res;
}
public static <T> List<T> unzipB(List<Pair<T>> list) {
List<T> res = new ArrayList<T>();
for (Pair<T> p : list)
res.add(p.b);
return res;
}
public static String join(
List<Pair<?>> pairs,
String itemSep,
String pairSep) {
StringBuilder sb = new StringBuilder();
boolean first = true;
for (Pair<?> pair : pairs) {
if (!first) sb.append(pairSep);
sb.append(pair.a);
sb.append(itemSep);
sb.append(pair.b);
first = false;
}
return sb.toString();
}
}

16
src/cd/util/Tuple.java Normal file
View file

@ -0,0 +1,16 @@
package cd.util;
/** Simple class for joining two objects of different type */
public class Tuple<A,B> {
public A a;
public B b;
public Tuple(A a, B b) {
this.a = a;
this.b = b;
}
public String toString() {
return "(" + a.toString() + ", " + b.toString() + ")";
}
}

View file

@ -0,0 +1,125 @@
package cd.util.debug;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import cd.ir.Ast;
import cd.ir.AstVisitor;
import cd.util.Pair;
public class AstDump {
public static String toString(Ast ast) {
return toString(ast, "");
}
public static String toString(List<? extends Ast> astRoots) {
StringBuilder sb = new StringBuilder();
for (Ast a : astRoots) {
sb.append(toString(a));
}
return sb.toString();
}
public static String toString(Ast ast, String indent) {
AstDump ad = new AstDump();
ad.dump(ast, indent);
return ad.sb.toString();
}
public static String toStringFlat(Ast ast) {
AstDump ad = new AstDump();
ad.dumpFlat(ast);
return ad.sb.toString();
}
private StringBuilder sb = new StringBuilder();
private Visitor vis = new Visitor();
protected void dump(Ast ast, String indent) {
// print out the overall class structure
sb.append(indent);
String nodeName = ast.getClass().getSimpleName();
List<Pair<?>> flds = vis.visit(ast, null);
sb.append(String.format("%s (%s)\n",
nodeName,
Pair.join(flds, ": ", ", ")));
// print out any children
String newIndent = indent + "| ";
for (Ast child : ast.children()) {
dump(child, newIndent);
}
}
protected void dumpFlat(Ast ast) {
String nodeName = ast.getClass().getSimpleName();
List<Pair<?>> flds = vis.visit(ast, null);
sb.append(String.format("%s(%s)[",
nodeName,
Pair.join(flds, ":", ",")));
// print out any children
for (int child = 0; child < ast.children().size(); child++) {
dumpFlat(ast.children().get(child));
if (child < ast.children().size() - 1)
sb.append(",");
}
sb.append("]");
}
protected class Visitor extends AstVisitor<List<Pair<?>>, Void> {
@Override
protected List<Pair<?>> dflt(Ast ast, Void arg) {
ArrayList<Pair<?>> res = new ArrayList<Pair<?>>();
// Get the list of fields and sort them by name:
java.lang.Class<? extends Ast> rclass = ast.getClass();
List<java.lang.reflect.Field> rflds =
Arrays.asList(rclass.getFields());
Collections.sort(rflds, new Comparator<java.lang.reflect.Field> () {
public int compare(Field o1, Field o2) {
return o1.getName().compareTo(o2.getName());
}
});
// Create pairs for each one that is not of type Ast:
for (java.lang.reflect.Field rfld : rflds) {
rfld.setAccessible(true);
// ignore various weird fields that show up from
// time to time:
if (rfld.getName().startsWith("$"))
continue;
// ignore fields of AST type, and rwChildren (they should be
// uncovered using the normal tree walk)
if (rfld.getType().isAssignableFrom(Ast.class))
continue;
if (rfld.getName().equals("rwChildren"))
continue;
// ignore NULL fields, but add others to our list of pairs
try {
Object value = rfld.get(ast);
if (value != null)
res.add(new Pair<Object>(rfld.getName(), value));
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
return res;
}
}
}

View file

@ -0,0 +1,160 @@
package cd.util.debug;
import cd.ir.Ast;
import cd.ir.Ast.Assign;
import cd.ir.Ast.BinaryOp;
import cd.ir.Ast.BooleanConst;
import cd.ir.Ast.BuiltInRead;
import cd.ir.Ast.BuiltInWrite;
import cd.ir.Ast.BuiltInWriteln;
import cd.ir.Ast.Cast;
import cd.ir.Ast.ClassDecl;
import cd.ir.Ast.Field;
import cd.ir.Ast.IfElse;
import cd.ir.Ast.Index;
import cd.ir.Ast.IntConst;
import cd.ir.Ast.MethodDecl;
import cd.ir.Ast.NewArray;
import cd.ir.Ast.NewObject;
import cd.ir.Ast.Nop;
import cd.ir.Ast.NullConst;
import cd.ir.Ast.Seq;
import cd.ir.Ast.ThisRef;
import cd.ir.Ast.UnaryOp;
import cd.ir.Ast.Var;
import cd.ir.Ast.VarDecl;
import cd.ir.Ast.WhileLoop;
import cd.ir.AstVisitor;
public class AstOneLine {
public static String toString(Ast ast) {
return new Visitor().visit(ast, null);
}
protected static class Visitor extends AstVisitor<String, Void> {
public String str(Ast ast) {
return ast.accept(this, null);
}
@Override
public String assign(Assign ast, Void arg) {
return String.format("%s = %s", str(ast.left()), str(ast.right()));
}
@Override
public String binaryOp(BinaryOp ast, Void arg) {
return String.format("(%s %s %s)",
str(ast.left()), ast.operator.repr, str(ast.right()));
}
@Override
public String booleanConst(BooleanConst ast, Void arg) {
return Boolean.toString(ast.value);
}
@Override
public String builtInRead(BuiltInRead ast, Void arg) {
return String.format("read()");
}
@Override
public String builtInWrite(BuiltInWrite ast, Void arg) {
return String.format("write(%s)", str(ast.arg()));
}
@Override
public String builtInWriteln(BuiltInWriteln ast, Void arg) {
return String.format("writeln()");
}
@Override
public String cast(Cast ast, Void arg) {
return String.format("(%s)(%s)", ast.typeName, str(ast.arg()));
}
@Override
public String classDecl(ClassDecl ast, Void arg) {
return String.format("class %s {...}", ast.name);
}
@Override
public String field(Field ast, Void arg) {
return String.format("%s.%s", str(ast.arg()), ast.fieldName);
}
@Override
public String ifElse(IfElse ast, Void arg) {
return String.format("if (%s) {...} else {...}", str(ast.condition()));
}
@Override
public String index(Index ast, Void arg) {
return String.format("%s[%s]", str(ast.left()), str(ast.right()));
}
@Override
public String intConst(IntConst ast, Void arg) {
return Integer.toString(ast.value);
}
@Override
public String methodDecl(MethodDecl ast, Void arg) {
return String.format("%s %s(...) {...}", ast.returnType, ast.name);
}
@Override
public String newArray(NewArray ast, Void arg) {
return String.format("new %s[%s]", ast.typeName, str(ast.arg()));
}
@Override
public String newObject(NewObject ast, Void arg) {
return String.format("new %s()", ast.typeName);
}
@Override
public String nop(Nop ast, Void arg) {
return "nop";
}
@Override
public String nullConst(NullConst ast, Void arg) {
return "null";
}
@Override
public String seq(Seq ast, Void arg) {
return "(...)";
}
@Override
public String thisRef(ThisRef ast, Void arg) {
return "this";
}
@Override
public String unaryOp(UnaryOp ast, Void arg) {
return String.format("%s(%s)", ast.operator.repr, str(ast.arg()));
}
@Override
public String var(Var ast, Void arg) {
{
return ast.name;
}
}
@Override
public String varDecl(VarDecl ast, Void arg) {
return String.format("%s %s", ast.type, ast.name);
}
@Override
public String whileLoop(WhileLoop ast, Void arg) {
return String.format("while (%s) {...}", str(ast.condition()));
}
}
}