Quick Search
Browse
Pages
Blog
Labels
Attachments
Mail
Advanced
What’s New
Space Directory
Feed Builder
Keyboard Shortcuts
Confluence Gadgets
Log In
Sign Up
Dashboard
Clojure Design
Copy Page
You are not logged in. Any changes you make will be marked as
anonymous
. You may want to
Log In
if you already have an account. You can also
Sign Up
for a new account.
This page is being edited by
.
Paragraph
Paragraph
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Preformatted
Quote
Bold
Italic
Underline
Colour
More colours
Strikethrough
Subscript
Superscript
Monospace
Clear Formatting
Bullet list
Numbered list
Outdent
Indent
Align left
Align center
Align right
Link
Table
Insert
Insert Content
Image
Link
Attachment
Symbol
Emoticon
Wiki Markup
Horizontal rule
tinymce.confluence.insert_menu.macro_desc
Info
JIRA Issue
Status
Gallery
Tasklist
Table of Contents
Other Macros
Undo
Redo
Keyboard Shortcuts Help
<h1>Synopsis</h1><p>The ClojureScript compiler currently directly prints JavaScript source code strings. It is desirable to instead produce a JavaScript Abstract Syntax Tree to simplify code generation, emit source maps, and to enable higher level optimizations.</p><h1>Problems</h1><ul><li>Compiler should be more functionally pure<ul><li>Code generation currently emits strings as a side effect</li><li>Enhancing the compiler is difficult because printing forces ordering and limits higher order composition</li><li>It's not safe to interleave multiple passes of analysis, transformations, and code generation</li></ul></li><li>emit complects Code Generation and Code Printing<br /><ul><li>requires simultaneous consideration of JavaScript's abstract structure and particulars of syntax</li><li>code generation is trivially functionally pure; code printing could be, but wouldn't benefit much</li></ul></li><li>SourceMaps! Strings lack structure to associate mappings<ul><li>If you currently are printing "foo(bar)", you might need to assign different source lines to both foo and bar</li><li>Adding source mappings to printing would give very low mapping resolution for the current ad-hoc strings</li><li>Increasing the resolution would yield something that looks very much like an AST</li></ul></li></ul><h1>Goals</h1><ul><li>Decouple code generation from code printing</li><li>Simplify compiler.clj</li><li>Include source mappings on outputted AST</li><li>Preserve compiler and generated code performance</li></ul><h1>Approach</h1><ul><li>Target the Google Closure AST<ul><li>Advantages<ul><li>Keeps us out of the JS AST design business</li><li>Existing code printer</li><li>Includes facilities for Closure Compiler type system</li><li>Perf? Can skip roundtrip to JS source and to disk</li></ul></li><li>Disadvantages<ul><li>Closure AST nodes are stateful<ul><li>Each Node has an explicit parent reference</li><li>Cloning policy is necessary to reuse subtrees (wasn't an issue in my port so far, see below)</li></ul></li><li>Increases our dependence on Closure<ul><li>Closure AST evolves more quickly than the JS spec</li><li>Recent changes: <a href="http://code.google.com/p/closure-compiler/source/list?path=/trunk/src/com/google/javascript/jscomp/parsing/IRFactory.java&start=2295">http://code.google.com/p/closure-compiler/source/list?path=/trunk/src/com/google/javascript/jscomp/parsing/IRFactory.java&start=2295</a></li></ul></li></ul></li><li>Alternative: Intermediate JavaScript AST as Clojure data-structures<ul><li>Requires an additional translation step</li><li>GWT and Dart use a different AST; See: <a href="http://code.google.com/p/google-web-toolkit/source/browse/trunk/dev/core/src/com/google/gwt/dev/js/ClosureJsAstTranslator.java?r=10778">http://code.google.com/p/google-web-toolkit/source/browse/trunk/dev/core/src/com/google/gwt/dev/js/ClosureJsAstTranslator.java?r=10778</a></li></ul></li><li>Closure Compiler Discussion: <a href="https://groups.google.com/forum/?fromgroups=#!topic/closure-compiler-discuss/OEwLWkw4Kug">https://groups.google.com/forum/?fromgroups=#!topic/closure-compiler-discuss/OEwLWkw4Kug</a></li></ul></li><li>Thin JS-AST DSL<ul><li>Recursively transpiles arguments</li><li>Can be extended to automatically attach source mappings from dynamic bindings</li><li>Does a Hiccup like seq expansion</li><li>Eliminate js* form, replaces it with DSL invokes: (js* "foo({0})" x) becomes (js*/call 'foo x)</li></ul></li></ul><h1>Preliminary Progress</h1><ul><li>Fork: <a href="https://github.com/brandonbloom/clojurescript/tree/js-ast">https://github.com/brandonbloom/clojurescript/tree/js-ast</a><ul><li>Interesting files: <a href="https://github.com/brandonbloom/clojurescript/blob/js-ast/src/clj/cljs/compiler.clj">compiler.clj</a> and <a href="https://github.com/brandonbloom/clojurescript/blob/js-ast/src/clj/cljs/js.clj">js.clj</a></li></ul></li><li>As of Nov 9<ul><li>Compiles all the CLJS in the ClojureScript tree</li><li>Bugged in advanced compilation mode</li><li>Does not generate source mappings</li><li>Does not bypass the extra round-trip to JS source and to disk</li><li>Takes 3X as long as naive string printing; 10 vs 30 seconds for (compile-root "src/cljs/cljs") on my machine</li><li>core.clj and core.cljs are fully ported from (js* "..." ...) to (js*/... ...) </li></ul></li></ul>
Attachments
Labels
Location
< Edit
Preview >
Loading…
Save
Cancel
Next hint
search
attachments
weblink
advanced