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