]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - 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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/SCLCompiler.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/SCLCompiler.java
new file mode 100644 (file)
index 0000000..b5bd4ef
--- /dev/null
@@ -0,0 +1,200 @@
+package org.simantics.scl.compiler.compilation;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.simantics.scl.compiler.environment.EnvironmentFactory;
+import org.simantics.scl.compiler.errors.ErrorLog;
+import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
+import org.simantics.scl.compiler.internal.parsing.declarations.DeclarationAst;
+import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
+import org.simantics.scl.compiler.internal.parsing.parser.SCLParserImpl;
+import org.simantics.scl.compiler.module.ConcreteModule;
+import org.simantics.scl.compiler.module.options.ModuleCompilationOptions;
+import org.simantics.scl.compiler.top.ModuleInitializer;
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
+import org.simantics.scl.compiler.top.StandardModuleInitializer;
+
+public class SCLCompiler {
+    ErrorLog errorLog = new ErrorLog();
+    DeclarationClassification declarations = new DeclarationClassification(errorLog);
+    
+    // publishable results
+    Map<String, byte[]> classes;
+    ConcreteModule module;
+    ModuleInitializer moduleInitializer;
+    
+    private CompilationTimer timer;
+    private ModuleCompilationOptions options;
+    
+    public SCLCompiler(ModuleCompilationOptions options) {
+        this.options = options == null ? ModuleCompilationOptions.STANDARD_OPTIONS : options;
+    }
+
+    @SuppressWarnings("unchecked")
+    public void addSource(Reader sourceReader) {
+        if(SCLCompilerConfiguration.ENABLE_TIMING) initializeTiming();
+        try {
+            SCLParserImpl parser = new SCLParserImpl(sourceReader);
+            if(!parser.isEmpty())
+            for(DeclarationAst declaration : (ArrayList<DeclarationAst>)parser.parseModule())
+                declarations.handle(declaration);
+        } catch(SCLSyntaxErrorException e) {
+            errorLog.log(e.location, e.getMessage());
+        } catch(Exception e) {
+            errorLog.log(e);
+        } finally {
+            try {
+                sourceReader.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Parsing");
+    }
+    
+    public void compile(
+            EnvironmentFactory localEnvironmentFactory,
+            String moduleName,
+            JavaReferenceValidator<?, ?, ?, ?> javaReferenceValidator) {
+        try {
+            if(!errorLog.isEmpty()) return;
+            Elaboration elaboration = new Elaboration(errorLog,
+                    timer,
+                    localEnvironmentFactory,
+                    moduleName,
+                    declarations.importsAst,
+                    javaReferenceValidator,
+                    declarations.valueDefinitionsAst,
+                    declarations.relationDefinitionsAst);
+            if(options.computeCoverage)
+                elaboration.addCoverageBranchPoints();
+            // Elaboration
+            if(!errorLog.isEmpty()) return;
+            elaboration.addTypesToEnvironment(
+                    declarations.dataTypesAst,
+                    declarations.typeAliasesAst,
+                    declarations.effectsAst);
+            if(!errorLog.isEmpty()) return;
+            elaboration.processTypeAliases(declarations.typeAliasesAst);
+            if(!errorLog.isEmpty()) return;
+            elaboration.processDataTypes(declarations.dataTypesAst);
+            if(!errorLog.isEmpty()) return;
+            elaboration.processTypeClasses(declarations.typeClassesAst);
+            if(!errorLog.isEmpty()) return;
+            elaboration.processDerivingInstances(declarations.derivingInstancesAst, declarations.instancesAst);
+            if(!errorLog.isEmpty()) return;
+            elaboration.processInstances(declarations.instancesAst);
+            if(!errorLog.isEmpty()) return;
+            elaboration.processJavaMethods(declarations.javaMethodDeclarations);
+            if(!errorLog.isEmpty()) return;
+            elaboration.addDataTypesToEnvironment();
+            elaboration.addTypeClassesToEnvironment();
+            elaboration.preprocessValueDefinitions(declarations.typeAnnotationsAst);
+            elaboration.processMappingRelations(declarations.mappingRelationsAst);
+            elaboration.addFixityToEnvironment(declarations.fixityAst);
+            elaboration.addValueDefinitionsToEnvironment(declarations.typeAnnotationsAst);
+            elaboration.processRules(declarations.rulesAst);
+            elaboration.addSupplementedTypeAnnotationsToEnvironment();
+            if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Elaboration");
+            
+            // Type checking
+            if(!errorLog.isEmpty()) return;
+            //new TypeChecking(errorLog, elaboration.environment, elaboration.module).typeCheck();
+            new TypeChecking(errorLog, elaboration.environment, elaboration.module).typeCheck();
+            
+            if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Type checking");
+            
+            // FIXME HACK for testing
+            /*if(!elaboration.module.getRules().isEmpty()) {
+                TransformationBuilder tb = new TransformationBuilder(elaboration.module.getRules());
+                tb.compileRules(elaboration.environment);
+                System.out.println(tb.getCompiledExpression(elaboration.environment));
+            }*/
+            
+            // Documentation generation
+            new DocumentationGeneration(
+                    declarations.valueDocumentation,
+                    declarations.typeDocumentation,
+                    declarations.classDocumentation,
+                    elaboration.module
+                    )
+                .generateDocumentation();
+            this.declarations = null;
+            
+            // Code generation
+            if(!errorLog.isEmpty()) return;
+            CodeGeneration codeGeneration = new CodeGeneration(
+                    errorLog,
+                    elaboration.environment,
+                    elaboration.namingPolicy,
+                    elaboration.javaTypeTranslator,
+                    elaboration.javaReferenceValidator,
+                    elaboration.module);
+            codeGeneration.simplifyValues();
+            if(!errorLog.isEmpty()) return;
+            codeGeneration.convertToSSA();
+            if(!errorLog.isEmpty()) return;
+            codeGeneration.optimizeSSA();
+            
+            if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("SSA conversion and optimization");
+            
+            if(!errorLog.isEmpty()) return;
+            codeGeneration.generateCode();
+            if(!errorLog.isEmpty()) return;
+            codeGeneration.generateDataTypes(elaboration.dataTypes);
+            if(!errorLog.isEmpty()) return;
+            codeGeneration.generateTypeClasses();
+            if(!errorLog.isEmpty()) return;
+            codeGeneration.generateTypeClassInstances();
+            if(!errorLog.isEmpty()) return;
+
+            classes = codeGeneration.classes;
+            module =  codeGeneration.module;
+            moduleInitializer = StandardModuleInitializer.create(
+                    codeGeneration.namingPolicy.getModuleClassName(),
+                    codeGeneration.externalConstants);
+            
+            module.setClasses(classes);
+            module.setModuleInitializer(moduleInitializer);
+            module.setBranchPoints(elaboration.branchPoints);
+            
+            if(SCLCompilerConfiguration.ENABLE_TIMING) {
+                phaseFinished("Code generation");
+                reportTiming(moduleName);
+            }
+        } catch(Exception e) {
+            errorLog.log(e);
+        }
+    }
+
+    public ErrorLog getErrorLog() {
+        return errorLog;
+    }
+    
+    public Map<String, byte[]> getClasses() {
+        return classes;
+    }
+    
+    public ConcreteModule getModule() {
+        return module;
+    }
+    
+    public ModuleInitializer getModuleInitializer() {
+        return moduleInitializer;
+    }
+    
+    private void initializeTiming() {
+        timer = new CompilationTimer();
+    }
+    
+    private void phaseFinished(String phaseName) {
+        timer.phaseFinished(phaseName);
+    }
+    
+    private void reportTiming(String moduleName) {
+        timer.report(moduleName);
+    }
+}