(zilch lang go): document

Change-Id: I6a6a6964558b4fe2f96d78120b2e899f91d48c22
This commit is contained in:
puck 2025-06-23 12:22:20 +00:00
parent f0ce185d5c
commit 18f2887eba
13 changed files with 457 additions and 96 deletions

View file

@ -1,3 +1,4 @@
;; Handles the Go standard library.
(define-library (zilch lang go stdlib)
(import
(scheme base) (scheme file) (scheme write) (scheme process-context) (scheme lazy)
@ -9,7 +10,7 @@
(srfi-4)
(zilch lang go core)
(zilch lang go))
(export
go-stdlib-ref)
@ -20,12 +21,12 @@
out
(read-all-objects port (cons (json-read port) out))))
;; Runs `++go list++` (thru `++/bin/sh++`) and reads (IFD) the output to fetch the metadata of the Go standard library and commands.
;; Runs `go list` (thru `/bin/sh`) and reads the output to fetch the metadata of the Go standard library and commands.
(define stdlib-objects
(map vector->list
(call-with-port
(store-path-open
(cdar (store-path-for-ca-drv*
(cdar (store-path-for-ca-drv
"stdenv"
"x86_64-linux"
#~("/bin/sh" "-c" ,(string-append "GOCACHE=$TMPDIR/go-cache " #$go-toolchain "/bin/go list -json -deps std cmd > $out"))
@ -37,7 +38,7 @@
(if res (cdr res) '()))
;; Extract everything until the first space.
;; Space characters are illegal in Go package names, and `++go list -json std++`
;; Space characters are illegal in Go package names, and `go list -json std`
;; uses it to disambiguate multiple versions of some internal packages.
(define (strip-space-bits name)
(do
@ -48,9 +49,9 @@
(if (>= x (string-length name))
name
(substring name 0 x)))))
;; Tail-recursively remove any packages that, if ignoring the postfixed origin
;; (e.g. `++unsafe [cmd/compile]++`), match either `++unsafe++` or `++builtin++`;
;; (e.g. `unsafe [cmd/compile]`), match either `unsafe` or `builtin`;
;; these have no source code and are compiler-internal.
(define (remove-builtin-packages pkgs)
(if (eq? pkgs '())
@ -59,21 +60,23 @@
(if (or (string=? stripped "unsafe") (string=? stripped "builtin"))
(remove-builtin-packages (cdr pkgs))
(cons (car pkgs) (remove-builtin-packages (cdr pkgs)))))))
(define (starts-with left right)
(and
(>= (string-length right) (string-length left))
(string=? left (string-copy right 0 (string-length left)))))
(define (filter condition lst)
(if (eq? lst '())
'()
(if (condition (car lst))
(cons (car lst) (filter condition (cdr lst)))
(filter condition (cdr lst)))))
;; Helper that parses the JSON returned by `++go list -json -deps++` and builds a `++go-package++` record.
;; This is distinct from `go-package-compile` because of format differences,
;; Helper that parses the JSON returned by `go list -json -deps` and builds a `go-package` record.
;; This is distinct from `go-package-compile` because of format differences.
;;
;; TODO(puck): Is this still the case?
(define (make-stdlib-inner meta)
(define files (assoc-or-empty "GoFiles" meta)) ; .go files
(define sfiles (assoc-or-empty "SFiles" meta)) ; .s files
@ -89,7 +92,7 @@
(when (string=? package-name "main")
(set! name package-name))
(define dir (cdr (assoc "Dir" meta)))
; Fetch dependencies from the rest of the stdlib data.
; We only need the `++api++` at this point.
(define resolved-imports (map (lambda (v) (cons (strip-space-bits v) (go-package-api (go-stdlib-ref v)))) (remove-builtin-packages imports)))
@ -140,7 +143,7 @@
; Use `go tool pack` to merge the code together.
(define merged-code
(cdar
(store-path-for-ca-drv*
(store-path-for-ca-drv
(string-append "go-" (rewrite-package-name name) "-code") "x86_64-linux"
#~(,(string-append #$go-toolchain "/bin/go") "tool" "pack" "c" ,(make-placeholder "code") . #$all-code)
(env-for-goarch)
@ -148,11 +151,11 @@
(make-go-package name import-path go-api merged-code (map go-stdlib-ref (remove-builtin-packages imports))))
; Each entry is a list (name metadata (api code)).
; Use `++delay++` to resolve the DAG lazily on use.
; Each entry is a list of (name metadata (api code)).
; Use `delay` to resolve the DAG lazily on use.
(define stdlib-data (map (lambda (v) (list (cdr (assoc "ImportPath" v)) v (delay (make-stdlib-inner v)))) stdlib-objects))
;; Finds any package contained within Go's standard library.
;; Finds any package contained within Go's standard library, and returns a `<go-package>` for the package.
(define (go-stdlib-ref name)
(define entry (assoc name stdlib-data))
(unless entry (error (string-append "Could not find package " name " in stdlib")))