1 package org.simantics.scl.compiler.tests;
3 import java.util.Arrays;
5 import junit.framework.Assert;
7 import org.junit.Before;
9 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
10 import org.simantics.scl.compiler.elaboration.expressions.Expression;
11 import org.simantics.scl.compiler.elaboration.expressions.Variable;
12 import org.simantics.scl.compiler.environment.AbstractLocalEnvironment;
13 import org.simantics.scl.compiler.environment.Environment;
14 import org.simantics.scl.compiler.environment.LocalEnvironment;
15 import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
16 import org.simantics.scl.compiler.errors.CompilationErrorFormatter;
17 import org.simantics.scl.compiler.module.repository.ImportFailure;
18 import org.simantics.scl.compiler.module.repository.ImportFailureException;
19 import org.simantics.scl.compiler.module.repository.ModuleRepository;
20 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
21 import org.simantics.scl.compiler.source.repository.CompositeModuleSourceRepository;
22 import org.simantics.scl.compiler.source.repository.SourceRepositories;
23 import org.simantics.scl.compiler.top.ExpressionEvaluator;
24 import org.simantics.scl.compiler.top.SCLExpressionCompilationException;
25 import org.simantics.scl.compiler.types.Type;
26 import org.simantics.scl.compiler.types.Types;
27 import org.simantics.scl.runtime.function.Function;
28 import org.simantics.scl.runtime.tuple.Tuple0;
30 public class TestExpressionEvaluator {
32 public static final boolean TIMING = false;
33 public static final int COUNT = 10000;
35 ModuleRepository moduleRepository;
37 RuntimeEnvironment runtimeEnvironment;
40 public void initialize() throws Exception {
41 moduleRepository = new ModuleRepository(
42 new CompositeModuleSourceRepository(
43 SourceRepositories.BUILTIN_SOURCE_REPOSITORY,
44 SourceRepositories.PRELUDE_SOURCE_REPOSITORY
47 // Environment for compiling expressions
48 EnvironmentSpecification environmentSpecification = new EnvironmentSpecification();
49 environmentSpecification.importModule("Builtin", "");
50 environmentSpecification.importModule("Prelude", "");
53 runtimeEnvironment = moduleRepository.createRuntimeEnvironment(environmentSpecification,
54 getClass().getClassLoader());
55 } catch(ImportFailureException e) {
56 for(ImportFailure failure : e.failures)
57 System.err.println("Failed to import " + failure.moduleName);
62 private void testExpression0(String expressionText,
64 Type expectedType) throws Exception {
65 // Compiling and running expression
67 Object result = new ExpressionEvaluator(runtimeEnvironment, expressionText)
68 .expectedType(expectedType)
70 if(expectedValue != null)
71 Assert.assertEquals(expectedValue, result);
72 } catch(SCLExpressionCompilationException e) {
73 System.out.println(CompilationErrorFormatter.toString(expressionText, e.getErrors()));
78 private void testExpression(String expressionText,
80 Type expectedType) throws Exception {
82 System.out.println(expressionText);
83 long beginTime = System.nanoTime();
84 for(int i=0;i<COUNT;++i)
85 testExpression0(expressionText, expectedValue, expectedType);
86 long endTime = System.nanoTime();
87 System.out.println( " " + (endTime-beginTime)*1e-6/COUNT + " ms");
90 testExpression0(expressionText, expectedValue, expectedType);
94 public void testExpressionCompiler() throws Exception {
101 testExpression("map (\\(_,x) -> x) [(1,2),(2,3)]",
102 Arrays.asList(2.0, 3.0),
103 Types.list(Types.DOUBLE));
104 testExpression("map (\\x -> snd x) [(1,2),(2,3)]",
105 Arrays.asList(2.0, 3.0),
106 Types.list(Types.DOUBLE));
107 testExpression("let f x = x+1 in (f . f . f) 3",
111 testExpression("print \"Hello world!\"",
114 testExpression("[1,2+3,4+5]",
115 Arrays.asList(1,5,9),
116 Types.list(Types.INTEGER));
117 testExpression("let a = 5.3 in let f x = x+a in f 3",
120 testExpression("let mm x y = if x < y then x else y in mm 2 (mm 1 3)",
126 public void testLocalEnvironment() throws Exception {
127 String expressionText = "a + b";
128 LocalEnvironment localEnvironment = new AbstractLocalEnvironment() {
129 Variable[] localParameters = new Variable[] {
130 new Variable("a", Types.DOUBLE),
131 new Variable("b", Types.DOUBLE),
135 public Expression resolve(Environment environment, String localName) {
136 if(localName.equals("a"))
137 return new EVariable(localParameters[0]);
138 else if(localName.equals("b"))
139 return new EVariable(localParameters[1]);
145 protected Variable[] getContextVariables() {
146 return localParameters;
150 Object result = new ExpressionEvaluator(runtimeEnvironment, expressionText)
151 .localEnvironment(localEnvironment)
152 .expectedType(Types.DOUBLE)
155 Double.valueOf(15.0),
156 ((Function)result).apply(7.0, 8.0));
157 } catch(SCLExpressionCompilationException e) {
158 System.out.println(CompilationErrorFormatter.toString(expressionText, e.getErrors()));
164 public void testArities() throws Exception {
165 for(int arity=1;arity<50;++arity) {
167 StringBuilder b = new StringBuilder();
169 for(int i=0;i<arity;++i)
170 b.append("v" + i + " ");
172 for(int i=0;i<arity;++i) {
177 //System.out.println(b.toString());
180 Type expectedType = Types.INTEGER;
181 for(int i=0;i<arity;++i)
182 expectedType = Types.function(Types.INTEGER, expectedType);
184 Function function = (Function)new ExpressionEvaluator(runtimeEnvironment, b.toString())
185 .expectedType(expectedType)
186 .interpretIfPossible(false)
190 Object[] parameters = new Object[arity];
192 for(int i=0;i<arity;++i) {
194 parameters[i] = value;
197 Object result = function.applyArray(parameters);
198 Assert.assertEquals(sum, result);
203 public void testSeq() throws Exception {
204 String expressionText = "Sequences.runSequence mdo\n" +
205 " repeatForever mdo\n" +
206 " Sequences.wait 2\n" +
210 Object result = new ExpressionEvaluator(runtimeEnvironment, expressionText)
213 } catch(SCLExpressionCompilationException e) {
214 System.out.println(CompilationErrorFormatter.toString(expressionText, e.getErrors()));