]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/interpreted/ILambda.java
aac13af73abe661ddcc275f0e3f83908b6937e4f
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / interpreted / ILambda.java
1 package org.simantics.scl.compiler.internal.interpreted;
2
3 import org.simantics.scl.runtime.function.FunctionImpl1;
4 import org.simantics.scl.runtime.function.FunctionImpl2;
5 import org.simantics.scl.runtime.function.FunctionImpl3;
6 import org.simantics.scl.runtime.function.FunctionImpl4;
7 import org.simantics.scl.runtime.function.FunctionImplN;
8
9 public class ILambda implements IExpression {
10     private final int[] inheritedVariableIds;
11     private final int arity;
12     private final int variableBindingsLength;
13     private final IExpression body;
14     
15     public ILambda(int[] inheritedVariableIds, int arity,
16             int variableBindingsLength, IExpression body) {
17         this.inheritedVariableIds = inheritedVariableIds;
18         this.arity = arity;
19         this.variableBindingsLength = variableBindingsLength;
20         this.body = body;
21     }
22
23     @SuppressWarnings("rawtypes")
24     @Override
25     public Object execute(Object[] variableBindings) {
26         final Object[] inheritedVariableBindings = new Object[inheritedVariableIds.length];
27         for(int i=0;i<inheritedVariableIds.length;++i)
28             inheritedVariableBindings[i] = variableBindings[inheritedVariableIds[i]];
29         switch(arity) {
30         case 1:
31             return new FunctionImpl1() {
32                 @Override
33                 public Object apply(Object param0) {
34                     Object[] newVariableBindings = new Object[variableBindingsLength];
35                     int i = 0;;
36                     for(;i < inheritedVariableBindings.length;++i)
37                         newVariableBindings[i] = inheritedVariableBindings[i];
38                     newVariableBindings[i] = param0;
39                     return body.execute(newVariableBindings);
40                 }
41                 
42                 @Override
43                 public String toString() {
44                         return ILambda.this.toString(inheritedVariableBindings);
45                 }
46             };
47         case 2:
48             return new FunctionImpl2() {
49                 @Override
50                 public Object apply(Object param0, Object param1) {
51                     Object[] newVariableBindings = new Object[variableBindingsLength];
52                     int i = 0;;
53                     for(;i < inheritedVariableBindings.length;++i)
54                         newVariableBindings[i] = inheritedVariableBindings[i];
55                     newVariableBindings[i++] = param0;
56                     newVariableBindings[i] = param1;
57                     return body.execute(newVariableBindings);
58                 }
59                 
60                 @Override
61                 public String toString() {
62                         return ILambda.this.toString(inheritedVariableBindings);
63                 }
64             };
65         case 3:
66             return new FunctionImpl3() {
67                 @Override
68                 public Object apply(Object param0, Object param1, Object param2) {
69                     Object[] newVariableBindings = new Object[variableBindingsLength];
70                     int i = 0;;
71                     for(;i < inheritedVariableBindings.length;++i)
72                         newVariableBindings[i] = inheritedVariableBindings[i];
73                     newVariableBindings[i++] = param0;
74                     newVariableBindings[i++] = param1;
75                     newVariableBindings[i] = param2;
76                     return body.execute(newVariableBindings);
77                 }
78                 
79                 @Override
80                 public String toString() {
81                         return ILambda.this.toString(inheritedVariableBindings);
82                 }
83             };
84         case 4:
85             return new FunctionImpl4() {
86                 @Override
87                 public Object apply(Object param0, Object param1, Object param2, Object param3) {
88                     Object[] newVariableBindings = new Object[variableBindingsLength];
89                     int i = 0;;
90                     for(;i < inheritedVariableBindings.length;++i)
91                         newVariableBindings[i] = inheritedVariableBindings[i];
92                     newVariableBindings[i++] = param0;
93                     newVariableBindings[i++] = param1;
94                     newVariableBindings[i++] = param2;
95                     newVariableBindings[i] = param3;
96                     return body.execute(newVariableBindings);
97                 }
98                 
99                 @Override
100                 public String toString() {
101                         return ILambda.this.toString(inheritedVariableBindings);
102                 }
103             };
104         default:
105             return new FunctionImplN(arity) {
106                 @Override
107                 public Object doApply(Object... ps) {
108                     Object[] newVariableBindings = new Object[variableBindingsLength];
109                     int i = 0;;
110                     for(;i < inheritedVariableBindings.length;++i)
111                         newVariableBindings[i] = inheritedVariableBindings[i];
112                     for(Object p : ps)
113                         newVariableBindings[i++] = p;
114                     return body.execute(newVariableBindings);
115                 }
116                 
117                 @Override
118                 public String toString() {
119                         return ILambda.this.toString(inheritedVariableBindings);
120                 }
121             };
122         }
123     }
124     
125     @Override
126     public String toString() {
127         StringBuilder b = new StringBuilder();
128         b.append("(\\");
129         for(int i=0;i<inheritedVariableIds.length;++i)
130             b.append('v').append(i)
131             .append("(v").append(inheritedVariableIds[i]).append(") ");
132         for(int i=0;i<arity;++i)
133             b.append('v').append(i+inheritedVariableIds.length).append(' ');
134         b.append("-> ");
135         b.append(body);
136         b.append(')');
137         return b.toString();
138     }
139     
140     public String toString(Object[] variableBindings) {
141         StringBuilder sb = new StringBuilder();
142         appendVariableBindings(sb, variableBindings);
143         sb.append(this.toString());
144         return sb.toString();
145     }
146     
147     private static void appendVariableBindings(StringBuilder sb, Object[] variableBindings) {
148         if (variableBindings.length > 0) {
149                 sb.append("(let {");
150                 for(int i = 0; i < variableBindings.length; i++) {
151                         if (i > 0) sb.append("; ");
152                         sb.append("v").append(i).append("=").append(variableBindings[i].toString());
153                 }
154                 sb.append("} in ");
155         }       
156     }
157 }