75 lines
1.7 KiB
Brainfuck
75 lines
1.7 KiB
Brainfuck
; 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
|