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