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.