lang-bootstrap/05/main.b

247 lines
4.6 KiB
Brainfuck
Raw Normal View History

2022-01-07 23:32:27 -05:00
; add 24 + 16 = 40 to the stack pointer to put argc, argv in the right place
byte 0x48
byte 0x81
byte 0xc4
byte 40
byte 0
byte 0
byte 0
goto main
global output_fd
2022-01-08 14:37:39 -05:00
global object_macros_size
global function_macros_size
; these are allocated in main()
global object_macros
global function_macros
2022-01-11 00:09:11 -05:00
; accepts EITHER file index OR pointer to filename
function fprint_filename
argument fd
argument file
if file ] 65535 goto print_filename_string
file = file_get(file)
; (fallthrough)
:print_filename_string
fputs(2, file)
return
; accepts EITHER file index OR pointer to filename
2022-01-08 12:15:17 -05:00
function compile_error
argument file
argument line
argument message
2022-01-11 00:09:11 -05:00
fprint_filename(2, file)
2022-01-08 12:15:17 -05:00
fputc(2, ':)
fputn(2, line)
2022-01-08 14:37:39 -05:00
fputs(2, .str_error_prefix)
2022-01-08 12:15:17 -05:00
fputs(2, message)
fputc(2, 10)
exit(1)
2022-01-09 22:33:33 -05:00
2022-01-11 00:09:11 -05:00
; accepts EITHER file index OR pointer to filename
2022-01-09 22:33:33 -05:00
function compile_warning
argument file
argument line
argument message
2022-01-11 00:09:11 -05:00
fprint_filename(2, file)
2022-01-09 22:33:33 -05:00
fputc(2, ':)
fputn(2, line)
fputs(2, .str_warning_prefix)
fputs(2, message)
fputc(2, 10)
return
2022-01-08 12:15:17 -05:00
2022-01-08 14:37:39 -05:00
:str_error_prefix
2022-01-08 12:15:17 -05:00
string : Error:
byte 32
byte 0
2022-01-09 22:33:33 -05:00
:str_warning_prefix
string : Warning:
byte 32
byte 0
2022-01-11 17:36:33 -05:00
; powers of 10, stored in the following format:
; ulong significand
; ulong exponent
; where for i = -1023..1023, powers_of_10 + 16*i points to an entry where
; (significand / 2^58) * 2^exponent
global powers_of_10
2022-01-07 23:32:27 -05:00
#include util.b
#include constants.b
#include preprocess.b
2022-01-11 00:09:11 -05:00
#include tokenize.b
2022-01-07 23:32:27 -05:00
function main
argument argv2
argument argv1
argument argv0
argument argc
local input_filename
local output_filename
2022-01-08 12:15:17 -05:00
local pptokens
2022-01-10 15:12:24 -05:00
local processed_pptokens
2022-01-11 00:09:11 -05:00
local tokens
2022-01-07 23:32:27 -05:00
2022-01-11 17:36:33 -05:00
fill_in_powers_of_10()
print_powers_of_10()
2022-01-09 12:31:35 -05:00
dat_banned_objmacros = 255
dat_banned_fmacros = 255
2022-01-09 00:08:29 -05:00
2022-01-11 00:09:11 -05:00
file_list = malloc(40000)
*1file_list = 255
2022-01-08 14:37:39 -05:00
object_macros = malloc(4000000)
function_macros = malloc(4000000)
2022-01-07 23:32:27 -05:00
input_filename = .str_default_input_filename
output_filename = .str_default_output_filename
if argc == 1 goto have_filenames
if argc != 3 goto usage_error
input_filename = argv1
output_filename = argv2
:have_filenames
2022-01-08 12:15:17 -05:00
pptokens = split_into_preprocessing_tokens(input_filename)
2022-01-11 00:09:11 -05:00
;print_pptokens(pptokens)
;print_separator()
2022-01-10 15:12:24 -05:00
processed_pptokens = malloc(16000000)
translation_phase_4(input_filename, pptokens, processed_pptokens)
free(pptokens)
pptokens = processed_pptokens
2022-01-09 00:08:29 -05:00
print_pptokens(pptokens)
2022-01-11 00:09:11 -05:00
print_separator()
;print_object_macros()
;print_function_macros()
output_fd = open_w(output_filename)
rodata_end_offset = RODATA_OFFSET
2022-01-11 00:09:11 -05:00
tokens = malloc(16000000)
tokenize(pptokens, tokens)
print_tokens(tokens)
; NOTE: do NOT free pptokens as identifiers still reference them.
2022-01-07 23:32:27 -05:00
exit(0)
:usage_error
fputs(2, .str_usage_error)
exit(1)
:str_usage_error
string Please either specify no arguments or an input and output file.
:str_default_input_filename
string main.c
byte 0
:str_default_output_filename
string a.out
byte 0
2022-01-11 17:36:33 -05:00
function normalize_float
argument p_significand
argument p_exponent
local significand
local exponent
significand = *8p_significand
exponent = *8p_exponent
:float_reduce_loop
if significand [ 0x400000000000000 goto float_reduce_loop_end
significand >= 1
exponent += 1
goto float_reduce_loop
:float_reduce_loop_end
:float_increase_loop
if significand ]= 0x200000000000000 goto float_increase_loop_end
significand <= 1
exponent -= 1
goto float_increase_loop
:float_increase_loop_end
*8p_significand = significand
*8p_exponent = exponent
return
function fill_in_powers_of_10
local i
local p
local significand
local exponent
powers_of_10 = malloc(40000)
powers_of_10 += 20000
significand = 1 < 57
exponent = 1
i = 0
:pow10_loop_positive
p = powers_of_10
p += i < 4
*8p = significand
p += 8
*8p = exponent
significand *= 10
normalize_float(&significand, &exponent)
i += 1
if i < 1024 goto pow10_loop_positive
significand = 1 < 57
exponent = 1
i = 0
:pow10_loop_negative
p = powers_of_10
p += i < 4
*8p = significand
p += 8
*8p = exponent
significand *= 32
exponent -= 5
significand /= 10
normalize_float(&significand, &exponent)
i -= 1
if i > -1024 goto pow10_loop_negative
return
function print_powers_of_10
local i
local j
local b
local p
local significand
i = -325
:print_powers_of_10_loop
putc(49)
putc(48)
putc('^)
putn_signed(i)
putc(61)
p = powers_of_10
p += i < 4
significand = *8p
putc('.)
j = 57
:pow10_binary_loop
b = significand > j
b &= 1
b += '0
putc(b)
j -= 1
if j >= 0 goto pow10_binary_loop
putc('*)
putc('2)
putc('^)
p += 8
putn_signed(*8p)
putc(10)
i += 1
if i < 325 goto print_powers_of_10_loop
return