rebirth: Add `eval'
* build-aux/bootstrap/rebirth.scm: Provide env to `rebirth->ecmascript-prog'. (rebirth->ecmascript-prog)[env-es]: New param. Use for `_env' in generated self-executing ES function. (es:empty-env): New procedure. * build-aux/bootstrap/rebirth/es.scm (es:raw): Remove unused macro. (es:envf)[env]: New parameter. Use in place of hard-coded inherited env. (es:inherit-env): New procedure, extracted from proceeding. (lambda, let): Use it. (null-environment, eval): New procedures.master
parent
ec43d7717a
commit
e8c9c6cdd8
|
@ -844,15 +844,20 @@
|
|||
;; 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)
|
||||
(define (rebirth->ecmascript-prog ast env-es)
|
||||
;; (note that we no longer depend on libprebirth)
|
||||
(string-append "(function(_env){"
|
||||
(rebirth->ecmascript ast)
|
||||
"})({macros:{}});"))
|
||||
"})(" env-es ");"))
|
||||
|
||||
;; An empty environment.
|
||||
(define (es:empty-env)
|
||||
"{macros:{}}")
|
||||
|
||||
|
||||
;; at this point, this program can parse itself and output a CST (sans
|
||||
;; whitespace)
|
||||
(es:console (rebirth->ecmascript-prog
|
||||
(parse-lisp
|
||||
(es:file->string "/dev/stdin"))))
|
||||
(es:file->string "/dev/stdin"))
|
||||
(es:empty-env)))
|
||||
|
|
|
@ -79,20 +79,18 @@
|
|||
(define-macro (es:error . args)
|
||||
(`quote (%es:native-apply console.error (unquote@ args))))
|
||||
|
||||
(define-macro (es:raw . body)
|
||||
(`quote
|
||||
(string->es (unquote@ body))))
|
||||
|
||||
;; Expand the body BODY into a new environment inherited from the current
|
||||
;; environment. Environments are currently handled by the ES runtime, so
|
||||
;; this is easy.
|
||||
(define-macro (es:envf . body)
|
||||
;; Expand the body BODY into a new environment. Environments are
|
||||
;; currently handled by the ES runtime, so this is easy.
|
||||
(define-macro (es:envf env . body)
|
||||
(`quote
|
||||
(string-append
|
||||
"(function(_env){"
|
||||
"return "
|
||||
(unquote@ body)
|
||||
"})(Object.create(_env))")))
|
||||
"})(" (unquote env) ")")))
|
||||
|
||||
(define (es:inherit-env)
|
||||
"Object.create(_env)")
|
||||
|
||||
(define-macro (define-es-macro decl . body)
|
||||
(quasiquote
|
||||
|
@ -116,7 +114,7 @@
|
|||
"__whilebrk=true")
|
||||
|
||||
(define-es-macro (lambda fnargs . body)
|
||||
(es:envf
|
||||
(es:envf (es:inherit-env)
|
||||
"function(" (join ", " (map tparam->es fnargs)) "){\n"
|
||||
(env-params fnargs)
|
||||
(body->es body #t)
|
||||
|
@ -138,7 +136,7 @@
|
|||
(fparams (join ", " (map tparam->es params)))
|
||||
(args (map cadr bindings))
|
||||
(fargs (map sexp->es args)))
|
||||
(string-append (es:envf
|
||||
(string-append (es:envf (es:inherit-env)
|
||||
"(function(" fparams "){\n"
|
||||
(env-params params)
|
||||
(body->es body #t) "\n"
|
||||
|
@ -199,6 +197,23 @@
|
|||
(`quote (let () (unquote@ exprs))))
|
||||
|
||||
|
||||
;; This doesn't currently produce any sort of encapsulated
|
||||
;; environment---it just produces an ECMAScript string. This also
|
||||
;; does not provide any of the expected syntatic keywords yet.
|
||||
(define (null-environment version)
|
||||
(if (not (eq? version 5))
|
||||
(error "null-environment version must be 5")
|
||||
(es:empty-env)))
|
||||
|
||||
;; `eval' re-uses the macro `list->ast' procedure, immediately applying
|
||||
;; its result.
|
||||
(define-macro (eval expr env)
|
||||
(`quote (%es:native-apply
|
||||
eval
|
||||
(es:envf (unquote env)
|
||||
(sexp->es (list->ast (unquote expr)))))))
|
||||
|
||||
|
||||
;; We unfortunately have to worry about environment mutability in the
|
||||
;; current implementation. Since variables within environments are
|
||||
;; implemented using ECMAScript's prototype chain, any sets affect the
|
||||
|
|
Loading…
Reference in New Issue