What Parasol targets
Asked on 2026-08-31, while 0.1.0 was the whole of the project:
Will this language also work to create native machine code? As an example, if I wanted to make a BASIC compiler that compiled not to Solveig but to Mac Silicon binary? I’m not sure which sequence it would be, would it be a compiler I run in Parasol (
parasol cbasic.psol myprogram.bas -> a.out) or would I create a compiler (solvm cbasic.sob myprogram.bas -> a.out)?
Two questions are tangled in that, and separating them is most of the answer.
Parasol does not run programs
bin/parasol is a translator. A .psol goes in and Solveig source comes out,
and that is all it does — so parasol cbasic.psol myprogram.bas is not a
sequence that could exist. cbasic.psol is not a compiler Parasol runs. It is
source that becomes a compiler.
The second sequence is the right one, with one step in front of it:
parasol cbasic.psol -o cbasic.sol # Parasol -> Solveig source
solas cbasic.sol -o cbasic.sob # Solveig -> bytecode
solvm cbasic.sob myprogram.bas # run the BASIC compiler
What cbasic writes is cbasic’s business. Text, a .sob, ARM64, a .d64
image. Solveig has system:arguments, system:readFile, system:writeFile and
shell:run, which is everything a compiler needs from its host, so this works
today with nothing added to anything.
And it needs nothing from Parasol at all. Parasol is only the language the compiler was written in.
So there are two senses of “target”, and only one is a Parasol question
| What Parasol’s own back end emits | Solveig source. A Parasol question, answered in the README under What Parasol is allowed to know about Solveig. |
| What a program written in Parasol emits | Whatever that program writes. Not a Parasol question, any more than what a C program writes is a question about C. |
The BASIC compiler is the second. It is a program, and Parasol’s involvement ends when the program is compiled.
Could Parasol itself emit machine code?
Architecturally yes, and cleanly. The front end knows nothing about Solveig.
The lexer, the dialect table, the tree, the spans and the map are all substrate
-agnostic; parasol/src/emit.c is the only file that has ever heard of Solveig.
Replacing it is a seam rather than a rewrite.
It is still not planned, and for the reason ROADMAP.md gives against the
smaller version of it. Emitting .sob and bypassing Solas would mean owning
the instruction set and the file format and reimplementing what Solas does well.
Emitting machine code means owning register allocation, the AAPCS64 calling
convention, stack frames, relocations and Mach-O — none of which says anything
about whether a grammar declared per module is a good idea, which is the only
thing this project exists to find out.
does-it-pay.md is what seven programs and four readers who had
never seen the language have said about it so far — and the sixth program is a
BASIC interpreter, which is the half of this page’s own question that had no
program behind it until 2026-09-02.
On Apple Silicon the surprise is not the instruction encoding. It is that a
hand-written Mach-O arm64 executable is killed by the kernel until it is at
least ad-hoc signed — codesign -s -. ld does that quietly on every link,
which is why nobody meets the rule until they stop using ld.
Which points at the cheap path, and the one to take:
Emit ARM64 assembly text and let
ccassemble and link it.
Mach-O, relocations and signing all become somebody else’s problem, and the output is something a person can read.
parasol cbasic.psol -o cbasic.sol && solas cbasic.sol -o cbasic.sob
solvm cbasic.sob myprogram.bas > myprogram.s
cc myprogram.s -o a.out
Every step of that works now, and since 2026-09-14 the first line is also
parasol --sob cbasic.psol, which runs the same solas rather than replacing
it. That is the whole of what Parasol does about bytecode, and the reason it
is no more is the paragraph above.
Where this grows, if it grows
This page used to argue that @language was where it grows — that the
natural move was for it to choose the reader and the emitter, so that a back
end became a declared thing the way the grammar already is, and “Parasol targets
ARM64” was a line in a file rather than a fork of the project.
That sentence names the right feature and the wrong directive, which is why
@language was removed in 0.10.0 rather than grown into it. Read
@language <name>. at the top of a file and it says the body below is
written in <name> — and that is false in every file with a header, because a module that
declares + and while is exactly not Solveig any more. The only reading under
which it was true, the substrate is Solveig, is the same for every .psol
there will ever be and is already carried by the extension.
The thing that could differ between two files is the output. So the sentence
above already spells its own directive: @target arm64., naming the back end,
which is a thing a file could sensibly disagree with another file about. If a
second emitter is ever built, that is what gets added, and it will name what it
selects from the first commit instead of inheriting a word that misleads.
Selecting a reader is a separate and much larger question, and it keeps the
seam it always had: something read before the first statement would have to name
it. parasol/include/parasol/lex.h says so in a sentence now, instead of a
directive standing empty in every file. See COMPLETED.md 14.
Why a code generator is the right first real program
A BASIC compiler written in Parasol is a better test of the whole idea than another arithmetic example, and it is the one worth doing next.
A code generator is exactly the kind of program that wants a declared notation — instruction patterns, addressing modes, a peephole table. If declaring a grammar per module does not help there, that is worth knowing early, and it is not a thing a small example can tell you.