MogwaiNano v0.1.0
Added
Open Source Release
- MOGWAI NANO is now open source under Apache 2.0 license
- Available on GitHub at https://github.com/Sydney680928/MogwaiNano
Core Language
- Full RPN interpreter — tokenizer, stack, primitive dispatcher
- Arithmetic (
+,-,*,/), comparisons (==,!=,<,>,<=,>=), boolean operators - Stack operations (
dup,swap,drop,clear) - Control flow:
IF,IFELSE,WHILE,REPEAT,FOR,FORSTEP,FOREVER,FOREACH - Variable storage (
STO), local and global ($-prefixed) scopes - User-defined functions (
DEFUNC) with dedicated local scope, protected against name collisions with primitives and other functions - Reference sigil (
&) — direct object reference instead of copy, significantly reducing memory allocation and fragmentation on long-running scripts - Types:
MOGNumber(float-based, to leverage ESP32 hardware FPU),MOGString,MOGName,MOGList,MOGRecord,MOGKey,MOGCode,MOGFunction,MOGData(raw byte buffers,D:literal syntax) get/setprimitives for list (by index) and record (by key) access, plussizefor collection length- System primitives —
mogwai.halt,mogwai.memory(free RAM reporting),mogwai.reset,mogwai.sendMessage,mogwai.info(aMOGRecordwith system version, IP, device name, platform, session, free memory, target, MOGWAI NANO version, and OEM build details — everything in one call, useful from within an autorun program that has no active Studio connection to query) - Lifecycle hooks —
MOGWAI.onStop(any clean exit),MOGWAI.onError(unhandled error),MOGWAI.onReboot(pre-reboot cleanup, see below) - Structured error codes (
MW.xx), with a dedicatedMW.5xxrange reserved for hardware-related errors (MW.500-509GPIO,MW.510-519I2C, etc.)
Hardware Support
- GPIO —
gpio.setMode.*(input, inputPullDown, inputPullUp, output),gpio.write.high/gpio.write.low,gpio.read,gpio.toggle,gpio.close - Automatic cleanup of open GPIO pins at the end of every program run, regardless of how it ended (normal completion, error, or
STOP) - I2C, SPI, PWM and ADC packages are already referenced and validated for memory footprint — primitive implementations are planned for upcoming releases
Timers & Events
AFTER(one-shot) andEVERY(recurring) timers, named and independently startable/stoppable (timer.start,timer.stop,timer.purge)- Event subscription system (
EVENT, sugared asonEvent...doon the desktop side) — hardware events (e.g. GPIO value changes) deliver their data through an automatically-injectedeventDatalocal variable, shaped as aMOGRecord event.fire/event.purgeprimitives for manually firing or clearing registered eventsDI/EIprimitives for critical sections, protecting user code from being interrupted by pending timer/event callbacks- All pending timers and interrupt state are reset to a clean state at the start of every program run
Networking
- UDP-based device discovery (fixed port
1968) — devices respond with their name, version and platform details - Reliable TCP protocol (fixed port
9597) for remote code execution — length-prefixed, Base64-encoded JSON messages, single active client - Automatic disconnection detection via periodic
ALIVEheartbeat during long-running executions - Clean recovery on device reboot or unexpected disconnection, with no lingering blocked state on either side
Production Deployment
mogwai.rebootdevice-side primitive — called from within a running MOGWAI NANO script, it triggers the optionalMOGWAI.onReboothook for pre-reboot cleanup before actually rebootingnano.reboot/nano.haltremote commands from MOGWAI NANO Studio — force an immediate reboot/halt regardless of any program currently running on the device, bypassingMOGWAI.onRebootentirely- Persistent autorun storage — code saved to flash automatically executes on every boot, managed remotely via
nano.autorun.set/nano.autorun.get/nano.autorun.purge
Cross-Platform
- Validated on ESP32 and Raspberry Pi Pico W — the exact same compiled
.binruns unmodified on both, despite very different underlying architectures (Xtensa LX6 vs Cortex-M0+)
MOGWAI NANO Studio
- Desktop companion application built on the desktop MOGWAI engine
- Integrated Terminal.Gui-based code editor with F5-to-run workflow
- Extended primitives, exposed as regular MOGWAI host functions:
nano.connect,nano.disconnect,nano.isConnected— connection management.nano.connectpushestrue/falsedepending on success, a deliberate exception to the pattern below: connecting is expected to sometimes fail, so a boolean fits a straightforward feasibility checknano.name,nano.name.set— read or set the connected device's name, persisted on the device and reported as thenamefield innano.scan/nano.selectresults. Defaults to"MogwaiNanoDevice"; useful to tell multiple devices apart on the same networknano.scan— UDP network discovery (fixed 1s duration, with retransmission every 250ms to compensate for broadcast packet loss), returns a list of records (name, version, session, IP, platform, target, OEM, firmware version), deduplicated by IP. Thesessionfield is a random number generated once at boot, letting you detect a silent device reboot between two scans even without any visible errornano.select— runs its own scan and displays the responding devices (platform, IP) for interactive console selection; pushes the selected device's scan record on the stack, ornullif aborted or nothing respondednano.run— desugars and sends a code block for remote execution; unlikenano.connect, failure raises a distinctMW.xxerror (device not connected, unreachable, or busy already running something) rather than returning a boolean — running is expected to normally succeed, so a failure is treated as an incident with a diagnosable cause, not a routine outcomenano.state,nano.isRunning,nano.memory— query the connected device's current execution state and free RAM (GC.Run(false)result, non-blocking)nano.autorun.set,nano.autorun.get,nano.autorun.purge— manage code stored on the device for automatic execution on every bootnano.halt,nano.reboot— force an immediate halt/reboot on the device, bypassing theMOGWAI.onReboothook.nano.haltstops whatever is currently running (whether started vianano.runor as a stored autorun program) and returns the device's state fromRUNNINGtoIDLE, ready for a newnano.runnano.view— attaches to the currently running program on the device and displays its live console output (?/console.print,debug.write) in real time; exit withCtrl+C. Withoutnano.viewactive, output from anano.runor an autorun program is not displayed at all —nano.runitself only waits for confirmation that the program has started, it doesn't wait for it to finish or show anything. Likenano.run, failure raises anMW.xxerror rather than returning a boolean
- Zero-modification compatibility with the existing MOGWAI VS Code extension — canonical NANO primitives are declared as no-op stubs on the desktop engine purely so the extension can recognize and highlight them; using them outside of a
nano.runcontext on the desktop engine simply raises an "unknown word" error, with no other consequence
Known Limitations
- No step-by-step debugging on the device runtime (yet)
- Network configuration deployment (
nanoff --networkdeployment) support on Raspberry Pi Pico W is still being confirmed with the nanoFramework team MogwaiNanoRuntime.WaitResponsecorrelates a response to a request byFunctionname only, not by a unique request identifier — if two requests of the sameFunctionwere ever in flight concurrently, the wrong response could be matched to the wrong caller. Not an issue with the current sequential REPL-driven usage, but worth revisiting if concurrentnano.*calls are ever introduced.