-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding splittable class, split for sequence types
- Loading branch information
Showing
5 changed files
with
251 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
(coalton-library/utils:defstdlib-package #:coalton-library/split | ||
(:use | ||
#:coalton | ||
#:coalton-library/builtin | ||
#:coalton-library/classes) | ||
#+ignore(:import-from | ||
#:coalton-library/hash | ||
#:define-sxhash-hasher) | ||
#+ignore(:import-from | ||
#:coalton-library/vector | ||
#:Vector) | ||
(:local-nicknames | ||
(#:cell #:coalton-library/cell) | ||
(#:iter #:coalton-library/iterator) | ||
(#:list #:coalton-library/list) | ||
(#:vec #:coalton-library/vector) | ||
(#:seq #:coalton-library/seq) | ||
(#:types #:coalton-library/types) | ||
(#:slice #:coalton-library/slice)) | ||
(:export | ||
#:splittable | ||
#:split) | ||
#+ignore(:export | ||
#:concat | ||
#:reverse | ||
#:length | ||
#:substring | ||
#:split | ||
#:strip-prefix | ||
#:strip-suffix | ||
#:parse-int | ||
#:ref | ||
#:ref-unchecked | ||
#:substring-index | ||
#:substring? | ||
#:chars | ||
#:delim-split)) | ||
|
||
|
||
(in-package #:coalton-library/split) | ||
|
||
(named-readtables:in-readtable coalton:coalton) | ||
|
||
|
||
;;; | ||
;;; Split | ||
;;; | ||
|
||
(coalton-toplevel | ||
|
||
(define-class (Splittable :seq) | ||
"Sequence types that can be split by equality." | ||
(split ((Eq :a) (types:runtimerepr :a) => :a -> (:seq :a) -> (iter:iterator (:seq :a)))))) | ||
|
||
;;; | ||
;;; Instances | ||
;;; | ||
|
||
(coalton-toplevel | ||
|
||
(define-instance (Splittable List) | ||
(define (split delim xs) | ||
(let ((blocks (cell:new Nil)) | ||
(current-block (cell:new Nil)) | ||
(iter (iter:into-iter xs))) | ||
|
||
(iter:for-each! (fn (x) | ||
(cond | ||
((== x delim) | ||
(unless (list:null? (cell:read current-block)) | ||
(cell:push! blocks (list:reverse (cell:read current-block))) | ||
(cell:write! current-block nil) | ||
Unit)) | ||
(True | ||
(cell:push! current-block x) | ||
Unit))) | ||
iter) | ||
|
||
(unless (list:null? (cell:read current-block)) | ||
(cell:push! blocks (list:reverse (cell:read current-block))) | ||
Unit) | ||
|
||
(iter:into-iter (list:reverse (cell:read blocks)))))) | ||
|
||
(define-instance (Splittable vec:Vector) | ||
(define (split delim v) | ||
(let ((blocks (cell:new Nil)) | ||
(current-block (vec:new)) | ||
(iter (iter:into-iter v))) | ||
|
||
(iter:for-each! (fn (x) | ||
(cond | ||
((== x delim) | ||
(unless (vec:empty? current-block) | ||
(cell:push! blocks current-block) | ||
(vec:clear! current-block) | ||
Unit)) | ||
(True | ||
(vec:push! x current-block) | ||
Unit))) | ||
iter) | ||
|
||
(unless (vec:empty? current-block) | ||
(cell:push! blocks current-block) | ||
Unit) | ||
|
||
(iter:into-iter (list:reverse (cell:read blocks)))))) | ||
|
||
(define-instance (Splittable seq:Seq) | ||
(define (split delim xs) | ||
(let ((blocks (cell:new Nil)) | ||
(current-block (cell:new (seq:new))) | ||
(iter (iter:into-iter xs))) | ||
|
||
(iter:for-each! (fn (x) | ||
(cond | ||
((== x delim) | ||
(unless (seq:empty? (cell:read current-block)) | ||
(cell:push! blocks (cell:read current-block)) | ||
(cell:write! current-block (seq:new)) | ||
Unit)) | ||
(True | ||
(cell:write! current-block (seq:push (cell:read current-block) x)) | ||
Unit))) | ||
iter) | ||
|
||
(unless (seq:empty? (cell:read current-block)) | ||
(cell:push! blocks (cell:read current-block)) | ||
Unit) | ||
|
||
(iter:into-iter (list:reverse (cell:read blocks)))))) | ||
|
||
(define-instance (Splittable iter:Iterator) | ||
(define (split delim it) | ||
(let ((blocks (cell:new Nil)) | ||
(current-block (cell:new Nil))) | ||
|
||
(iter:for-each! (fn (x) | ||
(cond | ||
((== x delim) | ||
(unless (list:null? (cell:read current-block)) | ||
(cell:push! blocks (iter:into-iter (list:reverse (cell:read current-block)))) | ||
(cell:write! current-block nil) | ||
Unit)) | ||
(True | ||
(cell:push! current-block x) | ||
Unit))) | ||
it) | ||
|
||
(unless (list:null? (cell:read current-block)) | ||
(cell:push! blocks (iter:into-iter (list:reverse (cell:read current-block)))) | ||
Unit) | ||
|
||
(iter:into-iter (list:reverse (cell:read blocks)))))) | ||
|
||
(define-instance (Splittable slice:Slice) | ||
(define (split delim xs) | ||
(let ((blocks (cell:new Nil)) | ||
(current-block (cell:new Nil)) | ||
(iter:into-iter xs)) | ||
|
||
(iter:for-each! (fn (x) | ||
(cond | ||
((== x delim) | ||
(unless (list:null? (cell:read current-block)) | ||
(cell:push! blocks (iter:into-iter (list:reverse (cell:read current-block)))) | ||
(cell:write! current-block nil) | ||
Unit)) | ||
(True | ||
(cell:push! current-block x) | ||
Unit))) | ||
it) | ||
|
||
(unless (list:null? (cell:read current-block)) | ||
(cell:push! blocks (iter:into-iter (list:reverse (cell:read current-block)))) | ||
Unit) | ||
|
||
(iter:into-iter (list:reverse (cell:read blocks)))))) | ||
|
||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
(cl:in-package #:coalton-native-tests) | ||
|
||
(coalton-toplevel | ||
(define *path* "wow/ok/dir/file.txt") | ||
|
||
(define *path-undotted* (make-list | ||
(make-list #\w #\o #\w #\/ #\o #\k #\/ #\d #\i #\r #\/ #\f #\i #\l #\e) | ||
(make-list #\t #\x #\t))) | ||
|
||
(define *path-unslashed* (make-list | ||
(make-list #\w #\o #\w) | ||
(make-list #\o #\k) | ||
(make-list #\d #\i #\r) | ||
(make-list #\f #\i #\l #\e #\. #\t #\x #\t))) | ||
|
||
(declare list->vec (List :a -> Vector :a)) | ||
(define (list->vec x) | ||
(into x))) | ||
|
||
(define-test split-list () | ||
(is (== (iter:collect! (split:split #\. (iter:collect! (string:chars *path*)))) *path-undotted*)) | ||
(is (== (iter:collect! (split:split #\/ (iter:collect! (string:chars *path*)))) *path-unslashed*)) | ||
(is (== (iter:collect! (split:split 2 (make-list 1 2 3 4 2 5 2))) (make-list (make-list 1) | ||
(make-list 3 4) | ||
(make-list 5))))) | ||
|
||
;;; | ||
;;; splitting vectors | ||
;;; | ||
|
||
(coalton-toplevel | ||
|
||
) | ||
(define-test split-vector () | ||
(is (== (iter:collect! (split:split #\. (list->vec (iter:collect! (string:chars *path*))))) | ||
(map list->vec *path-undotted*))) | ||
(is (== (iter:collect! (split:split #\/ (list->vec (iter:collect! (string:chars *path*))))) | ||
(map list->vec *path-unslashed*)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters