Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Empty file modified .husky/pre-commit
100644 → 100755
Empty file.
22 changes: 20 additions & 2 deletions BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@ npm run build

`scripts/build-vendor.sh` clones and builds static archives for libgc, cJSON, libuv, tree-sitter, and libwebsockets into `vendor/`. It's idempotent — re-running skips already-built libraries.

## Run

After building, the compiler is available as a Node.js script:

```bash
node dist/chad-node.js build hello.ts -o hello
./hello
```

For a ~10x faster compiler, build the native binary once:

```bash
node dist/chad-node.js build src/chad-native.ts -o .build/chad
# Now tests and scripts auto-use .build/chad instead of node dist/chad-node.js
```

## Verify

```bash
Expand Down Expand Up @@ -95,11 +111,13 @@ bash scripts/build-target-sdk.sh

## Self-Hosting (Stage 0)

ChadScript can compile its own compiler to a native binary:
ChadScript can compile its own compiler to a native binary (this is what `scripts/self-hosting.sh` automates):

```bash
chad build src/chad-native.ts -o /tmp/chad-stage0
# Stage 0: Node.js compiler produces a native binary
node dist/chad-node.js build src/chad-native.ts -o /tmp/chad-stage0

# Stage 1: that native binary recompiles itself
/tmp/chad-stage0 build src/chad-native.ts -o /tmp/chad-stage1
```

Expand Down
14 changes: 14 additions & 0 deletions c_bridges/yyjson-bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ void *csyyjson_create_obj(void) {
return (void *)doc;
}

void *csyyjson_create_arr(void) {
yyjson_mut_doc *doc = yyjson_mut_doc_new(NULL);
if (!doc) return NULL;
yyjson_mut_val *root = yyjson_mut_arr(doc);
if (!root) { yyjson_mut_doc_free(doc); return NULL; }
yyjson_mut_doc_set_root(doc, root);
return (void *)doc;
}

void *csyyjson_mut_arr_add_obj(void *doc, void *arr) {
if (!doc || !arr) return NULL;
return (void *)yyjson_mut_arr_add_obj((yyjson_mut_doc *)doc, (yyjson_mut_val *)arr);
}

void *csyyjson_mut_get_root(void *doc) {
if (!doc) return NULL;
return (void *)yyjson_mut_doc_get_root((yyjson_mut_doc *)doc);
Expand Down
17 changes: 2 additions & 15 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,6 @@ export default defineConfig({
languages: [llvmGrammar],
},

transformPageData(pageData) {
const mdPath = path.resolve(__dirname, '..', pageData.relativePath)
try {
pageData.frontmatter.__rawMarkdown = fs.readFileSync(mdPath, 'utf-8')
} catch {}
},

themeConfig: {
search: {
provider: 'local'
Expand All @@ -40,11 +33,11 @@ export default defineConfig({
{
text: 'Getting Started',
items: [
{ text: 'Language Support', link: '/language/limitations' },
{ text: 'About ChadScript', link: '/language/architecture' },
{ text: 'Installation', link: '/getting-started/installation' },
{ text: 'Examples', link: '/getting-started/quickstart' },
{ text: 'How it Works', link: '/language/architecture' },
{ text: 'CLI Reference', link: '/getting-started/cli' },
{ text: 'Supported Features', link: '/language/limitations' },
{ text: 'Debugging', link: '/getting-started/debugging' }
]
},
Expand Down Expand Up @@ -84,12 +77,6 @@ export default defineConfig({
{ text: 'Benchmarks', link: '/benchmarks' }
]
},
{
text: 'Resources',
items: [
{ text: 'FAQ', link: '/faq' }
]
}
],

socialLinks: [
Expand Down
50 changes: 35 additions & 15 deletions docs/.vitepress/theme/CopyMarkdown.vue
Original file line number Diff line number Diff line change
@@ -1,29 +1,49 @@
<!-- Copy-as-markdown button: lazily loads the raw .md source on click. -->
<script setup lang="ts">
import { ref } from 'vue'
import { useData } from 'vitepress'

const { page, frontmatter } = useData()
const { page } = useData()
const copied = ref(false)

// Vite lazy-loads each .md as a raw string on demand (not bundled upfront)
const markdownModules = import.meta.glob('../../**/*.md', { query: '?raw', import: 'default' }) as Record<string, () => Promise<string>>

async function copyMarkdown() {
const raw = (frontmatter.value as any).__rawMarkdown
// Map page's relativePath (e.g. "getting-started/cli.md") to glob key
const key = `../../${page.value.relativePath}`
const loader = markdownModules[key]
if (!loader) return

const raw = await loader()
if (!raw) return

try {
await navigator.clipboard.writeText(raw)
copied.value = true
setTimeout(() => { copied.value = false }, 2000)
} catch {
const textarea = document.createElement('textarea')
textarea.value = raw
document.body.appendChild(textarea)
textarea.select()
document.execCommand('copy')
document.body.removeChild(textarea)
copied.value = true
setTimeout(() => { copied.value = false }, 2000)
if (navigator.clipboard?.writeText) {
navigator.clipboard.writeText(raw).then(() => flash(), () => fallbackCopy(raw))
} else {
fallbackCopy(raw)
}
}

function fallbackCopy(text: string) {
const ta = document.createElement('textarea')
ta.value = text
ta.style.position = 'fixed'
ta.style.left = '-9999px'
ta.style.top = '-9999px'
ta.style.opacity = '0'
document.body.appendChild(ta)
ta.focus()
ta.select()
document.execCommand('copy')
document.body.removeChild(ta)
flash()
}

function flash() {
copied.value = true
setTimeout(() => { copied.value = false }, 2000)
}
</script>

<template>
Expand Down
19 changes: 14 additions & 5 deletions docs/.vitepress/theme/ExampleTabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,18 @@ const examples = [
{
label: 'HTTP Server',
file: 'server.ts',
code: `ChadScript.embedDir("./public");
code: `// Static files baked into the binary at compile time
ChadScript.embedDir("./public");

const posts = [{ id: 1, title: "Hello World", likes: 42 }];

function handleRequest(req: HttpRequest): HttpResponse {
// JSON REST API
if (req.path === "/api/posts") {
return { status: 200, body: JSON.stringify(posts), headers: "" };
}
// Fallback: serve embedded static files (.html, .css, etc.)
// Content-Type is inferred from the file extension
return ChadScript.serveEmbedded(req.path);
}

Expand Down Expand Up @@ -57,18 +66,18 @@ sqlite.close(db);`,

async function main() {
const results = await Promise.all([
fetch("https://api.github.com/repos/cs01/ChadScript"),
fetch("https://api.github.com/repos/vuejs/vue"),
fetch("https://api.github.com/repos/facebook/react"),
]);
const cs = JSON.parse<Repo>(results[0].text());
const vue = JSON.parse<Repo>(results[0].text());
const react = JSON.parse<Repo>(results[1].text());
console.log("ChadScript: " + cs.stargazers_count + " stars");
console.log("Vue: " + vue.stargazers_count + " stars");
console.log("React: " + react.stargazers_count + " stars");
}

main();`,
run: '$ chad run stars.ts',
output: `ChadScript: mass stars\nReact: 235k stars`,
output: `Vue: 208k stars\nReact: 235k stars`,
},
]

Expand Down
Loading
Loading