rebirth: Extend `cond-expand' to dynamically support features
This will crudely detect "features" by seeing if the requested feature is a definition. Ideally that definition would be a procedure, but we don't check for that. This does what we need it to do. Obviously this is a poor implementation and will not persist past Rebirth. * build-aux/bootstrap/rebirth.scm (es:defined?): New procedure. (expand-cond-expand): New procedure. If first Rebirth pass, only support `string->es' and `else'; otherwise detect features using `es:defined?'. (fnmap)[cond-expand]: Use it.master
parent
0b0003578b
commit
0a1e530a76
|
@ -71,6 +71,11 @@
|
|||
;; for brevity
|
||||
(string->es "const _truep = x => x !== false")
|
||||
|
||||
;; intended for whether a procedure is defined, mostly
|
||||
(define (es:defined? x)
|
||||
(let ((id (tname->id x)))
|
||||
(string->es "eval('typeof ' + $$id) !== 'undefined'")))
|
||||
|
||||
(define (es:typeof x)
|
||||
(string->es "typeof $$x"))
|
||||
|
||||
|
@ -628,6 +633,43 @@
|
|||
"([" (%quote-maybe sexp #f) "])")))
|
||||
|
||||
|
||||
;; Statically expand expressions based on implementation features
|
||||
;;
|
||||
;; Support for `cond-expand' allows Rebirth to introduce new features each
|
||||
;; time that it is compiled. If matched, expressions will be evaluated as
|
||||
;; if they were entered in place of the `cond-expand' itself; otherwise,
|
||||
;; the entire `cond-expand' expression as a whole will be discarded.
|
||||
;;
|
||||
;; Birth will always discard `cond-expand' expressions unless they contain
|
||||
;; an `else' clause, which permits us to compile on the first pass without
|
||||
;; error.
|
||||
(define (expand-cond-expand args)
|
||||
(if (pair? args)
|
||||
(let* ((clause (car args))
|
||||
(feature (token-value (car clause)))
|
||||
(body (cdr clause)))
|
||||
;; now we get meta
|
||||
(cond-expand
|
||||
(string->es
|
||||
(case feature
|
||||
(("string->es" "else") (body->es body #f))
|
||||
(else (if (es:defined? feature)
|
||||
(body->es body #f)
|
||||
(expand-cond-expand (cdr args))))))
|
||||
;; if we're not yet compiled with Rebirth, then string->es will
|
||||
;; not yet be available---but it _will_ be in Rebirth, so
|
||||
;; compile cond-expand such that it marks it as supported
|
||||
(else
|
||||
(case feature
|
||||
;; these two are always supported in Rebirth Lisp
|
||||
(("string->es" "else") (body->es body #f))
|
||||
;; keep recursing until we find something (this allows us to
|
||||
;; short-circuit, most notably with "else")
|
||||
(else
|
||||
(expand-cond-expand (cdr args)))))))
|
||||
""))
|
||||
|
||||
|
||||
;; Function/procedure aliases and special forms
|
||||
;;
|
||||
;; And here we have what is probably the most grotesque part of this file.
|
||||
|
@ -653,13 +695,7 @@
|
|||
(string-append "console.error(" (map sexp->es args) ")"))
|
||||
|
||||
;; very primitive cond-expand
|
||||
(("cond-expand")
|
||||
(let* ((clause (car args))
|
||||
(feature (token-value (car clause)))
|
||||
(body (cdr clause)))
|
||||
(case feature
|
||||
(("string->es") (body->es body #f))
|
||||
(else ""))))
|
||||
(("cond-expand") (expand-cond-expand args))
|
||||
|
||||
;; output raw code into the compiled ECMAScript (what could go wrong?)
|
||||
(("string->es")
|
||||
|
|
Loading…
Reference in New Issue