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 models = new List(); 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; } }