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.JavaReferenceValidatorFactory;
11 import org.simantics.scl.compiler.internal.header.ModuleHeader;
12 import org.simantics.scl.compiler.internal.parsing.declarations.DeclarationAst;
13 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
14 import org.simantics.scl.compiler.internal.parsing.parser.SCLParserImpl;
15 import org.simantics.scl.compiler.internal.parsing.parser.SCLParserOptions;
16 import org.simantics.scl.compiler.module.ConcreteModule;
17 import org.simantics.scl.compiler.module.options.ModuleCompilationOptions;
18 import org.simantics.scl.compiler.top.ModuleInitializer;
19 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
20 import org.simantics.scl.compiler.top.StandardModuleInitializer;
22 public class SCLCompiler {
23 CompilationContext compilationContext = new CompilationContext();
24 DeclarationClassification declarations = new DeclarationClassification(compilationContext);
26 // publishable results
27 Map<String, byte[]> classes;
28 ConcreteModule module;
29 ModuleInitializer moduleInitializer;
31 private CompilationTimer timer;
32 private ModuleCompilationOptions options;
34 JavaReferenceValidatorFactory jrvFactory;
36 public SCLCompiler(ModuleCompilationOptions options, JavaReferenceValidatorFactory jrvFactory) {
37 this.options = options == null ? ModuleCompilationOptions.STANDARD_OPTIONS : options;
38 this.jrvFactory = jrvFactory;
41 @SuppressWarnings("unchecked")
42 public void addSource(Reader sourceReader) {
43 if(SCLCompilerConfiguration.ENABLE_TIMING) initializeTiming();
45 SCLParserImpl parser = new SCLParserImpl(sourceReader);
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);
58 } catch (IOException e) {
62 if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Parsing");
65 private boolean hasErrors() {
66 return !compilationContext.errorLog.hasNoErrors();
70 EnvironmentFactory localEnvironmentFactory,
73 if(hasErrors()) return;
74 Elaboration elaboration = new Elaboration(compilationContext,
76 localEnvironmentFactory,
78 compilationContext.header,
79 declarations.importsAst,
81 declarations.valueDefinitionsAst,
82 declarations.relationDefinitionsAst);
83 if(options.computeCoverage)
84 elaboration.addCoverageBranchPoints();
85 if(options.collectDebugInfo)
86 elaboration.collectDebugInfo();
88 if(hasErrors()) return;
89 elaboration.prepareExports();
90 if(hasErrors()) return;
91 elaboration.addTypesToEnvironment(
92 declarations.dataTypesAst,
93 declarations.typeAliasesAst,
94 declarations.effectsAst,
95 declarations.rulesetsAst);
96 if(hasErrors()) return;
97 elaboration.processTypeAliases(declarations.typeAliasesAst);
98 if(hasErrors()) return;
99 elaboration.processDataTypes(declarations.dataTypesAst);
100 if(hasErrors()) return;
101 elaboration.processTypeClasses(declarations.typeClassesAst);
102 if(hasErrors()) return;
103 elaboration.processDerivingInstances(declarations.derivingInstancesAst, declarations.instancesAst);
104 if(hasErrors()) return;
105 elaboration.processInstances(declarations.instancesAst);
106 if(hasErrors()) return;
107 elaboration.processJavaMethods(declarations.javaMethodDeclarations);
108 if(hasErrors()) return;
109 elaboration.processRulesets(declarations.rulesetsAst);
110 if(hasErrors()) return;
111 elaboration.addDataTypesToEnvironment();
112 elaboration.addTypeClassesToEnvironment();
113 elaboration.preprocessValueDefinitions(declarations.typeAnnotationsAst);
114 elaboration.processMappingRelations(declarations.mappingRelationsAst);
115 elaboration.addFixityToEnvironment(declarations.fixityAst);
116 elaboration.addValueDefinitionsToEnvironment(declarations.typeAnnotationsAst);
117 elaboration.processRules(declarations.rulesAst);
118 elaboration.addSupplementedTypeAnnotationsToEnvironment();
119 elaboration.checkExports();
120 if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Elaboration");
123 if(hasErrors()) return;
124 //new TypeChecking(errorLog, elaboration.environment, elaboration.module).typeCheck();
125 new TypeChecking(compilationContext, elaboration.module).typeCheck();
127 if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Type checking");
129 // FIXME HACK for testing
130 /*if(!elaboration.module.getRules().isEmpty()) {
131 TransformationBuilder tb = new TransformationBuilder(elaboration.module.getRules());
132 tb.compileRules(elaboration.environment);
133 System.out.println(tb.getCompiledExpression(elaboration.environment));
136 // Documentation generation
137 new DocumentationGeneration(
138 declarations.valueDocumentation,
139 declarations.typeDocumentation,
140 declarations.classDocumentation,
143 .generateDocumentation();
144 this.declarations = null;
147 if(hasErrors()) return;
148 CodeGeneration codeGeneration = new CodeGeneration(
150 elaboration.javaReferenceValidator,
152 codeGeneration.simplifyValues();
153 if(hasErrors()) return;
154 codeGeneration.convertToSSA();
155 if(hasErrors()) return;
156 codeGeneration.optimizeSSA();
158 if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("SSA conversion and optimization");
160 if(hasErrors()) return;
161 codeGeneration.generateCode();
162 if(hasErrors()) return;
163 codeGeneration.generateDataTypes(elaboration.dataTypes);
164 if(hasErrors()) return;
165 codeGeneration.generateTypeClasses();
166 if(hasErrors()) return;
167 codeGeneration.generateTypeClassInstances();
168 if(hasErrors()) return;
170 classes = codeGeneration.classes;
171 module = codeGeneration.module;
172 moduleInitializer = StandardModuleInitializer.create(
173 compilationContext.namingPolicy.getModuleClassName(),
174 codeGeneration.externalConstants);
176 module.setClasses(classes);
177 module.setParentClassLoader(elaboration.javaReferenceValidator.getClassLoader());
178 module.setModuleInitializer(moduleInitializer);
179 module.setBranchPoints(elaboration.branchPoints);
180 if(compilationContext.errorLog.hasErrorsOrWarnings())
181 module.setWarnings(compilationContext.errorLog.getErrors());
183 if(SCLCompilerConfiguration.ENABLE_TIMING) {
184 phaseFinished("Code generation");
185 reportTiming(moduleName);
187 } catch(Exception e) {
188 compilationContext.errorLog.log(e);
192 public ErrorLog getErrorLog() {
193 return compilationContext.errorLog;
196 public Map<String, byte[]> getClasses() {
200 public ConcreteModule getModule() {
204 public ModuleInitializer getModuleInitializer() {
205 return moduleInitializer;
208 private void initializeTiming() {
209 timer = new CompilationTimer();
212 private void phaseFinished(String phaseName) {
213 timer.phaseFinished(phaseName);
216 private void reportTiming(String moduleName) {
217 timer.report(moduleName);