1 package org.simantics.scl.compiler.compilation;
3 import java.io.IOException;
5 import java.util.ArrayList;
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;
20 public class SCLCompiler {
21 CompilationContext compilationContext = new CompilationContext();
22 DeclarationClassification declarations = new DeclarationClassification(compilationContext);
24 // publishable results
25 Map<String, byte[]> classes;
26 ConcreteModule module;
27 ModuleInitializer moduleInitializer;
29 private CompilationTimer timer;
30 private ModuleCompilationOptions options;
32 public SCLCompiler(ModuleCompilationOptions options) {
33 this.options = options == null ? ModuleCompilationOptions.STANDARD_OPTIONS : options;
36 @SuppressWarnings("unchecked")
37 public void addSource(Reader sourceReader) {
38 if(SCLCompilerConfiguration.ENABLE_TIMING) initializeTiming();
40 SCLParserImpl parser = new SCLParserImpl(sourceReader);
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);
51 } catch (IOException e) {
55 if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Parsing");
58 private boolean hasErrors() {
59 return !compilationContext.errorLog.isEmpty();
63 EnvironmentFactory localEnvironmentFactory,
65 JavaReferenceValidator<?, ?, ?, ?> javaReferenceValidator) {
67 if(hasErrors()) return;
68 Elaboration elaboration = new Elaboration(compilationContext,
70 localEnvironmentFactory,
72 declarations.importsAst,
73 javaReferenceValidator,
74 declarations.valueDefinitionsAst,
75 declarations.relationDefinitionsAst);
76 if(options.computeCoverage)
77 elaboration.addCoverageBranchPoints();
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");
108 if(hasErrors()) return;
109 //new TypeChecking(errorLog, elaboration.environment, elaboration.module).typeCheck();
110 new TypeChecking(compilationContext, elaboration.module).typeCheck();
112 if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Type checking");
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));
121 // Documentation generation
122 new DocumentationGeneration(
123 declarations.valueDocumentation,
124 declarations.typeDocumentation,
125 declarations.classDocumentation,
128 .generateDocumentation();
129 this.declarations = null;
132 if(hasErrors()) return;
133 CodeGeneration codeGeneration = new CodeGeneration(
135 elaboration.javaReferenceValidator,
137 codeGeneration.simplifyValues();
138 if(hasErrors()) return;
139 codeGeneration.convertToSSA();
140 if(hasErrors()) return;
141 codeGeneration.optimizeSSA();
143 if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("SSA conversion and optimization");
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;
155 classes = codeGeneration.classes;
156 module = codeGeneration.module;
157 moduleInitializer = StandardModuleInitializer.create(
158 compilationContext.namingPolicy.getModuleClassName(),
159 codeGeneration.externalConstants);
161 module.setClasses(classes);
162 module.setModuleInitializer(moduleInitializer);
163 module.setBranchPoints(elaboration.branchPoints);
165 if(SCLCompilerConfiguration.ENABLE_TIMING) {
166 phaseFinished("Code generation");
167 reportTiming(moduleName);
169 } catch(Exception e) {
170 compilationContext.errorLog.log(e);
174 public ErrorLog getErrorLog() {
175 return compilationContext.errorLog;
178 public Map<String, byte[]> getClasses() {
182 public ConcreteModule getModule() {
186 public ModuleInitializer getModuleInitializer() {
187 return moduleInitializer;
190 private void initializeTiming() {
191 timer = new CompilationTimer();
194 private void phaseFinished(String phaseName) {
195 timer.phaseFinished(phaseName);
198 private void reportTiming(String moduleName) {
199 timer.report(moduleName);