Roadmap

What's done, what's next, and where Aksa is headed.

  • P0: scaffold, Makefile (native+wasm), test harness, CLI aksa tokens
  • P1a: locale loader + lexer (id/en, Unicode idents, E001–E003) + wasm demo page
  • P1b: parser → AST (recursive descent, panic-mode recovery, aksa ast)
  • P1c: semantic checker (aksa check; static E100–E111, runs before every aksa run)
  • P1d: bytecode VM, aksa run (cetak/tanya, functions, loops, localized runtime errors)
  • P1e: golden tests (40 ok + 36 error programs, tests/golden.sh in make test)
  • P2a: browser run (console via WASM hooks, inline async tanya, stop button, instruction-budget yield)
  • P2b: CodeMirror 6 editor (bun-bundled; locale-driven highlighting, live squiggles, error panel)
  • P2c: turtle canvas (animated draw, live speed slider, reset, id color names)
  • P3: hardware simulator (virtual board: 3 LEDs, button, slider, buzzer, fan; pin builtins + non-blocking tunggu; examples dropdown; headless CLI board for 10 golden tests)
  • P4: C emitter (aksa emit) + tiny value runtime + sim/esp32 HAL; differential tests (tests/diff.sh) prove emitted C compiles -Werror and matches the VM on all golden ok/err programs (E109 depth excluded)
  • P5: compile server (Bun + arduino-cli in Docker, ESP32) + browser flasher (esptool-js) + serial monitor; flash path untested on a real board
  • P5b: flash verified on real ESP32-C6. Terminal: make aksa-flash FILE=x.aksa (flash.sh: emit→sketch→arduino-cli upload), auto-runs. Browser (play/device.html): manual download-mode (BOOT+RESET) + esptool-js no_reset flashes reliably — fixed the "device has been lost".
  • P5 deferred: browser auto-reboot-to-run on C6 native-USB (RTS/DTR pulse doesn't reboot via USB-JTAG controller → user taps RESET after flashing); tanya on device (serial read in HAL); Pico/UF2; per-IP rate limit; build+test Docker image (no Docker locally)
  • P6g: reference-counted heap strings in emitted C (rt.c); loops that build text free per-iteration, no leak on device; tests/mem.sh (AK_LIVE=0) + ASan-clean corpus
  • P6a (language only): IDE split into language page (lessons+turtle) and device page (board+flash); 15 graded lessons (id+en), basic→middle→advanced; share via URL hash
  • P6c: drawing cursor renamed turtle→robot, arrow replaced with a robot character (rounded body, eyes, nose showing heading)
  • P6d: lessons split into one file per locale (lessons.id.js/lessons.en.js), lessons.js just assembles the map
  • P6e: all JS → strict TypeScript (web+server, bun-native); tsconfig + make typecheck
  • P6f: auto-detect chip on flash (esptool-js CHIP_NAME → board); compile targets esp32c3/esp32c6, bootloader at 0x0; others rejected
  • P6b: more locales; device lesson track after real-board testing. Pin map C6 DONE: 15 named starter components → GPIO (device/aksabot_c6.aksa + docs pinmap). ADC=0-6, avoid 8/9/12/13. C6 Super Mini user LED=GPIO15. TODO: C3 map
  • P7: on-device runtime — board is its own hotspot + editor + interpreter (make device, default C6). Tested on real C6: AP join, GPIO15 blink, ulangi, live analog stream, Stop. Program runs in its own task (16KB stack); output via stream buffer + /output poll; Stop = poll hook checked each loop back-edge + interruptible tunggu; OOM-safe task start (no busy wedge); runs cooler: loop() yields 1ms, CPU 160->80MHz, WiFi TX 8.5dBm (one near client)
  • Battery endpoint (device/aksa_device.ino): GET /bat returns 0–100% (no UI). Aksabot STANDARD: battery sense on GPIO6/ADC1_6, B+→100k→GPIO6→100k→GND +100nF, linear 3.3V=0%/4.2V=100%. Boards with a spare ADC reserve GPIO6; Starter keeps GPIO6 for mic (no battery)
  • P8: Aksabot (closed kit, ESP32-C6) — reuse P7 AP+editor+on-chip VM; board profile (named components via generated buat name = gpio preamble, Starter tier map done); 3 core builtins (atur/pin_pwm, sudut/servo_write, baca_jarak/pin_read_distance) + 2 Starter driver builtins (7-seg TM1637 write, NeoPixel color) + HAL (esp32/sim); hardware lesson track. v1 editor = text. NOTE: pin map is Starter-only; higher tiers may remap
  • Production order (Aksabot): 1 prototype from off-the-shelf modules → prove C6 software → prove curriculum with kids → PCB+casing → mass. No PCB before wiring+curriculum validated
  • LineFollower board design (backup/kicad): round 100mm PCB — C6, 8 IR sensors (6 ADC+2 digital, emitters ganged via 1 MOSFET), DRV8833+2×N20, 1×18650 w/ TP4056+DW01A/8205A protection + boost 5V + reverse/polyfuse guards. ERC+DRC clean; fixed C6 pinout (power=right row). Gen via gen_sch.py/gen_pcb.py
  • Parse-depth cap (PARSE_DEPTH_MAX=128, parser.c): deep nesting hits E109 once, no stack-overflow reboot. Capping the parser caps checker+compiler too. Measured ~0.7KB/level → worst case ~30KB, so device task stack 16→48KB. Golden err deep_nest
  • On-board editor UX (index_html.h): syntax highlight via transparent-textarea-over-<pre> overlay (regex: keywords/builtins/strings/numbers///comments, both locales), + auto-indent on Enter (copies indent, +2 after {). No library, self-contained. ponytail: keyword list hand-copied from locales.
  • Browser terminal scrollback cap (index_html.h): selama(benar) printers grew #out DOM unbounded → tab crawl. Keep last 4000 chars. Device ring already bounded (drops on full), so browser was the only leak.
  • On-board editor polish: Run/Stop disable states + grey styling; editor persists to localStorage (restore on load, save on edit); hot forever-loops auto-throttle in dev_poll (delay(1) per 10ms, tunable) so no tunggu needed to stay cool.
  • Timer/interrupt for precise timing: task separation is fine for the web+VM split (jitter-tolerant), but reading encoders / fixed-rate sampling / safety stops need hardware timer or external interrupt (INT0), not a FreeRTOS task
  • Block+text editor: drag-drop blocks that emit Aksa text side-by-side. Deferred until text editor v1 proves out
  • Docs site (docs.aksabot.com): static bosia app in docs/ — en + /id, language guide, builtins/errors/CLI reference, 15 lessons, Aksabot section, search, llms.txt, Cloudflare deploy
  • Web redesign: playful kid theme (Lilita One/Nunito, sky bg, bouncy buttons); both pages, mobile stack <800px; brand + canvas cursor use favicon robot (antenna ball = pen color)
  • Play deploy (play.aksabot.com): CI builds wasm (emsdk) + bundle, flattens play/+wasm/+locales/ into site/, Cloudflare Pages aksa-play
  • tunggu unit = seconds (kid-friendly); decimals for sub-second (0.1=100ms). seconds→ms ×1000 in all 3 runtimes (core/rt.c, device dev_wait, play/); en examples/docs/golden updated
  • Renamed id print builtin tuliscetak (clearer "print"). One line in locales/id.json; runtimes dispatch on canonical print. Updated tests, golden .id, docs, lessons, highlighter regex