Skip to content

Commit 3ec9e53

Browse files
committed
add + and * tck snippets with custom verifiers
1 parent a605775 commit 3ec9e53

File tree

1 file changed

+73
-7
lines changed

1 file changed

+73
-7
lines changed

graalpython/com.oracle.graal.python.tck/src/com/oracle/graal/python/tck/PythonProvider.java

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,8 @@ public Collection<? extends Snippet> createExpressions(Context context) {
223223
List<Snippet> snippets = new ArrayList<>();
224224

225225
// @formatter:off
226-
addExpressionSnippet(context, snippets, "+", "lambda x, y: x + y", NUMBER, union(BOOLEAN, NUMBER), union(BOOLEAN, NUMBER));
227-
addExpressionSnippet(context, snippets, "+ str", "lambda x, y: x + y", NUMBER, union(BOOLEAN, NUMBER), union(BOOLEAN, NUMBER));
228-
addExpressionSnippet(context, snippets, "+ list", "lambda x, y: x + y", array(ANY), PNoListCoercionVerifier.INSTANCE, array(ANY), array(ANY));
226+
addExpressionSnippet(context, snippets, "+", "lambda x, y: x + y", union(STRING, NUMBER, array(ANY)), AddVerifier.INSTANCE, union(STRING, BOOLEAN, NUMBER, array(ANY)), union(STRING, BOOLEAN, NUMBER, array(ANY)));
227+
addExpressionSnippet(context, snippets, "*", "lambda x, y: x * y", union(STRING, NUMBER, array(ANY)), MulVerifier.INSTANCE, union(STRING, BOOLEAN, NUMBER, array(ANY)), union(STRING, BOOLEAN, NUMBER, array(ANY)));
229228

230229
addExpressionSnippet(context, snippets, "-", "lambda x, y: x - y", NUMBER, union(BOOLEAN, NUMBER), union(BOOLEAN, NUMBER));
231230

@@ -350,7 +349,7 @@ private abstract static class PResultVerifier implements ResultVerifier {
350349
/**
351350
* Only accepts exact matches of types.
352351
*/
353-
private static class PNoListCoercionVerifier extends PResultVerifier {
352+
private static class AddVerifier extends PResultVerifier {
354353

355354
public void accept(SnippetRun snippetRun) throws PolyglotException {
356355
List<? extends Value> parameters = snippetRun.getParameters();
@@ -363,14 +362,81 @@ public void accept(SnippetRun snippetRun) throws PolyglotException {
363362
// ignore '(1,2) + [3,4]'.
364363
if (par0.hasArrayElements() && par1.hasArrayElements()) {
365364
if (par0.getMetaObject() == par1.getMetaObject()) {
366-
ResultVerifier.getDefaultResultVerifier().accept(snippetRun);
365+
assert snippetRun.getException() == null;
366+
TypeDescriptor resultType = TypeDescriptor.forValue(snippetRun.getResult());
367+
assert array(ANY).isAssignable(resultType);
367368
}
369+
} else if (par0.isString() && par1.isString()) {
370+
assert snippetRun.getException() == null;
371+
TypeDescriptor resultType = TypeDescriptor.forValue(snippetRun.getResult());
372+
assert STRING.isAssignable(resultType);
373+
} else if ((par0.isNumber() || par0.isBoolean()) && (par1.isNumber() || par1.isBoolean())) {
374+
assert snippetRun.getException() == null;
375+
TypeDescriptor resultType = TypeDescriptor.forValue(snippetRun.getResult());
376+
assert NUMBER.isAssignable(resultType);
368377
} else {
369-
ResultVerifier.getDefaultResultVerifier().accept(snippetRun);
378+
assert snippetRun.getException() != null;
379+
TypeDescriptor argType = union(STRING, BOOLEAN, NUMBER, array(ANY));
380+
TypeDescriptor par0Type = TypeDescriptor.forValue(par0);
381+
TypeDescriptor par1Type = TypeDescriptor.forValue(par1);
382+
if (!argType.isAssignable(par0Type) || !argType.isAssignable(par1Type)) {
383+
// argument type error, rethrow
384+
throw snippetRun.getException();
385+
} else {
386+
// arguments are ok, just don't work in this combination
387+
}
388+
}
389+
}
390+
391+
private static final AddVerifier INSTANCE = new AddVerifier();
392+
}
393+
394+
private static class MulVerifier extends PResultVerifier {
395+
396+
private static boolean isStringMul(Value x, Value y) {
397+
return x.isString() && (y.isBoolean() || (y.isNumber() && y.fitsInInt()));
398+
}
399+
400+
private static boolean isArrayMul(Value x, Value y) {
401+
return x.hasArrayElements() && (y.isBoolean() || (y.isNumber() && (y.fitsInInt() || (y.fitsInLong() && y.asLong() < 0))));
402+
}
403+
404+
public void accept(SnippetRun snippetRun) throws PolyglotException {
405+
List<? extends Value> parameters = snippetRun.getParameters();
406+
assert parameters.size() == 2;
407+
408+
Value par0 = parameters.get(0);
409+
Value par1 = parameters.get(1);
410+
411+
if (isStringMul(par0, par1) || isStringMul(par1, par0)) {
412+
// string * number => string
413+
assert snippetRun.getException() == null;
414+
TypeDescriptor resultType = TypeDescriptor.forValue(snippetRun.getResult());
415+
assert STRING.isAssignable(resultType);
416+
} else if (isArrayMul(par0, par1) || isArrayMul(par1, par0)) {
417+
// array * number => array
418+
assert snippetRun.getException() == null;
419+
TypeDescriptor resultType = TypeDescriptor.forValue(snippetRun.getResult());
420+
assert array(ANY).isAssignable(resultType);
421+
} else if ((par0.isNumber() || par0.isBoolean()) && (par1.isNumber() || par1.isBoolean())) {
422+
assert snippetRun.getException() == null;
423+
TypeDescriptor resultType = TypeDescriptor.forValue(snippetRun.getResult());
424+
assert NUMBER.isAssignable(resultType);
425+
} else {
426+
assert snippetRun.getException() != null;
427+
TypeDescriptor argType = union(STRING, BOOLEAN, NUMBER, array(ANY));
428+
TypeDescriptor par0Type = TypeDescriptor.forValue(par0);
429+
TypeDescriptor par1Type = TypeDescriptor.forValue(par1);
430+
if (!argType.isAssignable(par0Type) || !argType.isAssignable(par1Type)) {
431+
// argument type error, rethrow
432+
throw snippetRun.getException();
433+
} else {
434+
// arguments are ok, just don't work in this combination
435+
}
370436
}
371437
}
372438

373-
private static final PNoListCoercionVerifier INSTANCE = new PNoListCoercionVerifier();
439+
private static final MulVerifier INSTANCE = new MulVerifier();
374440
}
375441

376442
/**

0 commit comments

Comments
 (0)