Merge commit 'origin/master'

This commit is contained in:
Danny Yoo 2011-07-12 15:27:23 -04:00
commit 70187d3b26
6 changed files with 136 additions and 33 deletions

View File

@ -11,6 +11,7 @@
"../parser/parse-bytecode.rkt" "../parser/parse-bytecode.rkt"
racket/match racket/match
racket/list racket/list
racket/promise
(prefix-in query: "../lang/js/query.rkt") (prefix-in query: "../lang/js/query.rkt")
(planet dyoo/closure-compile:1:1) (planet dyoo/closure-compile:1:1)
(prefix-in runtime: "get-runtime.rkt") (prefix-in runtime: "get-runtime.rkt")
@ -301,22 +302,25 @@ MACHINE.modules[~s] =
(define (compress x) (define (compress x)
(if (current-compress-javascript?) (cond [(current-compress-javascript?)
(closure-compile x) (log-debug "compressing javascript...")
x)) (closure-compile x)]
[else
(log-debug "not compressing javascript...")
x]))
(define *the-runtime* (define *the-runtime*
(let ([buffer (open-output-string)]) (delay (let ([buffer (open-output-string)])
(write-runtime buffer) (write-runtime buffer)
(compress (compress
(get-output-string buffer)))) (get-output-string buffer)))))
;; get-runtime: -> string ;; get-runtime: -> string
(define (get-runtime) (define (get-runtime)
*the-runtime*) (force *the-runtime*))

View File

@ -153,7 +153,7 @@ and if this does appear, then Whalesong should be installed successfully.
@subsection{Running Whalesong} @subsection{Making Standalone @tt{.xhtml} files with Whalesong}
Let's try making a simple, standalone executable. At the moment, the Let's try making a simple, standalone executable. At the moment, the
program must be written in the base language of @racket[(planet program must be written in the base language of @racket[(planet
@ -234,19 +234,102 @@ web browser, we should see a pale, green page with some output.
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@section{Extended example} @subsection{Using Whalesong functions from JavaScript}
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(This example needs to use modules. It should also show how we can use the Whalesong also allows functions defined from Racket to be used from
other command-line options to compress the javascript, and how to JavaScript. As an example, we can take the boring @emph{factorial}
use @tt{get-javascript} and @tt{get-runtime}, to allow the user to function and define it in a module called @filepath{fact.rkt}:
build a customized html file.)
@margin-note{
The files can also be downloaded here:
@itemlist[@item{@link["http://hashcollision.org/whalesong/fact-example/fact.rkt"]{fact.rkt}}
@item{@link["http://hashcollision.org/whalesong/fact-example/index.html"]{index.html}}]
with generated JavaScript binaries here:
@itemlist[
@item{@link["http://hashcollision.org/whalesong/fact-example/fact.js"]{fact.js}}
@item{@link["http://hashcollision.org/whalesong/fact-example/runtime.js"]{runtime.js}}
]
}
@filebox["fact.rkt"]{
@verbatim|{
#lang planet dyoo/whalesong
(provide fact)
(define (fact x)
(cond
[(= x 0)
1]
[else
(* x (fact (sub1 x)))]))
}|}
Instead of creating a standalone @tt{.xhtml}, we can use @tt{whalesong} to
get us the module's code. From the command-line:
@verbatim|{
$ whalesong get-javascript fact.rkt > fact.js
$ ls -l fact.js
-rw-r--r-- 1 dyoo dyoo 27421 2011-07-11 22:02 fact.js
}|
This file does require some runtime support not included in
@filepath{fact.js}; let's generate the @tt{runtime.js} and save
it as well. At the command-line:
@verbatim|{
$ whalesong get-runtime > runtime.js
$ ls -l runtime.js
-rw-r--r-- 1 dyoo dyoo 544322 2011-07-11 22:12 runtime.js
}|
Now that we have these, let's write an @filepath{index.html} that uses
the @racket[fact] function that we @racket[provide]ed from
@filepath{fact.rkt}.
@filebox["index.html"]{
@verbatim|{
<!DOCTYPE html>
<html>
<head>
<script src="runtime.js"></script>
<script src="fact.js"></script>
<script>
// Each module compiled with 'whalesong get-runtime' is treated as a
// main module. invokeMains() will invoke them.
plt.runtime.invokeMains();
plt.runtime.ready(function() {
// Grab the definition of 'fact'...
var myFactClosure = plt.runtime.lookupInMains('fact');
// Make it available as a JavaScript function...
var myFact = plt.baselib.functions.asJavaScriptFunction(
myFactClosure);
// And call it!
myFact(function(v) {
$('#answer').text(v.toString());
},
function(err) {
$('#answer').text(err.message).css("color", "red");
},
10000
// "one-billion-dollars"
);
});
</script>
</head>
<body>
The factorial of 10000 is <span id="answer">being computed</span>.
</body>
</html>
}|
}
Replacing the @racket[10000] with @racket["one-billion-dollars"] should
reliably produce a proper error message.
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View File

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
all: all:
../../whalesong get-javascript fact.rkt > fact.js ../../whalesong get-javascript --verbose --compress-javascript fact.rkt > fact.js
../../whalesong get-runtime > runtime.js ../../whalesong get-runtime --verbose --compress-javascript > runtime.js

View File

@ -8,4 +8,4 @@
(* x (fact (sub1 x)))])) (* x (fact (sub1 x)))]))
(printf "test: ~s\n" (fact 4)) ;;(printf "test: ~s\n" (fact 4))

View File

@ -3,29 +3,29 @@
<script src="runtime.js"></script> <script src="runtime.js"></script>
<script src="fact.js"></script> <script src="fact.js"></script>
<script>
plt.runtime.invokeMains();
</script>
<script> <script>
plt.runtime.invokeMains();
plt.runtime.ready(function() { plt.runtime.ready(function() {
var myFactClosure = plt.runtime.lookupInMains('fact'); var myFactClosure = plt.runtime.lookupInMains('fact');
var myFact = plt.baselib.functions.asJavaScriptFunction( var myFact = plt.baselib.functions.asJavaScriptFunction(
myFactClosure); myFactClosure);
$(document.body).append("The factorial of 1000 is: ");
myFact(function(v) { myFact(function(v) {
$(document.body).append(v.toString()); $('#answer').text(v.toString());
}, },
function(err) { function(err) {
$(document.body).append(err); $('#answer').text(err.message).css("color", "red");
}, },
1000); 10000
// "one-billion-dollars"
);
}); });
</script> </script>
</head> </head>
<body> <body>
The factorial of 10000 is <span id="answer">being computed</span>.
</body> </body>
</html> </html>

View File

@ -8,6 +8,7 @@
"js-assembler/package.rkt" "js-assembler/package.rkt"
"private/command.rkt" "private/command.rkt"
"logger.rkt" "logger.rkt"
"parameters.rkt"
raco/command-name) raco/command-name)
@ -43,6 +44,10 @@
[("-v" "--verbose") [("-v" "--verbose")
("Display verbose messages.") ("Display verbose messages.")
(current-verbose? #t)] (current-verbose? #t)]
[("--compress-javascript")
("Compress JavaScript with Google Closure (requires Java)")
(current-compress-javascript? #t)]
#:args (path) #:args (path)
(do-the-build path)] (do-the-build path)]
["get-runtime" "print the runtime library to standard output" ["get-runtime" "print the runtime library to standard output"
@ -51,6 +56,10 @@
[("-v" "--verbose") [("-v" "--verbose")
("Display verbose messages.") ("Display verbose messages.")
(current-verbose? #t)] (current-verbose? #t)]
[("--compress-javascript")
("Compress JavaScript with Google Closure (requires Java)")
(current-compress-javascript? #t)]
#:args () #:args ()
(print-the-runtime)] (print-the-runtime)]
["get-javascript" "Gets just the JavaScript code and prints it to standard output" ["get-javascript" "Gets just the JavaScript code and prints it to standard output"
@ -59,6 +68,11 @@
[("-v" "--verbose") [("-v" "--verbose")
("Display verbose messages.") ("Display verbose messages.")
(current-verbose? #t)] (current-verbose? #t)]
[("--compress-javascript")
("Compress JavaScript with Google Closure (requires Java)")
(current-compress-javascript? #t)]
#:args (file) #:args (file)
(get-javascript-code file)])) (get-javascript-code file)]))
@ -77,7 +91,8 @@
(let ([msg (sync receiver)]) (let ([msg (sync receiver)])
(match msg (match msg
[(vector level msg data) [(vector level msg data)
(printf "~a: ~a\n" level msg)])) (fprintf (current-error-port)"~a: ~a\n" level msg)
(flush-output (current-error-port))]))
(loop))))))) (loop)))))))
@ -109,15 +124,16 @@
(define (print-the-runtime) (define (print-the-runtime)
(turn-on-logger!) (turn-on-logger!)
(write-runtime (current-output-port))) (display (get-runtime) (current-output-port)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (get-javascript-code filename) (define (get-javascript-code filename)
(turn-on-logger!) (turn-on-logger!)
(write-standalone-code (display (get-standalone-code
(make-ModuleSource (build-path filename)) (make-ModuleSource (build-path filename)))
(current-output-port))) (current-output-port)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;