1 package org.simantics.scl.compiler.compilation;
3 import java.io.StringReader;
4 import java.util.ArrayList;
7 import org.simantics.scl.compiler.environment.EnvironmentFactory;
8 import org.simantics.scl.compiler.errors.ErrorLog;
9 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory;
10 import org.simantics.scl.compiler.internal.parsing.declarations.DeclarationAst;
11 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
12 import org.simantics.scl.compiler.internal.parsing.parser.SCLParserImpl;
13 import org.simantics.scl.compiler.internal.parsing.parser.SCLParserOptions;
14 import org.simantics.scl.compiler.internal.parsing.utils.LineLocators;
15 import org.simantics.scl.compiler.module.ConcreteModule;
16 import org.simantics.scl.compiler.module.options.ModuleCompilationOptions;
17 import org.simantics.scl.compiler.top.ModuleInitializer;
18 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
19 import org.simantics.scl.compiler.top.StandardModuleInitializer;
21 public class SCLCompiler {
22 CompilationContext compilationContext = new CompilationContext();
23 DeclarationClassification declarations = new DeclarationClassification(compilationContext);
25 // publishable results
26 Map<String, byte[]> classes;
27 ConcreteModule module;
28 ModuleInitializer moduleInitializer;
30 private CompilationTimer timer;
31 private ModuleCompilationOptions options;
33 JavaReferenceValidatorFactory jrvFactory;
35 public SCLCompiler(ModuleCompilationOptions options, JavaReferenceValidatorFactory jrvFactory) {
36 this.options = options == null ? ModuleCompilationOptions.STANDARD_OPTIONS : options;
37 this.jrvFactory = jrvFactory;
40 @SuppressWarnings("unchecked")
41 public void addSource(String source) {
42 if(SCLCompilerConfiguration.ENABLE_TIMING) initializeTiming();
44 compilationContext.lineLocator = LineLocators.createLineLocator(source);
45 SCLParserImpl parser = new SCLParserImpl(new StringReader(source));
46 parser.setParserOptions(SCLParserOptions.MODULE_DEFAULT);
47 parser.setCompilationContext(compilationContext);
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);
56 if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Parsing");
59 private boolean hasErrors() {
60 return !compilationContext.errorLog.hasNoErrors();
64 EnvironmentFactory localEnvironmentFactory,
67 if(hasErrors()) return;
68 Elaboration elaboration = new Elaboration(compilationContext,
70 localEnvironmentFactory,
72 compilationContext.header,
73 declarations.importsAst,
75 declarations.valueDefinitionsAst,
76 declarations.relationDefinitionsAst);
77 if(options.computeCoverage)
78 elaboration.addCoverageBranchPoints();
79 if(options.collectDebugInfo)
80 elaboration.collectDebugInfo();
82 if(hasErrors()) return;
83 elaboration.prepareExports();
84 if(hasErrors()) return;
85 elaboration.addTypesToEnvironment(
86 declarations.dataTypesAst,
87 declarations.typeAliasesAst,
88 declarations.effectsAst,
89 declarations.rulesetsAst);
90 if(hasErrors()) return;
91 elaboration.processTypeAliases(declarations.typeAliasesAst);
92 if(hasErrors()) return;
93 elaboration.processDataTypes(declarations.dataTypesAst);
94 if(hasErrors()) return;
95 elaboration.processTypeClasses(declarations.typeClassesAst);
96 if(hasErrors()) return;
97 elaboration.processDerivingInstances(declarations.derivingInstancesAst, declarations.instancesAst);
98 if(hasErrors()) return;
99 elaboration.processInstances(declarations.instancesAst);
100 if(hasErrors()) return;
101 elaboration.processJavaMethods(declarations.javaMethodDeclarations);
102 if(hasErrors()) return;
103 elaboration.processRulesets(declarations.rulesetsAst);
104 if(hasErrors()) return;
105 elaboration.addDataTypesToEnvironment();
106 elaboration.addTypeClassesToEnvironment();
107 elaboration.preprocessValueDefinitions(declarations.typeAnnotationsAst);
108 elaboration.processMappingRelations(declarations.mappingRelationsAst);
109 elaboration.addFixityToEnvironment(declarations.fixityAst);
110 elaboration.addValueDefinitionsToEnvironment(declarations.typeAnnotationsAst);
111 elaboration.processRules(declarations.rulesAst);
112 elaboration.addSupplementedTypeAnnotationsToEnvironment();
113 elaboration.checkExports();
114 if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Elaboration");
117 if(hasErrors()) return;
118 //new TypeChecking(errorLog, elaboration.environment, elaboration.module).typeCheck();
119 new TypeChecking(compilationContext, elaboration.module).typeCheck();
121 if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Type checking");
123 // FIXME HACK for testing
124 /*if(!elaboration.module.getRules().isEmpty()) {
125 TransformationBuilder tb = new TransformationBuilder(elaboration.module.getRules());
126 tb.compileRules(elaboration.environment);
127 System.out.println(tb.getCompiledExpression(elaboration.environment));
130 // Documentation generation
131 new DocumentationGeneration(
132 declarations.valueDocumentation,
133 declarations.typeDocumentation,
134 declarations.classDocumentation,
137 .generateDocumentation();
138 this.declarations = null;
141 if(hasErrors()) return;
142 CodeGeneration codeGeneration = new CodeGeneration(
144 elaboration.javaReferenceValidator,
146 codeGeneration.simplifyValues();
147 if(hasErrors()) return;
148 codeGeneration.convertToSSA();
149 if(hasErrors()) return;
150 codeGeneration.optimizeSSA();
152 if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("SSA conversion and optimization");
154 if(hasErrors()) return;
155 codeGeneration.generateCode();
156 if(hasErrors()) return;
157 codeGeneration.generateDataTypes(elaboration.dataTypes);
158 if(hasErrors()) return;
159 codeGeneration.generateTypeClasses();
160 if(hasErrors()) return;
161 codeGeneration.generateTypeClassInstances();
162 if(hasErrors()) return;
164 classes = codeGeneration.classes;
165 module = codeGeneration.module;
166 moduleInitializer = StandardModuleInitializer.create(
167 compilationContext.namingPolicy.getModuleClassName(),
168 codeGeneration.externalConstants);
170 module.setClasses(classes);
171 module.setParentClassLoader(elaboration.javaReferenceValidator.getClassLoader());
172 module.setModuleInitializer(moduleInitializer);
173 module.setBranchPoints(elaboration.branchPoints);
174 if(compilationContext.errorLog.hasErrorsOrWarnings())
175 module.setWarnings(compilationContext.errorLog.getErrors());
177 if(SCLCompilerConfiguration.ENABLE_TIMING) {
178 phaseFinished("Code generation");
179 reportTiming(moduleName);
181 } catch(Exception e) {
182 compilationContext.errorLog.log(e);
186 public ErrorLog getErrorLog() {
187 return compilationContext.errorLog;
190 public Map<String, byte[]> getClasses() {
194 public ConcreteModule getModule() {
198 public ModuleInitializer getModuleInitializer() {
199 return moduleInitializer;
202 private void initializeTiming() {
203 timer = new CompilationTimer();
206 private void phaseFinished(String phaseName) {
207 timer.phaseFinished(phaseName);
210 private void reportTiming(String moduleName) {
211 timer.report(moduleName);