(define-pass generate-javascript : L6 (e) -> * ()
(definitions
(define string-join
(lambda (str* jstr)
(cond
[(null? str*) ""]
[(null? (cdr str*)) (car str*)]
[else (string-append (car str*) jstr (string-join (cdr str*) jstr))])))
;; symbol->c-id - converts any Scheme symbol into a valid C identifier.
(define symbol->c-id
(lambda (sym)
(let ([ls (string->list (symbol->string sym))])
(if (null? ls)
"_"
(let ([fst (car ls)])
(list->string
(cons
(if (char-alphabetic? fst) fst #\_)
(map (lambda (c)
(if (or (char-alphabetic? c)
(char-numeric? c))
c
#\_))
(cdr ls)))))))))
(define format-set!
(lambda (x rhs)
(format "~a = ~a" (symbol->c-id x) rhs))))
(Expr : Expr (e) -> * ()
[(if ,[e0] ,[e1] ,[e2])
(format "if (~a) {\n~a\n} else {\n~a}" e0 e1 e2)]
[(set! ,x ,[e])
(format-set! x e)]
[(lambda (,x* ...) ,[body])
(format "function(~a) {\n~a\n}"
(string-join (map symbol->c-id x*) ", ")
body)]
;; primitive application
[(,pr ,[e*] ...)
(format "~a(~a)"
pr
(string-join e* ", "))]
;; lambda application
[(,[e] ,[e*] ...)
(format "~a(~a)"
e
(string-join e* ", "))]
[pr pr]))Exception in nano-meta-fields: #[#{nano-quote cgcczz9hmtue79yz919bpk-310} (#<syntax quote> #<syntax pr [line 1064, char 10 of javascript.ss]>)] is not of type #<record type nano-meta>I am trying to generate JavaScript using a final pass, but I can not figurethe correct code.
|
--
You received this message because you are subscribed to the Google Groups "nanopass-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nanopass-framew...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nanopass-framework/3408d0da-d704-446f-a57e-5754af16a3b3%40googlegroups.com.
Den tir. 23. jul. 2019 kl. 13.02 skrev Amirouche Boubekki <amirouch...@gmail.com>:I am trying to generate JavaScript using a final pass, but I can not figurethe correct code.
Is it the last line (which line is number 1064)?
[pr pr]
Maybe [,pr pr]
Apropos generating javascript:
I can recommend emitting a tree (made of cons-cells) of strings and numbers.
Instead of using format one can simply use list:
(format "~a = ~a" (symbol->c-id x) rhs)))
becomes
(list (symbol->c-id x) "=" rhs)
The advantage is that no new strings are allocated during code generation.
An (string-append a b) becomes (list a b) and allocating a list is cheaper than string concatenation.
Emitting the contents of the tree is simple:
; emit : tree -> void; display the elements in the tree in order (define (emit x) (cond [(or (number? x) (string? x)) (display x)] [(symbol? x) (display x) (display " ")] [(identifier? x) (display (mangle x))] [(list? x) (for-each emit x)] [else (displayln x) (error 'emit "got ~a" x)]))
That is what I end up doing. But since scheme-to-c does something else, I was under the impression that relying on a pass to generate the target code was the nanopass way.
PS: I got a proof-of-concept scheme-to-javascript compiler that eliminates the call stack via a trampolining https://github.com/scheme-live/scheme-to-javascript/commit/19087538b9ca76ba064133b1f08167b7e1b2e427