docs / Compiler
Compiler Pipeline
Four stages, no hidden runtime: preprocess, parse, IR generation, and codegen to server and client JavaScript (or Kotlin).
The compiler turns `.vsk` source into JavaScript targets from one intermediate representation: server codegen (SSR HTML) and client codegen (real DOM construction + hydration wiring). A native Kotlin path walks the same IR.
Pipeline stages
| Stage | Module | What happens |
|---|---|---|
| [1] Preprocess | parser.ts | preprocessForClauses() blanks `; key <expr>` / `; index <ident>` clauses in for-of headers, preserving source offsets with VeskAnnotations |
| [2] Parse | acorn + acorn-ts-plugin + VeskPlugin | ESTree-compatible AST with ComponentDeclaration, &[...] track atoms, statement-position JSX, VeskBlock islands, raw <style> |
| [3] IR generation | ir-generator.ts | AST → typed IR node tree; statement-mode dispatch; validateBlocks; extractStyle |
| [4] Codegen | server-jsgen.ts / client-codegen.ts | server emits HTML string chunks (event attrs stripped); client emits real DOM construction + tracked bindings + hydration wiring |
Notes
- Statement mode and expression mode produce the same IR node types — `props.items.map(...)` and `for (...; key ...)` both become a MapRegion.
- `isStaticIR(body)` decides whether a subtree is fully static; static components skip runtime effect wiring entirely.
- User code in statement-mode bodies stays raw — unrecognized statements are preserved as RuntimeStatement and re-emitted verbatim.
- There is no regex anywhere in parsing or codegen — tokenizer/character scans only.