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 ErrorLog errorLog = new ErrorLog();
22 DeclarationClassification declarations = new DeclarationClassification(errorLog);
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 errorLog.log(e.location, e.getMessage());
46 } catch(Exception e) {
51 } catch (IOException e) {
55 if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Parsing");
59 EnvironmentFactory localEnvironmentFactory,
61 JavaReferenceValidator<?, ?, ?, ?> javaReferenceValidator) {
63 if(!errorLog.isEmpty()) return;
64 Elaboration elaboration = new Elaboration(errorLog,
66 localEnvironmentFactory,
68 declarations.importsAst,
69 javaReferenceValidator,
70 declarations.valueDefinitionsAst,
71 declarations.relationDefinitionsAst);
72 if(options.computeCoverage)
73 elaboration.addCoverageBranchPoints();
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");
104 if(!errorLog.isEmpty()) return;
105 //new TypeChecking(errorLog, elaboration.environment, elaboration.module).typeCheck();
106 new TypeChecking(errorLog, elaboration.environment, elaboration.module).typeCheck();
108 if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Type checking");
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));
117 // Documentation generation
118 new DocumentationGeneration(
119 declarations.valueDocumentation,
120 declarations.typeDocumentation,
121 declarations.classDocumentation,
124 .generateDocumentation();
125 this.declarations = null;
128 if(!errorLog.isEmpty()) return;
129 CodeGeneration codeGeneration = new CodeGeneration(
131 elaboration.environment,
132 elaboration.namingPolicy,
133 elaboration.javaTypeTranslator,
134 elaboration.javaReferenceValidator,
136 codeGeneration.simplifyValues();
137 if(!errorLog.isEmpty()) return;
138 codeGeneration.convertToSSA();
139 if(!errorLog.isEmpty()) return;
140 codeGeneration.optimizeSSA();
142 if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("SSA conversion and optimization");
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;
154 classes = codeGeneration.classes;
155 module = codeGeneration.module;
156 moduleInitializer = StandardModuleInitializer.create(
157 codeGeneration.namingPolicy.getModuleClassName(),
158 codeGeneration.externalConstants);
160 module.setClasses(classes);
161 module.setModuleInitializer(moduleInitializer);
162 module.setBranchPoints(elaboration.branchPoints);
164 if(SCLCompilerConfiguration.ENABLE_TIMING) {
165 phaseFinished("Code generation");
166 reportTiming(moduleName);
168 } catch(Exception e) {
173 public ErrorLog getErrorLog() {
177 public Map<String, byte[]> getClasses() {
181 public ConcreteModule getModule() {
185 public ModuleInitializer getModuleInitializer() {
186 return moduleInitializer;
189 private void initializeTiming() {
190 timer = new CompilationTimer();
193 private void phaseFinished(String phaseName) {
194 timer.phaseFinished(phaseName);
197 private void reportTiming(String moduleName) {
198 timer.report(moduleName);