adding sections in internals to remind myself how all the pieces work.

This commit is contained in:
Danny Yoo 2011-12-14 14:56:17 -05:00
parent 7d6ddd4ee5
commit 2b82fb6a45
3 changed files with 93 additions and 29 deletions

View File

@ -6,7 +6,7 @@
racket/list)
;; Get the list of primitives implemented in js-vm-primitives.js
(define-runtime-path js-vm-primitives.js "runtime-src/js-vm-primitives.js")
;; (define-runtime-path js-vm-primitives.js "runtime-src/js-vm-primitives.js")
(define-runtime-path whalesong-primitives.js "runtime-src/baselib-primitives.js")
@ -19,16 +19,16 @@
name)
string<?)))
;; primitive-names: (listof symbol)
(define js-vm-primitive-names
(map string->symbol
(sort&unique
(map (lambda (a-str)
(substring a-str
(string-length "PRIMITIVES['")
(- (string-length a-str) (string-length "']"))))
(let ([contents (file->string js-vm-primitives.js)])
(regexp-match* #px"PRIMITIVES\\[('|\")[^\\]]*('|\")\\]" contents))))))
;; ;; primitive-names: (listof symbol)
;; (define js-vm-primitive-names
;; (map string->symbol
;; (sort&unique
;; (map (lambda (a-str)
;; (substring a-str
;; (string-length "PRIMITIVES['")
;; (- (string-length a-str) (string-length "']"))))
;; (let ([contents (file->string js-vm-primitives.js)])
;; (regexp-match* #px"PRIMITIVES\\[('|\")[^\\]]*('|\")\\]" contents))))))
@ -43,5 +43,5 @@
(regexp-match* #px"installPrimitiveProcedure\\(\\s+('|\")[^\\']*('|\")" contents))))))
(provide/contract [js-vm-primitive-names (listof symbol?)]
(provide/contract ;[js-vm-primitive-names (listof symbol?)]
[whalesong-primitive-names (listof symbol?)])

View File

@ -20,4 +20,5 @@
(define stmts (compile ast 'val next-linkage/drop-multiple))
(define op (open-output-string))
(assemble/write-invoke stmts op)
(assemble/write-invoke stmts op)
(get-output-string op)

View File

@ -226,6 +226,79 @@ they're finished.
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@subsection{A manual run through components}
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Let's try to use some of the modules in Whalesong manually and see
what comes out. For example, we'd like to see what the compiler produces when
we compile the following code:
@filebox["factorial.rkt"]{
@codeblock|{
#lang planet dyoo/whalesong
(define (f x)
(if (= x 0)
1
(* x (f (sub1 x)))))
(provide f)
}|
}
First, we can use the internal module
@racketmodname/this-package[get-module-bytecode] and
@racketmodname/this-package[parser/parse-bytecode] to read
@filepath{factorial.rkt} into an AST.
@interaction[#:eval my-evaluator
(require (planet dyoo/whalesong/get-module-bytecode)
(planet dyoo/whalesong/parser/parse-bytecode))
(define bytecode
(get-module-bytecode
(open-input-string
(string-append "#lang planet dyoo/whalesong\n"
"(define (f x)\n"
" (if (= x 0)\n"
" 1\n"
" (* x (f (sub1 x)))))\n\n"
"(provide f)"))))
(define ast (parse-bytecode (open-input-bytes bytecode)))
ast
]
At this point, we have an ast, using the structures defined in
@racketmodname/this-package[compiler/expression-structs] and
@racketmodname/this-package[compiler/lexical-structs]. This AST
should be similar to the one described by
@racketmodname[compiler/zo-parse] library, though the one in Whalesong
is intended to be independent of the Racket version.
We can now compile the AST into intermediate form.
@interaction[#:eval my-evaluator
(require (planet dyoo/whalesong/compiler/compiler)
(planet dyoo/whalesong/compiler/compiler-structs))
(define stmts (compile ast 'val next-linkage/drop-multiple))
]
The compilation process translates the AST into a linear sequence of
intermediate-level statements. Finally, we can assemble this sequence
into JavaScript by using @racketmodname/this-package[js-assembler/assemble].
@interaction[#:eval my-evaluator
(require (planet dyoo/whalesong/js-assembler/assemble))
(define op (open-output-string))
(assemble/write-invoke stmts op)
(define js-code (get-output-string op))
js-code
]
The ugly string stored in @racket[js-code] is the final result
of the compilation.
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@subsection{Values}
@ -428,6 +501,8 @@ browser for testing output.
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@subsection{What's in @tt{js-vm} that's missing from Whalesong?}
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -468,22 +543,6 @@ We need to bring around the following types previously defined in @tt{js-vm}:
@item{readerGraph}
]
@(define missing-primitives
(let ([in-whalesong-ht (make-hash)])
(for ([name whalesong-primitive-names])
(hash-set! in-whalesong-ht name #t))
(filter (lambda (name)
(not (hash-has-key? in-whalesong-ht name)))
js-vm-primitive-names))))
What are the list of primitives in @filepath{js-vm-primitives.js} that we
haven't yet exposed in whalesong? We're missing @(number->string (length missing-primitives)):
@(apply itemlist (map (lambda (name)
(item (symbol->string name)))
missing-primitives))
@ -659,3 +718,7 @@ language.
@defform[(vector->list ...)]{}
@defform[(list->vector ...)]{}
@section{Writing Extensions in JavaScript}
[FIXME]