]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/SCLCompiler.java
Merge "Re-enabled Acorn transaction cancellation support for testing"
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / compilation / SCLCompiler.java
1 package org.simantics.scl.compiler.compilation;
2
3 import java.io.IOException;
4 import java.io.Reader;
5 import java.util.ArrayList;
6 import java.util.Map;
7
8 import org.simantics.scl.compiler.environment.EnvironmentFactory;
9 import org.simantics.scl.compiler.errors.ErrorLog;
10 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
11 import org.simantics.scl.compiler.internal.parsing.declarations.DeclarationAst;
12 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
13 import org.simantics.scl.compiler.internal.parsing.parser.SCLParserImpl;
14 import org.simantics.scl.compiler.module.ConcreteModule;
15 import org.simantics.scl.compiler.module.options.ModuleCompilationOptions;
16 import org.simantics.scl.compiler.top.ModuleInitializer;
17 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
18 import org.simantics.scl.compiler.top.StandardModuleInitializer;
19
20 public class SCLCompiler {
21     CompilationContext compilationContext = new CompilationContext();
22     DeclarationClassification declarations = new DeclarationClassification(compilationContext);
23     
24     // publishable results
25     Map<String, byte[]> classes;
26     ConcreteModule module;
27     ModuleInitializer moduleInitializer;
28     
29     private CompilationTimer timer;
30     private ModuleCompilationOptions options;
31     
32     public SCLCompiler(ModuleCompilationOptions options) {
33         this.options = options == null ? ModuleCompilationOptions.STANDARD_OPTIONS : options;
34     }
35
36     @SuppressWarnings("unchecked")
37     public void addSource(Reader sourceReader) {
38         if(SCLCompilerConfiguration.ENABLE_TIMING) initializeTiming();
39         try {
40             SCLParserImpl parser = new SCLParserImpl(sourceReader);
41             if(!parser.isEmpty())
42             for(DeclarationAst declaration : (ArrayList<DeclarationAst>)parser.parseModule())
43                 declarations.handle(declaration);
44         } catch(SCLSyntaxErrorException e) {
45             compilationContext.errorLog.log(e.location, e.getMessage());
46         } catch(Exception e) {
47             compilationContext.errorLog.log(e);
48         } finally {
49             try {
50                 sourceReader.close();
51             } catch (IOException e) {
52                 e.printStackTrace();
53             }
54         }
55         if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Parsing");
56     }
57     
58     private boolean hasErrors() {
59         return !compilationContext.errorLog.isEmpty();
60     }
61     
62     public void compile(
63             EnvironmentFactory localEnvironmentFactory,
64             String moduleName,
65             JavaReferenceValidator<?, ?, ?, ?> javaReferenceValidator) {
66         try {
67             if(hasErrors()) return;
68             Elaboration elaboration = new Elaboration(compilationContext,
69                     timer,
70                     localEnvironmentFactory,
71                     moduleName,
72                     declarations.importsAst,
73                     javaReferenceValidator,
74                     declarations.valueDefinitionsAst,
75                     declarations.relationDefinitionsAst);
76             if(options.computeCoverage)
77                 elaboration.addCoverageBranchPoints();
78             // Elaboration
79             if(hasErrors()) return;
80             elaboration.addTypesToEnvironment(
81                     declarations.dataTypesAst,
82                     declarations.typeAliasesAst,
83                     declarations.effectsAst);
84             if(hasErrors()) return;
85             elaboration.processTypeAliases(declarations.typeAliasesAst);
86             if(hasErrors()) return;
87             elaboration.processDataTypes(declarations.dataTypesAst);
88             if(hasErrors()) return;
89             elaboration.processTypeClasses(declarations.typeClassesAst);
90             if(hasErrors()) return;
91             elaboration.processDerivingInstances(declarations.derivingInstancesAst, declarations.instancesAst);
92             if(hasErrors()) return;
93             elaboration.processInstances(declarations.instancesAst);
94             if(hasErrors()) return;
95             elaboration.processJavaMethods(declarations.javaMethodDeclarations);
96             if(hasErrors()) return;
97             elaboration.addDataTypesToEnvironment();
98             elaboration.addTypeClassesToEnvironment();
99             elaboration.preprocessValueDefinitions(declarations.typeAnnotationsAst);
100             elaboration.processMappingRelations(declarations.mappingRelationsAst);
101             elaboration.addFixityToEnvironment(declarations.fixityAst);
102             elaboration.addValueDefinitionsToEnvironment(declarations.typeAnnotationsAst);
103             elaboration.processRules(declarations.rulesAst);
104             elaboration.addSupplementedTypeAnnotationsToEnvironment();
105             if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Elaboration");
106             
107             // Type checking
108             if(hasErrors()) return;
109             //new TypeChecking(errorLog, elaboration.environment, elaboration.module).typeCheck();
110             new TypeChecking(compilationContext, elaboration.module).typeCheck();
111             
112             if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Type checking");
113             
114             // FIXME HACK for testing
115             /*if(!elaboration.module.getRules().isEmpty()) {
116                 TransformationBuilder tb = new TransformationBuilder(elaboration.module.getRules());
117                 tb.compileRules(elaboration.environment);
118                 System.out.println(tb.getCompiledExpression(elaboration.environment));
119             }*/
120             
121             // Documentation generation
122             new DocumentationGeneration(
123                     declarations.valueDocumentation,
124                     declarations.typeDocumentation,
125                     declarations.classDocumentation,
126                     elaboration.module
127                     )
128                 .generateDocumentation();
129             this.declarations = null;
130             
131             // Code generation
132             if(hasErrors()) return;
133             CodeGeneration codeGeneration = new CodeGeneration(
134                     compilationContext,
135                     elaboration.javaReferenceValidator,
136                     elaboration.module);
137             codeGeneration.simplifyValues();
138             if(hasErrors()) return;
139             codeGeneration.convertToSSA();
140             if(hasErrors()) return;
141             codeGeneration.optimizeSSA();
142             
143             if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("SSA conversion and optimization");
144             
145             if(hasErrors()) return;
146             codeGeneration.generateCode();
147             if(hasErrors()) return;
148             codeGeneration.generateDataTypes(elaboration.dataTypes);
149             if(hasErrors()) return;
150             codeGeneration.generateTypeClasses();
151             if(hasErrors()) return;
152             codeGeneration.generateTypeClassInstances();
153             if(hasErrors()) return;
154
155             classes = codeGeneration.classes;
156             module =  codeGeneration.module;
157             moduleInitializer = StandardModuleInitializer.create(
158                     compilationContext.namingPolicy.getModuleClassName(),
159                     codeGeneration.externalConstants);
160             
161             module.setClasses(classes);
162             module.setModuleInitializer(moduleInitializer);
163             module.setBranchPoints(elaboration.branchPoints);
164             
165             if(SCLCompilerConfiguration.ENABLE_TIMING) {
166                 phaseFinished("Code generation");
167                 reportTiming(moduleName);
168             }
169         } catch(Exception e) {
170             compilationContext.errorLog.log(e);
171         }
172     }
173
174     public ErrorLog getErrorLog() {
175         return compilationContext.errorLog;
176     }
177     
178     public Map<String, byte[]> getClasses() {
179         return classes;
180     }
181     
182     public ConcreteModule getModule() {
183         return module;
184     }
185     
186     public ModuleInitializer getModuleInitializer() {
187         return moduleInitializer;
188     }
189     
190     private void initializeTiming() {
191         timer = new CompilationTimer();
192     }
193     
194     private void phaseFinished(String phaseName) {
195         timer.phaseFinished(phaseName);
196     }
197     
198     private void reportTiming(String moduleName) {
199         timer.report(moduleName);
200     }
201 }