Commit 71869dc0 authored by Sven Gestegård Robertz's avatar Sven Gestegård Robertz
Browse files

added incremental ASTbuilding for typedefs

parent f6f91400
......@@ -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()) {
......
......@@ -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);
}
}
......@@ -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;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment