| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Streamline the factorial function; we don't need to save a stack variable
into a register before operating on it. All instructions can take a stack
variable directly.
In the process we found two bugs:
a) Opcode f7 was not implemented correctly. It was internally consistent
but I'd never validated it against a natively running program. Turns out
it encodes multiple instructions, not just 'not'.
b) The way we look up imm32 operands was sometimes reading them before
disp8/disp32 operands.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I'd been planning to add segment address computation after all labels were
computed, including labels in the data segment (which isn't built yet).
But now I realize that won't work, because labels in the data segment will
require segment start addresses. We need to deal in absolute addresses
rather than relative offsets as with the jump instructions that use code
labels.
Layer 34 is now broken by this change in a way that isn't obvious right
now: it is oblivious to imm32 and disp32 operand tags that are now going
to be present in the programs it sees. It's a lucky accident that everything
still works, because we're only using segment names right now for the very
first (code) segment in a program.
|
| |
|
|
|
|
| |
Make segment names a separate transform.
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Turns out I had totally the wrong idea. The stack at the start of the program
doesn't contain 2 words, one for argc and a second for argv that must then
be dereferenced to get to its contents (each a pointer to a string). It
contains a word for argc, one for argv[0], another for argv[1], and so
on.
Many thanks to Jeremiah Orians and the #bootstrappable channel on freenode
for showing me https://github.com/oriansj/mescc-tools/blob/master/test/test5/exec_enable_amd64.M1
which set me straight. I could just pop the args like that example does,
but it seems slightly more elegant, given the current calling convention,
to assume the imaginary caller handles the popping.
|
|
|
|
|
|
|
|
|
|
|
| |
The new example ex9 doesn't yet work natively.
In the process I've emulated the kernel's role in providing args, implemented
a couple of instructions acting on 8-bit operands (useful for ASCII string
operations), and begun the start of the standard library (ascii_length
is the same as strlen).
At the level of SubX we're just only going to support ASCII.
|
|
|
|
|
| |
New levels should be added at the top of list of transforms rather than
bottom. See layer 29.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I'm going to continue using them for now, but I'm fairly certain now
that they're just a temporary device to help rapidly-prototype ideas.
The reason: there's just too many ways to abuse low-level features, and
it ends up taking too much code to disallow things soon after you allow
them.
New plan: stop trying to write checks, just treat them as temporary
conventions for now. Goal is now to just get the core sequence of passes
nailed down. Then we'll start reimplementing them from the ground up.
First implication of this new plan: ripping out most existing checks.
I'm still going to eventually build type checks. But no degenerate
checks for code just being too low-level.
(This decision is the outcome of a few days of noodling over Forth and
https://mastodon.social/@akkartik/100549913519614800.)
|
|
|
|
| |
Don't use trace infrastructure if you're just going to immediately exit.
|
| |
|
| |
|
|
|
|
| |
Support both signed and unsigned numbers when parsing strings.
|
|
|
|
|
| |
We want to always print numbers in hex. This should make that a little
more comprehensive.
|
| |
|
|
|
|
| |
Fix CI.
|
|
|
|
|
|
|
|
| |
I'd been planning next to automatically namespace jump targets in
different functions. But just a check for duplicate labels should
suffice, and managing unique names isn't a huge burden. I'm wary of
growing the translator too much. All this will eventually need to be
self-hosted in SubX.
|
| |
|
|
|
|
|
|
|
|
|
| |
Targets you can jump to and ones you can call are conceptually disjoint
sets.
I'm highlighting these in Vim, but it's a pretty complex pattern.
Arguably errors shouldn't be highlighted. Only warnings that are easy to
be accidentally deployed.
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
| |
Side effect: better error messages when the tangler does something
unexpected.
|
| |
|
|
|
|
|
| |
As we climb the ladder of abstraction we'll gradually pull the ladder up
behind ourselves.
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
| |
More tweaks for check passes. Ensure they're never first-class
transforms.
|
| |
|
| |
|
| |
|
|
|
|
|
| |
It would be confusing to use negative numbers in raw hex. But we'll rely
on programmer taste there.
|
|
|
|
|
|
| |
Hacky test. I'm creating a helper to run tests just for this layer. But
I won't be able to do this when I want to selectively run just
transforms below some level.
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
| |
The current approach to warnings is workable. We'll just never print
warnings to the screen in tests. In tests you can do whatever you want.
This is simpler than messing with levels of warnings.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Draft attempt at cleaning up warnings, but this isn't quite right.
We still emit warnings for every level-1 scenario, and hiding for each
of them seems painful.
Even if we do that, level-2 scenarios would want to hide level-3 and
over warnings, but *not* level-1 warnings. So we need a cardinal number
rather than booleans.
|