Throw error when array is passed to variadic prelude function. Close #114.

This commit is contained in:
2022-10-06 17:57:25 +00:00
parent f867fea3a0
commit b95d927016
3 changed files with 42 additions and 12 deletions

View File

@@ -79,6 +79,16 @@ class Prelude {
} }
public static var or:Function = Reflect.makeVarArgs(_or); public static var or:Function = Reflect.makeVarArgs(_or);
static function makeVarArgsWithArrayCheck(f:Array<Dynamic>->Dynamic, name:String):Function {
function fWithArrayCheck(args:Array<Dynamic>):Dynamic {
if (args.length == 1 && args[0] is Array) {
throw 'Array ${args[0]} was passed to variadic function $name. Use (apply $name args) instead';
}
return f(args);
}
return Reflect.makeVarArgs(fWithArrayCheck);
}
// Kiss arithmetic will incur overhead because of these switch statements, but the results will not be platform-dependent // Kiss arithmetic will incur overhead because of these switch statements, but the results will not be platform-dependent
static function _add(values:Array<Dynamic>):Dynamic { static function _add(values:Array<Dynamic>):Dynamic {
var sum:Dynamic = values[0]; var sum:Dynamic = values[0];
@@ -87,7 +97,7 @@ class Prelude {
return sum; return sum;
} }
public static var add:Function = Reflect.makeVarArgs(_add); public static var add:Function = makeVarArgsWithArrayCheck(_add, "+");
static function _subtract(values:Array<Dynamic>):Dynamic { static function _subtract(values:Array<Dynamic>):Dynamic {
var difference:Float = values[0]; var difference:Float = values[0];
@@ -96,7 +106,7 @@ class Prelude {
return difference; return difference;
} }
public static var subtract:Function = Reflect.makeVarArgs(_subtract); public static var subtract:Function = makeVarArgsWithArrayCheck(_subtract, "-");
static function _multiply2(a:Dynamic, b:Dynamic):Dynamic { static function _multiply2(a:Dynamic, b:Dynamic):Dynamic {
return switch ([stringOrFloat(a), stringOrFloat(b)]) { return switch ([stringOrFloat(a), stringOrFloat(b)]) {
@@ -122,7 +132,7 @@ class Prelude {
return product; return product;
} }
public static var multiply:Function = Reflect.makeVarArgs(_multiply); public static var multiply:Function = makeVarArgsWithArrayCheck(_multiply, "*");
static function _divide(values:Array<Dynamic>):Dynamic { static function _divide(values:Array<Dynamic>):Dynamic {
var quotient:Float = values[0]; var quotient:Float = values[0];
@@ -131,7 +141,7 @@ class Prelude {
return quotient; return quotient;
} }
public static var divide:Function = Reflect.makeVarArgs(_divide); public static var divide:Function = makeVarArgsWithArrayCheck(_divide, "/");
public static function mod(top:Dynamic, bottom:Dynamic):Dynamic { public static function mod(top:Dynamic, bottom:Dynamic):Dynamic {
return top % bottom; return top % bottom;
@@ -148,7 +158,7 @@ class Prelude {
return min; return min;
} }
public static var min:Function = Reflect.makeVarArgs(_min); public static var min:Function = makeVarArgsWithArrayCheck(_min, "min");
static function _max(values:Array<Dynamic>):Dynamic { static function _max(values:Array<Dynamic>):Dynamic {
var max = values[0]; var max = values[0];
@@ -158,7 +168,7 @@ class Prelude {
return max; return max;
} }
public static var max:Function = Reflect.makeVarArgs(_max); public static var max:Function = makeVarArgsWithArrayCheck(_max, "max");
static function _comparison(op:String, values:Array<Dynamic>):Bool { static function _comparison(op:String, values:Array<Dynamic>):Bool {
for (idx in 1...values.length) { for (idx in 1...values.length) {
@@ -178,11 +188,11 @@ class Prelude {
return true; return true;
} }
public static var greaterThan:Function = Reflect.makeVarArgs(_comparison.bind(">")); public static var greaterThan:Function = makeVarArgsWithArrayCheck(_comparison.bind(">"), ">");
public static var greaterEqual:Function = Reflect.makeVarArgs(_comparison.bind(">=")); public static var greaterEqual:Function = makeVarArgsWithArrayCheck(_comparison.bind(">="), ">=");
public static var lessThan:Function = Reflect.makeVarArgs(_comparison.bind("<")); public static var lessThan:Function = makeVarArgsWithArrayCheck(_comparison.bind("<"), "<");
public static var lesserEqual:Function = Reflect.makeVarArgs(_comparison.bind("<=")); public static var lesserEqual:Function = makeVarArgsWithArrayCheck(_comparison.bind("<="), "<=");
public static var areEqual:Function = Reflect.makeVarArgs(_comparison.bind("==")); public static var areEqual:Function = makeVarArgsWithArrayCheck(_comparison.bind("=="), "=");
// Like quickNths but for division. Support int and float output: // Like quickNths but for division. Support int and float output:
private static function iFraction (num:Float, denom:Float) { private static function iFraction (num:Float, denom:Float) {

View File

@@ -375,7 +375,10 @@ class BasicTestCase extends Test {
function testPureKissClasses() { function testPureKissClasses() {
_testPureKissClasses(); _testPureKissClasses();
} }
function testArraysToVariadic() {
_testArraysToVariadic();
}
} }
class BasicObject { class BasicObject {

View File

@@ -704,4 +704,21 @@ From:[(assert false (+ \"false \" \"should \" \"have \" \"been \" \"true\"))]" m
(function _testPureKissClasses [] (function _testPureKissClasses []
(PureKissClass.test) (PureKissClass.test)
(Assert.pass))
(function _testArraysToVariadic []
(let [a [5 6 7]]
(assertThrows (+ a))
(assertThrows (- a))
(assertThrows (* a))
(assertThrows (/ a))
(assertThrows (min a))
(assertThrows (max a))
(assertThrows (= a))
(assertThrows (< a))
(assertThrows (<= a))
(assertThrows (> a))
(assertThrows (>= a))
)
(Assert.pass)) (Assert.pass))