Mica for Visual Studio Code
The editor face of Mica, the high-efficiency mathematics and systems language: every stage of the
compiler a view you can read and draw, one-click run, debug and profile across Mica and C, a runtime
view in which the stopped program explains its own tasks, and notebooks whose outputs are verified
facts. From formula to native code and GPU in one language.
mica-dev.com · Language & compiler documentation · Blog · VS Code extension · YouTube
Mica is a statically typed mathematics and systems language that compiles to native Linux x86-64 and
AArch64 binaries. Numerical code is ordinary Mica: vectors, matrices and tensors are types whose shapes the
compiler checks, the autograd tape is a language construct, and a run prints the same digits every time - which
is why AI is one of Mica's core capabilities rather than a library beside it. This extension teaches Visual
Studio Code the whole of it.
Each version of this extension accompanies one compiler release, which the change log
names. In the editor every stage the compiler passes through opens as a viewer in colour, a function's control
flow is drawn beside its listing, a program's time is shown on the line it goes to, a Mica program that calls C
debugs as one program, and a stopped program draws its own tasks and its autograd tape. The language server this
extension talks to is the compiler itself, so everything the editor answers is what the installed compiler knows.
The place to learn Mica is the website: the Learn area walks from the first
program to a GPT trained on a graphics card, the technical reports state the
design whole, and the blog announces every release with its measurements. Follow
the blog, and read this extension's change log for the editor's half of each release.
Here is the headline in one picture - the compiler, open in the editor. Show Placement draws where a
function keeps its values: its activation record as the prologue builds it, and its registers and stack
slots over time, one bar per name while it lives there. A click on a bar moves the editor to the source lines
the value lives across, and a line's number above the bars selects that line's instructions in the listing
beside it:
Run, debug, and the runtime view
- Nothing needs configuring. F5, or Debug above a program, builds the file you are in (or the
mica.project
it belongs to) at the debug tier and stops on its breakpoints, with locals, stepping and watch; Run above
the program runs it like a script. No launch.json and no tasks.json are involved.
- The Launch Card above a program is where you set how it runs. Pick a configuration (Debug, Release O2 checked,
Profile, Thread checker, Address sanitizer, Undefined behaviour, Fixed arena, or one of your own made with New
from this one…), set the program's tasking and memory class, which the card writes into
mica.project, and this
run's optimization, sanitizer, arguments, folder, standard input, architecture and runtime flags. Run, Debug and F5
all start the configuration the card shows, and Debug always builds it at the debug tier. The card shows the exact
command Run starts, with a Copy button, and before anything runs it says what that start resolves: carriers and
worker processes and why, output mode, the products record, the GPU card, usable processors, memory class and
tasking, read from the program itself, or the runtime's own sentence for a flag it refuses, with Keep flags open
for this run where a release build seals them.
- A configuration is yours in this workspace until you tick Share with the team, which writes it into
.vscode/launch.json as a mica configuration, where F5's own list shows it. Beside micaRuntimeFlags, args and
cwd, such a configuration takes micaOptimize, micaSanitize, micaStackSize, micaProcesses,
micaRuntimeFlagPolicy, micaTasking, micaMemoryClass, micaPlatform, micaRemarks and micaStdin. Each
configuration written there also gets its own Debug action above the program.
- While a program is stopped, each variable's value appears at the end of the lines that use it.
- The Mica Runtime view draws what the stopped program itself narrates: the task tree under the
scopes that own it, each task's state in colour, shape and words, every generator's suspension point,
and the autograd tape's recording window as a strip — read live from the process at every stop, and kept
dimmed while the program runs on.
- A program's memory class and tasking live in its
mica.project ("memory-class", "tasking"), which every road
reads, and the status bar shows the classes in force. A folder that still names them in the old settings
mica.build.memoryClass and mica.build.tasking is offered, once, a move into its mica.project.
- While a program is stopped, every suspended task appears in the Call Stack as a thread of its own, and its stack
opens down to the Mica line it waits on.
- Attach to Running Program draws a program that is running without a debugger: start it with
+mica rtp=listen -mica ahead of its arguments, attach, and watch its task tree as tasks begin and end —
suspend it, continue it, or cancel a task's scope from the view.
- Show What the Program Holds opens the view's Memory section: what the program holds in one sentence, in the
order memory is owned ("1 region holds 1.2 KB in one 64 KB block"), its cells summed by the type they hold with the
line that made each type, and every region block drawn as two bars, each with its caption: the block's fill, then
its used part, cell by cell. A legend says what each colour means: a value in use; released, waiting for reuse; the
region's own table of free lists. A program stopped at a breakpoint is read again at every stop; a running program
you attached to is stopped for each reading's moment and read again at every refresh. A release-tier program names
its regions and says which tier shows its cells.
Debugging Mica and C together
A project whose mica.project names a contract for a C library debugs as one program. Build the C archive with
-g beside the sources, and one Debug session follows calls across the boundary in both directions:
- Breakpoints can be set in
.mica and .c files alike, and so can function breakpoints on the name C calls
an exported Mica routine by (Program__Routine).
- The Call Stack lists Mica and C frames in one chain, each at its own file and line. Selecting a frame shows
that frame's variables in its own language.
- Step Into goes from Mica into C and from C into Mica, stopping at the routine's first line with its
parameters in place. Step Out returns to the caller in either language, and the returned value appears
under Locals as
$ReturnValue.
- Hover and watch expressions evaluate in Mica frames as they do in C frames, and inline values appear in Mica
files at every stop, including in a Mica routine that C called.
The compiler's case tests/cases/debug/CrossLanguageStepping is the example: Mica and C call each other four
times, down to a C leaf thirteen frames deep. npm run scenario:cross-language walks that chain through the
C/C++ extension's debugger and gdb and checks every stop.
The compiler's reading of a program
Export File asks the compiler for everything it makes of a source — the tokens, the syntax tree,
the Spectra intermediate language before and after static single assignment, the control flow graph,
dominance, liveness, reaching definitions, where every value is placed, the assembly, what each
optimization pass did, and what the heap will hold — and opens an overview beside the source. It draws the
road the export took through the compiler, one box per component in the order the compiler runs them with
the files each writes beneath it, every file a link that opens it: the debug road, or the release road that
O1 and O2 take through static single assignment, with the other road one click away. Below the drawing every
stage stands in the order the compiler's phases ran, each with one short line on what it holds:
Every stage opens as a language of its own, coloured and outlined:
- Spectra listings colour each operation by what it does, fold and outline by function and basic
block, and say in a hover what an operation means, in the compiler's own words. Go to Definition
jumps from a label or a temporary to where it is defined; on a source-line comment it opens the
source line.
- Every line knows where it came from. Hover any line of any stage to see the source line that
produced it, its routine and block, and what the stage states for it — the block, the live range, the
register or stack slot. A line no source line produced, such as the data the program carries or a
routine of the standard library, says so in words.
- Every number explains itself. Hover a
#34 to learn what it counts in that stage — the value id
one unit gives the value an instruction defines, with the stages that quote the same number, a name's
version in static single assignment form, or an AArch64 immediate — which routine it belongs to, and
follow the link to the line that defines it, in the listing of the unit the number belongs to.
- Links above every routine and block open its source line, its control flow, its placement and the
next stage at the same place, and the outline and breadcrumbs list the routines of every stage.
- Go to Definition (F12) and Peek Definition work from anywhere on a line and open its source line;
on a Spectra label or temporary they jump to its definition in the listing. The context menu offers
Go to Source Line, Show Control Flow and Show Placement only on a line they apply to.
- Open Export Stage moves to another stage of the same unit and lands on the same routine and source
line.
- The grammars and hovers are generated from the compiler's own tables, so they cannot fall behind it.
From a source line to its assembly and back
- Open a Mica source, run Mica: Export File and pick Debug; the index opens beside the source.
- Click the
assembly stage in the index. The outline lists the routines; the links above each one read
Source line · Control flow · Placement · Next stage.
- Hover any instruction: the hover quotes the source line it came from.
- Press F12 on the instruction, or pick Go to Source Line from its context menu: the source opens at
that line.
- Back in the stage, Open Export Stage to
spectra lands on the same routine and source line, so the
instruction and the intermediate code it came from stand side by side.
A stage beside its source
Open Export Stage Beside, from the context menu of a Mica source or of any stage, stands the source
and a stage of its export side by side and ties them together: every source line and the stage lines it
became share a colour band. Move the cursor in the source and the stage lines it became are outlined and
scrolled into view; move it in the stage and its source line is outlined the same way. The bands follow a
fresh export of the same source, and they work for every stage whose lines name source lines — the
tokens, the syntax tree, the Spectra listings, the placement and the assembly among them.
Diagrams of an export
Four diagrams draw a program as the compiler sees it: the call graph of a unit, and the control flow, the
dominator tree and the placement of each routine. Each opens beside any stage of an export — from the
editor's title bar, the stage's context menu, or the Command Palette — and a routine's diagram draws the
routine under the cursor, or asks which one to draw. Graphviz lays the graphs out inside the extension, so
they draw offline and in the editor's colours.
Show Call Graph draws which routine of the unit runs which: a call, a task spawned, a generator opened,
a device kernel launched or a routine's address taken, each edge with its count. A routine defined in
another unit is a dashed box, a routine the optimizer inlined everywhere stands alone, a recursive routine
carries an edge back to itself, and a click on a routine draws its control flow.
Show Control Flow draws the routine's control flow graph. Each basic block is a box holding its
instructions, each edge says which way the branch went — taken, falls through, jump table — and the edges
that close a loop are marked as loops. A block's colour is the source line it starts on, and its header names
its lines. A click on an instruction moves the editor to the source line it came from, and a click on the
block's name opens its label in the Spectra listing. An export writes two graphs, the one code generation
consumed and the one static single assignment was built on, and an optimized build numbers their blocks
differently: asked from the Spectra unit, the dominance, the reaching definitions or the SSA form, the drawing
shows the graph before SSA whose blocks those stages name, and from every other stage the graph code generation
consumed. The header says which.
Show the dominator tree, the link in the drawing's header, draws the routine's blocks under their immediate
dominators, each box naming its dominance frontier — where the block's dominance ends, and where static single
assignment places its merges. The tree is drawn over the graph before SSA, the graph the dominance numbers.
Show Placement draws where the routine keeps its values: its activation record as a strip of cells down
from the frame pointer — the static link, the saved registers, the parameter homes and every value the
allocator gave a stack home, each at its offset and the size its type states — and below it a lane for every
register and every stack slot over the routine's instructions, with a bar for each value while it lives
there, grouped under the source line each instruction came from. A click on a bar moves the editor to the
source lines the value lives across; a click on a line's number above the lanes selects that line's
instructions in the out-of-SSA listing.
Profiling
Profile File builds the program with its profiling tables, runs it under valgrind's callgrind, and
writes each source line's instruction count and share beside it, hotter lines in hotter colours. The
program starts as Run File starts it, with the runtime flags, arguments, standard input and folder of
the configuration chosen on its launch card; a configuration with a sanitizer is refused, since
callgrind would count the sanitizer's checks as the program's own instructions. The
Mica Profile view ranks the procedures that carry the instructions. The counts are exact and repeat
on every run, so a change's effect is the difference between two profiles. Profile Compile shows
where the compiler's own time went, phase by phase.
Mica Notebooks
A Mica notebook is a plain markdown file (.mica.md) in which every ```mica fence is a cell holding
one complete program and the ```output fence under it is a recorded fact. The file renders unchanged
on GitLab and the website, and git diffs show edits and nothing else.
- Run a cell and the fresh output lands under it, through the installed compiler's own runner.
- Verify Notebook re-runs every cell and holds the fresh output against the recorded fence: a
success mark for promises kept, a recorded-versus-this-run diff for drift, one summary line for the
document.
Verify proves outputs and never rewrites them.
- Verify Notebooks in Folder, from a folder's context menu in the explorer, sweeps a whole course:
every
.mica.md below the folder, cell by cell, without opening a single editor. The result is one
verdict line, a transcript in the Mica Notebook Verify output, and one problem per cell that broke its
promise — click it and the notebook opens at that fence. Each cell also keeps its run's status line, so
a document opened later already says what the sweep found.
- A loss-column sparkline draws the falling line of a training run directly under the output that
printed it, from the printed digits.
- Every cell stays one whole program. VS Code's own Split Cell cuts a cell at the cursor, which leaves two
halves of a program that cannot compile on their own; Join With Next Cell puts them back together.
The editor
- Semantic highlighting — every identifier colors by what the compiler resolved it to, not by its
spelling.
tracked values render italic and code inside a tape window renders bold, so autograd
code reads quietly different from plain arithmetic.
- Hover states the whole contract: a tensor's type with its shape —
tracked matrix[64, 48] of float64 — and a fallible function's signature with its fails domain. A tensor declared through an
alias carries its shape as a quiet badge at the end of the line.
- Diagnostics appear when a file opens, a moment after you stop typing, saved or not, and on every
save, at the exact positions the compiler reports; go to definition and the document outline
ride the same resolved program.
- Format Document lays the file out in the house style, exactly as
mica --format does: only white
space changes, every line break you wrote stays, and a file whose blocks do not close is left as it
is, with the reason shown.
- Glyph input — type
\alpha for α, \times for ×, \leq for ≤, w_1 for w₁: the formula
names and operators the compiler accepts in source, offered as you type.
- Syntax highlighting for the complete current language, generated from the compiler's own lexical
tables, with
begin/end folding, automatic indentation, and word selection that understands
0x, 0b, and 1_000_000.
What works without what
| Capability |
Needs |
| Syntax highlighting, folding, indentation, glyph input |
nothing — works out of the box |
| Diagnostics, definition, hover, outline, semantic highlighting, formatting |
the Mica compiler on PATH |
| Notebooks: run cells, Verify, sparkline |
the Mica compiler on PATH |
| Run File, Launch Card, Export File and every export viewer, Profile Compile |
the Mica compiler on PATH |
| Debug File, the Mica Runtime view |
the compiler, gdb, and Microsoft's C/C++ extension |
| Profile File |
the compiler and valgrind (sudo apt-get install valgrind) |
The language features are provided by the Mica compiler itself running as a language server, so what the
editor underlines is exactly what the build would report for the text on screen. The compiler is available from
mica-dev.com/learn/install; a different location can be set with
mica.languageServer.path. Without the compiler, the extension stays with highlighting and shows a
single notice.
Extension settings
| Setting |
Default |
Effect |
mica.languageServer.enabled |
true |
Start the language server for diagnostics, definition, hover, outline, and semantic highlighting. |
mica.languageServer.path |
(empty) |
Path to the Mica compiler executable. When empty, mica is resolved from PATH. |
mica.notebook.runTimeoutSeconds |
60 |
Stop a notebook cell's run after this many seconds. |
mica.remarks.visible |
true |
Show the compiler's remarks, which never gate a build. |
mica.debug.taskThreads |
true |
While a debugged program is stopped, show every suspended Mica task as a thread in the Call Stack view, with the stack its scheduler saved. Turn it off to debug through the C/C++ extension's adapter directly. |
Licence
This extension is licensed under the MIT licence. The Mica compiler is a separate product with
its own licence — see mica-dev.com.
| |