mirror of
https://github.com/carp-lang/Carp.git
synced 2024-08-16 00:30:24 +03:00
docs: make doc work on top level and document macros (#1265)
This commit is contained in:
parent
09c91c7f90
commit
97c0b5a61b
@ -1,3 +1,4 @@
|
||||
(hidden thread-first-internal)
|
||||
(defndynamic thread-first-internal [xs]
|
||||
(if (= (length xs) 2)
|
||||
(if (list? (last xs))
|
||||
@ -13,6 +14,7 @@
|
||||
(cdr (last xs)))
|
||||
(list (last xs) (thread-first-internal (all-but-last xs))))))
|
||||
|
||||
(hidden thread-last-internal)
|
||||
(defndynamic thread-last-internal [xs]
|
||||
(if (= (length xs) 2)
|
||||
(if (list? (last xs))
|
||||
@ -30,12 +32,35 @@
|
||||
(defmacro ==> [:rest forms]
|
||||
(thread-last-internal forms))
|
||||
|
||||
(doc -> "threads the first form through the following ones, making it the first
|
||||
argument.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
(-> 1
|
||||
(- 10)
|
||||
(* 5)
|
||||
) ; => -45
|
||||
```")
|
||||
(defmacro -> [:rest forms]
|
||||
(thread-first-internal forms))
|
||||
|
||||
(doc --> "threads the first form through the following ones, making it the last
|
||||
argument.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
(--> 1
|
||||
(- 10)
|
||||
(/ 45)
|
||||
) ; => 5
|
||||
```")
|
||||
(defmacro --> [:rest forms]
|
||||
(thread-last-internal forms))
|
||||
|
||||
(hidden comp-internal)
|
||||
(defndynamic comp-internal [sym fns]
|
||||
(if (= (length fns) 0)
|
||||
sym
|
||||
@ -90,26 +115,33 @@
|
||||
(list 'while (list 'not cnd)
|
||||
body))
|
||||
|
||||
(doc let-do "is a `let` with an implicit `do` body.")
|
||||
(defmacro let-do [bindings :rest forms]
|
||||
(list 'let bindings
|
||||
(cons 'do forms)))
|
||||
|
||||
(doc while-do "is a `while` with an implicit `do` body.")
|
||||
(defmacro while-do [condition :rest forms]
|
||||
(list 'while condition
|
||||
(cons 'do forms)))
|
||||
|
||||
(doc defn-do "is a `defn` with an implicit `do` body.")
|
||||
(defmacro defn-do [name arguments :rest body]
|
||||
(eval (list 'defn name arguments (cons 'do body))))
|
||||
|
||||
(doc forever-do "is a `forever` with an implicit `do` body.")
|
||||
(defmacro forever-do [:rest forms]
|
||||
(list 'while true (cons 'do forms)))
|
||||
|
||||
(doc when "is an `if` without an else branch.")
|
||||
(defmacro when [condition form]
|
||||
(list 'if condition form (list)))
|
||||
|
||||
(doc unless "is an `if` without a then branch.")
|
||||
(defmacro unless [condition form]
|
||||
(list 'if condition (list) form))
|
||||
|
||||
(hidden case-internal)
|
||||
(defndynamic case-internal [name xs]
|
||||
(if (= (length xs) 0)
|
||||
(list)
|
||||
@ -122,8 +154,20 @@
|
||||
(cadr xs)
|
||||
(case-internal name (cddr xs)))))))
|
||||
|
||||
(defmacro case [name :rest forms]
|
||||
(case-internal name forms))
|
||||
(doc case "takes a form and a list of branches which are value and operation
|
||||
pairs. If a value matches, the operation is executed. It takes a catch-all else
|
||||
branch that is executed if nothing matches.
|
||||
|
||||
Example:
|
||||
```
|
||||
(case (+ 10 1)
|
||||
10 (println* \"nope\")
|
||||
11 (println* \"yup\")
|
||||
(println* \"else branch\")
|
||||
)
|
||||
```")
|
||||
(defmacro case [form :rest branches]
|
||||
(case-internal form branches))
|
||||
|
||||
(defmodule Dynamic
|
||||
(doc flip
|
||||
|
@ -1,10 +1,12 @@
|
||||
;; Defining the meta data macros early so that they can be used by all the other code.
|
||||
;; Defined early so that `doc` can accept a rest arg
|
||||
(meta-set! map-internal "hidden" true)
|
||||
(defndynamic map-internal [f xs acc]
|
||||
(if (= 0 (length xs))
|
||||
acc
|
||||
(map-internal f (cdr xs) (cons-last (f (car xs)) acc))))
|
||||
|
||||
(meta-set! list-to-array-internal "hidden" true)
|
||||
(defndynamic list-to-array-internal [xs acc]
|
||||
(if (= 0 (length xs))
|
||||
acc
|
||||
@ -80,7 +82,7 @@
|
||||
(Dynamic.String.concat [x newline])))
|
||||
strings
|
||||
())]
|
||||
(list 'meta-set! name "doc" (Dynamic.String.concat (list-to-array-internal separated [])))))
|
||||
(eval (list 'meta-set! name "doc" (Dynamic.String.concat (list-to-array-internal separated []))))))
|
||||
|
||||
(doc print-doc "Print the documentation for a binding.")
|
||||
(defmacro print-doc [name]
|
||||
@ -113,6 +115,10 @@
|
||||
(if (= 1 (length xs))
|
||||
(car xs)
|
||||
(list 'if (car xs) (and- (cdr xs)) false) )))
|
||||
(doc and "evaluates the forms `xs` one at a time, from left to right. If a form
|
||||
evaluates to `false`, `and` returns that value and doesn't evaluate any of the
|
||||
other expressions, otherwise it returns the value of the last form in `xs`.
|
||||
`(and)` returns `true`.")
|
||||
(defmacro and [:rest xs]
|
||||
(and- xs))
|
||||
|
||||
@ -126,6 +132,10 @@
|
||||
(if (= 1 (length xs))
|
||||
(car xs)
|
||||
(list 'if (car xs) true (or- (cdr xs))) )))
|
||||
(doc or "evaluates the forms `xs` one at a time, from left to right. If a form
|
||||
evaluates to `true`, `or` returns that value and doesn't evaluate any of the
|
||||
other expressions, otherwise it returns the value of the last form in `xs`.
|
||||
`(or)` returns `false`.")
|
||||
(defmacro or [:rest xs]
|
||||
(or- xs))
|
||||
|
||||
@ -142,6 +152,7 @@
|
||||
(defmacro hidden? [name]
|
||||
(eval (list 'not (list 'list? (list 'meta name "hidden")))))
|
||||
|
||||
(hidden annotate-helper)
|
||||
(defndynamic annotate-helper [name annotation]
|
||||
(list 'cons annotation (list 'meta name "annotations")))
|
||||
|
||||
@ -168,6 +179,7 @@
|
||||
(eval (list 'hidden name))
|
||||
(list 'def name value)))
|
||||
|
||||
(hidden cond-internal)
|
||||
(defndynamic cond-internal [xs]
|
||||
(if (= (length xs) 0)
|
||||
(list)
|
||||
@ -194,16 +206,22 @@
|
||||
(defmacro cond [:rest xs]
|
||||
(cond-internal xs))
|
||||
|
||||
(doc refstr "stringifies `x` and takes the reference of that string.")
|
||||
(defmacro refstr [x]
|
||||
(list 'ref
|
||||
(list 'str x)))
|
||||
|
||||
(doc swap! "swaps its arguments `x` and `y` in place.
|
||||
|
||||
*Note*: Unhygienic!")
|
||||
(defmacro swap! [x y]
|
||||
(list 'let (array 'tmp y) (list 'do (list 'set! y x) (list 'set! x 'tmp))))
|
||||
|
||||
(doc update! "updates `x` in place using the function `f`.")
|
||||
(defmacro update! [x f]
|
||||
(list 'set! x (list f x)))
|
||||
|
||||
(hidden use-all-fn)
|
||||
(defndynamic use-all-fn [names]
|
||||
(if (= (length names) 0)
|
||||
(macro-error "Trying to call use-all without arguments")
|
||||
@ -213,17 +231,22 @@
|
||||
()
|
||||
(use-all-fn (cdr names))))))
|
||||
|
||||
(doc use-all "is a variadic version of `use`.")
|
||||
(defmacro use-all [:rest names]
|
||||
(use-all-fn names))
|
||||
|
||||
(doc load-and-use "loads a file and uses the module with in it. Assumes that
|
||||
the filename and module name are the same.")
|
||||
(defmacro load-and-use [name]
|
||||
(do
|
||||
(eval (list 'load (str name ".carp")))
|
||||
(eval (list 'use name))))
|
||||
|
||||
(doc comment "ignores `forms`.")
|
||||
(defmacro comment [:rest forms]
|
||||
())
|
||||
|
||||
(hidden build-vararg)
|
||||
(defndynamic build-vararg [func forms]
|
||||
(if (= (length forms) 0)
|
||||
(macro-error "vararg macro needs at least one argument")
|
||||
@ -231,6 +254,7 @@
|
||||
(car forms)
|
||||
(list func (car forms) (build-vararg func (cdr forms))))))
|
||||
|
||||
(doc ignore "ignores the return value of the expression `form`.")
|
||||
(defmacro ignore [form]
|
||||
(list 'let (array '_ form) (list)))
|
||||
|
||||
@ -253,6 +277,7 @@
|
||||
(defmacro inline-c [name defcode :rest declcode]
|
||||
(eval (list 'deftemplate name (list) defcode (if (empty? declcode) "" (car declcode)))))
|
||||
|
||||
(doc bottom "aborts the program if reached.")
|
||||
(deftemplate bottom (Fn [] a) "$a $NAME()" "$DECL { abort(); }")
|
||||
|
||||
(doc unreachable
|
||||
@ -270,6 +295,7 @@
|
||||
(list 'System.abort)
|
||||
(list 'bottom)))
|
||||
|
||||
(hidden implement-declaration)
|
||||
(defndynamic implement-declaration [mod interface]
|
||||
(list 'implements interface (Symbol.prefix mod interface)))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user