Skip to content

Commit 70c13d8

Browse files
authored
Merge pull request killme2008#376 from killme2008/v5.2.6-dev
V5.2.6 dev
2 parents 7ec7ae3 + 8f7fa29 commit 70c13d8

File tree

13 files changed

+214
-42
lines changed

13 files changed

+214
-42
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
<groupId>com.googlecode.aviator</groupId>
1111
<artifactId>aviator</artifactId>
12-
<version>5.2.6-SNAPSHOT</version>
12+
<version>5.2.7-SNAPSHOT</version>
1313
<name>aviator</name>
1414
<description>A lightweight, high performance expression evaluator for java</description>
1515
<url>https://github.com/killme2008/aviator</url>

src/main/java/com/googlecode/aviator/lexer/token/OperatorType.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,10 @@ public AviatorObject eval(final AviatorObject[] args, final Map<String, Object>
154154
// swap arguments
155155
return args[1].match(args[0], env);
156156
case AND:
157-
return args[0].booleanValue(env) && args[1].booleanValue(env) ? AviatorBoolean.TRUE
157+
return (args[0].booleanValue(env) && args[1].booleanValue(env)) ? AviatorBoolean.TRUE
158158
: AviatorBoolean.FALSE;
159159
case OR:
160-
return args[0].booleanValue(env) || args[1].booleanValue(env) ? AviatorBoolean.TRUE
160+
return (args[0].booleanValue(env) || args[1].booleanValue(env)) ? AviatorBoolean.TRUE
161161
: AviatorBoolean.FALSE;
162162
case FUNC:
163163
// TODO

src/main/java/com/googlecode/aviator/runtime/function/DispatchFunction.java

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public void install(final LambdaFunction fn) {
4141
} else {
4242
this.functions.put(fn.getArity(), fn);
4343
}
44+
fn.setInstalled(true);
4445
}
4546

4647
@Override
@@ -67,25 +68,7 @@ public AviatorObject variadicCall(final Map<String, Object> env, AviatorObject..
6768
assert (arity + 1 >= arity);
6869

6970
if (fn.isVariadic()) {
70-
if (arity + 1 == fn.getArity()) {
71-
AviatorObject[] newArgs = new AviatorObject[arity + 1];
72-
System.arraycopy(args, 0, newArgs, 0, arity);
73-
newArgs[arity] = AviatorRuntimeJavaType.valueOf(EMPTY_VAR_ARGS);
74-
75-
args = newArgs;
76-
} else {
77-
AviatorObject[] newArgs = new AviatorObject[fn.getArity()];
78-
System.arraycopy(args, 0, newArgs, 0, fn.getArity() - 1);
79-
Object[] varArgs = new Object[arity - fn.getArity() + 1];
80-
81-
for (int i = 0; i < varArgs.length; i++) {
82-
varArgs[i] = args[fn.getArity() - 1 + i].getValue(env);
83-
}
84-
85-
newArgs[fn.getArity() - 1] = AviatorRuntimeJavaType.valueOf(varArgs);
86-
87-
args = newArgs;
88-
}
71+
args = processVariadicArgs(env, arity, fn, args);
8972
}
9073

9174
switch (fn.getArity()) {
@@ -157,4 +140,28 @@ public AviatorObject variadicCall(final Map<String, Object> env, AviatorObject..
157140

158141
}
159142

143+
static AviatorObject[] processVariadicArgs(final Map<String, Object> env, final int arity,
144+
final LambdaFunction fn, AviatorObject[] args) {
145+
if (arity + 1 == fn.getArity()) {
146+
AviatorObject[] newArgs = new AviatorObject[arity + 1];
147+
System.arraycopy(args, 0, newArgs, 0, arity);
148+
newArgs[arity] = AviatorRuntimeJavaType.valueOf(EMPTY_VAR_ARGS);
149+
150+
args = newArgs;
151+
} else {
152+
AviatorObject[] newArgs = new AviatorObject[fn.getArity()];
153+
System.arraycopy(args, 0, newArgs, 0, fn.getArity() - 1);
154+
Object[] varArgs = new Object[arity - fn.getArity() + 1];
155+
156+
for (int i = 0; i < varArgs.length; i++) {
157+
varArgs[i] = args[fn.getArity() - 1 + i].getValue(env);
158+
}
159+
160+
newArgs[fn.getArity() - 1] = AviatorRuntimeJavaType.valueOf(varArgs);
161+
162+
args = newArgs;
163+
}
164+
return args;
165+
}
166+
160167
}

src/main/java/com/googlecode/aviator/runtime/function/LambdaFunction.java

Lines changed: 112 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ public final class LambdaFunction extends AbstractVariadicFunction {
3939

4040
private final String name;
4141

42+
// Whether to be installed in dispatch function.
43+
private boolean installed;
44+
45+
public boolean isInstalled() {
46+
return this.installed;
47+
}
48+
49+
public void setInstalled(final boolean installed) {
50+
this.installed = installed;
51+
}
4252

4353
public boolean isInheritEnv() {
4454
return this.inheritEnv;
@@ -89,62 +99,133 @@ public boolean isVariadic() {
8999
return this.isVariadic;
90100
}
91101

92-
93-
94102
@Override
95103
public AviatorObject call(final Map<String, Object> env) {
96-
return AviatorRuntimeJavaType.valueOf(this.expression.executeDirectly(newEnv(env)));
104+
try {
105+
if (this.isVariadic && !this.installed) {
106+
return variadicCall(env, true);
107+
}
108+
return AviatorRuntimeJavaType.valueOf(this.expression.executeDirectly(newEnv(env)));
109+
} finally {
110+
if (this.inheritEnv) {
111+
this.context = null;
112+
}
113+
}
97114
}
98115

99116
@Override
100117
public AviatorObject call(final Map<String, Object> env, final AviatorObject arg1) {
101-
return AviatorRuntimeJavaType.valueOf(this.expression.executeDirectly(newEnv(env, arg1)));
118+
try {
119+
if (this.isVariadic && !this.installed) {
120+
return variadicCall(env, true, arg1);
121+
}
122+
return AviatorRuntimeJavaType.valueOf(this.expression.executeDirectly(newEnv(env, arg1)));
123+
} finally {
124+
if (this.inheritEnv) {
125+
this.context = null;
126+
}
127+
}
102128
}
103129

104130
@Override
105131
public AviatorObject call(final Map<String, Object> env, final AviatorObject arg1,
106132
final AviatorObject arg2) {
107-
return AviatorRuntimeJavaType.valueOf(this.expression.executeDirectly(newEnv(env, arg1, arg2)));
133+
try {
134+
if (this.isVariadic && !this.installed) {
135+
return variadicCall(env, true, arg1, arg2);
136+
}
137+
return AviatorRuntimeJavaType
138+
.valueOf(this.expression.executeDirectly(newEnv(env, arg1, arg2)));
139+
} finally {
140+
if (this.inheritEnv) {
141+
this.context = null;
142+
}
143+
}
108144
}
109145

110146
@Override
111147
public AviatorObject call(final Map<String, Object> env, final AviatorObject arg1,
112148
final AviatorObject arg2, final AviatorObject arg3) {
113-
return AviatorRuntimeJavaType
114-
.valueOf(this.expression.executeDirectly(newEnv(env, arg1, arg2, arg3)));
149+
try {
150+
if (this.isVariadic && !this.installed) {
151+
return variadicCall(env, true, arg1, arg2, arg3);
152+
}
153+
return AviatorRuntimeJavaType
154+
.valueOf(this.expression.executeDirectly(newEnv(env, arg1, arg2, arg3)));
155+
} finally {
156+
if (this.inheritEnv) {
157+
this.context = null;
158+
}
159+
}
115160
}
116161

117162
@Override
118163
public AviatorObject call(final Map<String, Object> env, final AviatorObject arg1,
119164
final AviatorObject arg2, final AviatorObject arg3, final AviatorObject arg4) {
120-
return AviatorRuntimeJavaType
121-
.valueOf(this.expression.executeDirectly(newEnv(env, arg1, arg2, arg3, arg4)));
165+
try {
166+
if (this.isVariadic && !this.installed) {
167+
return variadicCall(env, true, arg1, arg2, arg3, arg4);
168+
}
169+
return AviatorRuntimeJavaType
170+
.valueOf(this.expression.executeDirectly(newEnv(env, arg1, arg2, arg3, arg4)));
171+
} finally {
172+
if (this.inheritEnv) {
173+
this.context = null;
174+
}
175+
}
122176
}
123177

124178
@Override
125179
public AviatorObject call(final Map<String, Object> env, final AviatorObject arg1,
126180
final AviatorObject arg2, final AviatorObject arg3, final AviatorObject arg4,
127181
final AviatorObject arg5) {
128-
return AviatorRuntimeJavaType
129-
.valueOf(this.expression.executeDirectly(newEnv(env, arg1, arg2, arg3, arg4, arg5)));
182+
try {
183+
if (this.isVariadic && !this.installed) {
184+
return variadicCall(env, true, arg1, arg2, arg3, arg4, arg5);
185+
}
186+
return AviatorRuntimeJavaType
187+
.valueOf(this.expression.executeDirectly(newEnv(env, arg1, arg2, arg3, arg4, arg5)));
188+
} finally {
189+
if (this.inheritEnv) {
190+
this.context = null;
191+
}
192+
}
130193
}
131194

132195

133196
@Override
134197
public AviatorObject call(final Map<String, Object> env, final AviatorObject arg1,
135198
final AviatorObject arg2, final AviatorObject arg3, final AviatorObject arg4,
136199
final AviatorObject arg5, final AviatorObject arg6) {
137-
return AviatorRuntimeJavaType
138-
.valueOf(this.expression.executeDirectly(newEnv(env, arg1, arg2, arg3, arg4, arg5, arg6)));
200+
try {
201+
if (this.isVariadic && !this.installed) {
202+
return variadicCall(env, true, arg1, arg2, arg3, arg4, arg5, arg6);
203+
}
204+
return AviatorRuntimeJavaType.valueOf(
205+
this.expression.executeDirectly(newEnv(env, arg1, arg2, arg3, arg4, arg5, arg6)));
206+
} finally {
207+
if (this.inheritEnv) {
208+
this.context = null;
209+
}
210+
}
139211
}
140212

141213

142214
@Override
143215
public AviatorObject call(final Map<String, Object> env, final AviatorObject arg1,
144216
final AviatorObject arg2, final AviatorObject arg3, final AviatorObject arg4,
145217
final AviatorObject arg5, final AviatorObject arg6, final AviatorObject arg7) {
146-
return AviatorRuntimeJavaType.valueOf(
147-
this.expression.executeDirectly(newEnv(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7)));
218+
try {
219+
if (this.isVariadic && !this.installed) {
220+
return variadicCall(env, true, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
221+
}
222+
return AviatorRuntimeJavaType.valueOf(
223+
this.expression.executeDirectly(newEnv(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7)));
224+
} finally {
225+
if (this.inheritEnv) {
226+
this.context = null;
227+
}
228+
}
148229
}
149230

150231

@@ -180,9 +261,24 @@ protected Map<String, Object> newEnv(final Map<String, Object> parentEnv,
180261
return env;
181262
}
182263

264+
public AviatorObject variadicCall(final Map<String, Object> env, final boolean processArgs,
265+
AviatorObject... args) {
266+
if (processArgs) {
267+
args = DispatchFunction.processVariadicArgs(env, args.length, this, args);
268+
}
269+
270+
return AviatorRuntimeJavaType.valueOf(this.expression.executeDirectly(newEnv(env, args)));
271+
}
272+
183273
@Override
184274
public AviatorObject variadicCall(final Map<String, Object> env, final AviatorObject... args) {
185-
return AviatorRuntimeJavaType.valueOf(this.expression.executeDirectly(newEnv(env, args)));
275+
try {
276+
return this.variadicCall(env, false, args);
277+
} finally {
278+
if (this.inheritEnv) {
279+
this.context = null;
280+
}
281+
}
186282
}
187283

188284
}

src/main/java/com/googlecode/aviator/runtime/function/internal/IfCallccFunction.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,14 @@ public String getName() {
3131
@Override
3232
public AviatorObject call(final Map<String, Object> env, final AviatorObject arg1,
3333
final AviatorObject arg2) {
34-
if (arg1 instanceof ReducerResult && ((ReducerResult) arg1).state != ReducerState.Cont) {
34+
if (arg1 instanceof ReducerResult) {
3535
return arg1;
3636
} else {
3737
final Object nextClauseVal = arg2.getValue(env);
3838
if (nextClauseVal == Constants.REDUCER_EMPTY) {
3939
return arg1;
4040
}
41+
4142
AviatorFunction otherClausesFn = (AviatorFunction) nextClauseVal;
4243
AviatorObject result = otherClausesFn.call(env);
4344
// No remaining statements, return the if statement result.

src/main/java/com/googlecode/aviator/utils/Reflector.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import java.lang.ref.Reference;
1717
import java.lang.ref.ReferenceQueue;
1818
import java.lang.ref.SoftReference;
19-
import java.lang.ref.WeakReference;
2019
import java.lang.reflect.Array;
2120
import java.lang.reflect.Field;
2221
import java.lang.reflect.Method;
@@ -371,7 +370,7 @@ private static Map<String, PropertyFoundResult> getClassPropertyResults(
371370
clearCache(rq, cache);
372371
results = new ConcurrentHashMap<String, PropertyFoundResult>();
373372
existsRef = cache.putIfAbsent(clazz,
374-
new WeakReference<Map<String, PropertyFoundResult>>(results, rq));
373+
new SoftReference<Map<String, PropertyFoundResult>>(results, rq));
375374
}
376375
if (existsRef == null) {
377376
return results;

src/main/resources/aviator.av

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ fn is_empty(s) {
130130
count(s) == 0
131131
}
132132

133+
fn partial(f, &args) {
134+
return fn(&remaining) {
135+
return f(*args, *remaining);
136+
};
137+
}
138+
133139
exports.take_while = take_while;
134140
exports.drop_while = drop_while;
135141
exports.repeat = repeat;
@@ -140,3 +146,4 @@ exports.concat = concat;
140146
exports.constantly = constantly;
141147
exports.is_empty = is_empty;
142148
exports.is_distinct = is_distinct;
149+
exports.partial = partial;

src/test/java/com/googlecode/aviator/scripts/TestScripts.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ public void testForLoop() {
247247
assertEquals(100, testScript("for_break4.av", "a", 101));
248248
assertEquals(4, testScript("for_break5.av", "a", 5));
249249
assertEquals(100, testScript("for_break5.av", "a", 101));
250+
assertEquals(3, testScript("for_break6.av", "a", 101));
250251
}
251252

252253
{
@@ -263,6 +264,10 @@ public void testForLoop() {
263264
assertEquals(108, testScript("for_continue4.av", "a", 51));
264265
assertEquals(10, testScript("for_continue4.av", "a", 11));
265266
assertEquals(21, testScript("for_continue4.av", "a", 12));
267+
268+
assertEquals(10, testScript("for_continue5.av", "a", 11));
269+
assertEquals(21, testScript("for_continue5.av", "a", 12));
270+
assertEquals(41, testScript("for_continue6.av"));
266271
}
267272

268273
{

src/test/resources/lib/test_aviator.av

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,23 @@ fn test_meta(){
340340
j.assertSame(a, without_meta(a, "not exists"));
341341
}
342342

343+
fn add(&args) {
344+
reduce(args, +, 0)
345+
}
346+
347+
fn test_partial() {
348+
tests = tests + 1;
349+
let add_3 = partial(+, 3);
350+
j.assertEquals(7, add_3(4));
351+
j.assertEquals(103, add_3(100));
352+
353+
let t = partial(add, 1, 2, 3);
354+
j.assertEquals(6, t());
355+
j.assertEquals(10, t(4));
356+
j.assertEquals(15, t(4, 5));
357+
j.assertEquals(21, t(4, 5, 6));
358+
}
359+
343360
test_take_while();
344361
test_drop_while();
345362
test_concat();
@@ -359,5 +376,6 @@ test_new_static_class();
359376
test_static_methods();
360377
test_is_distinct();
361378
test_meta();
379+
test_partial();
362380

363-
j.assertEquals(19, tests);
381+
j.assertEquals(20, tests);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
let y = 0;
2+
for x in range(0, a) {
3+
if(x > 3) {
4+
break;
5+
} else {
6+
let z = x;
7+
z = z + 1;
8+
}
9+
y = x;
10+
}
11+
return y;

0 commit comments

Comments
 (0)