1 Architecture
jess edited this page 2026-04-15 09:38:07 -07:00

Architecture

Layers

┌────────────────────────────────────────────┐
│  Swift app (src/)                          │
│  NSWindow, NSMenu, CVDisplayLink           │
│  File I/O, document browser, settings      │
│  NSView with wgpu/Metal layer              │
└────────────────────────────────────────────┘
            │  FFI (viewport/include/acord.h)
            ▼
┌────────────────────────────────────────────┐
│  Rust viewport (viewport/)                 │
│  iced 0.14 + iced_wgpu                     │
│  Editor state, blocks, table widgets       │
│  text_widget (forked text_editor)          │
│  Sidecar archive, crate export             │
└────────────────────────────────────────────┘
            │  acord-core dependency
            ▼
┌────────────────────────────────────────────┐
│  Cordial interpreter (core/)               │
│  Tokenizer, parser, AST, evaluator         │
│  Type system, unit algebra                 │
│  Numerical solver                          │
│  Module system, sidecar persistence        │
└────────────────────────────────────────────┘

Block compositor

  • Vec<Box<dyn Block>>
  • Kinds: text, heading, HR, table, computed-table, computed-tree
  • Iteration over recursion for selection paths
  • Layered draw order: Below / Content / Above / Top
  • Source: viewport/src/block.rs, viewport/src/blocks.rs

TextWidget

Forked from iced's text_editor. Per-line fill_paragraph() interleaves anchored child Elements in a sequential stream.

  • Renderer concretised to iced_wgpu::Renderer
  • Source: viewport/src/text_widget.rs

Sidecar archive

Base64-encoded ZIP in an HTML comment appended to the .md:

<!-- acord-archive
UEsDBBQAAAAIA…base64…AAAA
-->
Entry Contents
config.toml Display metadata (col widths, row heights, cell formulas)
src/<block>.cord Per-block TOML front-matter + source

Save: regenerated fresh each write. Load: only config.toml consulted. Source: viewport/src/sidecar.rs.

FFI

C ABI. Header: viewport/include/acord.h (cbindgen-generated).

Function Purpose
viewport_create / viewport_destroy Lifecycle
viewport_render Draw one frame
viewport_resize Reconfigure surface
viewport_mouse_event / viewport_key_event / viewport_scroll_event Input
viewport_set_text / viewport_get_text Document replace / read (handles sidecar)
viewport_set_lang / viewport_set_theme Highlighting, theme
viewport_send_command Menu command by integer ID
viewport_export_crate Write standalone Rust crate
viewport_render_mode 0=Live, 1=Editor, 2=View
viewport_free_string Free strings returned to Swift

Mouse event sentinel: button == 255 → pointer-move only.

Command IDs

ID Command
1 ToggleBold
2 ToggleItalic
3 InsertTable
4 SmartEval
5 Evaluate
6 TogglePreview
7 ZoomIn
8 ZoomOut
9 ZoomReset
10 FormatDocument
11 Live mode
12 Editor mode
13 View mode

Cordial interpreter

Hand-rolled tokenizer + recursive-descent parser + tree-walking evaluator.

  • use spice pre-scanned from source text → tokenizer mode
  • Implicit multiplication: number adjacent to identifier or ( → Star token insertion
  • solve! registry parallel to user fns; eval_call checks user fns → solved_fns → builtins
  • Unit algebra: pure string manipulation
  • Type system: round-trip coercion

Source: core/src/interp.rs, core/src/eval.rs.

See also