(range...)
This commit is contained in:
@@ -83,6 +83,14 @@ class Macros {
|
||||
CallExp(Symbol("Reflect.callMethod").withPosOf(wholeExp), [callOn, func, args]).withPosOf(wholeExp);
|
||||
};
|
||||
|
||||
macros["range"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k) -> {
|
||||
wholeExp.checkNumArgs(1, 3, '(range [?min] [max] [?step])');
|
||||
var min = if (exps.length > 1) exps[0] else Symbol("0").withPosOf(wholeExp);
|
||||
var max = if (exps.length > 1) exps[1] else exps[0];
|
||||
var step = if (exps.length > 2) exps[2] else Symbol("1").withPosOf(wholeExp);
|
||||
CallExp(Symbol("Prelude.range").withPosOf(wholeExp), [min, max, step]).withPosOf(wholeExp);
|
||||
};
|
||||
|
||||
function bodyIf(formName:String, negated:Bool, wholeExp:ReaderExp, args:Array<ReaderExp>, k) {
|
||||
wholeExp.checkNumArgs(2, null, '($formName [condition] [body...])');
|
||||
var condition = if (negated) {
|
||||
|
@@ -186,6 +186,23 @@ class Prelude {
|
||||
];
|
||||
}
|
||||
|
||||
// Ranges with a min, exclusive max, and step size, just like Python.
|
||||
public static function range(min, max, step):Iterator<Int> {
|
||||
if (step <= 0)
|
||||
throw "(range...) can only count up";
|
||||
var count = min;
|
||||
return {
|
||||
next: () -> {
|
||||
var oldCount = count;
|
||||
count += step;
|
||||
oldCount;
|
||||
},
|
||||
hasNext: () -> {
|
||||
count < max;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static dynamic function truthy(v:Any) {
|
||||
return switch (Type.typeof(v)) {
|
||||
case TNull: false;
|
||||
|
@@ -246,6 +246,10 @@ class BasicTestCase extends Test {
|
||||
function testMaps() {
|
||||
_testMaps();
|
||||
}
|
||||
|
||||
function testRange() {
|
||||
_testRange();
|
||||
}
|
||||
}
|
||||
|
||||
class BasicObject {
|
||||
|
@@ -349,8 +349,22 @@
|
||||
(doFor =>key value myMap
|
||||
(Assert.isTrue (<= 0 (.indexOf ["hey" "found"] key)))
|
||||
(Assert.isTrue (<= 0 (.indexOf ["you" "me"] value))))
|
||||
|
||||
|
||||
// Map destructuring:
|
||||
(let [[=>"hey" v1 =>"found" v2] myMap]
|
||||
(Assert.equals "you" v1)
|
||||
(Assert.equals "me" v2)))
|
||||
(Assert.equals "me" v2)))
|
||||
|
||||
(defun _testRange []
|
||||
// With just one arg, it's the max:
|
||||
(deflocal &mut :kiss.List<Int> myList (for i (range 5) i))
|
||||
(Assert.equals 4 (nth myList -1))
|
||||
// with two args, they are min and max:
|
||||
(set myList (for i (range 3 5) i))
|
||||
(Assert.equals 3 (first myList))
|
||||
(Assert.equals 4 (last myList))
|
||||
// With three args, they are min, max, and step:
|
||||
(set myList (for i (range 7 17 2) i))
|
||||
(Assert.equals 7 (first myList))
|
||||
(Assert.equals 9 (second myList))
|
||||
(Assert.equals 15 (last myList)))
|
Reference in New Issue
Block a user