Skip to content

Commit

Permalink
Tweaked file/class dependency ordering algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
thomashuston committed Dec 18, 2011
1 parent ee1d084 commit 1bb0b5f
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 63 deletions.
15 changes: 11 additions & 4 deletions src/pcp/Translator.java
Original file line number Diff line number Diff line change
Expand Up @@ -294,23 +294,27 @@ public void resolve(File file, JavaFile c) throws IOException, ParseException {
// Set the superclass
for (JavaClass cd : c.getClasses()) {
if (cd.hasParent()) {
boolean found = false;
String extCls = cd.getExtension().getType();
String ext = cd.getExtension().getPath();
String extpath;
// Check the current file
for (JavaClass cls : cd.getFile().getClasses()) {
if (cls.getName().equals(extCls)) {
cd.setParent(cls);
return;
found = true;
break;
}
}
if (found)
continue;
// If the superclass path is given explicitly, use that path
int index = ext.lastIndexOf("/");
if (-1 < index) {
extpath = classpath + ext;
if (null != JavaFile.getJavaFile(extpath)) {
cd.setParent(JavaFile.getJavaFile(extpath).getPublicClass());
return;
continue;
}
} else {
// Check the package
Expand All @@ -321,18 +325,21 @@ public void resolve(File file, JavaFile c) throws IOException, ParseException {
extpath = classpath + pkg.getPath() + "/" + ext;
if (null != JavaFile.getJavaFile(extpath)) {
cd.setParent(JavaFile.getJavaFile(extpath).getPublicClass());
return;
continue;
}
}
// Check the imports
for (JavaPackage i : imp) {
extpath = classpath + i.getPath();
if (null != JavaFile.getJavaFile(extpath)) {
cd.setParent(JavaFile.getJavaFile(extpath).getPublicClass());
return;
found = true;
break;
}
}
}
if (found)
continue;
runtime.errConsole().p("Superclass not found: ").p(ext).pln().flush();
}
}
Expand Down
12 changes: 8 additions & 4 deletions src/pcp/translator/JavaClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,8 @@ public Printer translateHeader(Printer out) {
con.translateHeaderDeclaration(out);
}
} else {
out.indent().p("static ").p(name).p(" ").p(name).pln("$void();");
out.indent().p("static ").p(name).p(" ").p(name).p("$void(");
out.p(name).pln(" __this = __rt::null());");
}

// Destructor
Expand Down Expand Up @@ -686,6 +687,7 @@ public Printer translate(Printer out) {
out.p(parent.getFile().getPackage().getNamespace()).p("::");
out.p("__").p(parent.getName()).pln("();");
}
out.pln();


// Initialize any static fields
Expand All @@ -706,13 +708,15 @@ public Printer translate(Printer out) {
}
// Otherwise create the default constructor
} else {
out.indent().p(name).p(" __").p(name).p("::").p(name).pln("$void() {").incr();
out.indent().p(name).p(" __this = new __").p(name).pln("();");
out.indent().p(name).p(" __").p(name).p("::").p(name).p("$void(");
out.p(name).pln(" __this) {").incr();
out.indent().pln("if (__rt::null() == __this)");
out.indentMore().p("__this = new __").p(name).pln("();");
if (null != parent) {
out.indent();
if (!parent.getFile().getPackage().getNamespace().equals(""))
out.p(parent.getFile().getPackage().getNamespace()).p("::");
out.p("__").p(parent.getName()).p("::__").p(parent.getName()).pln("$void(__this);");
out.p("__").p(parent.getName()).p("::").p(parent.getName()).pln("$void(__this);");
}
JavaClass temp = parent;
while (null != temp) {
Expand Down
1 change: 0 additions & 1 deletion src/pcp/translator/JavaConstructor.java
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,6 @@ public Printer translate(Printer out) {
out.p(sup.getFile().getPackage().getNamespace()).p("::");
out.p("__").p(sup.getName()).p("::").p(sup.getName()).pln("$void(__this);");
}

}

// Initialize class fields
Expand Down
40 changes: 29 additions & 11 deletions src/pcp/translator/JavaExpression.java
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,7 @@ public Printer translate(Printer out) {
if (isSuper)
cls = cls.getParent();
if (null == cls)
return out.p("java::lang::__Object::__Object$void(__this)");
return out.p("java::lang::Object::Object$void(__this)");
if (!cls.getFile().getPackage().getNamespace().equals(""))
out.p(cls.getFile().getPackage().getNamespace()).p("::");
out.p("__").p(cls.getName()).p("::").p(name).p("(");
Expand Down Expand Up @@ -2042,6 +2042,7 @@ private class PrimaryIdentifier extends JavaExpression {
private String name;
private JavaExpression parent;
private JavaPackage pkg;
private JavaClass scope;

/**
* Creates a new primary identifier.
Expand Down Expand Up @@ -2098,6 +2099,7 @@ public void determineType() {
if (parent.getStatement().getScope().getVariableScope("$" + name).hasName("JavaClass")
&& parent.getStatement().getScope().getVariableType("$" + name).isStatic()) {
isClassVar = true;
scope = (JavaClass)parent.getStatement().getScope().getVariableScope("$" + name);
}
return;

Expand All @@ -2116,6 +2118,12 @@ public void determineType() {
type.setStatic();
parent.setType(type);
return;
} else if (c.isInScope("$" + name) &&
c.getVariableType("$" + name).isStatic()) {
isClassVar = true;
scope = (JavaClass)c.getVariableScope("$" + name);
parent.setType(c.getVariableType("$" + name));
return;
}
}

Expand All @@ -2129,6 +2137,12 @@ public void determineType() {
type.setStatic();
parent.setType(type);
return;
} else if (f.getPublicClass().isInScope("$" + name) &&
f.getPublicClass().getVariableType("$" + name).isStatic()) {
isClassVar = true;
scope = (JavaClass)f.getPublicClass().getVariableScope("$" + name);
parent.setType(f.getPublicClass().getVariableType("$" + name));
return;
}
}

Expand All @@ -2143,6 +2157,12 @@ public void determineType() {
type.setStatic();
parent.setType(type);
return;
} else if (f.getPublicClass().isInScope("$" + name) &&
f.getPublicClass().getVariableType("$" + name).isStatic()) {
isClassVar = true;
scope = (JavaClass)f.getPublicClass().getVariableScope("$" + name);
parent.setType(f.getPublicClass().getVariableType("$" + name));
return;
}
}
}
Expand All @@ -2163,21 +2183,19 @@ public void determineType() {
public Printer translate(Printer out) {
// Now that we have all classes available, determine the type
determineType();

// If it's a static class variable, print out the class first
if (isClassVar) {
if (!scope.getFile().getPackage().getNamespace().equals(""))
out.p(scope.getFile().getPackage().getNamespace()).p("::");
return out.p("__").p(scope.getName()).p("::$").p(name);
}

// Check if it's a variable currently in scope
if (parent.getStatement().getScope().isInScope("$" + name)) {

// If it's a static class variable, print out the class first
if (isClassVar) {
JavaClass scope = (JavaClass)parent.getStatement().getScope().getVariableScope("$" + name);
if (!scope.getFile().getPackage().getNamespace().equals(""))
out.p(scope.getFile().getPackage().getNamespace()).p("::");
out.p("__").p(scope.getName()).p("::");

// Check if it's an instance variable
} else if (parent.getStatement().getScope().getVariableScope("$" + name).hasName("JavaClass")) {
if (parent.getStatement().getScope().getVariableScope("$" + name).hasName("JavaClass"))
out.p("__this->");
}
return out.p("$").p(name);

// If we can't locate the variable, it might be a class
Expand Down
25 changes: 25 additions & 0 deletions src/pcp/translator/JavaFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,30 @@ public boolean isMain() {

// ============================ Set Methods =======================

/**
* Orders classes in by dependencies.
*/
public void orderClasses() {
List<JavaClass> old = allClasses;
allClasses = new ArrayList<JavaClass>();
for (JavaClass cls : old) {
order(cls);
}
}

/**
* Recursively orders classes based on dependencies.
*
* @param cls The class to add to the list.
*/
private void order(JavaClass cls) {
if (allClasses.contains(cls))
return;
if (cls.hasParent())
order(cls.getParent());
allClasses.add(cls);
}

/**
* Marks this as the main file for the program.
*/
Expand Down Expand Up @@ -239,6 +263,7 @@ public void visitPackageDeclaration(GNode n) {
* @return The output stream.
*/
public Printer translate(Printer out) {
orderClasses();
for (JavaClass cls : allClasses) {
cls.translate(out).pln();
}
Expand Down
52 changes: 21 additions & 31 deletions src/pcp/translator/JavaPackage.java
Original file line number Diff line number Diff line change
Expand Up @@ -221,34 +221,26 @@ public void addFile(JavaFile file) {
* Orders the files based on dependencies.
*/
public void orderFiles() {
List<JavaFile> ordered = new ArrayList<JavaFile>();
for (JavaFile file : files) {
if (file.isMain())
main = file;
if (ordered.contains(file))
continue;
if (!file.getPublicClass().hasParent()) {
ordered.add(file);
continue;
}
JavaFile parent = file.getPublicClass().getParent().getFile();
if (null != parent.getPackage() && null != file.getPackage()) {
if (!parent.getPackage().equals(file.getPackage())) {
ordered.add(file);
} else {
if (!ordered.contains(parent))
ordered.add(parent);
ordered.add(file);
}
} else if (null != parent.getPackage() || null != file.getPackage()) {
ordered.add(file);
} else {
if (!ordered.contains(parent))
ordered.add(parent);
ordered.add(file);
}
List<JavaFile> old = files;
files = new ArrayList<JavaFile>();
for (JavaFile file : old) {
order(file);
}
files = ordered;
}

/**
* Recursively orders files based on dependencies.
*
* @param file The file to add to the list.
*/
private void order(JavaFile file) {
if (file.isMain())
main = file;
if (files.contains(file))
return;
if (file.getPublicClass().hasParent())
order(file.getPublicClass().getParent().getFile());
files.add(file);
}

// =========================== Other Methods ======================
Expand Down Expand Up @@ -360,10 +352,8 @@ public Printer translate(Printer out) {

// Print all the files in the package
for (JavaFile f : files) {
for (JavaClass cls : f.getClasses()) {
cls.translate(out);
out.pln();
}
f.translate(out);
out.pln();
}

// Close the namespace
Expand Down
63 changes: 63 additions & 0 deletions test/Magic.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
public class Magic {
public static final Magic STOPPER = new Expelliarmus();
public static final Magic SLASHER = new Sectumsempra();
public static final Magic TORTURER = new Crucio();

public static void show(String s) {
System.out.println(s);
}

public static void show(Magic m) {
show(m.getClass().getName());
}

public static Magic cast(Magic m) {
return m;
}

public Magic cast() {
return this;
}

public Magic counter(Magic m) {
return STOPPER;
}

public static void main(String[] args) {
show(STOPPER.counter(STOPPER));
show(STOPPER.counter(SLASHER));
show(SLASHER.counter(SLASHER));
show(TORTURER.counter(SLASHER));
show(new Sectumsempra().counter(SLASHER));
}
}

class Expelliarmus extends Magic { }

class DarkMagic extends Magic {
public static Magic cast(Magic m) {
return m instanceof DarkMagic ? m : SLASHER;
}

public Magic counter(Magic m) {
return cast(m);
}

public Magic counter(DarkMagic m) {
return TORTURER;
}
}

class Sectumsempra extends DarkMagic {
public Magic cast() {
return SLASHER;
}
}

class UnforgivableCurse extends DarkMagic { }

class Crucio extends UnforgivableCurse {
public Magic counter(Magic m) {
return TORTURER;
}
}
2 changes: 1 addition & 1 deletion test/finale/Final.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class Final {
public static void main(String[] args) {
System.out.println("There are " + args.length + " command-line arguments.");
for (int i = 0; i < args.length; i++) {
System.out.println(i + ": " + args[i]);
System.out.println((i + 1) + ": " + args[i]);
}
System.out.println();
Final f = new Final();
Expand Down
Loading

0 comments on commit 1bb0b5f

Please sign in to comment.