Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for (re-seq #"^$" "") #22

Closed
wants to merge 62 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
dfd0f00
Start of ClojureScript compiler in ClojureScript.
kanaka Nov 16, 2012
9055ada
Misc cleanup and add ns-snap.
kanaka Nov 16, 2012
9e88716
Fix strings, numbers, false, regexp.
kanaka Nov 17, 2012
dd643f7
Add chouser's jsrepl modified to use the analyzer/compiler.
kanaka Nov 17, 2012
df22857
Add build script for jsrepl.js.
kanaka Nov 17, 2012
3184a66
Add some explanatory text to the jsrepl page.
kanaka Nov 17, 2012
e58ebc2
Update README to explain the patched version.
kanaka Nov 17, 2012
78037a6
CLJS compiler and REPL working in Node.js
kanaka Nov 29, 2012
527f871
Generate analyzer namespace snapshot while compiling.
kanaka Dec 1, 2012
39d13a9
Make node and web REPL prompt be *cljs-ns*
kanaka Dec 8, 2012
8b24ba0
Remove verbose reader debug.
kanaka Dec 8, 2012
437658f
Move namespaces to cljs.core and "refer" it from cljs.analyzer.
kanaka Dec 8, 2012
fbfcfc5
Add macro support to JS built cljs analyzer/compiler.
kanaka Dec 8, 2012
f9d971e
Remove old multimethod version of emit-constant.
kanaka Dec 8, 2012
f0e8369
Remove old version of ns-snap from compiler.cljs
kanaka Dec 8, 2012
eaa8eeb
Move PushbackReader to core.cljs.
kanaka Dec 8, 2012
0345cad
Add syntax quote/unquote to the reader.
kanaka Dec 8, 2012
fe0a35e
Define *out* and *ns* to squelch compile warnings.
kanaka Dec 8, 2012
ca7996f
Remove debug.
kanaka Jan 3, 2009
0e23110
Remove require of bs from jsrepl.html.
kanaka Dec 8, 2012
fc472bf
Fix nodecljs.cljs wrapper to use correct push-back-reader location.
kanaka Jan 3, 2009
bb7a168
Update README and add runtime macro examples.
kanaka Jan 3, 2009
68081b5
Correction to web and node.js REPL startup comments.
kanaka Dec 8, 2012
f036298
Properly munge symbols to JS names in get-expander.
kanaka Dec 12, 2012
fbd5901
Debug and stack trace in noderepl and webrepl.
kanaka Dec 14, 2012
4255b31
Fix syntax quote typos and syntax quote nil handling.
kanaka Dec 14, 2012
74ed2d3
Activate and fix reader for ";" comments.
kanaka Dec 14, 2012
75dc7ca
Add readers for anonymous functions and args.
kanaka Dec 14, 2012
fd58b20
Add destructure and Clojure core macros.
kanaka Dec 14, 2012
e7338a6
Add ClojureScript core macros.
kanaka Dec 14, 2012
3c3cbbe
Misc node and web REPL fixes/cleanup.
kanaka Dec 15, 2012
c4d36bf
Update README.
kanaka Dec 15, 2012
b197f9f
Remove REPL note about missing predefined macros.
kanaka Dec 16, 2012
a66934b
Make symbols first class objects rather than prefixed strings.
kanaka Dec 24, 2012
913c689
Cleanup various exceptions.
kanaka Dec 24, 2012
e9a9405
Synchronize spacing/ordering with Clojure/ClojureScript core.*
kanaka Dec 24, 2012
eec83b1
Add array macros and add commented out '.. and 'js-obj
kanaka Dec 24, 2012
f838482
Add type/protocol macros from ClojureScript core.clj
kanaka Dec 24, 2012
3654132
Add multimethod macros (defmulti, defmethod).
kanaka Dec 24, 2012
9140c7c
Update TODOs and bugs in README.
kanaka Dec 24, 2012
ba2fe80
Fix iEquiv of namespaced symbols.
kanaka Dec 27, 2012
ec757d8
Fix protocol-prefix regex to match multiple delimiters.
kanaka Dec 27, 2012
20ddfa1
Allow ns multiple times for same namespace.
kanaka Dec 27, 2012
8d24864
Add in-ns, fix munging of names in create-ns
kanaka Dec 27, 2012
f67318f
Web and node REPL namespace related fixups.
kanaka Dec 27, 2012
29ecdba
Add extend-protocol.
kanaka Dec 27, 2012
c1b6287
Implement ".." macro with analyzer/compiler fixes.
kanaka Dec 28, 2012
1d7b6de
Update README
kanaka Dec 28, 2012
31d296d
Fix webrepl typo.
kanaka Dec 28, 2012
3a835a1
Refactor namespaces as normal Clojure datastructure.
kanaka Jan 1, 2013
a9ebebb
Add declare, defonce and stub defn-
kanaka Jan 5, 2013
9a420c1
Fix -prototype call in extend-type.
kanaka Jan 5, 2013
53f6cc6
Add load-file, forms-seq, compile-forms*.
kanaka Jan 5, 2013
daf59f0
Fix typo in comment.
kanaka Jan 5, 2013
a3cce03
Fix nodecljs.cljs to not rely on js/env.
kanaka Jan 5, 2013
b203409
Add quick.cljs test to cover basics quickly.
kanaka Jan 5, 2013
d963f82
Fix reader to read regexp properly.
Gozala Jan 6, 2013
b7619ff
Remove repeated definition of emit-str function
Gozala Jan 6, 2013
45a222d
Move regexp escaping from reader to compiler.
Gozala Jan 6, 2013
f60c828
Merge pull request #1 from Gozala/selfhosted/regexp
kanaka Jan 6, 2013
cded82c
`re-seq` has tail only if `past-match` is non empty string.
Gozala Jan 7, 2013
c2805bc
Fix regression introduced by #1
Gozala Jan 7, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ closure
/coreadvanced.js
/coresimple.js
/out
/web/out
/node/out
.repl
*.swp
*.zip
109 changes: 109 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,112 @@
## ClojureScript Compiler Compiled with ClojureScript? ##

This is a **patched version of the ClojureScript compiler** that
compiles to ClojureScript. Normally, the ClojureScript compiler is
a pure Clojure program that runs on the JVM. This patched version runs
from the compiled JavaScript. This project was kicked off by
[kanaka](https://github.com/kanaka) and
[chouser](https://github.com/chouser) during some intense hacking at
Clojure/conj 2012. Kanaka continues to develop the fork towards the
goal of being fully self-hosting (i.e. ClojureScript-in-ClojureScript).

### Why?

* Why not?
* Compilers are only cool once they are self-hosting (can compile
their own code). This fork is not self-hosting yet, but that is the
goal.
* You can use ClojureScript without a JVM.
* You can have a [ClojureScript REPL web
app](http://kanaka.github.com/clojurescript/web/jsrepl.html) that
runs locally in your browser (no server involved after loading the
page).

### Current Caveats

* JavaScript output is not optimized by the Google Closure Compiler
(which is a Java program).
* The code changes are not all compatible with the normal Clojure
ClojureScript (JVM based) compiler. To make it compatible we really
need [Feature Expressions in Clojure](http://dev.clojure.org/display/design/Feature+Expressions)
* The :nodejs compilation target is currently broken. However, the
`node/run.js` bootstrap script enables compiled CLJS code to be
invoked that was not compiled with a :target.
* Other miscellaneous broken things that have not been tracked down
yet.

### Bugs

- no division ("/" symbol in general is problematic)
- use of certain regexex causes hard hangs
- escaping in regexes is broken
- numeric keywords are broken
- anonymous functions do not warn about arity
- non-unicode symbol breakage
- warnings during compile about *unchecked-if*


### TODOs

- update to upstream ClojureScript
- file I/O (at least on the node.js side)
- misc functionality: require, use, var metadata, :private def check
- self-hosting (compile ClojureScript compiler using node.js hosted ClojureScript compiler)
- optional optimizations (single JS file output, etc)

### Build

You can build the ClojureScript analyzer and compiler with
ClojureScript like this:

```
bin/cljsc src/cljs/cljs/compiler.cljs > compiler.cljs
```

However, that is not all that useful because it does not have all the pieces
necessary to run it under a JavaScript engine (e.g. browser or node.js).

You can rebuild the ClojureScript analyzer, compiler, reader and
browser/node.js bootstrap pieces with a web REPL like this:

```
cd web
../bin/cljsc ../src/cljs/webrepl.cljs > webrepl.js
```
Now load the `web/jsrepl.html` file in a browser.

For a REPL in nodejs, build the `src/cljs/noderepl.cljs` code:

```
cd node
../bin/cljsc ../src/cljs/noderepl.cljs > noderepl.js
cp ../src/cljs/goog.js out/
```

Now use the `run.js` bootstrap code to launch the repl:

```
./run.js noderepl.js
```

For direct *.cljs file compilation/evaluation, build the nodecljs.cljs compiler:

```
cd node
../bin/cljsc ../src/cljs/nodecljs.cljs > nodecljs.js
cp ../src/cljs/goog.js out/
```

You can now use a combination of the `run.js` bootstrap code and
`nodecljs.js` to compile/evaluate the `hello.cljs` file:

```
./run.js nodecljs.js hello.cljs
```



--------

## What is ClojureScript? ##

ClojureScript is a new compiler for [Clojure](http://clojure.org) that targets JavaScript. It is designed to emit JavaScript code which is compatible with the advanced compilation mode of the [Google Closure](http://code.google.com/closure/) optimizing compiler.
Expand Down
3 changes: 3 additions & 0 deletions node/hello.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(def sqr (fn* [x] (* x x)))

(println "hello world" (sqr 16))
31 changes: 31 additions & 0 deletions node/run.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env node

// Launch a CLJS compiled program using node
// - First argument is the path to the compiled *.js file
// - Rest of the arguments are passed to the *main-cli*

(function() {
var path = require("path"),
targ = process.argv[2],
ns = path.basename(targ).replace(/[.]js$/, ""),
jsfile = path.resolve("./", targ);

// Load the Closure Library wrapper
require('./out/goog.js');

// Load the initial compiled file
require(jsfile);
goog.require(ns);

// Setup the print function
cljs.core._STAR_print_fn_STAR_ = require("util").print;

// Bootstrap an empty version of the cljs.user namespace
cljs.core.swap_BANG_.call(null,cljs.compiler._STAR_emitted_provides_STAR_,cljs.core.conj,(new cljs.core.Symbol(null,"cljs.user")));
goog.provide('cljs.user');
cljs.core._STAR_ns_sym_STAR_ = cljs.core.symbol.call(null,"cljs.user");
})();

// Call the users's main function
cljs.core.apply.call(null,cljs.core._STAR_main_cli_fn_STAR_,cljs.core.drop.call(null,3,process.argv));

4 changes: 2 additions & 2 deletions src/clj/cljs/analyzer.clj
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
{:name (symbol (str full-ns) (str (name sym)))
:ns full-ns}))

(.contains s ".")
(and (not= ".." s) (>= (.indexOf s ".") 0))
(let [idx (.indexOf s ".")
prefix (symbol (subs s 0 idx))
suffix (subs s (inc idx))
Expand Down Expand Up @@ -173,7 +173,7 @@
ns (if (= "clojure.core" ns) "cljs.core" ns)]
{:name (symbol (str (resolve-ns-alias env ns)) (name sym))})

(.contains s ".")
(and (not= ".." s) (>= (.indexOf s ".") 0))
(let [idx (.indexOf s ".")
prefix (symbol (subs s 0 idx))
suffix (subs s idx)
Expand Down
36 changes: 26 additions & 10 deletions src/clj/cljs/compiler.clj
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@
munged-name
(symbol (str munged-name "__$" depth))))
; String munging
(let [ss (string/replace (str s) #"\/(.)" ".$1") ; Division is special
(let [ss (string/replace (str s) #"[.][.]" "_DOTDOT_") ; .. is special
ss (string/replace ss #"\/(.)" ".$1") ; Division is special
ss (apply str (map #(if (reserved %) (str % "$") %)
(string/split ss #"(?<=\.)|(?=\.)")))
ms (clojure.lang.Compiler/munge ss)]
Expand Down Expand Up @@ -158,11 +159,14 @@
\"))

(defmethod emit-constant clojure.lang.Symbol [x]
(emits \" "\\uFDD1" \'
(if (namespace x)
(str (namespace x) "/") "")
(name x)
\"))
(emits "(new cljs.core.Symbol("
(if (meta x)
(emit-constant (meta x))
"null")
","
(str "\"" x "\"")
"))"))


(defn- emit-meta-constant [x & body]
(if (meta x)
Expand Down Expand Up @@ -778,6 +782,15 @@
(ana/analyze-file "cljs/core.cljs"))
~@body))

(defn ns-snap [ns]
(let [nss1 (dissoc (get @ana/namespaces ns) :requires-macros)
nss2 (read-string (pr-str (update-in nss1
[:defs] dissoc '/)))]
(apply str
(emit (ana/analyze (ana/empty-env)
(list 'swap! 'cljs.core/namespaces 'assoc (list 'quote ns) (list 'quote nss2)))))))


(defn compile-file* [src dest]
(with-core-cljs
(with-open [out ^java.io.Writer (io/make-writer dest {})]
Expand All @@ -797,10 +810,13 @@
(if (= (:op ast) :ns)
(recur (rest forms) (:name ast) (merge (:uses ast) (:requires ast)))
(recur (rest forms) ns-name deps))))
{:ns (or ns-name 'cljs.user)
:provides [ns-name]
:requires (if (= ns-name 'cljs.core) (set (vals deps)) (conj (set (vals deps)) 'cljs.core))
:file dest}))))))
(do
(println "\n// Analyzer namespace snapshot:")
(ns-snap ns-name)
{:ns (or ns-name 'cljs.user)
:provides [ns-name]
:requires (if (= ns-name 'cljs.core) (set (vals deps)) (conj (set (vals deps)) 'cljs.core))
:file dest})))))))

(defn requires-compilation?
"Return true if the src file requires compilation."
Expand Down
Loading