]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/SCLCompiler.java
Migrated source code from Simantics SVN
[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     ErrorLog errorLog = new ErrorLog();
22     DeclarationClassification declarations = new DeclarationClassification(errorLog);
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             errorLog.log(e.location, e.getMessage());
46         } catch(Exception e) {
47             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     public void compile(
59             EnvironmentFactory localEnvironmentFactory,
60             String moduleName,
61             JavaReferenceValidator<?, ?, ?, ?> javaReferenceValidator) {
62         try {
63             if(!errorLog.isEmpty()) return;
64             Elaboration elaboration = new Elaboration(errorLog,
65                     timer,
66                     localEnvironmentFactory,
67                     moduleName,
68                     declarations.importsAst,
69                     javaReferenceValidator,
70                     declarations.valueDefinitionsAst,
71                     declarations.relationDefinitionsAst);
72             if(options.computeCoverage)
73                 elaboration.addCoverageBranchPoints();
74             // Elaboration
75             if(!errorLog.isEmpty()) return;
76             elaboration.addTypesToEnvironment(
77                     declarations.dataTypesAst,
78                     declarations.typeAliasesAst,
79                     declarations.effectsAst);
80             if(!errorLog.isEmpty()) return;
81             elaboration.processTypeAliases(declarations.typeAliasesAst);
82             if(!errorLog.isEmpty()) return;
83             elaboration.processDataTypes(declarations.dataTypesAst);
84             if(!errorLog.isEmpty()) return;
85             elaboration.processTypeClasses(declarations.typeClassesAst);
86             if(!errorLog.isEmpty()) return;
87             elaboration.processDerivingInstances(declarations.derivingInstancesAst, declarations.instancesAst);
88             if(!errorLog.isEmpty()) return;
89             elaboration.processInstances(declarations.instancesAst);
90             if(!errorLog.isEmpty()) return;
91             elaboration.processJavaMethods(declarations.javaMethodDeclarations);
92             if(!errorLog.isEmpty()) return;
93             elaboration.addDataTypesToEnvironment();
94             elaboration.addTypeClassesToEnvironment();
95             elaboration.preprocessValueDefinitions(declarations.typeAnnotationsAst);
96             elaboration.processMappingRelations(declarations.mappingRelationsAst);
97             elaboration.addFixityToEnvironment(declarations.fixityAst);
98             elaboration.addValueDefinitionsToEnvironment(declarations.typeAnnotationsAst);
99             elaboration.processRules(declarations.rulesAst);
100             elaboration.addSupplementedTypeAnnotationsToEnvironment();
101             if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Elaboration");
102             
103             // Type checking
104             if(!errorLog.isEmpty()) return;
105             //new TypeChecking(errorLog, elaboration.environment, elaboration.module).typeCheck();
106             new TypeChecking(errorLog, elaboration.environment, elaboration.module).typeCheck();
107             
108             if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Type checking");
109             
110             // FIXME HACK for testing
111             /*if(!elaboration.module.getRules().isEmpty()) {
112                 TransformationBuilder tb = new TransformationBuilder(elaboration.module.getRules());
113                 tb.compileRules(elaboration.environment);
114                 System.out.println(tb.getCompiledExpression(elaboration.environment));
115             }*/
116             
117             // Documentation generation
118             new DocumentationGeneration(
119                     declarations.valueDocumentation,
120                     declarations.typeDocumentation,
121                     declarations.classDocumentation,
122                     elaboration.module
123                     )
124                 .generateDocumentation();
125             this.declarations = null;
126             
127             // Code generation
128             if(!errorLog.isEmpty()) return;
129             CodeGeneration codeGeneration = new CodeGeneration(
130                     errorLog,
131                     elaboration.environment,
132                     elaboration.namingPolicy,
133                     elaboration.javaTypeTranslator,
134                     elaboration.javaReferenceValidator,
135                     elaboration.module);
136             codeGeneration.simplifyValues();
137             if(!errorLog.isEmpty()) return;
138             codeGeneration.convertToSSA();
139             if(!errorLog.isEmpty()) return;
140             codeGeneration.optimizeSSA();
141             
142             if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("SSA conversion and optimization");
143             
144             if(!errorLog.isEmpty()) return;
145             codeGeneration.generateCode();
146             if(!errorLog.isEmpty()) return;
147             codeGeneration.generateDataTypes(elaboration.dataTypes);
148             if(!errorLog.isEmpty()) return;
149             codeGeneration.generateTypeClasses();
150             if(!errorLog.isEmpty()) return;
151             codeGeneration.generateTypeClassInstances();
152             if(!errorLog.isEmpty()) return;
153
154             classes = codeGeneration.classes;
155             module =  codeGeneration.module;
156             moduleInitializer = StandardModuleInitializer.create(
157                     codeGeneration.namingPolicy.getModuleClassName(),
158                     codeGeneration.externalConstants);
159             
160             module.setClasses(classes);
161             module.setModuleInitializer(moduleInitializer);
162             module.setBranchPoints(elaboration.branchPoints);
163             
164             if(SCLCompilerConfiguration.ENABLE_TIMING) {
165                 phaseFinished("Code generation");
166                 reportTiming(moduleName);
167             }
168         } catch(Exception e) {
169             errorLog.log(e);
170         }
171     }
172
173     public ErrorLog getErrorLog() {
174         return errorLog;
175     }
176     
177     public Map<String, byte[]> getClasses() {
178         return classes;
179     }
180     
181     public ConcreteModule getModule() {
182         return module;
183     }
184     
185     public ModuleInitializer getModuleInitializer() {
186         return moduleInitializer;
187     }
188     
189     private void initializeTiming() {
190         timer = new CompilationTimer();
191     }
192     
193     private void phaseFinished(String phaseName) {
194         timer.phaseFinished(phaseName);
195     }
196     
197     private void reportTiming(String moduleName) {
198         timer.report(moduleName);
199     }
200 }