diff options
author | pommicket <pommicket@gmail.com> | 2022-01-07 23:32:27 -0500 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2022-01-07 23:32:27 -0500 |
commit | 5d6b490cce1a99a2541d1fcee101df4331d4d86a (patch) | |
tree | 902295cbd43a7a32e179412d98f75dd2705fd6db /05/preprocess.b | |
parent | 262824b21491446bb20acba8be1054207b5f50f0 (diff) |
start C compiler
Diffstat (limited to '05/preprocess.b')
-rw-r--r-- | 05/preprocess.b | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/05/preprocess.b b/05/preprocess.b new file mode 100644 index 0000000..36fcbd2 --- /dev/null +++ b/05/preprocess.b @@ -0,0 +1,75 @@ +; 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 |