]> gerrit.simantics Code Review - simantics/platform.git/blob
2e887ca1a420b04a0ed1dda7cc702f64bdd9b728
[simantics/platform.git] /
1 package org.simantics.scl.compiler.tests;
2
3 import java.util.Arrays;
4
5 import org.junit.Assert;
6 import org.junit.Before;
7 import org.junit.Test;
8 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
9 import org.simantics.scl.compiler.elaboration.expressions.Expression;
10 import org.simantics.scl.compiler.elaboration.expressions.Variable;
11 import org.simantics.scl.compiler.environment.AbstractLocalEnvironment;
12 import org.simantics.scl.compiler.environment.Environment;
13 import org.simantics.scl.compiler.environment.LocalEnvironment;
14 import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
15 import org.simantics.scl.compiler.errors.CompilationErrorFormatter;
16 import org.simantics.scl.compiler.module.repository.ImportFailure;
17 import org.simantics.scl.compiler.module.repository.ImportFailureException;
18 import org.simantics.scl.compiler.module.repository.ModuleRepository;
19 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
20 import org.simantics.scl.compiler.source.repository.CompositeModuleSourceRepository;
21 import org.simantics.scl.compiler.source.repository.SourceRepositories;
22 import org.simantics.scl.compiler.top.ExpressionEvaluator;
23 import org.simantics.scl.compiler.top.SCLExpressionCompilationException;
24 import org.simantics.scl.compiler.types.Type;
25 import org.simantics.scl.compiler.types.Types;
26 import org.simantics.scl.runtime.function.Function;
27 import org.simantics.scl.runtime.tuple.Tuple0;
28
29 public class TestExpressionEvaluator {
30
31     public static final boolean TIMING = false;
32     public static final int COUNT = 10000;
33
34     ModuleRepository moduleRepository;
35     
36     RuntimeEnvironment runtimeEnvironment;
37     
38     @Before
39     public void initialize() throws Exception {
40         moduleRepository = InitialRepository.getInitialRepository();
41         
42         // Environment for compiling expressions
43         EnvironmentSpecification environmentSpecification = new EnvironmentSpecification();
44         environmentSpecification.importModule("Builtin", "");
45         environmentSpecification.importModule("Prelude", "");
46         
47         try {
48             runtimeEnvironment = moduleRepository.createRuntimeEnvironment(environmentSpecification,
49                     getClass().getClassLoader());
50         } catch(ImportFailureException e) {
51             for(ImportFailure failure : e.failures)
52                 System.err.println("Failed to import " + failure.moduleName);
53             throw e;
54         }
55     }
56
57     private void testExpression0(String expressionText,
58             Object expectedValue,
59             Type expectedType) throws Exception {
60         // Compiling and running expression
61         try {
62             Object result = new ExpressionEvaluator(runtimeEnvironment, expressionText)
63             .expectedType(expectedType)
64             .eval();
65             if(expectedValue != null)
66                 Assert.assertEquals(expectedValue, result);
67         } catch(SCLExpressionCompilationException e) {
68             System.out.println(CompilationErrorFormatter.toString(expressionText, e.getErrors()));
69             throw e;
70         }
71     }
72     
73     private void testExpression(String expressionText,
74             Object expectedValue,
75             Type expectedType) throws Exception {
76         if(TIMING) {
77             System.out.println(expressionText);
78             long beginTime = System.nanoTime();
79             for(int i=0;i<COUNT;++i)
80                 testExpression0(expressionText, expectedValue, expectedType);
81             long endTime = System.nanoTime();
82             System.out.println( "    " + (endTime-beginTime)*1e-6/COUNT + " ms");
83         }
84         else
85             testExpression0(expressionText, expectedValue, expectedType);
86     }
87
88     @Test
89     public void testExpressionCompiler() throws Exception {
90         testExpression("1",
91                 Integer.valueOf(1),
92                 Types.INTEGER);
93         testExpression("1+2",
94                 Integer.valueOf(3),
95                 Types.INTEGER);
96         testExpression("map (\\(_,x) -> x) [(1,2),(2,3)]",
97                 Arrays.asList(2.0, 3.0),
98                 Types.list(Types.DOUBLE));
99         testExpression("map (\\x -> snd x) [(1,2),(2,3)]",
100                 Arrays.asList(2.0, 3.0),
101                 Types.list(Types.DOUBLE));
102         testExpression("let f x = x+1 in (f . f . f) 3",
103                 Double.valueOf(6.0),
104                 Types.DOUBLE);
105         if(!TIMING)
106             testExpression("print \"Hello world!\"",
107                     Tuple0.INSTANCE,
108                     Types.UNIT);
109         testExpression("[1,2+3,4+5]",
110                 Arrays.asList(1,5,9),
111                 Types.list(Types.INTEGER));
112         testExpression("let a = 5.3 in let f x = x+a in f 3",
113                 Double.valueOf(8.3),
114                 Types.DOUBLE);
115         testExpression("let mm x y = if x < y then x else y in mm 2 (mm 1 3)",
116                 Double.valueOf(1.0),
117                 Types.DOUBLE);
118     }
119
120     @Test
121     public void testLocalEnvironment() throws Exception {
122         String expressionText = "a + b";
123         LocalEnvironment localEnvironment = new AbstractLocalEnvironment() {
124             Variable[] localParameters = new Variable[] {
125                     new Variable("a", Types.DOUBLE),
126                     new Variable("b", Types.DOUBLE),
127             };
128             
129             @Override
130             public Expression resolve(Environment environment, String localName) {
131                 if(localName.equals("a"))
132                     return new EVariable(localParameters[0]);
133                 else if(localName.equals("b"))
134                     return new EVariable(localParameters[1]);
135                 else
136                     return null;
137             }
138             
139             @Override
140             protected Variable[] getContextVariables() {
141                 return localParameters;
142             }
143         };
144         try {
145             Object result = new ExpressionEvaluator(runtimeEnvironment, expressionText)
146             .localEnvironment(localEnvironment)
147             .expectedType(Types.DOUBLE)
148             .eval();
149             Assert.assertEquals(
150                     Double.valueOf(15.0),
151                     ((Function)result).apply(7.0, 8.0));
152         } catch(SCLExpressionCompilationException e) {
153             System.out.println(CompilationErrorFormatter.toString(expressionText, e.getErrors()));
154             throw e;
155         }
156     }
157     
158     @Test
159     public void testArities() throws Exception {
160         for(int arity=1;arity<50;++arity) {
161             // Build expressions
162             StringBuilder b = new StringBuilder();
163             b.append('\\');
164             for(int i=0;i<arity;++i)
165                 b.append("v" + i + " ");
166             b.append("-> ");
167             for(int i=0;i<arity;++i) {
168                 if(i > 0)
169                     b.append(" + ");
170                 b.append("v" + i);
171             }
172             //System.out.println(b.toString());
173             
174             // Compile
175             Type expectedType = Types.INTEGER;
176             for(int i=0;i<arity;++i)
177                 expectedType = Types.function(Types.INTEGER, expectedType);
178             
179             Function function = (Function)new ExpressionEvaluator(runtimeEnvironment, b.toString())
180             .expectedType(expectedType)
181             .interpretIfPossible(false)
182             .eval();
183             
184             // Evaluate
185             Object[] parameters = new Object[arity];
186             int sum = 0;
187             for(int i=0;i<arity;++i) {
188                 int value = i+1;
189                 parameters[i] = value;
190                 sum += value;
191             }
192             Object result = function.applyArray(parameters);
193             Assert.assertEquals(sum, result);
194         }
195     }
196 }