4 ms·
...one of the items on my Very Long List Of Potential Projects is a self-hosted compiler for a proper modern type-safe C-like language for the 6502. I was plann
by david-given 9y ago
...one of the items on my Very Long List Of Potential Projects is a self-hosted compiler for a proper modern type-safe C-like language for the 6502. I was planning to target the BBC Micro, as it's the only 6502 8-bit I've found with a real operating system, but it ought to be easy to port.
Making it self-hosting means lots of interesting design choices: I was planning that it'd be a multipass streaming design, where each stage would consume tokens from the previous stage and write out tokens for the next stage, keeping in-memory as little state as possible; depending how much RAM you had you could pipeline stages together for faster compilation, provided you were willing to have less memory available for symbol information.
One other interesting feature is that a lot of these early processors don't really do stack-relative addressing, so stack-frame-based languages like C and Pascal generally work really badly. (The Z80 failed at this, too.) The solution here is easy: forbid recursion. Now there are no stack frames! So each variable is effectively static. This simplifies the design no end, as well as playing to the processors' strengths in being basically memory-memory architectures.
Deciding what variables to put where becomes an easy and effective exercise in optimisation. On the 6502, placing frequently-accessed variables in zero page makes the code smaller and faster. Walking the call tree and figuring out which variables are never used at the same time allows variable storage to overlap. And since calling a function involves copying values directly from the caller into the function's parameters, which are just static variables like everything else, then if you can find places where the value lives at the same address in both the caller and the function, then you can skip the copy entirely...
Ah, well. Maybe one day.
- sehugg 9y agoYou'd probably want to disallow/discourage structs as well, favoring striped arrays, because the $aaaa,x addressing mode is a lot more efficient than doing pointer arithmetic in zero-page. (Would be cool if the compiler could figure this out, too...)
- david-given 9y agoI probably wouldn't want to do automatic striping of arrays of structures, because it'd only make sense in some circumstances, but it'd be trivial to add logic to the code generator to use indexed addressing modes --- you'd need to check to see if the thing being indexed was an array with bounds small enough to be indexed with an 8-bit variable. <thinking out loud follows> ...that would produce something like: lda index rol a # scale for 16-bit values tax lda address+0, x # read low byte ldy address+1, x # read high byte == 11 bytes (assuming index and address weren't in zero page). But of course if I were reading a 16-bit value, I'd probably be wanting to dereference it as a pointer or do arithmetic on it, so I wouldn't want to read it into registers all at once --- the 6502 likes streaming maths through the accumulator a byte at a time. Something like 'result = array1[index] + array2[index]' would end up: lda index rol a tax clc lda array1+0, x adc array2+0, x sta result+0 lda array1+1, x adc array2+1, x sta result+1 == 24 bytes! (When I was about 10, the 6502's lack of 16-bit arithmetic made me very sad. It still does, but it did then, too.)
- spc476 9y agoYou could always incorporate SWEET16 (https://en.wikipedia.org/wiki/SWEET16 https://en.wikipedia.org/wiki/SWEET16) to support 16 bit math.
- unwiredben 9y agoThis sounds a lot like the language Action! (https://sourceforge.net/projects/atari-action/ https://sourceforge.net/projects/atari-action/) which was popular on the Atari 8-bit systems. Very C and Pascal-like, but with tweaks to make it work better on the 6502.