#lang scheme/base
(require scheme/gui/base
scheme/file
scheme/class
scheme/port
scheme/runtime-path
scheme/contract
"config.ss"
"stx-helpers.ss"
"image-lift.ss"
"compiler/stx.ss"
"compiler/pinfo.ss"
"compiler/env.ss"
"compiler/permission.ss")
(define-runtime-path yui.jar "../support/yuicompressor-2.4.2.jar")
(define (parse-text-as-program a-text [source-name #f])
(let* ([ip (open-input-text-editor a-text)])
(port-count-lines! ip)
(parameterize ([read-accept-reader #t])
(let ([stx (read-syntax source-name ip)])
(syntax-case stx ()
[(module name lang body ...)
(map syntax->stx (syntax->list #'(body ...)))]
[else
(error 'moby
(string-append "The input does not appear to be a Moby module; "
"I don't see a \"#lang moby\" at the top of the file."))])))))
(define (get-permissions a-pinfo)
(define ht (make-hash))
(for ([b (pinfo-used-bindings a-pinfo)])
(cond
[(binding:function? b)
(for ([p (binding:function-permissions b)])
(hash-set! ht p #t))]))
(for/list ([p (in-hash-keys ht)])
p))
(define (get-on-start-code a-pinfo)
(apply string-append
(map permission->on-start-code (get-permissions a-pinfo))))
(define (get-on-pause-code a-pinfo)
(apply string-append
(map permission->on-pause-code (get-permissions a-pinfo))))
(define (get-on-destroy-code a-pinfo)
(apply string-append
(map permission->on-destroy-code (get-permissions a-pinfo))))
(define (lift-images-to-directory a-text resource-dir)
(make-directory* resource-dir)
(let ([named-bitmaps (lift-images! a-text)])
(for ([nb named-bitmaps])
(named-bitmap-save nb resource-dir))
named-bitmaps))
(define (copy-port-to-debug-log inp)
(let loop ([line (read-line inp)])
(unless (eof-object? line)
(log-debug line)
(loop (read-line inp)))))
(define (copy-port-to-error-log inp)
(let loop ([line (read-line inp)])
(unless (eof-object? line)
(log-error line)
(loop (read-line inp)))))
(define (open-beginner-program path)
(define text (new text%))
(send text insert-file (path->string path))
text)
(define (run-ant-build.xml dest-dir target)
(parameterize ([current-directory dest-dir])
(let*-values ([(string-error-port) (open-output-string "")]
[(a-subprocess inp outp errp)
(subprocess #f #f #f (current-ant-bin-path) target)]
[(t1 t2)
(values (thread (lambda ()
(copy-port-to-debug-log inp)))
(thread (lambda ()
(copy-port-to-error-log (peeking-input-port errp))
(copy-port errp string-error-port))))])
(close-output-port outp)
(subprocess-wait a-subprocess)
(sync t1)
(sync t2)
(unless (= 0 (subprocess-status a-subprocess))
(error 'ant "Internal error while running ant: ~a"
(get-output-string string-error-port)))
(void))))
(define (yui-compress source-code)
(let ([get-java-path
(lambda ()
(find-executable-path "java"))])
(let*-values ([(bytes-output-port) (open-output-bytes)]
[(a-subprocess inp outp errp)
(subprocess #f #f #f (get-java-path) "-jar" (path->string yui.jar) "--type" "js" )]
[(t1 t2)
(values (thread (lambda ()
(copy-port inp bytes-output-port)))
(thread (lambda ()
(copy-port errp (current-output-port)))))])
(copy-port (open-input-bytes source-code) outp)
(close-output-port outp)
(subprocess-wait a-subprocess)
(sync t1)
(sync t2)
(get-output-bytes bytes-output-port))))
(provide/contract
[parse-text-as-program (((is-a?/c text%)) ((or/c string? false/c)) . ->* . (listof stx?))]
[get-permissions (pinfo? . -> . (listof permission?))]
[get-on-start-code (pinfo? . -> . string?)]
[get-on-pause-code (pinfo? . -> . string?)]
[get-on-destroy-code (pinfo? . -> . string?)]
[lift-images-to-directory ((is-a?/c text%) path? . -> . (listof named-bitmap?))]
[open-beginner-program (path-string? . -> . (is-a?/c text%))]
[run-ant-build.xml (path? string? . -> . any)]
[yui-compress (bytes? . -> . bytes?)])