Skip to content

Commit cd9aeca

Browse files
authored
Merge pull request #1046 from live-codes/clojurescript
add ClojureScript (self-hosted) language support
2 parents 7470548 + d9baa5f commit cd9aeca

108 files changed

Lines changed: 1070 additions & 242 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.agents/skills/livecodes/language-support/references/languages.md‎

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -108,39 +108,40 @@ Enabled via `processors` config:
108108

109109
### Backend Languages
110110

111-
| Name | Aliases | Notes |
112-
| ------------- | ----------------------------------------- | ----------------------- |
113-
| Python | `python`, `py` | Brython (Python -> JS) |
114-
| Python (Wasm) | `pyodide`, `python-wasm`, `py-wasm` | Pyodide runtime (~15MB) |
115-
| Ruby | `ruby`, `rb` | Opal (Ruby -> JS) |
116-
| Ruby (Wasm) | `ruby-wasm`, `wasm.rb` | Ruby WASM |
117-
| Go | `go`, `golang` | Gopherjs (Go -> JS) |
118-
| Go (Wasm) | `go-wasm`, `wasm.go` | Go WASM |
119-
| PHP | `php` | Uniter (PHP -> JS) |
120-
| PHP | `php`, `php-wasm`, `wasm.php` | PHP WASM |
121-
| C (Wasm) | `c-wasm`, `cwasm`, `wasm.c`, `c` | Clang WASM |
122-
| C++ | `cpp`, | JSCPP interpreter |
123-
| C++ (Wasm) | `cpp-wasm`, `clang`, `wasm.cpp` | Clang WASM |
124-
| Objective-C | `objc-wasm`, `objc`, `wasm.m` | Clang WASM |
125-
| Objective-C++ | `objcpp-wasm`, `objcpp`, `wasm.mm` | Clang WASM |
126-
| Java | `java` | Java runtime |
127-
| C# | `csharp-wasm`, `cs`, `cs-wasm`, `wasm.cs` | C# WASM |
128-
| VB.NET | `vb-wasm`, `vb`, `vbnet`, `wasm.vb` | VB.NET WASM |
129-
| R | `r`, `rlang`, `rstats`, `r-wasm` | R WASM |
130-
| Lua | `lua`, `lua-wasm`, `luawasm`, `wasm.lua` | Lua WASM |
131-
| Teal | `teal`, `tl` | Typed Lua |
132-
| Fennel | `fennel`, `fnl` | Lua lisp |
133-
| Julia | `julia`, `jl` | Julia runtime |
134-
| Scheme | `scheme`, `scm` | BiwaScheme |
135-
| Common Lisp | `commonlisp`, `common-lisp`, `lisp` | Common Lisp |
136-
| ClojureScript | `clojurescript`, `clojure`, `cljs`, `clj` | Clojure |
137-
| Perl | `perl`, `pl`, `pm` | Perl runtime |
138-
| Gleam | `gleam` | Gleam language |
139-
| Elm | `elm` | Elm compiler (WASM) |
140-
| Haskell | `haskell`, `hs`, `lhs` | MicroHs (not GHC) |
141-
| Haskell (Wasm) | `haskell-wasm`, `hs-wasm`, `wasm.hs`, `hswasm` | GHC WASM |
142-
| Tcl | `tcl` | Tcl interpreter |
143-
| WebAssembly | `wat`, `wast`, `wasm`, `webassembly` | WAT format |
111+
| Name | Aliases | Notes |
112+
| --------------------------- | ---------------------------------------------- | ----------------------------------------------------- |
113+
| Python | `python`, `py` | Brython (Python -> JS) |
114+
| Python (Wasm) | `pyodide`, `python-wasm`, `py-wasm` | Pyodide runtime (~15MB) |
115+
| Ruby | `ruby`, `rb` | Opal (Ruby -> JS) |
116+
| Ruby (Wasm) | `ruby-wasm`, `wasm.rb` | Ruby WASM |
117+
| Go | `go`, `golang` | Gopherjs (Go -> JS) |
118+
| Go (Wasm) | `go-wasm`, `wasm.go` | Go WASM |
119+
| PHP | `php` | Uniter (PHP -> JS) |
120+
| PHP | `php`, `php-wasm`, `wasm.php` | PHP WASM |
121+
| C (Wasm) | `c-wasm`, `cwasm`, `wasm.c`, `c` | Clang WASM |
122+
| C++ | `cpp`, | JSCPP interpreter |
123+
| C++ (Wasm) | `cpp-wasm`, `clang`, `wasm.cpp` | Clang WASM |
124+
| Objective-C | `objc-wasm`, `objc`, `wasm.m` | Clang WASM |
125+
| Objective-C++ | `objcpp-wasm`, `objcpp`, `wasm.mm` | Clang WASM |
126+
| Java | `java` | Java runtime |
127+
| C# | `csharp-wasm`, `cs`, `cs-wasm`, `wasm.cs` | C# WASM |
128+
| VB.NET | `vb-wasm`, `vb`, `vbnet`, `wasm.vb` | VB.NET WASM |
129+
| R | `r`, `rlang`, `rstats`, `r-wasm` | R WASM |
130+
| Lua | `lua`, `lua-wasm`, `luawasm`, `wasm.lua` | Lua WASM |
131+
| Teal | `teal`, `tl` | Typed Lua |
132+
| Fennel | `fennel`, `fnl` | Lua lisp |
133+
| Julia | `julia`, `jl` | Julia runtime |
134+
| Scheme | `scheme`, `scm` | BiwaScheme |
135+
| Common Lisp | `commonlisp`, `common-lisp`, `lisp` | Common Lisp |
136+
| ClojureScript (Cherry) | `clojurescript-cherry`, `cljs-cherry` | Cherry transpiler; imports npm packages as ES modules |
137+
| ClojureScript (self-hosted) | `clojurescript-selfhosted`, `cljs-selfhosted` | Official ClojureScript compiler; no npm imports |
138+
| Perl | `perl`, `pl`, `pm` | Perl runtime |
139+
| Gleam | `gleam` | Gleam language |
140+
| Elm | `elm` | Elm compiler (WASM) |
141+
| Haskell | `haskell`, `hs`, `lhs` | MicroHs (not GHC) |
142+
| Haskell (Wasm) | `haskell-wasm`, `hs-wasm`, `wasm.hs`, `hswasm` | GHC WASM |
143+
| Tcl | `tcl` | Tcl interpreter |
144+
| WebAssembly | `wat`, `wast`, `wasm`, `webassembly` | WAT format |
144145

145146
### Data & Logic Languages
146147

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# ClojureScript (Cherry)
2+
3+
[ClojureScript](https://clojurescript.org/) is a robust, practical, and fast programming language with a set of useful features that together form a simple, coherent, and powerful tool.
4+
5+
ClojureScript is a compiler for [Clojure](https://clojure.org/) that targets
6+
JavaScript. <br />In LiveCodes, it runs in the browser using
7+
[Cherry](https://github.com/squint-cljs/cherry).
8+
9+
:::warning Deprecation
10+
11+
The language aliases: `clojurescript`, `cljs`, `cljc`, `clj`, `edn`, `clojure` will use the [self-hosted ClojureScript compiler](./clojurescript.mdx) in the future.
12+
If you want to use the Cherry-based ClojureScript compiler, use the alias: `clojurescript-cherry` or `cljs-cherry` instead.
13+
14+
:::
15+
16+
## Language Info
17+
18+
### Name
19+
20+
`clojurescript-cherry`
21+
22+
### Aliases
23+
24+
`cljs-cherry`
25+
26+
Deprecated aliases: `clojurescript`, `cljs`, `cljc`, `clj`, `edn`, `clojure`
27+
28+
### Editor
29+
30+
`script`
31+
32+
## Compiler
33+
34+
[Cherry](https://github.com/squint-cljs/cherry)
35+
36+
If `JSX` is used (using `#jsx` reader tag - [example](https://github.com/squint-cljs/cherry/blob/60adcf6e3a8fb940a80c6a193599da0272fe3058/examples/jsx/pages/component.cljs)), it is also compiled ([JSX](./jsx.mdx)). See [example usage](#example-usage).
37+
38+
### Version
39+
40+
`cherry-cljs`: v0.6.38
41+
42+
## Code Formatting
43+
44+
Using [Parinfer](https://shaunlebron.github.io/parinfer/).
45+
46+
## Example Usage
47+
48+
import LiveCodes from '../../src/components/LiveCodes.tsx';
49+
50+
export const params = {
51+
cljs: `(ns demo\n${' '};; you can use npm modules\n${' '}(:require ["canvas-confetti$default" :as confetti]))\n\n(let [el (js/document.getElementById "test")]\n${' '}(.addEventListener el "click"\n ${' '}(fn []\n ${' '}(confetti)\n${' '}(println "test"))))\n`,
52+
html: '<button id="test">test</button>',
53+
console: 'open',
54+
};
55+
56+
<LiveCodes params={params}></LiveCodes>
57+
58+
Using React (with JSX):
59+
60+
<LiveCodes template="clojurescript"></LiveCodes>
61+
62+
## Starter Template
63+
64+
https://livecodes.io/?template=clojurescript
65+
66+
## Links
67+
68+
- [ClojureScript official website](https://clojurescript.org/)
69+
- [Clojure official website](https://clojure.org/)
70+
- [Cherry repo](https://github.com/squint-cljs/cherry)
71+
- [ClojureScript (self-hosted)](./clojurescript.mdx) in LiveCodes

‎docs/docs/languages/clojurescript.mdx‎

Lines changed: 100 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,65 +3,143 @@
33
[ClojureScript](https://clojurescript.org/) is a robust, practical, and fast programming language with a set of useful features that together form a simple, coherent, and powerful tool.
44

55
ClojureScript is a compiler for [Clojure](https://clojure.org/) that targets
6-
JavaScript. <br />In LiveCodes, it runs in the browser using
7-
[Cherry](https://github.com/squint-cljs/cherry).
6+
JavaScript. <br />In LiveCodes, it runs in the browser using the official
7+
[ClojureScript](https://clojurescript.org/) compiler, [self-hosted](https://clojurescript.org/guides/self-hosting)
8+
in the compiler worker. The compiler is provided by the
9+
[`@live-codes/cljs-selfhosted-compiler`](https://www.npmjs.com/package/@live-codes/cljs-selfhosted-compiler)
10+
package.
811

912
:::info Note
1013

11-
Lisp language family supported in LiveCodes includes [Common Lisp](./commonlisp.mdx), [Scheme](./scheme.mdx), [ClojureScript](./clojurescript.mdx) and [Fennel](./fennel.mdx).
14+
The `clojurescript`, `cljs`, `clj`, `cljc`, `edn` and `clojure` aliases currently use the
15+
Cherry-based ClojureScript compiler and will switch to this self-hosted compiler in the future.
16+
Use the [`clojurescript-cherry`](./clojurescript-cherry.mdx) alias to keep using Cherry.
1217

1318
:::
1419

1520
## Language Info
1621

1722
### Name
1823

19-
`clojurescript`
24+
`clojurescript-selfhosted`
2025

21-
### Extensions
26+
### Aliases
2227

23-
`cljs`, `cljc`, `clj`, `edn`, `clojure`
28+
`clojurescript`, `cljs-selfhosted`, `cljs`, `clj`, `cljc`, `edn`, `clojure`
2429

2530
### Editor
2631

2732
`script`
2833

2934
## Compiler
3035

31-
[Cherry](https://github.com/squint-cljs/cherry)
32-
33-
If `JSX` is used (using `#jsx` reader tag - [example](https://github.com/squint-cljs/cherry/blob/60adcf6e3a8fb940a80c6a193599da0272fe3058/examples/jsx/pages/component.cljs)), it is also compiled ([JSX](./jsx.mdx)). See [example usage](#example-usage).
36+
The official [ClojureScript compiler](https://clojurescript.org/), self-hosted in the compiler worker.
3437

3538
### Version
3639

37-
`cherry-cljs`: v0.2.18
40+
`@live-codes/cljs-selfhosted-compiler`: v0.3.0
41+
42+
## Usage
43+
44+
LiveCodes compiles ClojureScript to JavaScript in the browser using the official compiler,
45+
self-hosted in the compiler worker. This provides real `cljs.core` semantics and real analyzer
46+
diagnostics.
47+
48+
`(:require ...)` can resolve the namespaces that are bundled with the compiler:
49+
50+
- `cljs.core`
51+
- `clojure.string`
52+
- `clojure.set`
53+
- `clojure.walk`
54+
- `clojure.edn`
55+
- `cljs.pprint`
56+
- `clojure.core.reducers`
57+
- `clojure.core.protocols`
58+
- `clojure.data`
59+
- `clojure.zip`
60+
- `clojure.datafy`
61+
- `cljs.math`
62+
- `cljs.proxy`
63+
- `cljs.stacktrace`
64+
- `cljs.test`
65+
66+
Three reader namespaces are also require-able, because they are already present in the page runtime:
67+
68+
- `cljs.reader`
69+
- `cljs.tools.reader`
70+
- `cljs.tools.reader.edn`
3871

39-
## Code Formatting
72+
They (and the `cljs.tools.reader.reader-types` and `cljs.tools.reader.impl.*` namespaces under them)
73+
are already present in the page runtime because `clojure.edn` pulls them in transitively, so they
74+
cost nothing extra; they are listed here because they are require-able and work.
4075

41-
Using [Parinfer](https://shaunlebron.github.io/parinfer/).
76+
`defmacro` works and is evaluated at compile time. Source maps are on by default.
4277

43-
## Example Usage
78+
`cljs.test`'s macros expand in the compiler worker like any other macro. `deftest`, `is`,
79+
`testing` and `run-tests` come from its `cljs/test.cljc` macros half, and `are` expands through
80+
`clojure.template`, which is served to the worker next to it. The compiled test file is page
81+
JavaScript that calls `cljs.test`'s runtime (`cljs/test.cljs`), which the page provides alongside
82+
the other bundled namespaces.
4483

4584
import LiveCodes from '../../src/components/LiveCodes.tsx';
4685

47-
export const params = {
48-
cljs: `(ns demo\n${' '};; you can use npm modules\n${' '}(:require ["canvas-confetti$default" :as confetti]))\n\n(let [el (js/document.getElementById "test")]\n${' '}(.addEventListener el "click"\n ${' '}(fn []\n ${' '}(confetti)\n${' '}(println "test"))))\n`,
49-
html: '<button id="test">test</button>',
50-
console: 'open',
86+
This example demonstrates usage and JavaScript interoperability:
87+
88+
export const selfHostedCljsDemo = {
89+
activeEditor: 'script',
90+
markup: {
91+
language: 'html',
92+
content: `<div class="container">
93+
<h1>Hello, <span id="title">World</span>!</h1>
94+
<p>You clicked <span id="counter">0</span> times.</p>
95+
<button id="counter-button">Click me</button>
96+
</div>
97+
`,
98+
},
99+
style: {
100+
language: 'css',
101+
content: `.container,
102+
.container button {
103+
text-align: center;
104+
font: 1em sans-serif;
105+
}
106+
`,
107+
},
108+
script: {
109+
language: 'clojurescript-selfhosted',
110+
content: `(ns demo)\n
111+
(def title "ClojureScript")\n
112+
(set! (.-innerText (js/document.querySelector "#title")) title)\n
113+
(def counter (atom 0))\n
114+
;; you can use JS interop to wire up DOM events
115+
(.addEventListener
116+
(js/document.querySelector "#counter-button")
117+
"click"
118+
(fn [_]
119+
(swap! counter inc)
120+
(set! (.-innerText (js/document.querySelector "#counter")) (str @counter))))\n
121+
;; check console
122+
(js/console.log (str "Hello, " title "!"))
123+
`,
124+
},
51125
};
52126

53-
<LiveCodes params={params}></LiveCodes>
127+
<LiveCodes config={selfHostedCljsDemo} height="70vh"></LiveCodes>
54128

55-
Using React (with JSX):
129+
### npm Imports
56130

57-
<LiveCodes template="clojurescript"></LiveCodes>
131+
npm packages are **not** supported, unlike the [Cherry-based ClojureScript](./clojurescript-cherry.mdx),
132+
which imports npm packages as ES modules. For example, `(:require ["react" :as React])` fails with
133+
`No such namespace`. Use the [Cherry-based ClojureScript](./clojurescript-cherry.mdx) for
134+
npm-dependent code.
58135

59136
## Starter Template
60137

61-
https://livecodes.io/?template=clojurescript
138+
https://livecodes.io/?template=clojurescript-selfhosted
62139

63140
## Links
64141

65142
- [ClojureScript official website](https://clojurescript.org/)
66143
- [Clojure official website](https://clojure.org/)
67-
- [Cherry repo](https://github.com/squint-cljs/cherry)
144+
- [ClojureScript self-hosting guide](https://clojurescript.org/guides/self-hosting)
145+
- [Cherry-based ClojureScript](./clojurescript-cherry.mdx) in LiveCodes (with npm imports)

‎docs/docs/languages/commonlisp.mdx‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@
44

55
In LiveCodes, Common Lisp code runs in the browser using [JSCL](https://github.com/jscl-project/jscl), a Common Lisp to JavaScript compiler.
66

7-
:::info Note
8-
9-
Lisp language family supported in LiveCodes includes [Common Lisp](./commonlisp.mdx), [Scheme](./scheme.mdx), [ClojureScript](./clojurescript.mdx) and [Fennel](./fennel.mdx).
10-
11-
:::
12-
137
## Usage
148

159
LiveCodes runs Common Lisp code in the browser. JSCL implements a subset of Common Lisp, but covers enough functionality to write practical code.

‎docs/docs/languages/fennel.mdx‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@
44

55
Fennel code is compiled to Lua, which then runs in the browser using [Fengari](https://fengari.io/). See documentation for Lua language support in LiveCodes [here](./lua.mdx).
66

7-
:::info Note
8-
9-
Lisp language family supported in LiveCodes includes [Common Lisp](./commonlisp.mdx), [Scheme](./scheme.mdx), [ClojureScript](./clojurescript.mdx) and [Fennel](./fennel.mdx).
10-
11-
:::
12-
137
## Usage
148

159
JavaScript interoperability and DOM access is achieved using [`"js"` module](https://github.com/fengari-lua/fengari-interop).

‎docs/docs/languages/scheme.mdx‎

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@
44

55
In LiveCodes, Scheme code runs in the browser using [BiwaScheme](https://www.biwascheme.org/), a Scheme interpreter written in JavaScript.
66

7-
:::info Note
8-
9-
Lisp language family supported in LiveCodes includes [Common Lisp](./commonlisp.mdx), [Scheme](./scheme.mdx), [ClojureScript](./clojurescript.mdx) and [Fennel](./fennel.mdx).
10-
11-
:::
12-
137
## Usage
148

159
LiveCodes runs Scheme code in the browser. BiwaScheme [implements](https://www.biwascheme.org/doc/features.html) most of the features of [R7RS small](https://small.r7rs.org/), including first-class continuation and tail call optimization.
@@ -45,14 +39,12 @@ export const basicSchemeDemo = {
4539
script: {
4640
language: 'scheme',
4741
content: `(let ((title "Scheme"))
48-
(set-content! "#title" title))
49-
42+
(set-content! "#title" title))\n
5043
(let ((counter 0))
5144
(add-handler! "#counter-button" "click"
5245
(lambda (ev)
5346
(set! counter (+ counter 1))
54-
(set-content! "#counter" (number->string counter)))))
55-
47+
(set-content! "#counter" (number->string counter)))))\n
5648
; check console
5749
(let ((time-now (date-hour (current-date))))
5850
(console-log

‎docs/src/components/LanguageSliders.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ export default function Sliders() {
103103
{ name: 'fsharp-wasm', title: 'F# (Wasm)' },
104104
{ name: 'scheme', title: 'Scheme' },
105105
{ name: 'commonlisp', title: 'Lisp' },
106-
{ name: 'clojurescript', title: 'CLJS' },
106+
{ name: 'clojurescript-cherry', title: 'CLJS (Cherry)' },
107+
{ name: 'clojurescript-selfhosted', title: 'CLJS' },
107108
{ name: 'gleam', title: 'Gleam' },
108109
{ name: 'perl', title: 'Perl' },
109110
{ name: 'lua', title: 'Lua' },

‎docs/src/components/TemplateList.tsx‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ const templates = [
6262
{ name: 'scheme', title: 'Scheme Starter', thumbnail: 'scheme.svg' },
6363
{ name: 'commonlisp', title: 'Common Lisp Starter', thumbnail: 'commonlisp.svg' },
6464
{ name: 'clojurescript', title: 'ClojureScript Starter', thumbnail: 'cljs.svg' },
65+
{ name: 'cljs-selfhosted', title: 'CLJS (self-hosted) Starter', thumbnail: 'cljs.svg' },
6566
{ name: 'gleam', title: 'Gleam Starter', thumbnail: 'gleam.svg' },
6667
{ name: 'perl', title: 'Perl Starter', thumbnail: 'perl.svg' },
6768
{ name: 'lua', title: 'Lua Starter', thumbnail: 'lua.svg' },

0 commit comments

Comments
 (0)