PageRenderTime 44ms CodeModel.GetById 27ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

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