slcom/slangc/model/SourceModel.sauce

125 lines
3.6 KiB
Plaintext

package slangc.model;
import slang.data.List;
import slangc.parser.Branch;
import slangc.parser.Node;
import slangc.parser.NodeType;
import slangc.parser.Token;
public class SourceModel {
private PackageModel pkg;
private String filename;
private Branch parsed;
private boolean included;
private CombinedImportModel imports = null;
public SourceModel(PackageModel packageModel, String filename, Branch parsed, boolean included) {
this.pkg = packageModel;
this.filename = filename;
this.parsed = parsed;
this.included = included;
}
public PackageModel getPackage() {
return pkg;
}
public String getFilename() {
return filename;
}
public Branch getParsed() {
return parsed;
}
public Branch getImportsBranch() {
return (Branch) parsed.getSubnode(1);
}
public Branch getTypesBranch() {
return (Branch) parsed.getSubnode(2);
}
public ImportModel parseImport(Branch b) {
Node pkgOrTyp = b.getSubnode(1);
if (pkgOrTyp instanceof Branch && pkgOrTyp.getNodeType() == NodeType.IMPORTED_PACKAGE) {
return parseImportedPackage((Branch) pkgOrTyp);
} else if (pkgOrTyp instanceof Branch && pkgOrTyp.getNodeType() == NodeType.IMPORTED_TYPE) {
return parseImportedType((Branch) pkgOrTyp);
} else {
throw new Error("INTERNAL ERROR/TODO: Bad import declaration in parse tree");
}
}
private String nameStr(Node n) {
if (n instanceof Branch && ((Branch) n).countSubnodes() == 1 /*n.getNodeType() == NodeType.NAME*/) {
return nameStr(((Branch)n).getSubnode(0));
} else if (n instanceof Token) {
return ((Token)n).getSnippet().getSource();
} else {
throw new Error("INTERNAL ERROR/TODO: Name string for " + n.getNodeType());
}
}
public ImportModel parseImportedType(Branch b) {
String typnam = nameStr(b.getSubnode(b.countSubnodes() - 1));
String pkgnam = "";
for (int i = 0; i < b.countSubnodes() - 2; i++) {
pkgnam += nameStr(b.getSubnode(i));
}
//System.err.println("IMPORTING " + pkgnam + " . " + typnam);
return new TypeImportModel(pkg.getSystem(), b, pkgnam, typnam);
}
public ImportModel parseImportedPackage(Branch b) {
Branch pkgpart = (Branch) b.getSubnode(0);
String pkgnam = "";
for (int i = 0; i < pkgpart.countSubnodes(); i++) {
pkgnam += nameStr(pkgpart.getSubnode(i));
}
//System.err.println("IMPORTING " + pkgnam + " (.*)");
return new PackageImportModel(pkg.getSystem(), false, pkgnam);
}
public CombinedImportModel parseImports(boolean includeGlobals) {
List<ImportModel> models = new List<ImportModel>();
if (includeGlobals) {
models.append(getPackage().getSystem().getGlobalImports());
}
Branch b = getImportsBranch();
for (int i = 0; i < b.countSubnodes(); i++) {
Node n = b.getSubnode(i);
if (n instanceof Branch && n.getNodeType() == NodeType.IMPORT_DECLARATION) {
models.append(parseImport((Branch) n));
} else {
throw new Error("INTERNAL ERROR/TODO: Bad import declaration in parse tree");
}
//System.out.println("> GOT IMPORT " + b.getSubnode(i).getNodeType());
}
ImportModel[] modelsArray = models.arrayCopy();
return new CombinedImportModel(getPackage().getSystem(), false, modelsArray);
}
public CombinedImportModel getImports() {
if (imports == null) {
imports = parseImports(true);
}
return imports;
}
public int countErrors() {
return parsed.countErrorsRecursively();
}
public int deleteErrors() {
return parsed.deleteErrorsRecursively();
}
public boolean isIncluded() {
return included;
}
}