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;
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: {
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)
}
// 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());
}
throw new SCLExpressionCompilationException(errorLog.getErrors());
}
Map<String, byte[]> classes = moduleBuilder.getClasses();
+ ssaModule.cleanup();
// Load generated code and execute
try {