X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Ftop%2FExpressionEvaluator.java;h=f14a3be967438af2e93d134e9e1024513e5eb193;hp=d87beec65a7380361a2c45961fa41c2c886b8c18;hb=0861b325fcbbfa8c5985f1e11cfc39154a3808d1;hpb=cb5fc8d606d8b322563e9345c441eecfa7f01753 diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java index d87beec65..f14a3be96 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java @@ -27,6 +27,7 @@ import org.simantics.scl.compiler.elaboration.expressions.block.Statement; import org.simantics.scl.compiler.elaboration.java.Builtins; import org.simantics.scl.compiler.environment.Environment; import org.simantics.scl.compiler.environment.LocalEnvironment; +import org.simantics.scl.compiler.errors.CompilationError; import org.simantics.scl.compiler.errors.ErrorLog; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.ssa.SSAModule; @@ -41,12 +42,12 @@ import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; import org.simantics.scl.compiler.internal.codegen.writer.ExternalConstant; import org.simantics.scl.compiler.internal.codegen.writer.ModuleWriter; import org.simantics.scl.compiler.internal.elaboration.decomposed.DecomposedExpression; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.interpreted.IExpression; import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException; import org.simantics.scl.compiler.internal.parsing.parser.SCLBlockParser; import org.simantics.scl.compiler.internal.parsing.parser.SCLParserImpl; import org.simantics.scl.compiler.internal.parsing.parser.SCLParserOptions; +import org.simantics.scl.compiler.internal.parsing.utils.LineLocators; import org.simantics.scl.compiler.runtime.MutableClassLoader; import org.simantics.scl.compiler.runtime.RuntimeEnvironment; import org.simantics.scl.compiler.types.TVar; @@ -57,11 +58,15 @@ import org.simantics.scl.compiler.types.util.Polarity; import org.simantics.scl.compiler.types.util.ProcedureType; import org.simantics.scl.runtime.function.FunctionImpl1; import org.simantics.scl.runtime.tuple.Tuple0; +import org.slf4j.LoggerFactory; +import org.slf4j.Logger; import gnu.trove.set.hash.THashSet; public class ExpressionEvaluator { + private static final Logger LOGGER = LoggerFactory.getLogger(ExpressionEvaluator.class); + public static final boolean TRACE_INTERPRETATION_VS_COMPILATION = false; private static final String COMPUTATION_METHOD_NAME = "main"; @@ -77,6 +82,7 @@ public class ExpressionEvaluator { private LocalStorage localStorage; private boolean interpretIfPossible = true; private ExpressionParseMode parseMode = ExpressionParseMode.EXPRESSION; + private boolean validateOnly; public ExpressionEvaluator(RuntimeEnvironment runtimeEnvironment, String expressionText) { @@ -115,6 +121,11 @@ public class ExpressionEvaluator { return this; } + public ExpressionEvaluator validateOnly(boolean validateOnly) { + this.validateOnly = validateOnly; + return this; + } + /** * Sets a local environment that can arbitrarily modify the resolving of the expression. */ @@ -175,6 +186,16 @@ public class ExpressionEvaluator { return "store_" + name; } } + + public CompilationError[] validate() { + try { + validateOnly = true; + eval(); + return CompilationError.EMPTY_ARRAY; + } catch(SCLExpressionCompilationException e) { + return e.getErrors(); + } + } public Object eval() throws SCLExpressionCompilationException { fillDefaults(); @@ -186,6 +207,7 @@ public class ExpressionEvaluator { // Parse expression if(expressionText != null) { + compilationContext.lineLocator = LineLocators.createLineLocator(expressionText); try { switch(parseMode) { case BLOCK: { @@ -207,19 +229,21 @@ public class ExpressionEvaluator { } } catch(SCLSyntaxErrorException e) { errorLog.log(e.location, e.getMessage()); - //System.out.println(errorLog.getErrorsAsString()); + //LOGGER.info(errorLog.getErrorsAsString()); throw new SCLExpressionCompilationException(errorLog.getErrors()); } catch(Exception e) { errorLog.log(e); throw new SCLExpressionCompilationException(errorLog.getErrors()); } } + else + compilationContext.lineLocator = LineLocators.DUMMY_LOCATOR; // Store local variables ArrayList lvTypes = new ArrayList(); if(expression instanceof EBlock) { EBlock block = (EBlock)expression; - if(localStorage != null && !(block.getStatements().getLast() instanceof GuardStatement)) { + if(localStorage != null && !(block.getLast() instanceof GuardStatement)) { THashSet localVariables = new THashSet(); ListIterator it = block.getStatements().listIterator(); while(it.hasNext()) { @@ -243,17 +267,19 @@ public class ExpressionEvaluator { Types.functionE(type, Types.PROC, Types.UNIT)), new EVar(variableName) ))); + if(validateOnly) + localStorage.store(variableName, null, type); } } - if(!(block.getStatements().getLast() instanceof GuardStatement)) + if(!(block.getLast() instanceof GuardStatement)) block.addStatement(new GuardStatement(new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]))); } // Elaboration { - TranslationContext context = new TranslationContext(compilationContext, localEnvironment); + TranslationContext context = new TranslationContext(compilationContext, localEnvironment, "expression"); expression = expression.resolve(context); - if(!errorLog.isEmpty()) + if(!errorLog.hasNoErrors()) throw new SCLExpressionCompilationException(errorLog.getErrors()); } @@ -278,21 +304,24 @@ public class ExpressionEvaluator { expectedType.addPolarity(Polarity.POSITIVE); context.solveSubsumptions(expression.location); - if(!errorLog.isEmpty()) + if(!errorLog.hasNoErrors()) throw new SCLExpressionCompilationException(errorLog.getErrors()); if(decorateExpression && Types.canonical(expectedEffect) != Types.NO_EFFECTS) { - ExpressionDecorator decorator = + ToplevelEffectDecorator decorator = new ToplevelEffectDecorator(errorLog, environment); - expression = expression.decorate(decorator); + expression = expression.accept(decorator); } expression = context.solveConstraints(environment, expression); expressionType = expression.getType(); - if(!errorLog.isEmpty()) + if(!errorLog.hasNoErrors()) throw new SCLExpressionCompilationException(errorLog.getErrors()); if(localEnvironment != null) expression = localEnvironment.postDecorateExpression(expression); + + if(validateOnly) + return null; Type type = expression.getType(); type = type.convertMetaVarsToVars(); @@ -319,11 +348,11 @@ public class ExpressionEvaluator { new SimplificationContext(compilationContext, DummyJavaReferenceValidator.INSTANCE); expression = expression.simplify(context); - if(!errorLog.isEmpty()) + if(!errorLog.hasNoErrors()) throw new SCLExpressionCompilationException(errorLog.getErrors()); if(SCLCompilerConfiguration.SHOW_EXPRESSION_BEFORE_EVALUATION) - System.out.println(expression); + LOGGER.info("{}", expression); if(interpretIfPossible) { // Try to interpret @@ -333,9 +362,9 @@ public class ExpressionEvaluator { new TransientClassBuilder(classLoader, javaTypeTranslator)); IExpression iexp = expression.toIExpression(expressionInterpretationContext); if(TRACE_INTERPRETATION_VS_COMPILATION) - System.out.println("INTERPRETED " + expressionText); + LOGGER.info("INTERPRETED " + expressionText); if(SCLCompilerConfiguration.SHOW_INTERPRETED_EXPRESSION) - System.out.println("INTERPRETED AS: " + iexp); + LOGGER.info("INTERPRETED AS: " + iexp); return iexp.execute(new Object[expressionInterpretationContext.getMaxVariableId()]); } catch(UnsupportedOperationException e) { // This is normal when expression cannot be interpreted. We compile it instead. @@ -343,9 +372,9 @@ public class ExpressionEvaluator { } // Convert to SSA - ModuleWriter mw = new ModuleWriter(namingPolicy.getModuleClassName()); + ModuleWriter mw = new ModuleWriter(namingPolicy.getModuleClassName(), compilationContext.lineLocator); DecomposedExpression decomposed = - DecomposedExpression.decompose(expression); + DecomposedExpression.decompose(errorLog, expression); SCLConstant constant = new SCLConstant( Name.create(moduleName, COMPUTATION_METHOD_NAME), @@ -366,16 +395,17 @@ public class ExpressionEvaluator { IVal[] parameterVals = w.getParameters(); for(int i=0;i classes = moduleBuilder.getClasses(); + ssaModule.cleanup(); // Load generated code and execute try {