shithub: sl

Download patch

ref: 9dc5cac76dd203b5b7e2f8d99cb4d5e587fd6a2d
parent: 3f571ecf6862467a912305dc4f38abf7414609c3
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sun Mar 23 16:22:03 EDT 2025

doc-for: use separate-doc-from-body to get paired list for doc extras

--- a/boot/sl.boot
+++ b/boot/sl.boot
@@ -29,23 +29,11 @@
   (:print-header help-print-header)))  rand-u32 (NIL)  = ((a . rest))  rand-u64 (NIL)  not ((v))  separate-doc-from-body ((body
   (doc NIL)))  set-cdr! ((cell new-second))  fn? ((v))  help-print-header ((term sigs))  lz-pack ((data
   (level 0)))  *prompt* (NIL)  eq? ((a b))  getprop ((symbol key (def NIL)))  vm-stats (NIL)  * (rest)  putprop ((symbol
-  key val))  io->str ((io)))  *doc* #table(identity "Return `x`."  bound? "Return `T` if `symbol` has a value associated with it, `NIL` otherwise."  sym-set-doc "Set the documentation for the symbol."  io-eof? "Return `T` if `io` is currently in the \"end of file\" state, `NIL`\notherwise."  < "Return `T` if the arguments are in strictly increasing order (next\none is greater than the previous one).  With a single argument\nthe result is always `T`."  cadr "Shorthand for `(car (cdr cell))`, that is, \"first element of the\nsecond element\".\n\nExamples:\n\n    (cadr '(1 2 3)) → 2\n    (cadr '(1))     → NIL\n    (cadr NIL)      → NIL"  sym "Convert terms to a symbol.\n\nThis is equivalent to `(sym (str terms…))`."  nan? "Return `T` if `v` is a floating point representation of NaN, either\nnegative or positive, `NIL` otherwise."  for "Call the function `fn` with a single integer argument, starting from\n`min` and ending with `max`.\n\nExamples:\n\n    (for 0 2 (λ (i) (print (- 2 i)))) → 210"  fixnum? "Return `T` if `v` is of a fixnum type, `NIL` otherwise."  exit "Terminate the process with the specified status.  Does not return.\nThe status is expected to be a string in case of an error.\n\nExamples:\n\n    (exit)\n    (exit \"error\")"  > "Return `T` if the arguments are in strictly decreasing order (previous\none is greater than the next one)."  + "Return sum of the arguments or `0` when none specified."  div0 "Return the quotient of two numbers.  For non-integers this is\nequivalent to `(div0 (floor a) (floor b))`.  The result is always an\ninteger.\n\nExamples:\n\n    (div0 7 2)     → 3\n    (div0 10 -2)   → -5\n    (div0 6.9 1.9) → 6"  __finish "A function called right before exit by the VM."  lz-unpack "Return decompressed data previously compressed using lz-pack.\n\nEither destination for the decompressed data or the expected size of\nthe decompressed data must be specified.  In the latter case a new\narray is allocated."  defstruct "Defines a structure type with a specific name and slots.\n\nThe default underlying type is a \"named\" vector (`:type vec`),\nwhere the first element is the name of the structure's type, the\nrest are the slot values.  If the name as the first element isn't\nrequired, `:named NIL` should be used.  A list can be used instead\nof a vector by adding `:type list` option.\n\nAn example of a default constructor signature, based on structure\ndefinition:\n\n    (defstruct blah a b c) →\n      (make-blah (:a NIL) (:b NIL) (:c NIL))\n\nIt can be customized in several ways. For example:\n\n    ; disable the constructor altogether\n    (defstruct blah :constructor NIL a b c)\n    ; only change its name\n    (defstruct blah :constructor blargh a b c)\n    ; rename AND avoid using keywords\n    (defstruct blah :constructor (blah a b c) a b c)\n\nThe option `:conc-name` specifies the slot accessor prefix, which\ndefaults to `name-`.\n\nDefault predicate name (`name?`) can be changed:\n\n    ; use \"blargh?\" instead of \"blah?\"\n    (defstruct blah :predicate blargh? a b c)"  compare "Return -1 if `x` is less than `y`, 0 if equal, and `1` if `y` is\ngreater than `x`.\n\nExamples:\n\n    (compare 'a 'b)       → -1\n    (compare 1 1)         → 0\n    (compare \"b\" \"a\") → 1"  buffer "Return an in-memory buffer for I/O, of `io` type.\n\nA buffer can be used for both reading and writing at the same\ntime."  num? "Return `T` if `v` is of a numerical type, `NIL` otherwise.\n\nNumerical types include floating point, fixnum, bignum, etc.\nNote: ironically, a NaN value is considered a number by this function\nsince it's only testing the _type_ of the value."  add-exit-hook "Puts an one-argument function on top of the list of exit hooks.\n\nOn shutdown each exit hook is called with the exit status as a single\nargument, which is (usually) `NIL` on success and a string describing\nan error otherwise."  rand-float "Return a random float on [0.0, 1.0] interval."  builtin? "Return `T` if `v` is a built-in function implemented in C, `NIL`\notherwise.\n\nExamples:\n\n    (builtin? map) 
\ No newline at end of file
-  builtin)  sym-set-doc ((:doc-group . docs))  io-eof? (:doc-group io)  < (:doc-group builtin)  cadr (:doc-group
-  builtin)  nan? (:doc-group builtin)  for (:doc-group builtin)  fixnum? (:doc-group builtin)  > ((:doc-group . compare))  + (:doc-group
-  builtin)  div0 (:doc-group builtin)  compare (:doc-group builtin)  buffer (:doc-group io)  num? (:doc-group
-  builtin)  set-car! (:doc-group builtin)  builtin? (:doc-group builtin)  cons? (:doc-group builtin)  aref (:doc-group
-  builtin)  *properties* (:doc-group props)  vec (:doc-group builtin)  >= ((:doc-group . compare))  sym? (:doc-group
-  builtin)  zero? ((:doc-group . compare))  length= ((:doc-group . list))  positive? ((:doc-group . compare))  doc-for ((:doc-group . docs))  aset! (:doc-group
-  builtin)  car (:doc-group builtin)  <= ((:doc-group . compare))  str (:doc-see T)  cons (:doc-group
-  builtin)  - (:doc-group builtin)  remprop ((:doc-group . props))  negative? ((:doc-group . compare))  file (:doc-group
-  io)  cdr (:doc-group builtin)  atom? (:doc-group builtin)  vec? (:doc-group builtin)  T (:doc-see
-  NIL)  equal? (:doc-group builtin)  / (:doc-group builtin)  eqv? (:doc-group builtin)  io? (:doc-group
-  io)  eof-object? (:doc-group io)  list (:doc-group builtin)  apply (:doc-group builtin)  help ((:doc-group . docs))  separate-doc-from-body ((:doc-group . docs))  = (:doc-group
-  builtin)  not (:doc-group builtin)  set-cdr! (:doc-group builtin)  fn? (:doc-group builtin)  help-print-header ((:doc-group . docs))  eq? (:doc-group
-  builtin)  getprop ((:doc-group . props))  putprop ((:doc-group . props))  * (:doc-group builtin)  io->str (:doc-group
-  io)))
-            *syntax-environment* #table(bcode:nconst #fn("n1200r2e3:" #(aref))  doc-for #fn("z10B86;35040<;J404086;35040=863H0202187e2211e22188e2e4:202187e2211e2e3:" #(sym-set-doc
-  quote))  with-input-from #fn("z12021e1220e2e1e12315163:" #(#fn(nconc) with-bindings *io-in* #fn(copy-list)))  unless #fn("z1200q211Pe4:" #(if
+  key val))  io->str ((io)))  *doc* #table(identity "Return `x`."  bound? "Return `T` if `symbol` has a value associated with it, `NIL` otherwise."  sym-set-doc "Set the documentation for the symbol."  io-eof? "Return `T` if `io` is currently in the \"end of file\" state, `NIL`\notherwise."  < "Return `T` if the arguments are in strictly increasing order (next\none is greater than the previous one).  With a single argument\nthe result is always `T`."  cadr "Shorthand for `(car (cdr cell))`, that is, \"first element of the\nsecond element\".\n\nExamples:\n\n    (cadr '(1 2 3)) → 2\n    (cadr '(1))     → NIL\n    (cadr NIL)      → NIL"  nan? "Return `T` if `v` is a floating point representation of NaN, either\nnegative or positive, `NIL` otherwise."  for "Call the function `fn` with a single integer argument, starting from\n`min` and ending with `max`.\n\nExamples:\n\n    (for 0 2 (λ (i) (print (- 2 i)))) → 210"  fixnum? "Return `T` if `v` is of a fixnum type, `NIL` otherwise."  > "Return `T` if the arguments are in strictly decreasing order (previous\none is greater than the next one)."  + "Return sum of the arguments or `0` when none specified."  div0 "Return the quotient of two numbers.  For non-integers this is\nequivalent to `(div0 (floor a) (floor b))`.  The result is always an\ninteger.\n\nExamples:\n\n    (div0 7 2)     → 3\n    (div0 10 -2)   → -5\n    (div0 6.9 1.9) → 6"  __finish "A function called right before exit by the VM."  defstruct "Defines a structure type with a specific name and slots.\n\nThe default underlying type is a \"named\" vector (`:type vec`),\nwhere the first element is the name of the structure's type, the\nrest are the slot values.  If the name as the first element isn't\nrequired, `:named NIL` should be used.  A list can be used instead\nof a vector by adding `:type list` option.\n\nAn example of a default constructor signature, based on structure\ndefinition:\n\n    (defstruct blah a b c) →\n      (make-blah (:a NIL) (:b NIL) (:c NIL))\n\nIt can be customized in several ways. For example:\n\n    ; disable the constructor altogether\n    (defstruct blah :constructor NIL a b c)\n    ; only change its name\n    (defstruct blah :constructor blargh a b c)\n    ; rename AND avoid using keywords\n    (defstruct blah :constructor (blah a b c) a b c)\n\nThe option `:conc-name` specifies the slot accessor prefix, which\ndefaults to `name-`.\n\nDefault predicate name (`name?`) can be changed:\n\n    ; use \"blargh?\" instead of \"blah?\"\n    (defstruct blah :predicate blargh? a b c)"  compare "Return -1 if `x` is less than `y`, 0 if equal, and `1` if `y` is\ngreater than `x`.\n\nExamples:\n\n    (compare 'a 'b)       → -1\n    (compare 1 1)         → 0\n    (compare \"b\" \"a\") → 1"  buffer "Return an in-memory buffer for I/O, of `io` type.\n\nA buffer can be used for both reading and writing at the same\ntime."  num? "Return `T` if `v` is of a numerical type, `NIL` otherwise.\n\nNumerical types include floating point, fixnum, bignum, etc.\nNote: ironically, a NaN value is considered a number by this function\nsince it's only testing the _type_ of the value."  add-exit-hook "Puts an one-argument function on top of the list of exit hooks.\n\nOn shutdown each exit hook is called with the exit status as a single\nargument, which is (usually) `NIL` on success and a string describing\nan error otherwise."  builtin? "Return `T` if `v` is a built-in function implemented in C, `NIL`\notherwise.\n\nExamples:\n\n    (builtin? map)         → T\n    (builtin? macroexpand) → NIL"  set-car! "Modify a cons cell (a list) in-place by putting `new-first` as its\nfirst element (head of the list).  Return the modified cons\ncell (list).\n\nExamples:\n\n    (def q '(1 2 3 4 5))\n    (set-car! q 0) → (0 6 7)\n    q              → (0 6 7)"  cons? "Return `T` if `v` is a cons cell, `NIL` otherwise.\n\nExamples:\n\n    (cons? 0)    → NIL\n    (cons? NIL)  → NIL\n    (cons? '(1)) → T"  1+ "Equivalent to `(+ n 1)`."  aref "Return the sequence element specified by the subscripts.  The se
\ No newline at end of file
+  props)  vec ((:doc-group . builtin))  >= ((:doc-group . compare))  sym? ((:doc-group . builtin))  zero? ((:doc-group . compare))  length= ((:doc-group . list))  positive? ((:doc-group . compare))  doc-for ((:doc-group . docs))  aset! ((:doc-group . builtin))  car ((:doc-group . builtin))  *builtins* ((:doc-group . builtin))  str ((:doc-see . T))  cons ((:doc-group . builtin))  - ((:doc-group . builtin))  remprop ((:doc-group . props))  <= ((:doc-group . compare))  negative? ((:doc-group . compare))  Instructions ((:doc-group . builtin))  file ((:doc-group . io))  cdr ((:doc-group . builtin))  atom? ((:doc-group . builtin))  T ((:doc-see))  vec? ((:doc-group . builtin))  equal? ((:doc-group . builtin))  / ((:doc-group . builtin))  eqv? ((:doc-group . builtin))  io? ((:doc-group . io))  eof-object? ((:doc-group . io))  list ((:doc-group . builtin))  apply ((:doc-group . builtin))  help ((:doc-group . docs))  separate-doc-from-body ((:doc-group . docs))  = ((:doc-group . builtin))  not ((:doc-group . builtin))  set-cdr! ((:doc-group . builtin))  fn? ((:doc-group . builtin))  help-print-header ((:doc-group . docs))  arg-counts ((:doc-group . builtin))  eq? ((:doc-group . builtin))  getprop ((:doc-group . props))  putprop ((:doc-group . props))  * ((:doc-group . builtin))  io->str ((:doc-group . io))))
+            *syntax-environment* #table(bcode:nconst #fn("n1200r2e3:" #(aref))  doc-for #fn("z10B86;35040<;J404086;35040=70151<863I0212287e22289e22288e2e4:212287e22289e2e3:" #(separate-doc-from-body
+  sym-set-doc quote))  with-input-from #fn("z12021e1220e2e1e12315163:" #(#fn(nconc) with-bindings
+                                                                         *io-in* #fn(copy-list)))  unless #fn("z1200q211Pe4:" #(if
 ulti-dimensional sequences of variating types are also supported.\n\nExamples:\n\n    (def a '((1 #(2 (3)) 4)))\n    (aset! a 1 'x)     → index 1 out of bounds\n    (aset! a 0 0 'x)   → x\n    a                  → ((x #(2 (3)) 4))\n    (aset! a 0 1 9)    → 9\n    a                  → ((x #(9 (3)) 4))"  car "Return the first element of a cons cell (head of a list) or `NIL` if\nnot available.\n\nExamples:\n\n    (car NIL)      → NIL\n    (car '(1 2 3)) → 1\n    (car '(1 . 2)) → 1"  *builtins* "VM instructions as closures."  str "Convert terms to a concatenated string.\n\nThis is equivalent to `(princ terms…)`, except the string is\nreturned, rather than printed."  cons "Return a cons cell containing two arguments.\n\nExamples:\n\n    (cons 1 2)                     → (1 . 2)\n    (cons 1 '(2))                  → (1 2)\n    (cons 1 (cons 2 (cons 3 NIL))) → (1 2 3)"  - "Return the result of subtraction.  With only one argument a\nnegation is performed.\n\nExamples:\n\n    (- 1.5) → -1.5\n    (- 3 2) → 1"  remprop "Remove a property value associated with the symbol."  <= "Return `T` if the arguments are in non-decreasing order (previous\none is less than or equal to the next one)."  rand "Return a random non-negative fixnum on its maximum range."  void "Return the constant `#<void>` while ignoring any arguments.\n\n`#<void>` is mainly used when a function has side effects but does not\nproduce any meaningful value to return, so even though `T` or `NIL` could\nbe returned instead, in case of `#<void>` alone, REPL will not print\nit."  negative? "Return `T` if `x` is negative."  Instructions "VM instructions mapped to their encoded byte representation."  file "Open a file for I/O.\n\nAn `io` object is returned.  Without any modes specified the file\nis opened in read-only mode."  rand-double "Return a random double on interval [0.0, 1.0]."  1- "Equivalent to `(- n 1)`."  atom? "Return `T` if `v` is a _not_ a cons cell, `NIL` otherwise.  This is\nthe opposite of `cons?`.\n\nThe term \"atom\" comes from the idea of being indivisible.\n\nExamples:\n\n    (atom? \"a\")  → T\n    (atom? NIL)  → T\n    (atom? '(1)) → NIL"  cdr "Return the second element of a cons cell (tail of a list) or `NIL` if\nnot available.\n\nExamples:\n\n    (cdr NIL)      → NIL\n    (cdr '(1 2 3)) → (2 3)\n    (cdr '(1 . 2)) → 2"  T "A boolean \"true\".\n\nExamples:\n\n    (not T)         → NIL\n    (if T 'yes 'no) → yes"  vec? "Return `T` if `v` is a vector, `NIL` otherwise."  equal? "Return `T` if both `a` and `b` are of the same value.  For non-leaf\ntypes (cons cell and vector), the equality test is performed\nthroughout the whole structure of the values.\n\nExamples:\n\n    (equal? 0.0 0) → NIL\n    (equal? 0 0)   → T\n    (def a \"1\")\n    (def b \"1\")\n    (equal? a b)   → T\n    (def a '(1))\n    (def b '(1))\n    (equal? a b)   → T"  / "Return the division of the arguments.  With only one argument the\nresult of `1/x` is returned.  If the result is integer-valued, it is\nreturned as an integer.\n\nExamples:\n\n    (/ 2)       → 0.5\n    (/ 7 2 2)   → 1.75\n    (/ 10 -2)   → -5 ; a fixnum\n    (/ 6.9 1.9) → 3.6315…"  eqv? "Return `T` if both `a` and `b` are of the same value and primitive\n(leaf) type, `NIL` otherwise.  Neither cons cell nor vector are not\nconsidered primitive types as they may define deep structures.\n\nExamples:\n\n    (eqv? 0.0 0) → NIL\n    (eqv? 0 0)   → T\n    (def a \"1\")\n    (def b \"1\")\n    (eqv? a b)   → T\n    (def a '(1))\n    (def b '(1))\n    (eqv? a b)   → NIL"  io? "Return `T` if `term` is of `io` type, `NIL` otherwise."  eof-object? "Return `T` if `term` is `#<eof>`, `NIL` otherwise.\n\nThis object is returned by I/O functions to signal end of file,\nwhere applicable."  list "Return a list constructed of the arguments.\n\nExamples:\n\n    (list)              → NIL ; empty list\n    (list 1 2.5 \"a\" 'b) → (1 2.5 \"a\" b)"  apply "Return the result of applying a function to a list of arguments.\n\nThe last argument must always be a list wh
\ No newline at end of file
   builtin)  sym-set-doc ((:doc-group . docs))  io-eof? (:doc-group io)  < (:doc-group builtin)  cadr (:doc-group
   builtin)  nan? (:doc-group builtin)  for (:doc-group builtin)  fixnum? (:doc-group builtin)  > ((:doc-group . compare))  + (:doc-group
--- a/src/docs_extra.sl
+++ b/src/docs_extra.sl
@@ -5,10 +5,11 @@
    the signature will be included in the documentation, without
    replacing any previously defined."
   :doc-group docs
-  (let* ((call (cons? term))
-         (sym  (or (and call (car term))
-                   term))
-         (callvars (and call (cdr term))))
+  (let* {[call (cons? term)]
+         [sym (or (and call (car term))
+                  term)]
+         [callvars (and call (cdr term))]
+         [doc (car (separate-doc-from-body doc))]}
     (if call
         `(sym-set-doc ',sym ',doc ',callvars)
         `(sym-set-doc ',sym ',doc))))
--- a/tools/gen.sl
+++ b/tools/gen.sl
@@ -436,6 +436,7 @@
 
   (write `(def Instructions
             "VM instructions mapped to their encoded byte representation."
+            :doc-group builtin
             ,op-to-byte)
          instructions)
   (newline instructions)
@@ -442,6 +443,7 @@
   (newline instructions)
   (write `(def arg-counts
             "VM instructions mapped to their expected arguments count."
+            :doc-group builtin
             ,op-to-argc)
          instructions)
   (newline instructions)
@@ -449,6 +451,7 @@
   (set! op-to-closure (cons vec (reverse! op-to-closure)))
   (write `(def *builtins*
             "VM instructions as closures."
+            :doc-group builtin
             ,op-to-closure)
          builtins)
   (newline builtins)