Compiler
The Devlish compiler (devlish_core) parses English-like source into typed statements, then emits bytecode instructions targeting the Devlish VM. The compiler is a single-pass system written in Rust.
Statement Types
Section titled “Statement Types”The parser recognizes 32 statement types that cover the full language surface:
| Category | Statements |
|---|---|
| I/O | Input, Output, FileWrite, FileRead, ReadXlsxCell, ReadPdfText, ReadDocxText |
| Assignment | Assignment, ConditionalAssignment, SetField, Definition |
| Control flow | Branch, ForEach, WhileLoop, UntilLoop, Break, Continue |
| Error handling | TryRecover, Fail, Require |
| Validation | Validate, Assertion, ExportAssertions |
| HTTP | HttpRequest, HttpDownload |
| Filesystem | FileCopy, FileMove, FileMkdir, FileDelete, FileExists, FileStat, FileList, FileGlob |
| Structure | Import, Load, Extract, RespondWith, Checkpoint, Trigger |
| Collections | Append, Pop |
| Services | ServiceCall, Route, Bind |
Each statement carries its source line number and original text for diagnostics.
Opcodes
Section titled “Opcodes”The compiler emits 42 opcodes in the current instruction set:
CONST LOAD STORE ADD SUBMUL DIV AND OR NOTEQ NEQ LT LTE GTGTE JUMP JUMP_IF_FALSE PRINTASK EXPORT RETURN VALIDATE ASSERTEXPORT_ASSERTIONS REQUIRE FAIL TRY_PUSHTRY_POP RESPOND SERVICE_CALL HTTP_REQUESTREAD_FILE WRITE_FILE CALL_BUILTIN SET_FIELDFOR_EACH CHECKPOINT FILE_COPY FILE_MOVE FILE_MKDIRFILE_DELETE FILE_EXISTS FILE_STAT FILE_LIST FILE_GLOBEach instruction is a JSON object with an op field and operands:
{"op": "CONST", "dest": "r0", "const": 0}{"op": "STORE", "name": "threshold", "src": "r0"}{"op": "VALIDATE", "target": "amount", "rule": "minimum", "value": "r1"}{"op": "JUMP_IF_FALSE", "cond": "r2", "target": 15}Source Maps
Section titled “Source Maps”Every instruction maps back to its source line for error reporting:
{ "source_map": [ {"line": 1, "source": "threshold equals 1000000"}, {"line": 2, "source": "amount must be at least threshold"}, {"line": 4, "source": "If status equals \"approved\":"} ]}When the VM encounters a runtime error, it uses the source map to report the original Devlish line, not a bytecode address.
Manifest Extraction
Section titled “Manifest Extraction”If a program declares Permissions, Boundaries, or Callers, the compiler extracts them into a manifest field:
Permissions: Read files from "/data/" Write files to "/output/"Callers: Any MCP clientCompiles to:
{ "manifest": { "permissions": [ {"kind": "read_file", "scope": "/data/"}, {"kind": "write_file", "scope": "/output/"} ], "boundaries": [], "callers": ["Any MCP client"] }}Compile Errors
Section titled “Compile Errors”The compiler produces structured diagnostics with line numbers:
line 5: undefined variable: customer_name: Print customer_nameline 8: expected indented block after If: If score > 70:Each diagnostic includes the line number, error message, and the original source text.
Class-Style Compilation
Section titled “Class-Style Compilation”Class programs compile each method into a separate instruction stream. The bytecode package includes a methods array:
{ "methods": [ { "name": "calculate wages", "ruby_name": "calculate_wages", "params": ["hours_worked", "hourly_rate"], "is_private": false, "instructions": [...], "source_map": [...] } ]}The --method flag at runtime selects which method to execute.
Disassembly
Section titled “Disassembly”Inspect compiled bytecode with human-readable output:
devlish disassemble program.dvlc.json0000 CONST r0, 10 ; line 2: base score equals 100001 STORE base_score, r0 ; line 20002 CONST r1, 5 ; line 3: bonus score equals 50003 STORE bonus_score, r1 ; line 30004 LOAD r2, base_score ; line 40005 LOAD r3, bonus_score ; line 40006 ADD r4, r2, r3 ; line 4: total equals base_score plus bonus_score