2022-01-11 00:09:11 -05:00
|
|
|
global file_list ; initialized in main -- null-separated 255-terminated array of strings
|
|
|
|
|
|
|
|
; get the name of the file with the given index
|
|
|
|
function file_get
|
|
|
|
argument idx
|
|
|
|
local p
|
|
|
|
p = file_list
|
|
|
|
:file_get_loop
|
|
|
|
if idx == 0 goto file_got
|
|
|
|
if *1p == 255 goto file_uhoh
|
|
|
|
idx -= 1
|
|
|
|
p = memchr(p, 0)
|
|
|
|
p += 1
|
|
|
|
goto file_get_loop
|
|
|
|
:file_got
|
|
|
|
return p
|
|
|
|
:file_uhoh
|
|
|
|
fputs(2, .str_bad_file_index)
|
|
|
|
exit(1)
|
|
|
|
:str_bad_file_index
|
|
|
|
string Bad file index. This shouldn't happen.
|
|
|
|
byte 10
|
|
|
|
byte 0
|
|
|
|
|
|
|
|
; get the index of the given file, returns -1 if file does not exist
|
|
|
|
function file_get_index
|
|
|
|
argument filename
|
|
|
|
local p
|
|
|
|
local b
|
|
|
|
local i
|
|
|
|
p = file_list
|
|
|
|
i = 0
|
|
|
|
:file_get_index_loop
|
|
|
|
if *1p == 255 goto return_minus1
|
|
|
|
b = str_equals(p, filename)
|
|
|
|
if b != 0 goto file_found
|
|
|
|
i += 1
|
|
|
|
p = memchr(p, 0)
|
|
|
|
p += 1
|
|
|
|
goto file_get_index_loop
|
|
|
|
:file_found
|
|
|
|
return i
|
|
|
|
|
|
|
|
; add to list of files if not already there
|
|
|
|
function file_add
|
|
|
|
argument filename
|
|
|
|
local p
|
|
|
|
p = file_get_index(filename)
|
|
|
|
if p != -1 goto return_0
|
|
|
|
p = memchr(file_list, 255)
|
|
|
|
p = strcpy(p, filename)
|
|
|
|
p += 1
|
|
|
|
*1p = 255
|
|
|
|
return
|
|
|
|
|
2022-01-11 11:53:36 -05:00
|
|
|
; return keyword ID associated with str, or 0 if it's not a keyword
|
|
|
|
function get_keyword_id
|
|
|
|
argument keyword_str
|
|
|
|
local p
|
|
|
|
local c
|
|
|
|
local b
|
|
|
|
p = .keyword_table
|
|
|
|
:keyword_id_loop
|
|
|
|
c = *1p
|
|
|
|
if c == 255 goto no_such_keyword_str
|
|
|
|
p += 1
|
|
|
|
b = str_equals(keyword_str, p)
|
|
|
|
if b != 0 goto got_keyword_id
|
|
|
|
p = memchr(p, 0)
|
|
|
|
p += 1
|
|
|
|
goto keyword_id_loop
|
|
|
|
:no_such_keyword_str
|
|
|
|
return 0
|
|
|
|
:got_keyword_id
|
|
|
|
return c
|
|
|
|
|
|
|
|
; get string associated with keyword id, or "@BAD_KEYWORD_ID" if it's not a keyword
|
|
|
|
function get_keyword_str
|
|
|
|
argument keyword_id
|
|
|
|
local p
|
|
|
|
local c
|
|
|
|
local b
|
|
|
|
p = .keyword_table
|
|
|
|
:keyword_str_loop
|
|
|
|
c = *1p
|
|
|
|
if c == 255 goto no_such_keyword_id
|
|
|
|
if c == keyword_id goto found_keyword_id
|
|
|
|
p = memchr(p, 0)
|
|
|
|
p += 1
|
|
|
|
goto keyword_str_loop
|
|
|
|
:found_keyword_id
|
|
|
|
return p + 1
|
|
|
|
:no_such_keyword_id
|
|
|
|
return .str_no_such_keyword_id
|
|
|
|
:str_no_such_keyword_id
|
|
|
|
string @BAD_KEYWORD_ID
|
|
|
|
byte 0
|
|
|
|
|
2022-01-11 00:09:11 -05:00
|
|
|
; turn pptokens into tokens, written to out.
|
|
|
|
; tokens are 16 bytes and have the following format:
|
|
|
|
; ushort type
|
|
|
|
; ushort file
|
|
|
|
; uint line
|
|
|
|
; ulong data
|
|
|
|
function tokenize
|
|
|
|
argument pptokens
|
|
|
|
argument out
|
|
|
|
local in
|
|
|
|
local file
|
|
|
|
local line_number
|
|
|
|
local b
|
|
|
|
in = pptokens
|
|
|
|
:tokenize_loop
|
|
|
|
if *1in == '$ goto tokenize_line_directive
|
|
|
|
if *1in == 32 goto tokenize_skip_pptoken
|
|
|
|
if *1in == 10 goto tokenize_newline
|
|
|
|
if *1in == 0 goto tokenize_loop_end
|
|
|
|
|
2022-01-11 11:53:36 -05:00
|
|
|
b = get_keyword_id(in)
|
|
|
|
if b != 0 goto tokenize_keyword
|
2022-01-11 00:09:11 -05:00
|
|
|
|
|
|
|
byte 0xcc
|
|
|
|
|
|
|
|
:tokenize_newline
|
|
|
|
line_number += 1
|
|
|
|
pptoken_skip(&in)
|
|
|
|
goto tokenize_loop
|
|
|
|
:tokenize_skip_pptoken
|
|
|
|
pptoken_skip(&in)
|
|
|
|
goto tokenize_loop
|
|
|
|
:tokenize_line_directive
|
|
|
|
in += 1
|
|
|
|
line_number = stoi(in)
|
|
|
|
in = memchr(in, 32)
|
|
|
|
in += 1
|
|
|
|
file_add(in)
|
|
|
|
file = file_get_index(in)
|
|
|
|
pptoken_skip(&in)
|
|
|
|
goto tokenize_loop
|
|
|
|
:tokenize_keyword
|
|
|
|
*2out = b ; type
|
|
|
|
out += 2
|
|
|
|
*2out = file
|
|
|
|
out += 2
|
|
|
|
*4out = line_number
|
|
|
|
out += 4
|
|
|
|
; no data
|
|
|
|
out += 8
|
|
|
|
pptoken_skip(&in)
|
|
|
|
goto tokenize_loop
|
|
|
|
:tokenize_loop_end
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
function print_tokens
|
|
|
|
argument tokens
|
|
|
|
local p
|
2022-01-11 11:53:36 -05:00
|
|
|
local s
|
2022-01-11 00:09:11 -05:00
|
|
|
p = tokens
|
|
|
|
:print_tokens_loop
|
|
|
|
if *2p == 0 goto print_tokens_loop_end
|
2022-01-11 11:53:36 -05:00
|
|
|
if *2p > 20 goto print_token_keyword
|
|
|
|
fputs(2, .str_print_bad_token)
|
|
|
|
exit(1)
|
|
|
|
:print_token_keyword
|
|
|
|
s = get_keyword_str(*2p)
|
|
|
|
puts(s)
|
|
|
|
goto print_token_data
|
|
|
|
|
|
|
|
:print_token_data
|
2022-01-11 00:09:11 -05:00
|
|
|
p += 2
|
2022-01-11 11:53:36 -05:00
|
|
|
putc('@)
|
2022-01-11 00:09:11 -05:00
|
|
|
putn(*2p)
|
|
|
|
p += 2
|
|
|
|
putc(':)
|
|
|
|
putn(*4p)
|
|
|
|
p += 4
|
2022-01-11 11:53:36 -05:00
|
|
|
putc(61)
|
2022-01-11 00:09:11 -05:00
|
|
|
putn(*8p)
|
|
|
|
p += 8
|
|
|
|
putc(32)
|
|
|
|
goto print_tokens_loop
|
|
|
|
:print_tokens_loop_end
|
|
|
|
putc(10)
|
|
|
|
return
|
2022-01-11 11:53:36 -05:00
|
|
|
:str_print_bad_token
|
|
|
|
string Unrecognized token type in print_tokens. Aborting.
|
|
|
|
byte 10
|