The Algol language was extended into AED [citation needed] The first BCPL compiler was written in AED Ken Thomson used a BCPL compiler to write the B compiler. He then used the B language to re-implement the B compiler. The bootstrapped B compiler was gradually transformed into New B, then later C.
Sources:
- AED is based on Algol 60: http://dspace.mit.edu/bitstream/handle/1721.1/755/FR-0351-19563962.pdf?sequence=1 ; http://foldoc.org/Automated%20Engineering%20Design
- AED -> BCPL: https://www.quora.com/C-programs-are-compiled-using-gcc-which-itself-is-written-in-C-so-how-code-for-gcc-is-compiled
- BCPL -> C: https://www.bell-labs.com/usr/dmr/www/chist.html
- write elf body compiler in elf
- write basic assembler in elf body
- gradually replace elf body with assembly
- evolve into stack language
Stack language notes:
- I could have a
load
command that pops an address off the top of the stack and push the corresponding value in memory. Same applies tostore
, but with two items off the top of the stack (the address needs to be at very top with value below) - needs global variables??
; - or, do a
pop memory
command with apop address
command - needs
push global {n}
andpop global {n}
High-level implementation notes:
- needed stacks:
- loop end labels (for break statements)
- between each pass, we need to de-fragment memory
- discard input
- shift output
- reset input length indicator
- needs memory access via
base[offset]
which can be read or written to
High-level implementation passes:
- remove comments
- rename params
- rename local vars, restart counter at end of each function
High-level function
Initial high-level language limitations:
- no variable name shadowing
- assumption that user identifiers won't collide with generated identifiers (maybe?)
fn compile a b {
}
; fn multiply a b {
func multiply 2 ; (2 is the number of locals (just count number of `var`s))
; var out = 0;
push constant 0
pop local 0
; var count = b;
push param 1
pop local 1
; while {
label whileStart
; out = out + a;
push local 0
push param 0
add?
pop local 0
; count = count - 1;
push local 1
push constant 1
sub?
pop local 1
; if count < 0 {
push local 1
push constant 0
lt?
not?
if-goto ifEnd
; break
goto whileEnd
; }
label ifEnd
; }
label whileEnd
; return out
; }
0[]