-
Sven Gestegård Robertz authored
TypeDefParser/ASTbuilder
Sven Gestegård Robertz authoredTypeDefParser/ASTbuilder
ASTbuilder.java 6.15 KiB
package se.lth.control.labcomm2014;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.EOFException;
import se.lth.control.labcomm2014.compiler.LabComm;
import se.lth.control.labcomm2014.compiler.LabCommParser;
import se.lth.control.labcomm2014.compiler.List;
import se.lth.control.labcomm2014.compiler.Specification;
import se.lth.control.labcomm2014.compiler.Decl;
import se.lth.control.labcomm2014.compiler.TypeDecl;
import se.lth.control.labcomm2014.compiler.SampleDecl;
import se.lth.control.labcomm2014.compiler.TypeInstance;
import se.lth.control.labcomm2014.compiler.DataType;
import se.lth.control.labcomm2014.compiler.VoidType;
import se.lth.control.labcomm2014.compiler.PrimType;
import se.lth.control.labcomm2014.compiler.UserType;
import se.lth.control.labcomm2014.compiler.StructType;
import se.lth.control.labcomm2014.compiler.Field;
import se.lth.control.labcomm2014.compiler.ArrayType;
import se.lth.control.labcomm2014.compiler.VariableArrayType;
import se.lth.control.labcomm2014.compiler.FixedArrayType;
import se.lth.control.labcomm2014.compiler.Dim;
import se.lth.control.labcomm2014.compiler.Exp;
import se.lth.control.labcomm2014.compiler.IntegerLiteral;
import se.lth.control.labcomm2014.compiler.VariableSize;
/** A class for building a JastAdd AST from the parsed types
* created by a TypeDefParser. This class depends on the LabComm compiler.
*/
public class ASTbuilder implements SignatureSymbolVisitor {
private LinkedList<DataType> typeStack;
private LinkedList<Field> fieldStack;
public ASTbuilder() {
this.typeStack = new LinkedList<DataType>();
this.fieldStack = new LinkedList<Field>();
}
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");
}
}
public void visit(TypeSymbol s){
throw new Error("not implemented? needed?");
}
public void visit(SampleSymbol s){
throw new Error("not implemented? needed?");
}
public void visit(NameSymbol s){
throw new Error("not implemented? needed?");
}
public void visit(SigPrimitiveType t){
typeStack.push(new PrimType(t.getName(), t.getTag()));
}
// SampleRefs are currently represented as primitive types,
// see comment in TypeDefParser
// public void visit(TypeDefParser.SampleRefType t){
// typeStack.push(new SampleRefType());
// }
public void visit(SigStructType t){
if(t.isVoid()) {
typeStack.push(new VoidType());
} else {
List<Field> tmpF = new List<Field>();
for( SigField f : t.getFields()) {
f.accept(this);
tmpF.add(fieldStack.pop());
}
typeStack.push(new StructType(tmpF));
}
}
public void visit(SigField t){
t.getType().accept(this);
fieldStack.push(new Field(new TypeInstance(typeStack.pop(),t.getName())));
}
public void visit(SigArrayType 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(), new Dim(dim)));
} else {
typeStack.push(new VariableArrayType(typeStack.pop(), new Dim(dim)));
}
}
public void visit(SigUserType t){
typeStack.push(new UserType(t.getName()));
}
public Decl makeDecl(SigTypeDef d) {
d.getType().accept(this);
Decl result = new TypeDecl(new TypeInstance(typeStack.pop(), d.getName()));
return result;
}
private Specification createAndCheckSpecification(List<Decl> ds) {
Specification p = new Specification(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 Specification makeSpecification(SigTypeDef d) {
assertStacksEmpty();
List<Decl> ds = new List<Decl>();
ds.add(makeDecl(d));
assertStacksEmpty();
return createAndCheckSpecification(ds);
}
public Decl makeDecl(SigSampleDef d) {
d.getType().accept(this);
Decl result = new SampleDecl(new TypeInstance(typeStack.pop(), d.getName()));
return result;
}
private void addAllDeps(List<Decl> ds, SigTypeDef d) {
Iterator<SigTypeDef> it = d.getDepIterator();
while(it.hasNext()){
SigTypeDef dd = it.next();
addAllDeps(ds,dd);
ds.add(makeDecl(dd));
}
}
public Specification makeSpecification(ParsedSampleDef d) {
assertStacksEmpty();
List<Decl> ds = new List<Decl>();
addAllDeps(ds, d);
ds.add(makeDecl(d));
assertStacksEmpty();
return createAndCheckSpecification(ds);
}
}