fuzzy's compiler is written in assembly now :)
This commit is contained in:
parent
2d4df76be7
commit
c0e7f4024c
24
README.md
24
README.md
|
@ -16,16 +16,26 @@ fuzzy is part of george, and shouldn't run anywhere else.
|
|||
|
||||
#### low-level
|
||||
|
||||
(most of) fuzzy could be made with assembler macros, but that's no fun
|
||||
(most of) fuzzy could be written as assembler macros, but that's no fun
|
||||
|
||||
#### reliable
|
||||
|
||||
if fuzzy says it can run, george can run it
|
||||
|
||||
## feature progress
|
||||
## how to work on fuzzy
|
||||
|
||||
- [x] parser
|
||||
- roughly complete, but want to finish the whole pipeline before adding things to the parser
|
||||
- [x] typechecker
|
||||
- generates a "type stack" from parsed input and checks that word definition types match their body
|
||||
- [ ] code generation
|
||||
edit `program.asm` and run `./run.sh`. the program gets included in the fuzzy compiler `fuzzy.asm` and is assembled with `vasm6502_oldstyle`, then george runs the program, reading out her system image when she reaches `stp` or `brk`
|
||||
|
||||
then the program she compiled gets formatted as a standard 32k rom, and she reads it again, and then shows her system image again when the program finishes (hits `stp` or `brk`).
|
||||
|
||||
since fuzzy works on a zero-page data stack, it's pretty easy to read the results of a program from the hexdump.
|
||||
|
||||
for now this loop only works on apple silicon, but eventually i'll compile a `george` binary for x86 linux and switch based on the host platform.
|
||||
|
||||
## reference help
|
||||
|
||||
i wrote [syntax](./syntax.md) and [semantics](./semantics.md) docs to keep track of how fuzzy works before starting work on the compiler implementation in assembly. they're the _official_ source of truth for how fuzzy works. assume that the compiler implementation is always in flux :)
|
||||
|
||||
## a note on implementation
|
||||
|
||||
i was writing fuzzy's compiler in rust for a sec, but then i realized that it would be a fun challenge to write it in assembly. it's been wayyy easier! and fun! and so rewarding :) this feels like a flex but i'm genuinely just so happy to see george & fuzzy playing together in this little computer world i've made <3
|
||||
|
|
46
fuzzy.asm
46
fuzzy.asm
|
@ -12,7 +12,7 @@ binary_subroutine_address = binary_base_index + 1 ; pointer to a subroutine to b
|
|||
.include "./subroutines.inc"
|
||||
|
||||
program_text:
|
||||
.asciiz '2 3 +'
|
||||
.include "./program.inc"
|
||||
|
||||
reset:
|
||||
sei
|
||||
|
@ -74,6 +74,9 @@ compile_values_op:
|
|||
; cmp #"#"
|
||||
|
||||
; a holds character value, y program text index, only iny if you find a matching character & consume it
|
||||
; TODO:
|
||||
; 1-3 digit decimal values
|
||||
; 1-2 digit hex values
|
||||
compile_values_nat:
|
||||
; TODO:
|
||||
; cmp #"$" ; is hex?
|
||||
|
@ -84,14 +87,20 @@ compile_values_nat:
|
|||
bcc .not_nat
|
||||
cmp #57 ; greater than end of 0-9 georgescii range?
|
||||
bcs .not_nat
|
||||
pha
|
||||
lda #$a9 ; $a9: lda imm
|
||||
jsr store_binary
|
||||
pla
|
||||
jsr georgescii_decimal_to_value
|
||||
jsr store_binary
|
||||
lda #2 ; push
|
||||
jsr store_subroutine
|
||||
iny
|
||||
rts
|
||||
.not_nat:
|
||||
rts
|
||||
|
||||
; georgescii decmal value in a register, return equivalent plain value in a register
|
||||
; georgescii decimal value in a register, return equivalent plain value in a register
|
||||
georgescii_decimal_to_value:
|
||||
clc
|
||||
sbc #$30 ; decimal digits start at georgescii $30
|
||||
|
@ -113,11 +122,9 @@ store_binary:
|
|||
; the first byte at the subroutine's address is its length
|
||||
store_contiguous_binary:
|
||||
pha ; just to be safe
|
||||
phy
|
||||
phx
|
||||
lda (binary_subroutine_address) ; get the subroutine length
|
||||
tax ; loop counter
|
||||
ldy #0 ; index into subroutine
|
||||
ldy #1 ; index into subroutine, offset by one to skip subroutine length
|
||||
.loop:
|
||||
lda (binary_subroutine_address), y
|
||||
jsr store_binary
|
||||
|
@ -125,8 +132,6 @@ store_contiguous_binary:
|
|||
dex
|
||||
bne .loop
|
||||
.end:
|
||||
phx
|
||||
ply
|
||||
pla
|
||||
rts
|
||||
|
||||
|
@ -136,6 +141,7 @@ store_contiguous_binary:
|
|||
; for now, pass the index of the subroutine (in subroutines.asm)
|
||||
; to a and it will get written to binary_subroutine_address
|
||||
get_subroutine_address:
|
||||
pha
|
||||
tax ; set up counter
|
||||
bne .loop ; first subrotine?
|
||||
stz binary_subroutine_address ; yes, store its address
|
||||
|
@ -155,16 +161,42 @@ get_subroutine_address:
|
|||
.no_carry:
|
||||
dex ; is this our address?
|
||||
bne .loop ; yes, we're done
|
||||
pla
|
||||
rts
|
||||
|
||||
|
||||
; pass subroutine index to a and it will get written into the binary
|
||||
; TODO: stabilize subroutine location & just write a `jsr $subroutine` to the binary
|
||||
store_subroutine:
|
||||
pha
|
||||
phy
|
||||
phx
|
||||
jsr get_subroutine_address
|
||||
jsr store_contiguous_binary
|
||||
; reset subroutine address
|
||||
stz binary_subroutine_address
|
||||
lda #$80
|
||||
sta binary_subroutine_address + 1
|
||||
plx
|
||||
ply
|
||||
pla
|
||||
rts
|
||||
|
||||
; write error message and stop execution
|
||||
error:
|
||||
ldy #0
|
||||
.loop:
|
||||
lda .message, y
|
||||
sta $4000, y
|
||||
beq .end
|
||||
iny
|
||||
bra .loop
|
||||
.end:
|
||||
stp
|
||||
.message:
|
||||
.asciiz "ruh roh! fuzzy couldn't compile"
|
||||
|
||||
|
||||
|
||||
isr: ; interrupt service routine
|
||||
pha
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
.asciiz '2 3 +'
|
13
run.sh
13
run.sh
|
@ -2,6 +2,15 @@
|
|||
|
||||
set -e
|
||||
|
||||
vasm6502_oldstyle fuzzy.asm -dotdir -wdc02 -ldots -Fbin -o fuzzy.rom;
|
||||
cat fuzzy.rom | ./george > result.bin;
|
||||
rm *.bin *.rom
|
||||
vasm6502_oldstyle fuzzy.asm -dotdir -wdc02 -ldots -Fbin -o fuzzy.rom &> /dev/null;
|
||||
echo -e "\nʕ·ᴥ·ʔ- source text:\n";
|
||||
cat program.inc;
|
||||
cat fuzzy.rom | ./george > compiled.bin;
|
||||
dd skip=16384 count=500 if=compiled.bin of=compiled.rom bs=1 &> /dev/null;
|
||||
truncate -s 32k compiled.rom &> /dev/null;
|
||||
printf '\x80\x00\x00' | dd of=compiled.rom bs=1 seek=32765 count=3 conv=notrunc &> /dev/null;
|
||||
cat compiled.rom | ./george > result.bin;
|
||||
echo -e "\n\nʕ·ᴥ·ʔ- compiled program result:\n";
|
||||
hexdump -C ./result.bin;
|
||||
echo -e "";
|
||||
|
|
|
@ -4,4 +4,12 @@ test_contiguous_binary:
|
|||
|
||||
; 1 - assembled from "plus.asm"
|
||||
subroutine_plus:
|
||||
.byte 17,$b5,$18,$75,$00,$95,$02,$b5,$02,$75,$01,$95,$03,$e8,$03,$60,$e8,$60
|
||||
.byte 15, $18,$b5,$00,$75,$02,$95, $02, $b5, $01, $75, $03, $95, $03, $ca, $ca
|
||||
|
||||
; 2
|
||||
subroutine_push:
|
||||
.byte 6,$ca,$ca,$95,$0,$74,$1
|
||||
; dex
|
||||
; dex
|
||||
; sta 0, x
|
||||
; stz 1, x
|
||||
|
|
Loading…
Reference in New Issue