rebirth: Add `include'

This is technically not a correct implementation---it doesn't wrap in
`begin'.  But that's just because we don't have a `begin' yet, and it's not
yet necessary.

This will allow us to begin breaking the mess that is rebirth.scm into
separate files, and does so cheaply (not much development effort, that is).

* build-aux/bootstrap/rebirth.scm (expand-cond-expand): Recognize "include".
  (fnmap): Add "include".
  (rebirth->ecmascript): Do not wrap compiled ECMAScript in self-executing
    function (see below).
  (rebirth->ecmascript-prog): Wrap compiled ECMAScript in self-executing
    function, as `rebirth->ecmascript' was.  Use it at end of script.
master
Mike Gerwitz 2018-02-03 01:05:35 -05:00
parent 62ab1ee732
commit 203d468b83
Signed by: mikegerwitz
GPG Key ID: 8C917B7F5DC51BA2
1 changed files with 25 additions and 10 deletions

View File

@ -1,6 +1,6 @@
;;; Rebirth Lisp implemented in Birth Lisp (self-hosting)
;;; Rebirth Lisp implemented in Birth and Rebirth Lisp (self-hosting)
;;;
;;; Copyright (C) 2017 Mike Gerwitz
;;; Copyright (C) 2017, 2018 Mike Gerwitz
;;;
;;; This file is part of Gibble.
;;;
@ -17,7 +17,7 @@
;;; You should have received a copy of the GNU Affero General Public License
;;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;;
;;; THIS IS TEMPORARY CODE that will be REWRITTEN IN GIBBLE LISP ITSELF after
;;; THIS IS TEMPORARY CODE that will be REWRITTEN IN ULAMBDA SCHEME after
;;; a very basic bootstrap is complete. It is retained as an important
;;; artifact for those who wish to build Gibble from scratch without using
;;; another version of Gibble itself. This is called "self-hosting".
@ -1173,7 +1173,7 @@
(cond-expand
(string->es
(case feature
(("string->es" "else") (body->es body #f))
(("string->es" "include" "else") (body->es body #f))
(else (if (es:defined? feature)
(body->es body #f)
(expand-cond-expand (cdr args))))))
@ -1183,7 +1183,7 @@
(else
(case feature
;; these two are always supported in Rebirth Lisp
(("string->es" "else") (body->es body #f))
(("string->es" "include" "else") (body->es body #f))
;; keep recursing until we find something (this allows us to
;; short-circuit, most notably with "else")
(else
@ -1249,6 +1249,14 @@
(("define") (cdfn t))
(("define-macro") (cdfn-macro t)) ; not defined until string->es cond
;; Defining `include' is trivial right now since we're not doing any
;; sort of static analysis---we just need to start compilation of the
;; requested file and inline it right where we are. Note that this
;; doesn't enclose the file in `begin', so this isn't yet proper.
(("include") (rebirth->ecmascript
(parse-lisp
(es:file->string (token-value (car args))))))
;; If we have macro support (`cdfn-macro'), then assume that they exist
;; and try to use them; otherwise, continue to use built-in forms, which
;; have been moved into `fnmap-premacro').
@ -1428,16 +1436,23 @@
;;
;; The AST can be generated with `parse-lisp'.
(define (rebirth->ecmascript ast)
;; compiled output, wrapped in a self-executing function to limit scope
;; and create the toplevel environment (note that we no longer depend on
;; libprebirth)
(join "\n\n" (map sexp->es ast)))
;; Compile Rebirth Lisp AST into an ECMAScript program.
;;
;; This compiles the AST into ECMAScript using `rebirth->ecmascript' and
;; then wraps it in a self-executing function to limit scope and create the
;; toplevel environment.
(define (rebirth->ecmascript-prog ast)
;; (note that we no longer depend on libprebirth)
(string-append "(function(_env){"
(join "\n\n" (map sexp->es ast))
(rebirth->ecmascript ast)
"})({macros:{}});"))
;; at this point, this program can parse itself and output a CST (sans
;; whitespace)
(es:console (rebirth->ecmascript
(es:console (rebirth->ecmascript-prog
(parse-lisp
(es:file->string "/dev/stdin"))))