diff --git a/examples/user_types/TDDecoder.java b/examples/user_types/TDDecoder.java index 6bfdb3ca8f33b5af819472e65a229f4f177e3fd3..2f6caf5ac4054c7cba5beb817fd532e7fb8e8550 100644 --- a/examples/user_types/TDDecoder.java +++ b/examples/user_types/TDDecoder.java @@ -32,6 +32,8 @@ public class TDDecoder private DecoderChannel decoder; private TypeDefParser tdp; + private final ASTbuilder astBuilder; + private Program curAST; public TDDecoder(InputStream in) throws Exception @@ -45,6 +47,7 @@ public class TDDecoder intAndRef.register(decoder, this); doavoid.registerSampleRef(decoder); this.tdp = TypeDefParser.registerTypeDefParser(decoder); + this.astBuilder = new ASTbuilder(tdp); // TypeDef.register(decoder, this); // TypeBinding.register(decoder, this); @@ -78,8 +81,7 @@ public class TDDecoder public void onTypeDef(TypeDefParser.ParsedTypeDef d) { if(d.isSampleDef()){ System.out.println("onTypeDef (sample): "); - ASTbuilder v = new ASTbuilder(); - Program p = v.makeProgram((TypeDefParser.ParsedSampleDef) d); + Program p = astBuilder.makeProgram(d, curAST); try { //FileOutputStream f = new FileOutputStream("/tmp/foopp"+d.getName()+".txt"); //PrintStream out = new PrintStream(f); @@ -91,6 +93,7 @@ public class TDDecoder System.err.println("Exception: " + e); e.printStackTrace(); } + curAST = p; } //System.out.println(" "+d.getName()+";"); //for(byte b: d.getSignature()) { diff --git a/lib/java/se/lth/control/labcomm/ASTbuilder.java b/lib/java/se/lth/control/labcomm/ASTbuilder.java index 73bd171750c722c910a12549f535272eafc3b5a5..d16b15621bfab4335b96cca4084fb4a2a8c59383 100644 --- a/lib/java/se/lth/control/labcomm/ASTbuilder.java +++ b/lib/java/se/lth/control/labcomm/ASTbuilder.java @@ -41,38 +41,40 @@ import se.lth.control.labcomm2014.compiler.VariableSize; */ public class ASTbuilder implements TypeDefParser.ParsedSymbolVisitor { - private LinkedList<Type> typeStack; - private LinkedList<Field> fieldStack; + private LinkedList<Type> typeStack; + private LinkedList<Field> fieldStack; + private TypeDefParser tdp; + + public ASTbuilder(TypeDefParser tdp) { + this.typeStack = new LinkedList<Type>(); + this.fieldStack = new LinkedList<Field>(); + this.tdp = tdp; + } - public ASTbuilder() { - this.typeStack = new LinkedList<Type>(); - this.fieldStack = new LinkedList<Field>(); + private void assertStacksEmpty() throws RuntimeException { + if(!typeStack.isEmpty()) { + throw new RuntimeException("Error: type stack not empty"); } - - private void assertStacksEmpty() throws RuntimeException { - if(!typeStack.isEmpty()) { - throw new RuntimeException("Error: type stack not empty"); - } - if(!fieldStack.isEmpty()) { - throw new RuntimeException("Error: field stack not empty"); - } + if(!fieldStack.isEmpty()) { + throw new RuntimeException("Error: field stack not empty"); } + } - public void visit(TypeDefParser.TypeSymbol s){ - throw new Error("not implemented? needed?"); + public void visit(TypeDefParser.TypeSymbol s){ + throw new Error("not implemented? needed?"); - } - public void visit(TypeDefParser.SampleSymbol s){ - throw new Error("not implemented? needed?"); + } + public void visit(TypeDefParser.SampleSymbol s){ + throw new Error("not implemented? needed?"); - } - public void visit(TypeDefParser.NameSymbol s){ - throw new Error("not implemented? needed?"); - } + } + public void visit(TypeDefParser.NameSymbol s){ + throw new Error("not implemented? needed?"); + } - public void visit(TypeDefParser.PrimitiveType t){ - typeStack.push(new PrimType(t.getName(), t.getTag())); - } + public void visit(TypeDefParser.PrimitiveType t){ + typeStack.push(new PrimType(t.getName(), t.getTag())); + } // SampleRefs are currently represented as primitive types, // see comment in TypeDefParser @@ -80,98 +82,140 @@ public class ASTbuilder implements TypeDefParser.ParsedSymbolVisitor { // typeStack.push(new SampleRefType()); // } - public void visit(TypeDefParser.ParsedStructType t){ - if(t.isVoid()) { - typeStack.push(new VoidType()); - } else { - List<Field> tmpF = new List<Field>(); - for( TypeDefParser.ParsedField f : t.getFields()) { - f.accept(this); - tmpF.add(fieldStack.pop()); - } - typeStack.push(new StructType(tmpF)); + public void visit(TypeDefParser.ParsedStructType t){ + if(t.isVoid()) { + typeStack.push(new VoidType()); + } else { + List<Field> tmpF = new List<Field>(); + for( TypeDefParser.ParsedField f : t.getFields()) { + f.accept(this); + tmpF.add(fieldStack.pop()); } + typeStack.push(new StructType(tmpF)); } - public void visit(TypeDefParser.ParsedField t){ - t.getType().accept(this); - fieldStack.push(new Field(typeStack.pop(),t.getName())); - - } - public void visit(TypeDefParser.ArrayType t){ - boolean isFixed = true; - List<Exp> dim = new List<Exp>(); - for(int i : t.getIdx()) { - if(i == 0) { - dim.add(new VariableSize()); - isFixed = false; - } else { - dim.add(new IntegerLiteral(Integer.toString(i))); - } - } - t.getType().accept(this); - if(isFixed) { - typeStack.push(new FixedArrayType(typeStack.pop(), dim)); + } + public void visit(TypeDefParser.ParsedField t){ + t.getType().accept(this); + fieldStack.push(new Field(typeStack.pop(),t.getName())); + + } + public void visit(TypeDefParser.ArrayType t){ + boolean isFixed = true; + List<Exp> dim = new List<Exp>(); + for(int i : t.getIdx()) { + if(i == 0) { + dim.add(new VariableSize()); + isFixed = false; } else { - typeStack.push(new VariableArrayType(typeStack.pop(), dim)); + dim.add(new IntegerLiteral(Integer.toString(i))); } - } - public void visit(TypeDefParser.ParsedUserType t){ - typeStack.push(new UserType(t.getName())); + t.getType().accept(this); + if(isFixed) { + typeStack.push(new FixedArrayType(typeStack.pop(), dim)); + } else { + typeStack.push(new VariableArrayType(typeStack.pop(), dim)); } + + } + public void visit(TypeDefParser.ParsedUserType t){ + typeStack.push(new UserType(t.getName())); + } + + public Decl makeDecl(TypeDefParser.ParsedTypeDef d) { + d.getType().accept(this); + Decl result = new TypeDecl(typeStack.pop(), d.getName()); + return result; + } - public Decl makeDecl(TypeDefParser.ParsedTypeDef d) { - d.getType().accept(this); - Decl result = new TypeDecl(typeStack.pop(), d.getName()); - return result; + private Program createAndCheckProgram(List<Decl> ds) { + Program p = new Program(ds); + LinkedList errors = new LinkedList(); + p.errorCheck(errors); + if(errors.isEmpty()) { + return p; + } else { + // This should not happen + // get errors and throw exception + StringBuilder sb = new StringBuilder(); + for (Iterator iter = errors.iterator(); iter.hasNext(); ) { + String s = (String)iter.next(); + sb.append(s); + } + throw new RuntimeException("Internal error: parsed labcomm declaration has errors: "+sb.toString()); } + } - private Program createAndCheckProgram(List<Decl> ds) { - Program p = new Program(ds); - LinkedList errors = new LinkedList(); - p.errorCheck(errors); - if(errors.isEmpty()) { - return p; - } else { - // This should not happen - // get errors and throw exception - StringBuilder sb = new StringBuilder(); - for (Iterator iter = errors.iterator(); iter.hasNext(); ) { - String s = (String)iter.next(); - sb.append(s); - } - throw new RuntimeException("Internal error: parsed labcomm declaration has errors: "+sb.toString()); - } - } - - public Program makeProgram(TypeDefParser.ParsedTypeDef d) { - assertStacksEmpty(); - List<Decl> ds = new List<Decl>(); - - ds.add(makeDecl(d)); - assertStacksEmpty(); - return createAndCheckProgram(ds); - } + /** Create a labcomm AST for the ParsedTypeDef d. + * If d is a sampleDecl, include the typedefs it depends on. + */ + public Program makeProgram(TypeDefParser.ParsedTypeDef d) { + List<Decl> ds = new List<Decl>(); + return makeProgram(d, ds); + } - public Decl makeDecl(TypeDefParser.ParsedSampleDef d) { - d.getType().accept(this); - Decl result = new SampleDecl(typeStack.pop(), d.getName()); - return result; - } - public Program makeProgram(TypeDefParser.ParsedSampleDef d) { - assertStacksEmpty(); - List<Decl> ds = new List<Decl>(); + /** Create a labcomm AST for the ParsedTypeDef d, including + * all declarations from p. + * + * This copies the declarations in p, and creates a new AST. + * + * If d is a sampleDecl, include the typedefs it depends on. + */ + public Program makeProgram(TypeDefParser.ParsedTypeDef d, + Program p) { + if(p != null) { + return makeProgram(d, p.getDecls().fullCopy()); + } else { + return makeProgram(d); + } + } - Iterator<TypeDefParser.ParsedTypeDef> it = d.getDepIterator(); - while(it.hasNext()){ - ds.add(makeDecl(it.next())); - } - ds.add(makeDecl(d)); - assertStacksEmpty(); - return createAndCheckProgram(ds); - } + //TODO: The above method, adding to an arbitrary Program + // does not really allow "recreating the labcomm file" + // This method is a placeholder for + public Program makeProgram(TypeDefParser.ParsedTypeDef d, + TypeDefParser source) { + throw new Error("Not yet implemented"); } - + + private void tryAdd(Decl decl, List<Decl> ds){ + boolean exists = false; + + // Check if decl already exists in ds + // otherwise add it + + // Maybe add a Program.lookupDecl(String Name) + // to the NameAnalysis aspect instead of doing + // it here. + Iterator<Decl> it = ds.iterator(); + while(!exists && it.hasNext()) { + Decl inList = it.next(); + if(inList.getName().equals(decl.getName())){ + exists = true; + } + } + if(!exists) { + ds.add(decl); + } + } + + protected Program makeProgram(TypeDefParser.ParsedTypeDef d, + List<Decl> ds) { + assertStacksEmpty(); + + // add dependencies for sample decls + if(d.isSampleDef()) { + Iterator<TypeDefParser.ParsedTypeDef> it = d.getDepIterator(); + while(it.hasNext()){ + Decl decl = makeDecl(it.next()); + tryAdd(decl,ds); + } + } + ds.add(makeDecl(d)); + assertStacksEmpty(); + return createAndCheckProgram(ds); + } +} diff --git a/lib/java/se/lth/control/labcomm/TypeDefParser.java b/lib/java/se/lth/control/labcomm/TypeDefParser.java index a72e96510e6ee1544f42aa39c548b637172c1cbd..773ba32431a0c406229889e57436f8f1a869987e 100644 --- a/lib/java/se/lth/control/labcomm/TypeDefParser.java +++ b/lib/java/se/lth/control/labcomm/TypeDefParser.java @@ -420,6 +420,10 @@ public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler { return false; } + Iterator<ParsedTypeDef> getDepIterator() { + throw new Error("ParseTypeDef has no dependencies"); + } + void setType(ParsedType type) { this.type = type; }