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;
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;
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";
private LocalStorage localStorage;
private boolean interpretIfPossible = true;
private ExpressionParseMode parseMode = ExpressionParseMode.EXPRESSION;
+ private boolean validateOnly;
public ExpressionEvaluator(RuntimeEnvironment runtimeEnvironment,
String expressionText) {
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.
*/
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();
// Parse expression
if(expressionText != null) {
+ compilationContext.lineLocator = LineLocators.createLineLocator(expressionText);
try {
switch(parseMode) {
case BLOCK: {
}
} 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<Type> lvTypes = new ArrayList<Type>();
if(expression instanceof EBlock) {
EBlock block = (EBlock)expression;
- if(localStorage != null && !(block.getStatements().getLast() instanceof GuardStatement)) {
+ if(localStorage != null && !(block.getLast() instanceof GuardStatement)) {
THashSet<String> localVariables = new THashSet<String>();
ListIterator<Statement> it = block.getStatements().listIterator();
while(it.hasNext()) {
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());
}
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();
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
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.
}
// 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),
IVal[] parameterVals = w.getParameters();
for(int i=0;i<decomposed.parameters.length;++i)
decomposed.parameters[i].setVal(parameterVals[i]);
- w.return_(decomposed.body.toVal(environment, w));
+ w.return_(decomposed.body.location, decomposed.body.toVal(compilationContext, w));
} catch(RuntimeException e) {
errorLog.setExceptionPosition(expression.location);
+ errorLog.log(e);
throw new SCLExpressionCompilationException(errorLog.getErrors());
}
SSAModule ssaModule = mw.getModule();
if(SCLCompilerConfiguration.SHOW_SSA_BEFORE_OPTIMIZATION) {
- System.out.println("=== SSA before optimization ==================================");
- System.out.println(ssaModule);
+ LOGGER.info("=== SSA before optimization ==================================");
+ LOGGER.info("{}", ssaModule);
}
if(SCLCompilerConfiguration.DEBUG)
ssaModule.validate();
for(int phase=0;phase<CodeGeneration.OPTIMIZATION_PHASES;++phase) {
int optCount = 0;
while(optCount++ < 4 && ssaModule.simplify(environment, phase)) {
- //System.out.println("simplify " + optCount);
+ //LOGGER.info("simplify " + optCount);
}
}
if(SCLCompilerConfiguration.SHOW_SSA_BEFORE_LAMBDA_LIFTING) {
- System.out.println("=== SSA before lambda lifting ==================================");
- System.out.println(ssaModule);
+ LOGGER.info("=== SSA before lambda lifting ==================================");
+ LOGGER.info("{}", ssaModule);
}
//ssaModule.saveInlinableDefinitions();
ssaModule.lambdaLift(errorLog);
// Generate code
if(SCLCompilerConfiguration.SHOW_FINAL_SSA)
- System.out.println(ssaModule);
+ LOGGER.info("{}", ssaModule);
try {
ssaModule.generateCode(moduleBuilder);
} catch (CodeBuildingException e) {
throw new SCLExpressionCompilationException(errorLog.getErrors());
}
Map<String, byte[]> classes = moduleBuilder.getClasses();
+ ssaModule.cleanup();
// Load generated code and execute
try {