package scotch.compiler; import static java.util.Arrays.asList; import java.util.List; import java.util.Map; import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.CommonTokenStream; import scotch.compiler.analyzer.DependencyAccumulator; import scotch.compiler.analyzer.NameAccumulator; import scotch.compiler.analyzer.OperatorAccumulator; import scotch.compiler.analyzer.PatternAnalyzer; import scotch.compiler.analyzer.PrecedenceParser; import scotch.compiler.analyzer.NameQualifier; import scotch.compiler.analyzer.TypeChecker; import scotch.compiler.intermediate.IntermediateGenerator; import scotch.compiler.intermediate.IntermediateGraph; import scotch.compiler.output.GeneratedClass; import scotch.compiler.parser.ModulesMapper; import scotch.compiler.parser.ScotchLayoutLexer; import scotch.compiler.parser.ScotchLexer; import scotch.compiler.parser.ScotchParser; import scotch.compiler.parser.ScotchParser.ModuleContext; import scotch.compiler.parser.ScotchParser.ModulesContext; import scotch.compiler.parser.SyntaxTransformer; import scotch.compiler.syntax.definition.DefinitionGraph; import scotch.compiler.target.BytecodeGenerator; import scotch.symbol.SymbolResolver; import scotch.compiler.syntax.util.DefaultSymbolGenerator; // TODO multiple file compilation // TODO incremental compilation public class Compiler { public static Compiler compiler(SymbolResolver symbolResolver, String... lines) { ANTLRInputStream input = new ANTLRInputStream(String.join("\n", lines)); ScotchLayoutLexer tokenSource = new ScotchLayoutLexer(new ScotchLexer(input)); ModulesContext modules = new ScotchParser(new CommonTokenStream(tokenSource)).modules(); return new Compiler(symbolResolver, new ModulesMapper().map(asList(modules))); } private final SymbolResolver symbolResolver; private final Map<String, List<ModuleContext>> modules; public Compiler(SymbolResolver symbolResolver, Map<String, List<ModuleContext>> modules) { this.symbolResolver = symbolResolver; this.modules = modules; } public List<GeneratedClass> generateBytecode() { return new BytecodeGenerator(generateIntermediateCode()).generateBytecode(); } public DefinitionGraph accumulateDependencies() { return new DependencyAccumulator(reducePatterns()).accumulateDependencies(); } public DefinitionGraph accumulateNames() { return new NameAccumulator(parsePrecedence()).accumulateNames(); } public DefinitionGraph accumulateOperators() { return new OperatorAccumulator(transformSyntax()).accumulateOperators(); } public DefinitionGraph checkTypes() { return new TypeChecker(accumulateDependencies()).checkTypes(); } public IntermediateGraph generateIntermediateCode() { return new IntermediateGenerator(checkTypes()).generateIntermediateCode(); } public DefinitionGraph transformSyntax() { return new SyntaxTransformer(symbolResolver, new DefaultSymbolGenerator()).transform(modules); } public DefinitionGraph parsePrecedence() { return new PrecedenceParser(accumulateOperators()).parsePrecedence(); } public DefinitionGraph qualifyNames() { return new NameQualifier(accumulateNames()).qualifyNames(); } public DefinitionGraph reducePatterns() { return new PatternAnalyzer(qualifyNames()).reducePatterns(); } }