Skip to content

Commit

Permalink
- replaced render-pretty-javascript? with javascript-rendering-mode;
Browse files Browse the repository at this point in the history
  - added javascript->packed-string;
  - tested/fixed bug where named function declarations were not allowed in !begin blocks.
  • Loading branch information
Dave Gurnell committed Jun 20, 2009
1 parent 68d01d2 commit 13d005f
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 35 deletions.
4 changes: 3 additions & 1 deletion info.ss
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

(define release-notes
'((p "Changes and additions:")
(ul (li "named function declarations are now allowed within !begin blocks;"))))
(ul (li "replaced the " (tt "render-pretty-javascript?") " parameter with " (tt "javascript-rendering-mode") ";")
(li "added " (tt "javascript->packed-string") ";")
(li "fixed bug that disallowed named function declarations within " (tt "!begin") " blocks."))))

(define primary-file "mirrors.ss")

Expand Down
2 changes: 1 addition & 1 deletion javascript/render-fast.ss
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
(display-js expr))]
[(struct FunctionDeclaration (_ id args body)) (display-str "function ")
(display-js id)
(display-str " (")
(display-str "(")
(display-list ", " args)
(display-str ") { ")
(for-each display-js body)
Expand Down
60 changes: 37 additions & 23 deletions javascript/render.ss
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,38 @@

; Parameters -------------------------------------

; (parameter boolean)
(define render-pretty-javascript?
(make-parameter #t))
; (parameter (U 'pretty 'packed 'fast))
(define javascript-rendering-mode
(make-parameter 'pretty))

; Public procedures ------------------------------

; javascript -> string
(define (javascript->string js)
#;(parameterize ([allow-nested-function-declarations? #t]
[formatters/Expression (list* format-FunctionExpression
format-RawExpression
(formatters/Expression))]
[formatters/Statement (list* format-BeginStatement
(formatters/Statement))])
(pretty-format (group (format-term js)) #f))
(if (render-pretty-javascript?)
(javascript->pretty-string js)
(fast-javascript->string js)))
(case (javascript-rendering-mode)
[(pretty) (parameterize ([formatters/Expression (list* format-FunctionExpression
format-RawExpression
(formatters/Expression))]
[formatters/Statement (list* format-BeginStatement
(formatters/Statement))])
(pretty-format (format-term js)))]
[(packed) (parameterize ([formatters/Expression (list* format-FunctionExpression
format-RawExpression
(formatters/Expression))]
[formatters/Statement (list* format-BeginStatement
(formatters/Statement))])
(pretty-format (group (format-term js)) #f))]
[(fast) (fast-javascript->string js)]))

; javascript -> string
(define (javascript->packed-string js)
(parameterize ([javascript-rendering-mode 'packed])
(javascript->string js)))

; javascript -> string
(define (javascript->pretty-string js)
(parameterize ([allow-nested-function-declarations? #t]
[formatters/Expression (list* format-FunctionExpression
format-RawExpression
(formatters/Expression))]
[formatters/Statement (list* format-BeginStatement
(formatters/Statement))])
(pretty-format (format-term js))))
(parameterize ([javascript-rendering-mode 'pretty])
(javascript->string js)))

; Custom printers --------------------------------

Expand Down Expand Up @@ -67,12 +70,22 @@
(let ([statements (reverse (collect-begin-substatements statements))])
(if (null? statements)
(h-append)
(h-append (format-substatement (car statements))
(h-append (format-begin-substatement (car statements))
(format-map (lambda (statement)
(h-append line (format-substatement statement)))
(h-append line (format-begin-substatement statement)))
(cdr statements)
formatters/StatementList))))]))

; (U Declaration Statement) -> doc
; Named function declarations aren't allowed inside regular statements in some
; JS VMs, so by default JS.plt disallows this arrangement using the contract on
; format-substatement. This is obviously no good for BeginStatements: the function
; below provides a workaround.
(define (format-begin-substatement stmt+decl)
(if (Declaration? stmt+decl)
(format-declaration stmt+decl)
(format-statement stmt+decl)))

; RawStatement -> doc
(define format-RawExpression
(match-lambda
Expand All @@ -92,6 +105,7 @@
; Provide statements -----------------------------

(provide/contract
[render-pretty-javascript? (parameter/c boolean?)]
[javascript-rendering-mode (parameter/c (or/c 'pretty 'packed 'fast))]
[javascript->string (-> javascript? string?)]
[javascript->packed-string (-> javascript? string?)]
[javascript->pretty-string (-> javascript? string?)])
10 changes: 9 additions & 1 deletion javascript/syntax-test.ss
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
(define syntax-tests
(test-suite "syntax.ss"

#:before (cut javascript-rendering-mode 'packed)

(test-js "expander: decl"
(!var-debug [a 1] [b 2])
"var a = 1; console.log(\"a\" + a); var b = 2; console.log(\"b\" + b);")
Expand Down Expand Up @@ -76,7 +78,7 @@
(test-js "decl: var unquote"
(var [,(make-Identifier #f 'x) 1] [y ,(+ 2 3)])
"var x = 1, y = 5;")

(test-js "stmt: empty begin" (!begin) "")

(test-js "stmt: begin"
Expand All @@ -85,6 +87,12 @@
(+ 3 4 5))
"1 + 2 + 3; var x = 2 + 3 + 4; 3 + 4 + 5;")

(test-js "stmt: begin containing nested function declarations"
(!begin (function a () (return))
(function b () (return)))
"function a() { return; } function b() { return; }")


(test-js "stmt: empty block" (!block) "{}")

(test-js "stmt: block"
Expand Down
36 changes: 27 additions & 9 deletions scribblings/javascript-response.scrbl
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,46 @@

@(require (file "base.ss"))

@(define-eval js-eval (for-syntax scheme/base) (planet untyped/mirrors/javascript/javascript))

@title[#:tag "javascript-response"]{Rendering Javascript and sending Javascript responses}

@(declare-exporting (planet untyped/mirrors/javascript/javascript))

@section{Rendering Javascript in string form}

@defproc[(javascript->string [val javascript-statement?]) string?]{
Renders a Javascript statement as a compact string with no line breaks or indentation.}
Renders a Javascript statement using the current @scheme[javascript-rendering-mode].}

@defproc[(javascript->pretty-string [val javascript-statement?]) string?]{
Renders a Javascript statement as a formatted string with line breaks and indentation.}

@defthing[render-pretty-javascript? (parameter boolean?)]{
Affects the output of @scheme[javascript->string] and @scheme[javascript->pretty-string]:
@defproc[(javascript->packed-string [val javascript-statement?]) string?]{
Renders a Javascript statement on a single line with no indentation.}

@itemize{
@item{when @scheme[render-pretty-javascript?] is set to @scheme[#t] (the default value), the rendering procedures behave as documented above;}
@item{when @scheme[render-pretty-javascript?] is set to @scheme[#f], the rendering procedures switch to an experimental renderer that writes all Javascript extremely quickly onto a single line.}}

Essentially, setting @scheme[render-pretty-javascript?] to @scheme[#t] gives better rendering performance at the expense of legibility. The performance gains are only noticeable when rendering large (1000+ line) blocks of Javascript.
@defthing[javascript-rendering-mode (parameter (U 'pretty 'packed 'fast))]{
Affects the output of @scheme[javascript->string] and @scheme[javascript->pretty-string]. The possible values are:

At the time of writing the fast renderer has not been properly tested: use it with caution!}
@itemize{
@item{@scheme['pretty] (the default value) - @scheme[javascript->string] renders Javascript as well formatted blocks;}
@item{@scheme['packed] - @scheme[javascript->string] renders Javascript on a single line, with no indentation;}
@item{@scheme['fast] - @scheme[javascript->string] uses an experimental renderer that writes all Javascript extremely quickly onto a single line.}}

The @scheme['fast] rendering mode is extremely naive: it inserts extra parentheses in expressions and extra semicolons between statements. At the time of writing, it has not been properly tested: use it with caution!

@examples[
#:eval js-eval
(define (display-statement)
(display
(javascript->string
(js (function average (a b)
(return (+ (/ a 2) (/ b 2))))))))
(parameterize ([javascript-rendering-mode 'pretty])
(display-statement))
(parameterize ([javascript-rendering-mode 'packed])
(display-statement))
(parameterize ([javascript-rendering-mode 'fast])
(display-statement))]}

@section{Sending HTTP responses with Javascript content}

Expand Down

0 comments on commit 13d005f

Please sign in to comment.