lang-bootstrap/05/preprocess.b

76 lines
1.7 KiB
Brainfuck
Raw Normal View History

2022-01-07 23:32:27 -05:00
; returns a string of null character-separated preprocessing tokens
; this corresponds to translation phases 1-3 in the C89 standard
function split_into_preprocessing_tokens
argument filename
local fd
local file_contents
local pptokens
local p
local c
local in
local out
local n
fd = open_r(filename)
file_contents = malloc(2000000)
pptokens = malloc(2000000)
p = file_contents
:pptokens_read_loop
n = syscall(0, fd, p, 4096)
if n == 0 goto pptokens_read_loop_end
p += n
:pptokens_read_loop_end
; okay we read the file. first, delete every backslash-newline sequence (phase 2)
local newlines ; we add more newlines to keep line numbers right
newlines = 1
in = file_contents
out = file_contents
:backslashnewline_loop
c = *1in
if c == 0 goto backslashnewline_loop_end
if c == 10 goto proper_newline_loop
if c != '\ goto not_backslashnewline
p = in + 1
c = *1p
if c != 10 goto not_backslashnewline
in += 2 ; skip backlash and newline
newlines += 1 ; add one additional newline the next time around to compensate
goto backslashnewline_loop
:not_backslashnewline
*1out = *1in
out += 1
in += 1
goto backslashnewline_loop
:proper_newline_loop
if newlines == 0 goto proper_newline_loop_end
; output a newline
*1out = 10
out += 1
newlines -= 1
goto proper_newline_loop
:proper_newline_loop_end
newlines = 1
in += 1
goto backslashnewline_loop
:backslashnewline_loop_end
*1out = 0
in = file_contents
fputs(1, file_contents)
free(file_contents)
close(fd)
return
:unterminated_comment
fputs(2, .str_unterminated_comment)
fputs(2, filename)
fputc(2, 10)
exit(1)
:str_unterminated_comment
string Unterminated comment in file
byte 32
byte 0