Sigrid Solveig Haflínudóttirfor: make the range end exclusive67bc92e1 year agoHistory
3373 lines · 93.0 KB · Text
RawDownload
;;;; standard library ;;; void (def (void . rest)  "Return the constant `#<void>` while ignoring any arguments.    `#<void>` is mainly used when a function has side effects but does not   produce any meaningful value to return, so even though `T` or `NIL` could   be returned instead, in case of `#<void>` alone, REPL will not print   it."  :doc-group misc  :doc-see void?  #.(void)) (def (void? v)  "Return `T` if `v` is `#<void>`, `NIL` otherwise."  :doc-group type  :doc-group misc  :doc-see void  (eq? v #.(void))) ;;; syntax environment (unless (bound? '*syntax-environment*)  (def *syntax-environment*    "Table containing macro definitions.      The keys are macro names, the values are their application functions."    :doc-group syntax    :doc-see get-syntax    :doc-see set-syntax!    (table))) (def (set-syntax! sym fn)  "Associate a macro name with its application function."  :doc-group syntax  :doc-see get-syntax  (put! *syntax-environment* sym fn)) (def (get-syntax sym)  "Return a macro application function based on its name, or `NIL` if   it's not defined."  :doc-group syntax  :doc-see set-syntax!  (get *syntax-environment* sym NIL)) ;;; props ;; This is implemented in a slightly different fashion as expected:;;;;     *properties* : key → { symbol → value };;;; The assumption here is that keys will most likely be the same across multiple symbols;; so it makes more sense to reduce the number of subtables for the *properties* table.(unless (bound? '*properties*)  (def *properties*    "All properties of symbols recorded with `putprop` are recorded in this     table."    :doc-group prop    (table))) (def (putprop symbol key val)  "Associate a property value with the symbol."  :doc-group prop  :doc-see getprop  (let ((kt (get *properties* key NIL)))    (unless kt        (let ((ta (table)))          (put! *properties* key ta)          (set! kt ta)))    (put! kt symbol val)    val)) (def (getprop symbol key (def NIL def-supplied?))  "Return a property value associated with the symbol or `def` if   missing.    If the default value is not supplied and the property is missing,   an exception will be thrown."  :doc-group prop  :doc-see putprop  (let ((kt (get *properties* key NIL)))    (if def-supplied?        (or (and kt (get kt symbol def)) def)        (if kt            (get kt symbol)            (raise (list 'key-error key)))))) (def (remprop symbol key)  "Remove a property value associated with the symbol."  :doc-group prop  (void (let ((kt (get *properties* key NIL)))          (and kt (has? kt symbol) (del! kt symbol))))) ;;; documentation (def (separate-doc-from-body body (doc NIL))  "Take a list of terms and return a pair `(doc . body)`, where the first   element contains a list of documentation-related terms, and the second   contains the rest of the terms."  :doc-group doc  (def (doc? kw)    (<= :doc-a kw :doc-z))  (let {[hd (car body)]        [tl (cdr body)]}    (cond [(and (str? hd) (not doc) tl)           (separate-doc-from-body tl (cons hd doc))]          [(and doc (doc? hd))           (separate-doc-from-body (cdr tl) (cons (cons hd (car tl)) doc))]          [else (cons (reverse doc) body)]))) (def (sym-set-doc symbol doc-seq . formals-list)  "Set the documentation for the symbol."  :doc-group doc  (def (formals-clean fs)    (when (atom? fs)      (return fs))    (let ((f (car fs)))      (cons (if (and (cons? f)                     (length> f 2))                (subseq f 0 2)                f)            (formals-clean (cdr fs)))))  (let* {[doc-only (str? doc-seq)]         [doc (if doc-only doc-seq (car doc-seq))]         [extra (if doc-only NIL (cdr doc-seq))]         [formals-list (map formals-clean formals-list)]}    (when (and (bound? 'str-join) doc)      (let* {[lines (str-split doc "\n")]             [hd (car lines)]             [tl (cdr lines)]             [snd (any (λ (s) (and (> (length s) 0)                                   (rune-whitespace? (str-rune s 0))                                   s))                       tl)]             [indent (and snd                          (- (length snd)                             (length (str-trim snd))))]             [trimmed (and snd                        (map (λ (s) (if (<= indent (length s))                                        (str-sub s indent)                                        s))                             tl))]             [final (str-join (cons hd trimmed) "\n")]}      (putprop symbol '*doc* final)      (when extra (putprop symbol '*doc-extra* extra))))    (when (cons? formals-list)      (putprop symbol               '*formals-list*               (delete-duplicates [append (getprop symbol '*formals-list* NIL)                                          formals-list])))    #.(void))) (def (help-print-header term sigs (:kind NIL) (:lpad ""))  "Format and print signature(s) of the term for `(help term)` output."  :doc-group doc  (def (print-type e)    (set! print-type void)    (princ " ;; ["           [cond             ((not (sym? e)) (type-of e))             ((and (sym? e) (bound? e)) (type-of (top-level-value term)))             ((get-syntax e) "macro")             (else "any")]           "]"))  (if sigs      (for-each (λ (sig) (princ lpad)                         (print (cons term sig))                         (print-type term)                         (newline))                sigs)      (princ lpad)      (if kind          (begin (princ (caddr term))                 (print-type "doc group"))          (print term)          (print-type term))      (newline))  (newline)) (defmacro (help topic (:print-header help-print-header) . rest)  "Display documentation for a specific term or group of terms, if   available.    An optional symbol `group` is used to query for documentation on a   group instead of a single term.  All available documentation groups   can be displayed with `(help groups)`.    Asterisk can be added to the beginning and/or end of the term in order   to list the matching terms defined in the current environment.  This   can be useful to recall a function's name.    Examples:        (help str?)       ; show documentation for str?       (help groups)     ; show documentation groups       (help type group) ; list items for dealing with types       (help group type) ; same as ^       (help str->*)     ; find functions converting from strings       (help *->str)     ; find functions converting to strings       (help *num*)      ; find anything related to numbers"  :doc-group doc  (let* {[term (if (eq? topic 'group) (car rest) topic)]         [kind (if (eq? topic term) (car rest) topic)]         [doc-extra-term (and kind (cons (sym ":doc-" kind) term))]         [docterm (if kind (list 'doc kind term) term)]         [doc (getprop docterm '*doc* NIL)]         [formals-list (getprop docterm '*formals-list* NIL)]         [term-bound (and (sym? term) (bound? term))]}    (def (environment-find-matching)      (let* {[s (str term)]             [ts (eq? 0 (str-find s "*"))] ; starts with             [s (or (and ts (str-sub s 1)) s)]             [ei (1- (length s))]             [te (eq? (str-find s "*") ei)]             [s (or (and te (str-sub s 0 ei)) s)]             [slen (length s)]             [matches? (λ (term) (let* {[name (str term)]                                        [i (str-find name s)]                                        [nlen (and i (length name))]}                                   (and i                                        (or ts (= 0 i))                                        (or te (= nlen (+ i slen))))))]             [matching (nconc (filter matches? (environment))                              (filter matches? (table-keys *syntax-environment*)))]}        (when matching          (for-each (λ (term) (princ term) (newline))                    (sort matching <)))))    (def (print-sig term sigs lpad)      (if sigs          (for-each (λ (sig) (newline)                             (princ lpad)                             (princ (cons term sig)))                    sigs)          (newline)          (princ lpad)          (princ term)))    (def (first-line s)      (str-sub s 0 (str-find s "\n")))    (def (doc-group? k)      (and (cons? k)           (eq? (car k) 'doc)           (eq? (cadr k) 'group)))    (def (doc-extra-term? k)      (and (atom? k)           (member doc-extra-term (getprop k '*doc-extra* NIL))))    (def (table-keys-filter-sort tbl pred)      (sort (table-fold (λ (k _ z) (if (pred k) (cons k z) z)) NIL tbl) <))    (if (eq? term 'groups)        (for-each (λ (k) (princ (str-rpad (str (caddr k)) 10)                                (first-line (getprop k '*doc* NIL)))                         (newline))                  (table-keys-filter-sort (get *properties* '*doc*)                                          doc-group?))        (if (or doc formals-list)            (begin (print-header docterm formals-list :kind kind)                   (let* {[extra (getprop docterm '*doc-extra* NIL)]                          [fmt (filter (λ (v) (eq? (car v) :doc-fmt)) extra)]                          [see (filter (λ (v) (eq? (car v) :doc-see)) extra)]}                     (when doc                       (princ (foldl (λ (fmt doc) ((cdr fmt) doc)) doc fmt))                       (newline))                     (when see                       (newline)                       (princ "See also:")                       (newline)                       (for-each (λ (v) (print-sig (cdr v)                                                   (getprop (cdr v) '*formals-list* NIL)                                                   "    "))                                 see)                       (newline)))                   (when kind                     (newline)                     (princ "Members:")                     (newline)                     (for-each (λ (k) (print-sig k                                                 (getprop k '*formals-list* NIL)                                                 "    "))                               (table-keys-filter-sort (get *properties* '*doc*)                                                       doc-extra-term?))                     (newline))                   #.(void))            (unless (and (not term-bound) (environment-find-matching))              (princ "no help for " (if kind (str kind " ") "") term)              (when (and (not kind)                         (sym? term)                         (not term-bound))                (princ " (undefined)"))                (newline))))  (void))) ;;; standard procedures (def (member item lst)  "Return the tail of a list beginning with the item, or `NIL` otherwise.   List elements are compared to the `item` using `equal?`.    Examples:        (member 1 '(3 2 1 0))       ; ↳ (1 0)        (member 1 '(2 3))       ; ↳ NIL"  :doc-group list  :doc-see memq  :doc-see memv  (cond ((equal? (car lst) item) lst)        (lst                     (member item (cdr lst))))) (def (memv item lst)  "Return the tail of a list beginning with the item, or `NIL` otherwise.   List elements are compared to the `item` using `eqv?`."  :doc-group list  :doc-see member  :doc-see memq  (cond ((eqv? (car lst) item) lst)        (lst                   (memv item (cdr lst))))) (def (assoc-list . kvs)  "Construct an association list from the arguments.    Every two arguments are expected to be a key and a value associated   with that key.    Examples:        (assoc-list 'a 0 'b 1)       ; ↳ ((a . 0) (b . 1))"  :doc-group list  :doc-see assoc  (let ((s (cdr kvs)))    (when (cons? s)      (cons (cons (car kvs) (car s))            (apply assoc-list (cdr s)))))) (def (assoc key lst)  "Return a pair of a matching key and the associated value, or `NIL` if   none matched.  Keys are compared using `equal?`.    Examples:        (def L (assoc-list 'a 0 'b 1))       (assoc 'b L)       ; ↳ (b . 1)       (assoc 'c L)       ; ↳ NIL"  :doc-group list  :doc-see assoc-list  :doc-see assq  :doc-see assv  (cond ((equal? (caar lst) key) (car lst))        (lst                     (assoc key (cdr lst))))) (def (assv key lst)  "Return a pair of a matching key and the associated value, or `NIL` if   none matched.  Keys are compared using `eqv?`."  :doc-group list  :doc-see assoc  :doc-see assq  (cond ((eqv? (caar lst) key) (car lst))        (lst                   (assv key (cdr lst))))) (doc-group compare  "Comparison operators.") (def (> v . rest)  "Return `T` if the arguments are in strictly decreasing order (previous   one is greater than the next one)."  :doc-group compare  (let loop ((v v) (rest rest))    (or (not rest)        (and (< (car rest) v)             (loop (car rest) (cdr rest))))))(defmacro (> v . rest)  `(< ,.(reverse rest) ,v)) (def (<= v . rest)  "Return `T` if the arguments are in non-decreasing order (previous   one is less than or equal to the next one)."  :doc-group compare  (let loop ((v v) (rest rest))    (or (not rest)        (unless (or (< (car rest) v)                    (nan? v))          (loop (car rest) (cdr rest)))))) (def (>= v . rest)  "Return `T` if the arguments are in non-increasing order (previous   one is greater than or equal to the next one)."  :doc-group compare  (let loop ((v v) (rest rest))    (or (not rest)        (unless (or (< v (car rest))                    (nan? v))          (loop (car rest) (cdr rest)))))) (doc-group number  "Operations on numbers, mathematical constants.") (def (negative? n)  "Return `T` if `n` is a negative number. Shorthand for `(< n 0)`."  :doc-group number  :doc-group compare  (< n 0)) (def (zero? n)  "Return `T` if `n` is zero. Shorthand for `(= n 0)`."  :doc-group number  :doc-group compare  (= n 0)) (def (positive? n)  "Return `T` if `n` is greater than zero. Shorthand for `(> n 0)`."  :doc-group number  :doc-group compare  (< 0 n)) (def (even? n)  "Return `T` if `n` is an even integer, `NIL` otherwise."  :doc-group number  :doc-see odd?  (= (logand n 1) 0)) (def (odd? n)  "Return `T` if `n` is an odd integer, `NIL` otherwise."  :doc-group number  :doc-see even?  (not (even? n))) (def (1+ n)  "Equivalent to `(+ n 1)` - increment by one."  :doc-group number  :doc-see 1-  (+ n 1)) (def (1- n)  "Equivalent to `(- n 1)` - decrement by one."  :doc-group number  :doc-see 1+  (- n 1)) (def (div a n)  "Return the quotient of the Euclidean division `a/n`.    Examples:        (div 10 3)       ; ↳ 3        (div -10 3)       ; ↳ -4        (div -10 -3)       ; ↳ 4        (div 10 -3)       ; ↳ -3"  :doc-group number  :doc-see mod  :doc-see div0  (+ (div0 a n)     (or (and (< a 0)              (or (and (< n 0) 1)                  -1))         0))) (def (mod a n)  "Return the remainder of the Euclidean division `a/n`.    Examples:        (mod  10 3)       ; ↳ 1        (mod -10 3)       ; ↳ 2        (mod -10 -3)       ; ↳ 2        (mod  10 -3)       ; ↳ 1"  :doc-group number  :doc-see div  :doc-see mod0  (- a (* (div a n) n))) (def (mod0 a n)  "Return the remainder of the truncated division `a/n`.    Examples:        (mod0 10 3)       ; ↳ 1        (mod0 -10 3)       ; ↳ -1 

Lines 1–500 of 3373.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t