Login
7 branches 0 tags
Ben (Win10) Proper Stacktraces!!! 7f3aaa1 4 years ago 220 Commits
nujel / stdlib / lists.nuj
; Put all the LISt Processing stuff in here

[defun except-last-pair/iter [list rest]
       "Iterator for except-last-pair"
       [if [nil? [cdr list]]
           [reverse rest]
           [except-last-pair/iter [cdr list] [cons [car list] rest]]]
]

[defun except-last-pair [list]
       "Return a copy of LIST without the last pair"
       [except-last-pair/iter list #nil]
]

[defun last-pair [list]
        "Return the last pair of l"
        [if [cdr list]
            [last-pair [cdr list]]
            list]
]

[defun make-list/iter [number value l]
       "Iterator for make-list"
       [if [<= number 0]
           l
           [make-list/iter [- number 1] value [cons value l]]]
]

[defun make-list [number value]
       "Return a list of NUMBER elements containing VALUE in every car"
       [make-list/iter number value #nil]
]

[defun reduce [o l s]
       "Combine all elements in l using operation o and starting value s"
       [if [nil? l]
           s
           [reduce o [cdr l] [o s [car l]]]]
]

[defun list-ref [l i]
       "Returns the the element of list l at location i"
       [cond [[nil? l] #nil]
             [[<= i 0] [car l]]
             [#t [list-ref [cdr l] [+ -1 i]]]
       ]
]

[defun join/iter [str l glue]
       "Iterator for join/iter"
       [cond [[nil? l] [substr str 0 [- [string/length str] [string/length glue]]]]
             [#t [join/iter [cat str [car l] glue] [cdr l] glue]]
       ]
]

[defun join [l glue]
       "Join LIST into a string with GLUE in between each element"
       [join/iter "" l [string glue]]
]

[defun split [str separator]
       [def separator-len [string/length separator]]
       [def slen [string/length str]]
       [def start 0]
       [def ret #nil]
       [while [< start slen]
              [def pos-found [index-of str separator start]]
              [if [>= pos-found 0]
                  [do [def pos-found [max pos-found [+ start 1]]]
                      [set! ret [cons [substr str start pos-found]
                                      ret]]
                      [set! start [+ separator-len pos-found]]
                  ]
                  [do [set! ret [cons [substr str start slen]
                                      ret]]
                      [set! start slen]
                  ]]
       ]
       [reverse ret]
]

[defun reverse [l r]
        "Return the list l in reverse order"
        [if [nil? l]
            r
            [reverse [cdr l] [cons [car l] r]]]
]

[defun list-length [a t]
        "Returns the length of list a"
        [if [nil? a]
            t
            [list-length [cdr a] [+ 1 t]]]
]

[defun filter [p l]
        "Runs predicate p over every item in list l and returns a list consiting solely of items where p is true"
        [def ret #nil]
        [if l
            [if [p [car l]]
                [cons [car l] [filter p [cdr l]]]
                [filter p [cdr l]]
            #nil]]
]

[defun for-each [f l]
        "Runs f over every item in list l and returns the resulting list"
        [while l
               [f [car l]]
               [set! l [cdr l]]
        ]
]

[defun map [f l]
        "Runs f over every item in list l and returns the resulting list"
        [if [nil? l]
            l
            [cons [f [car l]] [map f [cdr l]]]]
]

[defun append/iter [a b]
       "Iterator for append"
       [if [nil? a]
           b
           [append/iter [cdr a] [cons [car a] b]]]
]

[defun append [a b]
       "Appends to two lists a and b together"
       [append/iter [reverse a] b]
]

[defun sublist [l start end ret]
        "Returns a new list containing all elements of l from start to end"
        [cond [[nil?    l] [reverse ret]]
              [[neg?  end] [sublist      l      start  [+ [length l] end]]]
              [[zero? end] [reverse ret]]
              [[> start 0] [sublist [cdr l] [+ -1 start] [+ -1 end] #nil]]
              [[> end   0] [sublist [cdr l] 0            [+ -1 end] [cons [car l] ret]]]
        ]
]

[defun list-head [l k]
        "Returns the first k elemnts of list l"
        [sublist l 0 k]
]

[defun list-tail [l k]
        "Returns the sublist of l obtained by omitting the first l elements"
        [sublist l k [length l]]
]

[defun member [m l]
        "Returns the first pair of list l whose car is equal to m"
        [cond [[nil? l] #f]
              [[eq? [car l] m] l]
              [#t [member m [cdr l]]]
        ]
]

[defun delete [e l]
        "Returns a filtered list l with all elements equal to e omitted"
        [filter [\ [a] [not [eq? a e]]] l]
]

[defun arg-list [f]
        "Return the Argument list of f which can be a Native Function or a Lambda"
        [cond [[lambda? f] [reduce cat [map [\ [a] [" " [car a]]] [cl-data f]]]]
              [[native? f] [reduce cat [map [\ [a] [" " a]] [car [cl-data f]]]]]
              [#t ""]
        ]
]

[defun getf [l key]
       "Return the value in LIST following KEY"
       [cond [[nil? l] #nil]
             [[eq? key [car l]] [cadr l]]
             [#t [getf [cdr l] key]]
       ]
]