fuzzy's compiler is written in assembly now :)

This commit is contained in:
august kline 2024-10-07 01:43:30 -04:00
parent 2d4df76be7
commit c0e7f4024c
6 changed files with 77 additions and 17 deletions

View File

@ -16,16 +16,26 @@ fuzzy is part of george, and shouldn't run anywhere else.
#### low-level #### 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 #### reliable
if fuzzy says it can run, george can run it if fuzzy says it can run, george can run it
## feature progress ## how to work on fuzzy
- [x] parser 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`
- roughly complete, but want to finish the whole pipeline before adding things to the parser
- [x] typechecker 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`).
- generates a "type stack" from parsed input and checks that word definition types match their body
- [ ] code generation 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

View File

@ -12,7 +12,7 @@ binary_subroutine_address = binary_base_index + 1 ; pointer to a subroutine to b
.include "./subroutines.inc" .include "./subroutines.inc"
program_text: program_text:
.asciiz '2 3 +' .include "./program.inc"
reset: reset:
sei sei
@ -74,6 +74,9 @@ compile_values_op:
; cmp #"#" ; cmp #"#"
; a holds character value, y program text index, only iny if you find a matching character & consume it ; 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: compile_values_nat:
; TODO: ; TODO:
; cmp #"$" ; is hex? ; cmp #"$" ; is hex?
@ -84,14 +87,20 @@ compile_values_nat:
bcc .not_nat bcc .not_nat
cmp #57 ; greater than end of 0-9 georgescii range? cmp #57 ; greater than end of 0-9 georgescii range?
bcs .not_nat bcs .not_nat
pha
lda #$a9 ; $a9: lda imm
jsr store_binary
pla
jsr georgescii_decimal_to_value jsr georgescii_decimal_to_value
jsr store_binary jsr store_binary
lda #2 ; push
jsr store_subroutine
iny iny
rts rts
.not_nat: .not_nat:
rts 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: georgescii_decimal_to_value:
clc clc
sbc #$30 ; decimal digits start at georgescii $30 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 ; the first byte at the subroutine's address is its length
store_contiguous_binary: store_contiguous_binary:
pha ; just to be safe pha ; just to be safe
phy
phx
lda (binary_subroutine_address) ; get the subroutine length lda (binary_subroutine_address) ; get the subroutine length
tax ; loop counter tax ; loop counter
ldy #0 ; index into subroutine ldy #1 ; index into subroutine, offset by one to skip subroutine length
.loop: .loop:
lda (binary_subroutine_address), y lda (binary_subroutine_address), y
jsr store_binary jsr store_binary
@ -125,8 +132,6 @@ store_contiguous_binary:
dex dex
bne .loop bne .loop
.end: .end:
phx
ply
pla pla
rts rts
@ -136,6 +141,7 @@ store_contiguous_binary:
; for now, pass the index of the subroutine (in subroutines.asm) ; for now, pass the index of the subroutine (in subroutines.asm)
; to a and it will get written to binary_subroutine_address ; to a and it will get written to binary_subroutine_address
get_subroutine_address: get_subroutine_address:
pha
tax ; set up counter tax ; set up counter
bne .loop ; first subrotine? bne .loop ; first subrotine?
stz binary_subroutine_address ; yes, store its address stz binary_subroutine_address ; yes, store its address
@ -155,16 +161,42 @@ get_subroutine_address:
.no_carry: .no_carry:
dex ; is this our address? dex ; is this our address?
bne .loop ; yes, we're done bne .loop ; yes, we're done
pla
rts rts
; pass subroutine index to a and it will get written into the binary ; 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 ; TODO: stabilize subroutine location & just write a `jsr $subroutine` to the binary
store_subroutine: store_subroutine:
pha
phy
phx
jsr get_subroutine_address jsr get_subroutine_address
jsr store_contiguous_binary jsr store_contiguous_binary
; reset subroutine address
stz binary_subroutine_address
lda #$80
sta binary_subroutine_address + 1
plx
ply
pla
rts 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 isr: ; interrupt service routine
pha pha

BIN
george

Binary file not shown.

1
program.inc Normal file
View File

@ -0,0 +1 @@
.asciiz '2 3 +'

13
run.sh
View File

@ -2,6 +2,15 @@
set -e set -e
vasm6502_oldstyle fuzzy.asm -dotdir -wdc02 -ldots -Fbin -o fuzzy.rom; rm *.bin *.rom
cat fuzzy.rom | ./george > result.bin; 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; hexdump -C ./result.bin;
echo -e "";

View File

@ -4,4 +4,12 @@ test_contiguous_binary:
; 1 - assembled from "plus.asm" ; 1 - assembled from "plus.asm"
subroutine_plus: 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