luv

Workshop wiki

introspect.lisp

wiki/introspect.lisp

system luv-wiki/introspect · 7 definitions · on GitHub

Gathering real lambda lists for the operators the corpus uses.

The dexp renderer draws a form according to a layout. For the long tail of operators, luv's own macros above all, the honest source of layout is the operator's real lambda list: what precedes &BODY is the head, a destructuring pattern in a position means a clause there, &KEY marks where keyword pairs begin. This file gathers those facts from a Lisp image in which the systems are loaded, the way SLY's slynk-indentation derives indentation from macro arglists, and writes them to wiki/arglists.sexp so the site can be rendered without loading luv.

defpackage#:luv.wiki.introspect
:use#:cl
:local-nicknames
#:wiki#:luv.wiki
:export#:gather-arglists#:write-arglists#:operator-symbols
in-package#:luv.wiki.introspect
defunpackage-designator-name
text

The package name written in an IN-PACKAGE form: #:foo, :foo, "foo", foo.

let
name
string-trim"#:\""text
string-upcasename
defunoperator-symbols
source-files

Every (package-name . symbol-name) that appears as the first element of a list in source-files, resolved against each file's IN-PACKAGE for unprefixed symbols; keywords and unknown packages are left out.

let
seen
make-hash-table:test'equal
result'
dolist
filesource-files
let
labels
walk
typecasenode
wiki:lisp-list
let
head
first
wiki:element-childrennode
when
let*
package
wiki:lisp-symbol-packagehead
package-name
cond
nullpackage
current
stringppackage
string-upcasepackage
tnil
when
andpackage-name
not
equalpackage-name"KEYWORD"
let
key
conspackage-name
string-upcase
wiki:lisp-symbol-namehead
unless
gethashkeyseen
setf
gethashkeyseen
t
pushkeyresult
mapc#'walk
wiki:element-childrennode
wiki:lisp-prefix
walk
wiki::lisp-prefix-childnode
wiki:lisp-conditional
when
wiki::lisp-conditional-formnode
walk
wiki::lisp-conditional-formnode
mapc#'walk
wiki:source-file-nodesfile
nreverseresult
defunsanitize
tree

Turn a lambda list into readable data: symbols become their names, lambda-list keywords keywords, other atoms strings; lists are kept.

typecasetree
nullnil
cons
cons
sanitize
cartree
sanitize
cdrtree
symbol
if
membertreelambda-list-keywords
intern
symbol-nametree
:keyword
symbol-nametree
t
princ-to-stringtree
defunsymbol-facts
symbol

A plist describing symbol as an operator, or NIL if it is not one.

let
kind
cond
special-operator-psymbol
:special-operator
macro-functionsymbol
:macro
and
fboundpsymbol
typep
fdefinitionsymbol
'generic-function
:generic-function
fboundpsymbol
:function
tnil
whenkind
let
lambda-list
ignore-errors
sb-introspect:function-lambda-listsymbol
list:kindkind:lambda-list
sanitizelambda-list
defungather-arglists
source-files

An alist ((home-package . name) . facts) for every operator of source-files whose symbol exists and is fbound in this image, each symbol once under its home package.

let
seen
make-hash-table:test'eq
result'
loopfor
package-name.name
in
operator-symbolssource-files
forpackage=
find-packagepackage-name
forsymbol=
andpackage
find-symbolnamepackage
forfacts=
andsymbol
not
gethashsymbolseen
whenfactsdo
setf
gethashsymbolseen
t
push
cons
cons
package-name
symbol-packagesymbol
name
facts
result
nreverseresult
defunwrite-arglists
source-filespathname

Write the gathered facts to pathname as one readable form per operator.

let
entries
sort
gather-arglistssource-files
#'string<:key
lambda
entry
formatnil"~A:~A"
caarentry
cdarentry
with-open-file
outpathname:direction:output:if-exists:supersede
with-standard-io-syntax
let
*print-case*:downcase
*print-readably*nil
*package*
find-package:cl-user
formatout";;; Operator lambda lists gathered by scripts/wiki introspect.~%"
formatout";;; ((package . name) :kind KIND :lambda-list LIST), symbols as strings.~%~%"
dolist
entryentries
prin1entryout
terpriout
lengthentries