diff --git a/spec/jastadd/Backend.jadd b/spec/jastadd/Backend.jadd index b7a4b101064bb652fcaf77bfeacecb9b777588fe..3506e24eff9307f7bb677217f43d216bbfe966c4 100644 --- a/spec/jastadd/Backend.jadd +++ b/spec/jastadd/Backend.jadd @@ -53,10 +53,14 @@ aspect BackendAbstractGrammar { } public String RelationComponent.generateAbstractGrammar() { - return "<_impl_" + getID() + ":" + ofTypeDecl() + ">"; + return "<" + getImplAttributeName() + ":" + ofTypeDecl() + ">"; } public String ManyRelationComponent.generateAbstractGrammar() { - return "<_impl_" + getID() + ":MySet<" + ofTypeDecl() + ">>"; + return "<" + getImplAttributeName() + ":ArrayList<" + ofTypeDecl() + ">>"; + } + + public String RelationComponent.getImplAttributeName() { + return "_impl_" + getID(); } } @@ -68,6 +72,7 @@ aspect BackendAspect { } public void Program.generateAspect(StringBuilder sb) { + sb.append("import java.util.*;\n"); sb.append("aspect RelAstAPI {\n"); for (TypeDecl td: getTypeDecls()) { if (td.needsConstructor()) { @@ -78,6 +83,11 @@ aspect BackendAspect { r.generateAPI(sb); } + sb.append(ind(1) + "public void ASTNode.assertNotNull(Object obj) {\n"); + sb.append(ind(2) + "if (obj == null) {\n"); + sb.append(ind(3) + "throw new NullPointerException();\n"); + sb.append(ind(2) + "}\n"); + sb.append(ind(1) + "}\n"); sb.append("}\n"); } @@ -105,12 +115,79 @@ aspect BackendAPI { } public abstract void Direction.generateAPI(StringBuilder sb); public void RightDirection.generateAPI(StringBuilder sb) { - + relation().getLeft().generateDirectedAPI(sb); } public void Bidirectional.generateAPI(StringBuilder sb) { } + public abstract void RelationComponent.generateDirectedAPI(StringBuilder sb); + public void OneRelationComponent.generateDirectedAPI(StringBuilder sb) { + generateDirectedZeroOneAPI(sb, false); + } + public void OptionalRelationComponent.generateDirectedAPI(StringBuilder sb) { + generateDirectedZeroOneAPI(sb, true); + + // has + sb.append(ind(1) + "public boolean " + toTypeDecl()); + sb.append(".has" + nameCapitalized() + "() {\n"); + sb.append(ind(2) + "return " + name() + "() != null;\n"); + sb.append(ind(1) + "}\n"); + } + public void RelationComponent.generateDirectedZeroOneAPI(StringBuilder sb, boolean optional) { + // Get + sb.append(ind(1) + "public " + ofTypeDecl() + " " + toTypeDecl()); + sb.append("." + name() + "() {\n"); + sb.append(ind(2) + "return get" + getImplAttributeName() + "();\n"); + sb.append(ind(1) + "}\n"); + + // Set + sb.append(ind(1) + "public void " + toTypeDecl()); + sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); + if (!optional) { + sb.append(ind(2) + "assertNotNull(o);\n"); + } + sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n"); + sb.append(ind(1) + "}\n"); + } + + public void ManyRelationComponent.generateDirectedAPI(StringBuilder sb) { + // Get + sb.append(ind(1) + "public Collection<" + ofTypeDecl() + "> " + toTypeDecl()); + sb.append("." + name() + "() {\n"); + sb.append(ind(2) + "return get" + getImplAttributeName() + "();\n"); + sb.append(ind(1) + "}\n"); + + // Add + sb.append(ind(1) + "public void " + toTypeDecl() + ".addTo"); + sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); + sb.append(ind(2) + "assertNotNull(o);\n"); + sb.append(ind(2) + "ArrayList<" + ofTypeDecl() + "> list = get" + getImplAttributeName() + "();\n"); + sb.append(ind(2) + "if (list == null) {\n"); + sb.append(ind(3) + "list = new ArrayList<>();\n"); + sb.append(ind(2) + "}\n"); + sb.append(ind(2) + "list.add(o);\n"); + sb.append(ind(2) + "set" + getImplAttributeName() + "(list);\n"); + sb.append(ind(1) + "}\n"); + + // Remove + sb.append(ind(1) + "public void " + toTypeDecl() + ".removeFrom"); + sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); + sb.append(ind(2) + "assertNotNull(o);\n"); + sb.append(ind(2) + "ArrayList<" + ofTypeDecl() + "> list = get" + getImplAttributeName() + "();\n"); + sb.append(ind(2) + "if (list != null && list.remove(o)) {\n"); + sb.append(ind(3) + "set" + getImplAttributeName() + "(list);\n"); + sb.append(ind(2) + "}\n"); + sb.append(ind(1) + "}\n"); + } + + inh Relation Direction.relation(); + eq Relation.getChild().relation() = this; + eq Program.getChild().relation() = null; + + public String RelationComponent.nameCapitalized() { + return name().substring(0,1).toUpperCase() + name().substring(1); + } } aspect PrettyPrint { diff --git a/src/java/org/jastadd/relast/compiler/Compiler.java b/src/java/org/jastadd/relast/compiler/Compiler.java index 0a0cf2a9f3280612b8b76f7b0ba62ec53b6e0b6b..27f50ac2bad23c1ce3417adc90c4bf1e6acc6d55 100644 --- a/src/java/org/jastadd/relast/compiler/Compiler.java +++ b/src/java/org/jastadd/relast/compiler/Compiler.java @@ -1,7 +1,6 @@ package org.jastadd.relast.compiler; import org.jastadd.relast.ast.*; - import static org.jastadd.relast.compiler.Utils.filterToList; import java.io.*; @@ -20,8 +19,7 @@ import beaver.Parser; public class Compiler { protected ArrayList<Option<?>> options; - protected FlagOption optionPrintDot; - protected FlagOption optionFlatPrettyPrint; + protected FlagOption optionWriteToFile; protected CommandLine commandLine; public Compiler(String args[]) throws CommandLineException { @@ -31,7 +29,12 @@ public class Compiler { commandLine = new CommandLine(options); commandLine.parse(args); - Program p = parseProgram(commandLine.getArguments().get(0)); + if (commandLine.getArguments().size() != 1) { + error("specify one input file"); + } + + String filename = commandLine.getArguments().get(0); + Program p = parseProgram(filename); if (!p.errors().isEmpty()) { System.out.println(p.dumpTree()); @@ -41,38 +44,33 @@ public class Compiler { } System.exit(1); } else { - System.out.println(p.generateAbstractGrammar()); - System.out.println(p.generateAspect()); - } -/* } else { - if (optionPrintDot.isSet()) { - System.out.println(p.genDot()); - } else if (optionFlatPrettyPrint.isSet()) { - System.out.println(p.flatPrettyPrint()); - } else { - System.out.println("# AST"); - System.out.println(p.dumpTree()); - - FlatState s = p.stoppingState(); - for (FlatDependency d: s.getDependencyList()) { - System.out.println(d.sourceDecl()); - System.out.println(d.sourceDecl().getAccess() + " " + d.targetDecl().getAccess()); - } - for (Node n: s.getNodes()) { - System.out.println(n + ", succ: " + n.succ()); - } - System.out.println(s.startingNodes()); - System.out.println(s.endingNodes()); - System.out.println("# Transitive reduction"); - System.out.println(p.startingState().transitiveReduction()); + if (optionWriteToFile.isSet()) { + File file = new File(filename); + String absPath = file.getAbsolutePath(); + String absPathExclExt = absPath.substring(0, absPath.lastIndexOf('.')); + writeToFile(absPathExclExt + "Gen.ast", p.generateAbstractGrammar()); + writeToFile(absPathExclExt + "Gen.jadd", p.generateAspect()); } - }*/ + else { + System.out.println(p.generateAbstractGrammar()); + System.out.println(p.generateAspect()); + } + } } + protected void writeToFile(String filename, String str) { + try { + PrintWriter writer = new PrintWriter(filename, "UTF-8"); + writer.print(str); + writer.close(); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + } protected void addOptions() { - optionPrintDot = addOption(new FlagOption("dot", "print DOT format")); - optionFlatPrettyPrint = addOption(new FlagOption("flat", "flat pretty print")); + optionWriteToFile = addOption(new FlagOption("file", "write output to file")); } protected <OptionType extends Option<?>> OptionType addOption(OptionType option) { @@ -98,8 +96,7 @@ public class Compiler { try { return (Program) parser.parse(scanner); } catch (IOException e) { - System.err.println(e.getMessage()); - System.exit(1); + error(e.getMessage()); } catch (Parser.Exception e) { System.err.println("Parse error in file " + file); System.err.println(e.getMessage()); @@ -112,6 +109,11 @@ public class Compiler { return null; } + protected void error(String message) { + System.err.println("Error: " + message); + System.exit(1); + } + private void showUsageAndExit() { //System.out.println("Usage: java -jar bloqqi-compiler.jar [--option1] [--option2=value] ... <filename1> [filename2] [filename3] ..."); //System.exit(1);