Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Add support for destructuring in cycle, grep and grep:set

  • Loading branch information...
commit 91799fceb5d425939d12910963e11a0d70fbe6c7 1 parent 3a5b7a7
Ola Bini olabini authored

Showing 2 changed files with 136 additions and 10 deletions. Show diff stats Hide diff stats

  1. +10 7 src/builtin/F30_enumerable.ik
  2. +126 3 test/enumerable_spec.ik
17 src/builtin/F30_enumerable.ik
@@ -540,12 +540,13 @@ Mixins Enumerable cycle = dmacro(
540 540
541 541 [argName, theCode]
542 542 internal = list()
543   - lexicalCode = LexicalBlock createFrom(list(argName, theCode), call ground)
  543 + destructor = Destructor from(argName)
  544 + lexicalCode = LexicalBlock createFrom(destructor argNames + list(theCode), call ground)
544 545 self each(n,
545 546 internal << cell(:n)
546   - lexicalCode call(cell(:n)))
  547 + lexicalCode call(*(destructor unpack(cell(:n)))))
547 548 if(internal empty?, return(nil))
548   - loop(internal each(x, lexicalCode call(cell(:x)))))
  549 + loop(internal each(x, lexicalCode call(*(destructor unpack(cell(:x)))))))
549 550
550 551 Mixins Enumerable zip = method(
551 552 "takes zero or more arguments, where all arguments should be a list, except that the last might also be a lexical block. zip will create a list of lists, where each internal list is a combination of the current element, and the corresponding elements from all the lists. if the lists are shorter than this collection, nils will be supplied. if a lexical block is provided, it will be called with each list created, and if that's the case nil will be returned from zip",
@@ -614,11 +615,12 @@ Mixins Enumerable grep = dmacro(
614 615 result,
615 616
616 617 [>matchingAgainst, argName, theCode]
  618 + destructor = Destructor from(argName)
617 619 result = list()
618   - lexicalCode = LexicalBlock createFrom(list(argName, theCode), call ground)
  620 + lexicalCode = LexicalBlock createFrom(destructor argNames + list(theCode), call ground)
619 621 self each(n,
620 622 if(matchingAgainst === cell(:n),
621   - result << lexicalCode call(cell(:n))))
  623 + result << lexicalCode call(*(destructor unpack(cell(:n))))))
622 624 result)
623 625
624 626
@@ -640,11 +642,12 @@ Mixins Enumerable grep:set = dmacro(
640 642 result,
641 643
642 644 [>matchingAgainst, argName, theCode]
  645 + destructor = Destructor from(argName)
643 646 result = set()
644   - lexicalCode = LexicalBlock createFrom(list(argName, theCode), call ground)
  647 + lexicalCode = LexicalBlock createFrom(destructor argNames + list(theCode), call ground)
645 648 self each(n,
646 649 if(matchingAgainst === cell(:n),
647   - result << lexicalCode call(cell(:n))))
  650 + result << lexicalCode call(*(destructor unpack(cell(:n))))))
648 651 result)
649 652
650 653
129 test/enumerable_spec.ik
@@ -3224,7 +3224,48 @@ describe(Mixins,
3224 3224 Ground res should == [1,2,3,1,2,3,1,2,3,1]
3225 3225 )
3226 3226
3227   - it("should be possible to destructure on the argument name")
  3227 + it("should be able to destructure on the argument name",
  3228 + Ground result = []
  3229 + method([[1,2], [2,3], [4,5]] cycle((x,y), Ground result << [x+1, y-1]. if(Ground result length == 4, return))) call
  3230 + result should == [[2,1], [3,2], [5,4], [2,1]]
  3231 + )
  3232 +
  3233 + it("should be able to destructure and ignore the rest of something",
  3234 + Ground result = []
  3235 + method([[1,2,9,10], [2,3,11,12], [4,5,13,14]] cycle((x,y,_), cell?(:"_") should not be true. Ground result << [x, y]. if(Ground result length == 4, return))) call
  3236 + result should == [[1,2], [2,3], [4,5],[1,2]]
  3237 + )
  3238 +
  3239 + it("should be able to destructure and ignore in the middle of the pattern without binding anything",
  3240 + Ground result = []
  3241 + method([[1,2,9], [2,3,11], [4,5,13]] cycle((x,_,y), cell?(:"_") should not be true. Ground result << [x, y]. if(Ground result length == 4, return))) call
  3242 + result should == [[1,9], [2,11], [4,13],[1,9]]
  3243 + )
  3244 +
  3245 + it("should be able to destructure and ignore several times in the middle of the pattern without binding anything",
  3246 + Ground result = []
  3247 + method([[1,2,9,10,11], [2,3,11,12,13], [4,5,13,14,15]] cycle((x,_,y,_,q), cell?(:"_") should not be true. Ground result << [x, y, q]. if(Ground result length == 4, return))) call
  3248 + result should == [[1,9,11], [2,11,13], [4,13,15],[1,9,11]]
  3249 + )
  3250 +
  3251 + it("should be able to destructure recursively",
  3252 + Ground result = []
  3253 + method([[[:x, :y, :z], [:q, :r, :p]], [[:b, :c, :d], [:i, :j, :k]], [[:i, :j, :k], [:i2, :j3, :k4]]] cycle(
  3254 + (v, (v2, _, v3)), cell?(:"_") should be false. Ground result << [v, v2, v3]. if(Ground result length == 4, return))) call
  3255 + result should == [[[:x, :y, :z], :q, :p], [[:b, :c, :d], :i, :k], [[:i, :j, :k], :i2, :k4], [[:x, :y, :z], :q, :p]]
  3256 + )
  3257 +
  3258 + it("should report a destructuring match error if destructuring doesn't add upp",
  3259 + fn([[1,2], [3,4], [4,5]] cycle((q,p,r), nil)) should signal(Condition Error DestructuringMismatch)
  3260 + fn([[1,2], [3,4], [4,5]] cycle((q), nil)) should signal(Condition Error DestructuringMismatch)
  3261 + fn([[1,2], [3,4], [4,5]] cycle((q,_,r), nil)) should signal(Condition Error DestructuringMismatch)
  3262 + )
  3263 +
  3264 + it("should report a destructuring match error if recursive destructuring doesn't add upp",
  3265 + fn([[[1,2],[1,2]], [[3,4],[1,2]], [[1,2],[4,5]]] cycle((q,(p)), nil)) should signal(Condition Error DestructuringMismatch)
  3266 + fn([[[1,2],[1,2]], [[3,4],[1,2]], [[1,2],[4,5]]] cycle((q,(p,r,f)), nil)) should signal(Condition Error DestructuringMismatch)
  3267 + fn([[[1,2],[1,2]], [[3,4],[1,2]], [[1,2],[4,5]]] cycle((q,(p,_,f)), nil)) should signal(Condition Error DestructuringMismatch)
  3268 + )
3228 3269 )
3229 3270
3230 3271 describe("sortBy",
@@ -3362,7 +3403,48 @@ describe(Mixins,
3362 3403 [1,2,3,4,5,6,7,8,9] grep(customObj, x, (x+1) asText) should == ["2","3","7","8","9","10"]
3363 3404 )
3364 3405
3365   - it("should be possible to destructure on the argument name")
  3406 + it("should be able to destructure on the argument name",
  3407 + result = []
  3408 + [[1,2], [2,3], [4,5]] grep(Origin, (x,y), result << [x+1, y-1]. nil)
  3409 + result should == [[2,1], [3,2], [5,4]]
  3410 + )
  3411 +
  3412 + it("should be able to destructure and ignore the rest of something",
  3413 + result = []
  3414 + [[1,2,9,10], [2,3,11,12], [4,5,13,14]] grep(Origin, (x,y,_), cell?(:"_") should not be true. result << [x, y]. nil)
  3415 + result should == [[1,2], [2,3], [4,5]]
  3416 + )
  3417 +
  3418 + it("should be able to destructure and ignore in the middle of the pattern without binding anything",
  3419 + result = []
  3420 + [[1,2,9], [2,3,11], [4,5,13]] grep(Origin, (x,_,y), cell?(:"_") should not be true. result << [x, y]. nil)
  3421 + result should == [[1,9], [2,11], [4,13]]
  3422 + )
  3423 +
  3424 + it("should be able to destructure and ignore several times in the middle of the pattern without binding anything",
  3425 + result = []
  3426 + [[1,2,9,10,11], [2,3,11,12,13], [4,5,13,14,15]] grep(Origin, (x,_,y,_,q), cell?(:"_") should not be true. result << [x, y, q]. nil)
  3427 + result should == [[1,9,11], [2,11,13], [4,13,15]]
  3428 + )
  3429 +
  3430 + it("should be able to destructure recursively",
  3431 + result = []
  3432 + [[[:x, :y, :z], [:q, :r, :p]], [[:b, :c, :d], [:i, :j, :k]], [[:i, :j, :k], [:i2, :j3, :k4]]] grep(Origin,
  3433 + (v, (v2, _, v3)), cell?(:"_") should be false. result << [v, v2, v3]. nil)
  3434 + result should == [[[:x, :y, :z], :q, :p], [[:b, :c, :d], :i, :k], [[:i, :j, :k], :i2, :k4]]
  3435 + )
  3436 +
  3437 + it("should report a destructuring match error if destructuring doesn't add upp",
  3438 + fn([[1,2], [3,4], [4,5]] grep(Origin, (q,p,r), nil)) should signal(Condition Error DestructuringMismatch)
  3439 + fn([[1,2], [3,4], [4,5]] grep(Origin, (q), nil)) should signal(Condition Error DestructuringMismatch)
  3440 + fn([[1,2], [3,4], [4,5]] grep(Origin, (q,_,r), nil)) should signal(Condition Error DestructuringMismatch)
  3441 + )
  3442 +
  3443 + it("should report a destructuring match error if recursive destructuring doesn't add upp",
  3444 + fn([[[1,2],[1,2]], [[3,4],[1,2]], [[1,2],[4,5]]] grep(Origin, (q,(p)), nil)) should signal(Condition Error DestructuringMismatch)
  3445 + fn([[[1,2],[1,2]], [[3,4],[1,2]], [[1,2],[4,5]]] grep(Origin, (q,(p,r,f)), nil)) should signal(Condition Error DestructuringMismatch)
  3446 + fn([[[1,2],[1,2]], [[3,4],[1,2]], [[1,2],[4,5]]] grep(Origin, (q,(p,_,f)), nil)) should signal(Condition Error DestructuringMismatch)
  3447 + )
3366 3448 )
3367 3449
3368 3450 describe("grep:set",
@@ -3390,7 +3472,48 @@ describe(Mixins,
3390 3472 [1,2,3,4,5,6,7,8,9] grep:set(customObj, x, (x+1) asText) should == #{"2","3","7","8","9","10"}
3391 3473 )
3392 3474
3393   - it("should be possible to destructure on the argument name")
  3475 + it("should be able to destructure on the argument name",
  3476 + result = []
  3477 + [[1,2], [2,3], [4,5]] grep:set(Origin, (x,y), result << [x+1, y-1]. nil)
  3478 + result should == [[2,1], [3,2], [5,4]]
  3479 + )
  3480 +
  3481 + it("should be able to destructure and ignore the rest of something",
  3482 + result = []
  3483 + [[1,2,9,10], [2,3,11,12], [4,5,13,14]] grep:set(Origin, (x,y,_), cell?(:"_") should not be true. result << [x, y]. nil)
  3484 + result should == [[1,2], [2,3], [4,5]]
  3485 + )
  3486 +
  3487 + it("should be able to destructure and ignore in the middle of the pattern without binding anything",
  3488 + result = []
  3489 + [[1,2,9], [2,3,11], [4,5,13]] grep:set(Origin, (x,_,y), cell?(:"_") should not be true. result << [x, y]. nil)
  3490 + result should == [[1,9], [2,11], [4,13]]
  3491 + )
  3492 +
  3493 + it("should be able to destructure and ignore several times in the middle of the pattern without binding anything",
  3494 + result = []
  3495 + [[1,2,9,10,11], [2,3,11,12,13], [4,5,13,14,15]] grep:set(Origin, (x,_,y,_,q), cell?(:"_") should not be true. result << [x, y, q]. nil)
  3496 + result should == [[1,9,11], [2,11,13], [4,13,15]]
  3497 + )
  3498 +
  3499 + it("should be able to destructure recursively",
  3500 + result = []
  3501 + [[[:x, :y, :z], [:q, :r, :p]], [[:b, :c, :d], [:i, :j, :k]], [[:i, :j, :k], [:i2, :j3, :k4]]] grep:set(Origin,
  3502 + (v, (v2, _, v3)), cell?(:"_") should be false. result << [v, v2, v3]. nil)
  3503 + result should == [[[:x, :y, :z], :q, :p], [[:b, :c, :d], :i, :k], [[:i, :j, :k], :i2, :k4]]
  3504 + )
  3505 +
  3506 + it("should report a destructuring match error if destructuring doesn't add upp",
  3507 + fn([[1,2], [3,4], [4,5]] grep:set(Origin, (q,p,r), nil)) should signal(Condition Error DestructuringMismatch)
  3508 + fn([[1,2], [3,4], [4,5]] grep:set(Origin, (q), nil)) should signal(Condition Error DestructuringMismatch)
  3509 + fn([[1,2], [3,4], [4,5]] grep:set(Origin, (q,_,r), nil)) should signal(Condition Error DestructuringMismatch)
  3510 + )
  3511 +
  3512 + it("should report a destructuring match error if recursive destructuring doesn't add upp",
  3513 + fn([[[1,2],[1,2]], [[3,4],[1,2]], [[1,2],[4,5]]] grep:set(Origin, (q,(p)), nil)) should signal(Condition Error DestructuringMismatch)
  3514 + fn([[[1,2],[1,2]], [[3,4],[1,2]], [[1,2],[4,5]]] grep:set(Origin, (q,(p,r,f)), nil)) should signal(Condition Error DestructuringMismatch)
  3515 + fn([[[1,2],[1,2]], [[3,4],[1,2]], [[1,2],[4,5]]] grep:set(Origin, (q,(p,_,f)), nil)) should signal(Condition Error DestructuringMismatch)
  3516 + )
3394 3517 )
3395 3518
3396 3519 describe("max",

0 comments on commit 91799fc

Please sign in to comment.
Something went wrong with that request. Please try again.