#lang scheme/base
(require "../base.ss")
(require (javascript-in config print)
(pprint-in)
(unlib-in debug list profile)
"quote.ss"
"render-fast.ss"
"struct.ss")
(define javascript-rendering-mode
(make-parameter 'pretty))
(define (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)]))
(define (javascript->packed-string js)
(parameterize ([javascript-rendering-mode 'packed])
(javascript->string js)))
(define (javascript->pretty-string js)
(parameterize ([javascript-rendering-mode 'pretty])
(javascript->string js)))
(define format-FunctionExpression
(match-lambda
[(struct FunctionExpression (_ name args body))
(h-append (text "function")
(if name
(h-append (text " ")
(format-identifier name))
empty)
(text "(")
(h-concat (apply-infix (text ", ") (map format-identifier args)))
(text ") {")
(nest (current-indentation-width)
(format-map format-source-element body formatters/StatementList))
line
(text "}"))]))
(define format-BeginStatement
(match-lambda
[(struct BeginStatement (_ statements))
(let ([statements (reverse (collect-begin-substatements statements))])
(if (null? statements)
(h-append)
(h-append (format-begin-substatement (car statements))
(format-map (lambda (statement)
(h-append line (format-begin-substatement statement)))
(cdr statements)
formatters/StatementList))))]))
(define (format-begin-substatement stmt+decl)
(if (Declaration? stmt+decl)
(format-declaration stmt+decl)
(format-statement stmt+decl)))
(define format-RawExpression
(match-lambda
[(struct RawExpression (_ str))
(text str)]))
(define (collect-begin-substatements statements [accum null])
(match statements
[(list) accum]
[(list-rest curr rest)
(if (BeginStatement? curr)
(collect-begin-substatements rest (collect-begin-substatements (BeginStatement-statements curr) accum))
(collect-begin-substatements rest (cons curr accum)))]
[other (debug "bad item" other)]))
(provide/contract
[javascript-rendering-mode (parameter/c (or/c 'pretty 'packed 'fast))]
[javascript->string (-> javascript? string?)]
[javascript->packed-string (-> javascript? string?)]
[javascript->pretty-string (-> javascript? string?)])