/src/org/ooc/frontend/parser/ModuleParser.java

http://github.com/nddrylliog/ooc · Java · 155 lines · 127 code · 27 blank · 1 comment · 37 complexity · bdde4955bd9841b605b4efb1b7490ce4 MD5 · raw file

  1. package org.ooc.frontend.parser;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.util.Collection;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7. import org.ooc.frontend.model.ClassDecl;
  8. import org.ooc.frontend.model.CoverDecl;
  9. import org.ooc.frontend.model.Declaration;
  10. import org.ooc.frontend.model.Import;
  11. import org.ooc.frontend.model.Module;
  12. import org.ooc.frontend.model.Node;
  13. import org.ooc.frontend.model.NodeList;
  14. import org.ooc.frontend.model.OpDecl;
  15. import org.ooc.frontend.model.VariableDecl;
  16. import org.ooc.frontend.model.tokens.Token;
  17. import org.ooc.frontend.model.tokens.TokenReader;
  18. import org.ooc.frontend.model.tokens.Token.TokenType;
  19. import org.ooc.middle.OocCompilationError;
  20. import org.ooc.utils.FileUtils;
  21. import org.ubi.CompilationFailedError;
  22. import org.ubi.SourceReader;
  23. public class ModuleParser {
  24. // path -> module
  25. public final static Map<String, Module> cache = new HashMap<String, Module>();
  26. @SuppressWarnings("unchecked")
  27. public static void parse(final Module module, final String fullName, final File file, final SourceReader sReader,
  28. final TokenReader reader, final Parser parser) {
  29. module.lastModified = file.lastModified();
  30. try {
  31. addLangImports(module, parser);
  32. while(reader.hasNext()) {
  33. if(reader.peek().type == TokenType.LINESEP || reader.peek().type == TokenType.OOCDOC) {
  34. reader.skip();
  35. continue;
  36. }
  37. {
  38. ClassDecl classDecl = ClassDeclParser.parse(module, sReader, reader);
  39. if(classDecl != null) {
  40. module.getTypes().put(classDecl.getName(), classDecl);
  41. continue;
  42. }
  43. }
  44. {
  45. CoverDecl coverDecl = CoverDeclParser.parse(module, sReader, reader);
  46. if(coverDecl != null) {
  47. module.getTypes().put(coverDecl.getName(), coverDecl);
  48. continue;
  49. }
  50. }
  51. {
  52. OpDecl opDecl = OpDeclParser.parse(module, sReader, reader);
  53. if(opDecl != null) {
  54. module.getOps().add(opDecl);
  55. continue;
  56. }
  57. }
  58. Node candidate = VariableDeclParser.parseMulti(module, sReader, reader);
  59. if(candidate != null) {
  60. if(candidate instanceof NodeList<?>) {
  61. NodeList<VariableDecl> vDecls = (NodeList<VariableDecl>) candidate;
  62. for(VariableDecl vDecl : vDecls) {
  63. vDecl.addToModule(module);
  64. vDecl.setGlobal(true);
  65. }
  66. } else {
  67. VariableDecl vDecl = ((VariableDecl) candidate);
  68. vDecl.addToModule(module);
  69. vDecl.setGlobal(true);
  70. }
  71. continue;
  72. }
  73. Declaration declaration = DeclarationParser.parse(module, sReader, reader);
  74. if(declaration != null) {
  75. module.getBody().add(declaration);
  76. continue;
  77. }
  78. if(LineParser.fill(module, sReader, reader, module.getLoadFunc().getBody())) continue;
  79. if(IncludeParser.fill(sReader, reader, module.getIncludes())) continue;
  80. if(ImportParser.fill(module, sReader, reader)) continue;
  81. if(UseParser.fill(sReader, reader, module.getUses(), parser.params)) continue;
  82. if(CommentParser.parse(sReader, reader) != null) continue;
  83. Token errToken = reader.peek();
  84. throw new CompilationFailedError(sReader.getLocation(errToken),
  85. "Expected declaration, include, or import in source unit, but got "+errToken);
  86. }
  87. for(Import imp: module.getAllImports()) {
  88. String path = imp.getPath() + ".ooc";
  89. if(path.startsWith("..")) {
  90. path = FileUtils.resolveRedundancies(new File(module.getParentPath(), path)).getPath();
  91. }
  92. File impFile = parser.params.sourcePath.getElement(path);
  93. if(impFile == null) {
  94. path = module.getParentPath() + "/" + path;
  95. impFile = parser.params.sourcePath.getElement(path);
  96. if(impFile == null) {
  97. throw new OocCompilationError(imp, module, "Module not found in sourcepath: "+imp.getPath());
  98. }
  99. }
  100. Module cached = cache.get(path);
  101. if(cached == null || new File(impFile, path).lastModified() > cached.lastModified) {
  102. if(cached != null) {
  103. System.out.println(path+" has been changed, recompiling...");
  104. }
  105. cached = parser.parse(path, impFile, imp);
  106. }
  107. imp.setModule(cached);
  108. }
  109. } catch(IOException e) {
  110. e.printStackTrace();
  111. System.exit(1);
  112. }
  113. }
  114. static void addLangImports(Module module, Parser parser) {
  115. Collection<String> paths = parser.params.sourcePath.getRelativePaths("lang");
  116. for(String path: paths) {
  117. if(path.toLowerCase().endsWith(".ooc")) {
  118. path = path.substring(0, path.length() - 4);
  119. if(!path.equals(module.getPath())) {
  120. module.getGlobalImports().add(new Import(path, Token.defaultToken));
  121. }
  122. }
  123. }
  124. }
  125. public static void clearCache() {
  126. cache.clear();
  127. }
  128. }