mirror of
https://github.com/Ed94/pikuma_ps1.git
synced 2026-08-08 08:38:50 +00:00
adding comments for scan progress
This commit is contained in:
@@ -316,6 +316,7 @@ local function parse_pragma_operator(source, ident_pos, after_ident)
|
|||||||
return nil, open_paren + 1
|
return nil, open_paren + 1
|
||||||
end
|
end
|
||||||
local str, str_end = read_parens(source, open_paren)
|
local str, str_end = read_parens(source, open_paren)
|
||||||
|
-- scan: _Pragma(<string>)
|
||||||
str = trim(str)
|
str = trim(str)
|
||||||
if str:sub(1, 1) ~= '"' or str:sub(-1) ~= '"' then
|
if str:sub(1, 1) ~= '"' or str:sub(-1) ~= '"' then
|
||||||
return nil, str_end
|
return nil, str_end
|
||||||
@@ -350,6 +351,7 @@ local function parse_pragma_directive(source, ident_pos, after_ident)
|
|||||||
eol = eol + 1
|
eol = eol + 1
|
||||||
end
|
end
|
||||||
local line_text = trim(source:sub(rest_start, eol - 1))
|
local line_text = trim(source:sub(rest_start, eol - 1))
|
||||||
|
-- scan: #pragma <mac_name> tape_atom words=<N>
|
||||||
local tokens = split_ws(line_text)
|
local tokens = split_ws(line_text)
|
||||||
local entry
|
local entry
|
||||||
if #tokens >= 3 and tokens[2] == "tape_atom" and tokens[3]:sub(1, WORDS_KEY_PREFIX_LEN) == WORDS_KEY_PREFIX then
|
if #tokens >= 3 and tokens[2] == "tape_atom" and tokens[3]:sub(1, WORDS_KEY_PREFIX_LEN) == WORDS_KEY_PREFIX then
|
||||||
@@ -389,9 +391,11 @@ local function find_macro_word_annotations(source)
|
|||||||
pos = skip_preprocessor_line(source, pos)
|
pos = skip_preprocessor_line(source, pos)
|
||||||
else
|
else
|
||||||
local ident, after_ident = read_ident(source, pos)
|
local ident, after_ident = read_ident(source, pos)
|
||||||
|
-- scan: <ident>
|
||||||
if not ident then
|
if not ident then
|
||||||
pos = pos + 1
|
pos = pos + 1
|
||||||
elseif ident == PRAGMA_OPERATOR then
|
elseif ident == PRAGMA_OPERATOR then
|
||||||
|
-- scan: _Pragma(...)
|
||||||
local entry, new_pos = parse_pragma_operator(source, pos, after_ident)
|
local entry, new_pos = parse_pragma_operator(source, pos, after_ident)
|
||||||
if entry then
|
if entry then
|
||||||
local line_of = duffle.LineIndex(source)
|
local line_of = duffle.LineIndex(source)
|
||||||
@@ -400,6 +404,7 @@ local function find_macro_word_annotations(source)
|
|||||||
end
|
end
|
||||||
pos = new_pos
|
pos = new_pos
|
||||||
elseif ident == PRAGMA_IDENT then
|
elseif ident == PRAGMA_IDENT then
|
||||||
|
-- scan: #pragma <mac_name> tape_atom words=<N>
|
||||||
local entry, new_pos = parse_pragma_directive(source, pos, after_ident)
|
local entry, new_pos = parse_pragma_directive(source, pos, after_ident)
|
||||||
if entry then out[#out + 1] = entry end
|
if entry then out[#out + 1] = entry end
|
||||||
pos = new_pos
|
pos = new_pos
|
||||||
@@ -458,6 +463,7 @@ end
|
|||||||
local function parse_typedef_binds(source, ident_pos, after_typedef, line_of)
|
local function parse_typedef_binds(source, ident_pos, after_typedef, line_of)
|
||||||
local after_type = skip_ws_and_cmt(source, after_typedef)
|
local after_type = skip_ws_and_cmt(source, after_typedef)
|
||||||
local type_ident, after_type_ident = read_ident(source, after_type)
|
local type_ident, after_type_ident = read_ident(source, after_type)
|
||||||
|
-- scan: typedef <type_ident>
|
||||||
if type_ident ~= STRUCT_TYPE then
|
if type_ident ~= STRUCT_TYPE then
|
||||||
return nil, after_type_ident or (after_type + 1)
|
return nil, after_type_ident or (after_type + 1)
|
||||||
end
|
end
|
||||||
@@ -468,12 +474,15 @@ local function parse_typedef_binds(source, ident_pos, after_typedef, line_of)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local inner, after_paren = read_parens(source, open_paren)
|
local inner, after_paren = read_parens(source, open_paren)
|
||||||
|
-- scan: typedef Struct_(<name>)
|
||||||
local name = trim(inner)
|
local name = trim(inner)
|
||||||
|
|
||||||
local brace = scan_to_char(source, "{", after_paren)
|
local brace = scan_to_char(source, "{", after_paren)
|
||||||
|
-- scan: typedef Struct_(<name>) {
|
||||||
if not brace then return nil, open_paren + 1 end
|
if not brace then return nil, open_paren + 1 end
|
||||||
|
|
||||||
local body, after_brace = read_braces(source, brace)
|
local body, after_brace = read_braces(source, brace)
|
||||||
|
-- scan: typedef Struct_(<name>) { <fields> }
|
||||||
local fields, bytes = parse_binds_body(body)
|
local fields, bytes = parse_binds_body(body)
|
||||||
|
|
||||||
-- Only emit Binds_* structs (other Struct_ typedefs are ignored).
|
-- Only emit Binds_* structs (other Struct_ typedefs are ignored).
|
||||||
@@ -505,9 +514,11 @@ local function find_binds_structs(source)
|
|||||||
pos = skip_preprocessor_line(source, pos)
|
pos = skip_preprocessor_line(source, pos)
|
||||||
else
|
else
|
||||||
local ident, after_ident = read_ident(source, pos)
|
local ident, after_ident = read_ident(source, pos)
|
||||||
|
-- scan: <ident>
|
||||||
if not ident then
|
if not ident then
|
||||||
pos = pos + 1
|
pos = pos + 1
|
||||||
elseif ident == "typedef" then
|
elseif ident == "typedef" then
|
||||||
|
-- scan: typedef Struct_(<name>) { <fields> }
|
||||||
local binds_struct, new_pos = parse_typedef_binds(source, pos, after_ident, line_of)
|
local binds_struct, new_pos = parse_typedef_binds(source, pos, after_ident, line_of)
|
||||||
if binds_struct then out[#out + 1] = binds_struct end
|
if binds_struct then out[#out + 1] = binds_struct end
|
||||||
pos = new_pos
|
pos = new_pos
|
||||||
@@ -550,6 +561,7 @@ local function find_atom_names(source)
|
|||||||
if pos > str_len then break end
|
if pos > str_len then break end
|
||||||
|
|
||||||
local ident, after_ident = read_ident(source, pos)
|
local ident, after_ident = read_ident(source, pos)
|
||||||
|
-- scan: <ident>
|
||||||
if not ident then
|
if not ident then
|
||||||
pos = pos + 1
|
pos = pos + 1
|
||||||
elseif ident ~= ATOM_DECL then
|
elseif ident ~= ATOM_DECL then
|
||||||
@@ -560,13 +572,16 @@ local function find_atom_names(source)
|
|||||||
pos = open_paren + 1
|
pos = open_paren + 1
|
||||||
else
|
else
|
||||||
local inner, after_paren = read_parens(source, open_paren)
|
local inner, after_paren = read_parens(source, open_paren)
|
||||||
|
-- scan: MipsAtom_(<name>)
|
||||||
local name, _ = read_alnum_ident(inner, 1)
|
local name, _ = read_alnum_ident(inner, 1)
|
||||||
if name and name ~= "" then
|
if name and name ~= "" then
|
||||||
out[#out + 1] = { line = line_of(pos), name = name }
|
out[#out + 1] = { line = line_of(pos), name = name }
|
||||||
end
|
end
|
||||||
local brace = scan_to_char(source, "{", after_paren)
|
local brace = scan_to_char(source, "{", after_paren)
|
||||||
|
-- scan: MipsAtom_(<name>) {
|
||||||
if brace then
|
if brace then
|
||||||
local _, after_brace = read_braces(source, brace)
|
local _, after_brace = read_braces(source, brace)
|
||||||
|
-- scan: MipsAtom_(<name>) { <body> }
|
||||||
pos = after_brace
|
pos = after_brace
|
||||||
else
|
else
|
||||||
pos = open_paren + 1
|
pos = open_paren + 1
|
||||||
@@ -630,12 +645,14 @@ end
|
|||||||
local function parse_atom_info_call(source, atom_name, after_mipsatom_paren, line_of)
|
local function parse_atom_info_call(source, atom_name, after_mipsatom_paren, line_of)
|
||||||
local lookahead = skip_ws_and_cmt(source, after_mipsatom_paren)
|
local lookahead = skip_ws_and_cmt(source, after_mipsatom_paren)
|
||||||
local look_ident, look_after = read_ident(source, lookahead)
|
local look_ident, look_after = read_ident(source, lookahead)
|
||||||
|
-- scan: MipsAtom_(<name>) <look_ident>
|
||||||
if look_ident ~= ATOM_INFO then return nil, after_mipsatom_paren end
|
if look_ident ~= ATOM_INFO then return nil, after_mipsatom_paren end
|
||||||
|
|
||||||
local info_open = skip_ws_and_cmt(source, look_after)
|
local info_open = skip_ws_and_cmt(source, look_after)
|
||||||
if source:byte(info_open) ~= BYTE_OPEN_PAREN then return nil, info_open + 1 end
|
if source:byte(info_open) ~= BYTE_OPEN_PAREN then return nil, info_open + 1 end
|
||||||
|
|
||||||
local info_inner, info_after = read_parens(source, info_open)
|
local info_inner, info_after = read_parens(source, info_open)
|
||||||
|
-- scan: MipsAtom_(<name>) atom_info(<binds>, <reads>, <writes>)
|
||||||
local args = parse_atom_annot_args(info_inner)
|
local args = parse_atom_annot_args(info_inner)
|
||||||
local entry = new_annot_entry(line_of(lookahead), ATOM_INFO, atom_name, "info")
|
local entry = new_annot_entry(line_of(lookahead), ATOM_INFO, atom_name, "info")
|
||||||
ANNOT_ARG_HANDLERS.info(entry, args)
|
ANNOT_ARG_HANDLERS.info(entry, args)
|
||||||
@@ -661,6 +678,7 @@ local function find_atom_annotations(source)
|
|||||||
pos = skip_preprocessor_line(source, pos)
|
pos = skip_preprocessor_line(source, pos)
|
||||||
else
|
else
|
||||||
local ident, after_ident = read_ident(source, pos)
|
local ident, after_ident = read_ident(source, pos)
|
||||||
|
-- scan: <ident>
|
||||||
if not ident then
|
if not ident then
|
||||||
pos = pos + 1
|
pos = pos + 1
|
||||||
elseif ident == ATOM_DECL then
|
elseif ident == ATOM_DECL then
|
||||||
@@ -669,16 +687,20 @@ local function find_atom_annotations(source)
|
|||||||
pos = open_paren + 1
|
pos = open_paren + 1
|
||||||
else
|
else
|
||||||
local inner, after_paren = read_parens(source, open_paren)
|
local inner, after_paren = read_parens(source, open_paren)
|
||||||
|
-- scan: MipsAtom_(<name>)
|
||||||
local name, _ = read_alnum_ident(inner, 1)
|
local name, _ = read_alnum_ident(inner, 1)
|
||||||
|
|
||||||
local entry, new_pos = parse_atom_info_call(source, name, after_paren, line_of)
|
local entry, new_pos = parse_atom_info_call(source, name, after_paren, line_of)
|
||||||
|
-- scan: MipsAtom_(<name>) atom_info(<binds>, <reads>, <writes>)
|
||||||
if entry then annots[#annots + 1] = entry end
|
if entry then annots[#annots + 1] = entry end
|
||||||
pos = new_pos
|
pos = new_pos
|
||||||
|
|
||||||
-- Skip past the body { ... } if present.
|
-- Skip past the body { ... } if present.
|
||||||
local brace = scan_to_char(source, "{", pos)
|
local brace = scan_to_char(source, "{", pos)
|
||||||
|
-- scan: MipsAtom_(<name>) atom_info(...) {
|
||||||
if brace then
|
if brace then
|
||||||
local _, after_brace = read_braces(source, brace)
|
local _, after_brace = read_braces(source, brace)
|
||||||
|
-- scan: MipsAtom_(<name>) atom_info(...) { <body> }
|
||||||
pos = after_brace
|
pos = after_brace
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -173,7 +173,9 @@ local function find_function_args_for(source, name, before_pos)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local open_paren = last_idx + #name -- position of "("
|
local open_paren = last_idx + #name -- position of "("
|
||||||
|
-- scan: MipsAtom ac_X(
|
||||||
local inner = duffle.read_parens(source, open_paren)
|
local inner = duffle.read_parens(source, open_paren)
|
||||||
|
-- scan: MipsAtom ac_X(<args>)
|
||||||
if not inner then return nil end
|
if not inner then return nil end
|
||||||
return inner
|
return inner
|
||||||
end
|
end
|
||||||
@@ -408,8 +410,10 @@ end
|
|||||||
--- @return Component|nil, integer -- the component + new source position
|
--- @return Component|nil, integer -- the component + new source position
|
||||||
local function make_bare_component(source, name, ident_pos, after_paren, line_of, args, comment)
|
local function make_bare_component(source, name, ident_pos, after_paren, line_of, args, comment)
|
||||||
local brace = duffle.scan_to_char(source, "{", after_paren)
|
local brace = duffle.scan_to_char(source, "{", after_paren)
|
||||||
|
-- scan: <ident>(<name>) {
|
||||||
if not brace then return nil, after_paren + 1 end
|
if not brace then return nil, after_paren + 1 end
|
||||||
local body, after_brace = duffle.read_braces(source, brace)
|
local body, after_brace = duffle.read_braces(source, brace)
|
||||||
|
-- scan: <ident>(<name>) { <body> }
|
||||||
return {
|
return {
|
||||||
line = line_of(ident_pos),
|
line = line_of(ident_pos),
|
||||||
name = name:sub(AC_PREFIX_LEN + 1), -- strip "ac_" prefix
|
name = name:sub(AC_PREFIX_LEN + 1), -- strip "ac_" prefix
|
||||||
@@ -449,6 +453,7 @@ local function find_component_atoms(source)
|
|||||||
if pos > src_len then break end
|
if pos > src_len then break end
|
||||||
|
|
||||||
local ident, after_ident = duffle.read_ident(source, pos)
|
local ident, after_ident = duffle.read_ident(source, pos)
|
||||||
|
-- scan: <ident>
|
||||||
local is_comp = ident == ATOM_COMP or ident == ATOM_COMP_PROC
|
local is_comp = ident == ATOM_COMP or ident == ATOM_COMP_PROC
|
||||||
if not ident then
|
if not ident then
|
||||||
pos = pos + 1
|
pos = pos + 1
|
||||||
@@ -460,7 +465,9 @@ local function find_component_atoms(source)
|
|||||||
pos = open_paren + 1
|
pos = open_paren + 1
|
||||||
else
|
else
|
||||||
local inner, after_paren = duffle.read_parens(source, open_paren)
|
local inner, after_paren = duffle.read_parens(source, open_paren)
|
||||||
|
-- scan: <ident>(<args>)
|
||||||
local name, body = parse_atomcomp_inner(inner)
|
local name, body = parse_atomcomp_inner(inner)
|
||||||
|
-- scan: <ident>(<name>) OR <ident>(<name>, { <body> })
|
||||||
if not name or name:sub(1, AC_PREFIX_LEN) ~= AC_PREFIX then
|
if not name or name:sub(1, AC_PREFIX_LEN) ~= AC_PREFIX then
|
||||||
pos = open_paren + 1
|
pos = open_paren + 1
|
||||||
else
|
else
|
||||||
@@ -468,11 +475,14 @@ local function find_component_atoms(source)
|
|||||||
local comment = preceding_comment_block(source, pos)
|
local comment = preceding_comment_block(source, pos)
|
||||||
if body == nil then
|
if body == nil then
|
||||||
-- Bare form: body comes from the brace block after the parens.
|
-- Bare form: body comes from the brace block after the parens.
|
||||||
|
-- scan: <ident>(<name>) {
|
||||||
local comp, new_pos = make_bare_component(source, name, pos, after_paren, line_of, args, comment)
|
local comp, new_pos = make_bare_component(source, name, pos, after_paren, line_of, args, comment)
|
||||||
|
-- scan: <ident>(<name>) { <body> }
|
||||||
if comp then out[#out + 1] = comp end
|
if comp then out[#out + 1] = comp end
|
||||||
pos = new_pos
|
pos = new_pos
|
||||||
else
|
else
|
||||||
-- Function form: body was inside the parens.
|
-- Function form: body was inside the parens.
|
||||||
|
-- scan: <ident>(<name>, { <body> })
|
||||||
out[#out + 1] = make_proc_component(name, body, pos, line_of, args, comment)
|
out[#out + 1] = make_proc_component(name, body, pos, line_of, args, comment)
|
||||||
pos = after_paren
|
pos = after_paren
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ local function extract_ident_args(token, after_ident)
|
|||||||
local arg_start = duffle.skip_ws_and_cmt(token, after_ident)
|
local arg_start = duffle.skip_ws_and_cmt(token, after_ident)
|
||||||
if token:sub(arg_start, arg_start) ~= "(" then return {}, nil end
|
if token:sub(arg_start, arg_start) ~= "(" then return {}, nil end
|
||||||
local inner, after_paren = duffle.read_parens(token, arg_start)
|
local inner, after_paren = duffle.read_parens(token, arg_start)
|
||||||
|
-- scan: <marker>(<args>)
|
||||||
|
|
||||||
local args = {}
|
local args = {}
|
||||||
local pos = 1
|
local pos = 1
|
||||||
@@ -236,7 +237,9 @@ local function find_marker_call_end(tok)
|
|||||||
pos = (nx > pos) and nx or (pos + 1)
|
pos = (nx > pos) and nx or (pos + 1)
|
||||||
else
|
else
|
||||||
local ident, after_ident = duffle.read_ident(tok, pos)
|
local ident, after_ident = duffle.read_ident(tok, pos)
|
||||||
|
-- scan: <ident>
|
||||||
if ident == LABEL_MARKER or ident == OFFSET_MARKER then
|
if ident == LABEL_MARKER or ident == OFFSET_MARKER then
|
||||||
|
-- scan: atom_label(<name>) OR atom_offset(<tag>, <target>)
|
||||||
local open_paren = duffle.skip_ws_and_cmt(tok, after_ident)
|
local open_paren = duffle.skip_ws_and_cmt(tok, after_ident)
|
||||||
if tok:sub(open_paren, open_paren) == "(" then
|
if tok:sub(open_paren, open_paren) == "(" then
|
||||||
local _, end_paren = duffle.read_parens(tok, open_paren)
|
local _, end_paren = duffle.read_parens(tok, open_paren)
|
||||||
@@ -276,6 +279,7 @@ local function try_wrapped_atom(source_text, after_pos)
|
|||||||
local paren_pos = duffle.skip_ws_and_cmt(source_text, after_pos)
|
local paren_pos = duffle.skip_ws_and_cmt(source_text, after_pos)
|
||||||
if source_text:sub(paren_pos, paren_pos) ~= "(" then return nil end
|
if source_text:sub(paren_pos, paren_pos) ~= "(" then return nil end
|
||||||
local inner, after_paren = duffle.read_parens(source_text, paren_pos)
|
local inner, after_paren = duffle.read_parens(source_text, paren_pos)
|
||||||
|
-- scan: MipsAtom_(<name>)
|
||||||
|
|
||||||
local name_start = 1
|
local name_start = 1
|
||||||
while name_start <= #inner and duffle.is_space(inner:sub(name_start, name_start)) do
|
while name_start <= #inner and duffle.is_space(inner:sub(name_start, name_start)) do
|
||||||
@@ -289,8 +293,10 @@ local function try_wrapped_atom(source_text, after_pos)
|
|||||||
if name == "" then return nil end
|
if name == "" then return nil end
|
||||||
|
|
||||||
local brace_pos = duffle.scan_to_char(source_text, "{", after_paren)
|
local brace_pos = duffle.scan_to_char(source_text, "{", after_paren)
|
||||||
|
-- scan: MipsAtom_(<name>) {
|
||||||
if not brace_pos then return nil end
|
if not brace_pos then return nil end
|
||||||
local body, after_brace = duffle.read_braces(source_text, brace_pos)
|
local body, after_brace = duffle.read_braces(source_text, brace_pos)
|
||||||
|
-- scan: MipsAtom_(<name>) { <body> }
|
||||||
return { name = name, body = body, after_brace = after_brace }
|
return { name = name, body = body, after_brace = after_brace }
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -301,13 +307,17 @@ end
|
|||||||
local function try_raw_atom(source_text, after_pos)
|
local function try_raw_atom(source_text, after_pos)
|
||||||
local next_pos = duffle.skip_ws_and_cmt(source_text, after_pos)
|
local next_pos = duffle.skip_ws_and_cmt(source_text, after_pos)
|
||||||
local next_ident, next_after = duffle.read_ident(source_text, next_pos)
|
local next_ident, next_after = duffle.read_ident(source_text, next_pos)
|
||||||
|
-- scan: MipsCode <next_ident>
|
||||||
if not next_ident then return nil end
|
if not next_ident then return nil end
|
||||||
if not starts_with(next_ident, CODE_RAW_PREFIX) then return nil end
|
if not starts_with(next_ident, CODE_RAW_PREFIX) then return nil end
|
||||||
if #next_ident <= CODE_RAW_PREFIX_LEN then return nil end
|
if #next_ident <= CODE_RAW_PREFIX_LEN then return nil end
|
||||||
local atom_name = next_ident:sub(CODE_RAW_PREFIX_LEN + 1)
|
local atom_name = next_ident:sub(CODE_RAW_PREFIX_LEN + 1)
|
||||||
|
-- scan: MipsCode code_<name>
|
||||||
local brace_pos = duffle.scan_to_char(source_text, "{", next_after)
|
local brace_pos = duffle.scan_to_char(source_text, "{", next_after)
|
||||||
|
-- scan: MipsCode code_<name> {
|
||||||
if not brace_pos then return nil end
|
if not brace_pos then return nil end
|
||||||
local body, after_brace = duffle.read_braces(source_text, brace_pos)
|
local body, after_brace = duffle.read_braces(source_text, brace_pos)
|
||||||
|
-- scan: MipsCode code_<name> { <body> }
|
||||||
return { name = atom_name, body = body, after_brace = after_brace }
|
return { name = atom_name, body = body, after_brace = after_brace }
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -324,9 +334,11 @@ local function find_atoms(source_text)
|
|||||||
pos = skip_qualifiers(source_text, pos); if pos > src_len then break end
|
pos = skip_qualifiers(source_text, pos); if pos > src_len then break end
|
||||||
|
|
||||||
local ident, after = duffle.read_ident(source_text, pos)
|
local ident, after = duffle.read_ident(source_text, pos)
|
||||||
|
-- scan: <ident>
|
||||||
if not ident then
|
if not ident then
|
||||||
pos = pos + 1
|
pos = pos + 1
|
||||||
elseif ident == ATOM_PREFIX then
|
elseif ident == ATOM_PREFIX then
|
||||||
|
-- scan: MipsAtom_(<name>) { <body> }
|
||||||
local atom = try_wrapped_atom(source_text, after)
|
local atom = try_wrapped_atom(source_text, after)
|
||||||
if atom then
|
if atom then
|
||||||
atoms[#atoms + 1] = { name = atom.name, body = atom.body }
|
atoms[#atoms + 1] = { name = atom.name, body = atom.body }
|
||||||
@@ -335,6 +347,7 @@ local function find_atoms(source_text)
|
|||||||
pos = pos + 1
|
pos = pos + 1
|
||||||
end
|
end
|
||||||
elseif ident == CODE_DECL then
|
elseif ident == CODE_DECL then
|
||||||
|
-- scan: MipsCode code_<name> { <body> }
|
||||||
local atom = try_raw_atom(source_text, after)
|
local atom = try_raw_atom(source_text, after)
|
||||||
if atom then
|
if atom then
|
||||||
atoms[#atoms + 1] = { name = atom.name, body = atom.body }
|
atoms[#atoms + 1] = { name = atom.name, body = atom.body }
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ local function find_atom_bodies(source_text)
|
|||||||
pos = eol_pos + 1
|
pos = eol_pos + 1
|
||||||
else
|
else
|
||||||
local ident, ident_end = duffle.read_ident(source_text, pos)
|
local ident, ident_end = duffle.read_ident(source_text, pos)
|
||||||
|
-- scan: <ident>
|
||||||
if not ident then
|
if not ident then
|
||||||
pos = pos + 1
|
pos = pos + 1
|
||||||
elseif ident == "MipsAtom_"
|
elseif ident == "MipsAtom_"
|
||||||
@@ -175,6 +176,7 @@ local function find_atom_bodies(source_text)
|
|||||||
pos = open_paren + 1
|
pos = open_paren + 1
|
||||||
else
|
else
|
||||||
local inner, after_paren = duffle.read_parens(source_text, open_paren)
|
local inner, after_paren = duffle.read_parens(source_text, open_paren)
|
||||||
|
-- scan: <ident>(<args>)
|
||||||
|
|
||||||
if kind == "comp_proc" then
|
if kind == "comp_proc" then
|
||||||
-- MipsAtomComp_Proc_(sym, { body })
|
-- MipsAtomComp_Proc_(sym, { body })
|
||||||
@@ -216,6 +218,7 @@ local function find_atom_bodies(source_text)
|
|||||||
-- unmatched; bail
|
-- unmatched; bail
|
||||||
pos = open_paren + 1
|
pos = open_paren + 1
|
||||||
else
|
else
|
||||||
|
-- scan: <ident>(<name>, { <body> })
|
||||||
-- First ident in `inner` is the comp name.
|
-- First ident in `inner` is the comp name.
|
||||||
local name_match = inner:match("^%s*([%w_]+)")
|
local name_match = inner:match("^%s*([%w_]+)")
|
||||||
local name = name_match or "?"
|
local name = name_match or "?"
|
||||||
@@ -245,12 +248,15 @@ local function find_atom_bodies(source_text)
|
|||||||
local name_end = name_start
|
local name_end = name_start
|
||||||
while name_end <= #inner and inner:sub(name_end, name_end):match("[%w_]") do name_end = name_end + 1 end
|
while name_end <= #inner and inner:sub(name_end, name_end):match("[%w_]") do name_end = name_end + 1 end
|
||||||
local name = inner:sub(name_start, name_end - 1)
|
local name = inner:sub(name_start, name_end - 1)
|
||||||
|
-- scan: <ident>(<name>)
|
||||||
if name == "" then
|
if name == "" then
|
||||||
pos = open_paren + 1
|
pos = open_paren + 1
|
||||||
else
|
else
|
||||||
local brace = duffle.scan_to_char(source_text, "{", after_paren)
|
local brace = duffle.scan_to_char(source_text, "{", after_paren)
|
||||||
|
-- scan: <ident>(<name>) {
|
||||||
if brace then
|
if brace then
|
||||||
local body, after_brace = duffle.read_braces(source_text, brace)
|
local body, after_brace = duffle.read_braces(source_text, brace)
|
||||||
|
-- scan: <ident>(<name>) { <body> }
|
||||||
local body_off = brace + 1
|
local body_off = brace + 1
|
||||||
out[#out + 1] = {
|
out[#out + 1] = {
|
||||||
line = line_of(pos),
|
line = line_of(pos),
|
||||||
@@ -410,8 +416,7 @@ local function check_gte_pipeline_fill(atoms, findings, line_of)
|
|||||||
local ti = 1
|
local ti = 1
|
||||||
while ti <= tn do
|
while ti <= tn do
|
||||||
local tok = tokens[ti].tok
|
local tok = tokens[ti].tok
|
||||||
local cmdw_full = tok:match("^(gte_cmdw_[%w_]+)%s*[,%)]")
|
local cmdw_full = tok:match("^(gte_cmdw_[%w_]+)%s*[,%)]") or tok:match("^(gte_cmdw_[%w_]+)%s*$")
|
||||||
or tok:match("^(gte_cmdw_[%w_]+)%s*$")
|
|
||||||
if cmdw_full then
|
if cmdw_full then
|
||||||
local variant = cmdw_full:match("^gte_cmdw_(.+)$")
|
local variant = cmdw_full:match("^gte_cmdw_(.+)$")
|
||||||
local need = duffle.GTE_PIPELINE_LATENCY[cmdw_full]
|
local need = duffle.GTE_PIPELINE_LATENCY[cmdw_full]
|
||||||
@@ -597,11 +602,13 @@ local function find_binds_structs(source_text)
|
|||||||
pos = eol_pos + 1
|
pos = eol_pos + 1
|
||||||
else
|
else
|
||||||
local ident, ident_end = duffle.read_ident(source_text, pos)
|
local ident, ident_end = duffle.read_ident(source_text, pos)
|
||||||
|
-- scan: <ident>
|
||||||
if not ident then
|
if not ident then
|
||||||
pos = pos + 1
|
pos = pos + 1
|
||||||
elseif ident == "typedef" then
|
elseif ident == "typedef" then
|
||||||
local after_typedef = duffle.skip_ws_and_cmt(source_text, ident_end)
|
local after_typedef = duffle.skip_ws_and_cmt(source_text, ident_end)
|
||||||
local id2, id2_end = duffle.read_ident(source_text, after_typedef)
|
local id2, id2_end = duffle.read_ident(source_text, after_typedef)
|
||||||
|
-- scan: typedef <id2>
|
||||||
if id2 ~= "Struct_" then
|
if id2 ~= "Struct_" then
|
||||||
pos = id2_end or (after_typedef + 1)
|
pos = id2_end or (after_typedef + 1)
|
||||||
else
|
else
|
||||||
@@ -610,12 +617,15 @@ local function find_binds_structs(source_text)
|
|||||||
pos = open_paren + 1
|
pos = open_paren + 1
|
||||||
else
|
else
|
||||||
local inner, after_paren = duffle.read_parens(source_text, open_paren)
|
local inner, after_paren = duffle.read_parens(source_text, open_paren)
|
||||||
|
-- scan: typedef Struct_(<name>)
|
||||||
local name = duffle.trim(inner)
|
local name = duffle.trim(inner)
|
||||||
local brace = duffle.scan_to_char(source_text, "{", after_paren)
|
local brace = duffle.scan_to_char(source_text, "{", after_paren)
|
||||||
|
-- scan: typedef Struct_(<name>) {
|
||||||
if not brace then
|
if not brace then
|
||||||
pos = open_paren + 1
|
pos = open_paren + 1
|
||||||
else
|
else
|
||||||
local body, after_brace = duffle.read_braces(source_text, brace)
|
local body, after_brace = duffle.read_braces(source_text, brace)
|
||||||
|
-- scan: typedef Struct_(<name>) { <fields> }
|
||||||
local fields = {}
|
local fields = {}
|
||||||
local byte_off = 0
|
local byte_off = 0
|
||||||
local body_pos = 1
|
local body_pos = 1
|
||||||
@@ -668,6 +678,7 @@ local function find_atom_info(source_text)
|
|||||||
pos = eol_pos + 1
|
pos = eol_pos + 1
|
||||||
else
|
else
|
||||||
local ident, ident_end = duffle.read_ident(source_text, pos)
|
local ident, ident_end = duffle.read_ident(source_text, pos)
|
||||||
|
-- scan: <ident>
|
||||||
if not ident then
|
if not ident then
|
||||||
pos = pos + 1
|
pos = pos + 1
|
||||||
elseif ident == "MipsAtom_" then
|
elseif ident == "MipsAtom_" then
|
||||||
@@ -676,6 +687,7 @@ local function find_atom_info(source_text)
|
|||||||
pos = open_paren + 1
|
pos = open_paren + 1
|
||||||
else
|
else
|
||||||
local inner, after_paren = duffle.read_parens(source_text, open_paren)
|
local inner, after_paren = duffle.read_parens(source_text, open_paren)
|
||||||
|
-- scan: MipsAtom_(<name>)
|
||||||
local name_start = 1
|
local name_start = 1
|
||||||
while name_start <= #inner and inner:sub(name_start, name_start):match("[%s]") do name_start = name_start + 1 end
|
while name_start <= #inner and inner:sub(name_start, name_start):match("[%s]") do name_start = name_start + 1 end
|
||||||
local name_end = name_start
|
local name_end = name_start
|
||||||
@@ -683,10 +695,12 @@ local function find_atom_info(source_text)
|
|||||||
local atom_name = inner:sub(name_start, name_end - 1)
|
local atom_name = inner:sub(name_start, name_end - 1)
|
||||||
local lookahead = duffle.skip_ws_and_cmt(source_text, after_paren)
|
local lookahead = duffle.skip_ws_and_cmt(source_text, after_paren)
|
||||||
local look_ident, look_end = duffle.read_ident(source_text, lookahead)
|
local look_ident, look_end = duffle.read_ident(source_text, lookahead)
|
||||||
|
-- scan: MipsAtom_(<name>) <look_ident>
|
||||||
if look_ident == "atom_info" then
|
if look_ident == "atom_info" then
|
||||||
local info_open = duffle.skip_ws_and_cmt(source_text, look_end)
|
local info_open = duffle.skip_ws_and_cmt(source_text, look_end)
|
||||||
if source_text:sub(info_open, info_open) == "(" then
|
if source_text:sub(info_open, info_open) == "(" then
|
||||||
local info_inner, info_after = duffle.read_parens(source_text, info_open)
|
local info_inner, info_after = duffle.read_parens(source_text, info_open)
|
||||||
|
-- scan: MipsAtom_(<name>) atom_info(<binds>, <reads>, <writes>)
|
||||||
local binds, reads, writes = nil, nil, nil
|
local binds, reads, writes = nil, nil, nil
|
||||||
local sub_pos = 1
|
local sub_pos = 1
|
||||||
while sub_pos <= #info_inner do
|
while sub_pos <= #info_inner do
|
||||||
@@ -698,6 +712,7 @@ local function find_atom_info(source_text)
|
|||||||
local sub_open = duffle.skip_ws_and_cmt(info_inner, sub_end)
|
local sub_open = duffle.skip_ws_and_cmt(info_inner, sub_end)
|
||||||
if info_inner:sub(sub_open, sub_open) == "(" then
|
if info_inner:sub(sub_open, sub_open) == "(" then
|
||||||
local sub_inner, sub_after2 = duffle.read_parens(info_inner, sub_open)
|
local sub_inner, sub_after2 = duffle.read_parens(info_inner, sub_open)
|
||||||
|
-- scan: atom_bind(<Binds_X>)
|
||||||
binds = duffle.trim(sub_inner)
|
binds = duffle.trim(sub_inner)
|
||||||
sub_pos = sub_after2
|
sub_pos = sub_after2
|
||||||
else
|
else
|
||||||
@@ -708,6 +723,7 @@ local function find_atom_info(source_text)
|
|||||||
local sub_open = duffle.skip_ws_and_cmt(info_inner, sub_end)
|
local sub_open = duffle.skip_ws_and_cmt(info_inner, sub_end)
|
||||||
if info_inner:sub(sub_open, sub_open) == "(" then
|
if info_inner:sub(sub_open, sub_open) == "(" then
|
||||||
local sub_inner, sub_after2 = duffle.read_parens(info_inner, sub_open)
|
local sub_inner, sub_after2 = duffle.read_parens(info_inner, sub_open)
|
||||||
|
-- scan: atom_reads(<regs>) OR atom_writes(<regs>)
|
||||||
local regs = {}
|
local regs = {}
|
||||||
local sub_inner_pos = 1
|
local sub_inner_pos = 1
|
||||||
while sub_inner_pos <= #sub_inner do
|
while sub_inner_pos <= #sub_inner do
|
||||||
@@ -800,6 +816,7 @@ local function check_abi_handoff(atoms, atom_infos, binds_index, findings)
|
|||||||
if tok:match("^load_word%s*%(") then
|
if tok:match("^load_word%s*%(") then
|
||||||
if tok:find("R_TapePtr", 1, true) and tok:find("O_(" .. binds_name .. ",", 1, true) then
|
if tok:find("R_TapePtr", 1, true) and tok:find("O_(" .. binds_name .. ",", 1, true) then
|
||||||
local field = tok:match(bind_re)
|
local field = tok:match(bind_re)
|
||||||
|
-- scan: load_word(R_*, R_TapePtr, O_(<Binds_X>, <field>))
|
||||||
if field then
|
if field then
|
||||||
found_field_seq[#found_field_seq + 1] = field
|
found_field_seq[#found_field_seq + 1] = field
|
||||||
found_field_set[field] = true
|
found_field_set[field] = true
|
||||||
@@ -816,6 +833,7 @@ local function check_abi_handoff(atoms, atom_infos, binds_index, findings)
|
|||||||
end
|
end
|
||||||
if tok:find("R_TapePtr", 1, true)
|
if tok:find("R_TapePtr", 1, true)
|
||||||
and tok:find("S_(" .. binds_name .. ")", 1, true) then
|
and tok:find("S_(" .. binds_name .. ")", 1, true) then
|
||||||
|
-- scan: add_ui_self(R_TapePtr, S_(<Binds_X>))
|
||||||
found_advance = true
|
found_advance = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -893,8 +911,7 @@ local function check_gpu_portstore_shape(atoms, findings)
|
|||||||
local tok = t.tok
|
local tok = t.tok
|
||||||
-- Match `mac_format_<shape>_color(...)` and strip `_color`
|
-- Match `mac_format_<shape>_color(...)` and strip `_color`
|
||||||
-- to get the bare shape suffix (f3 / g4 / etc).
|
-- to get the bare shape suffix (f3 / g4 / etc).
|
||||||
local shape = tok:match("^mac_format_([%w_]+)_color%s*%(")
|
local shape = tok:match("^mac_format_([%w_]+)_color%s*%(") or tok:match("^mac_format_([%w_]+)_color%s*$")
|
||||||
or tok:match("^mac_format_([%w_]+)_color%s*$")
|
|
||||||
if shape and duffle.GP0_CMD_BY_SHAPE[shape] then
|
if shape and duffle.GP0_CMD_BY_SHAPE[shape] then
|
||||||
if not cmd_byte then
|
if not cmd_byte then
|
||||||
cmd_byte = duffle.GP0_CMD_BY_SHAPE[shape]
|
cmd_byte = duffle.GP0_CMD_BY_SHAPE[shape]
|
||||||
@@ -1279,10 +1296,8 @@ local function validate(ctx, src)
|
|||||||
-- either severity (errors for missing nops; warnings for unknown
|
-- either severity (errors for missing nops; warnings for unknown
|
||||||
-- cmdw macros not in the latency table). Bin by `kind`, not by
|
-- cmdw macros not in the latency table). Bin by `kind`, not by
|
||||||
-- check name.
|
-- check name.
|
||||||
if f.kind == "error" then
|
if f.kind == "error" then errors [#errors + 1] = { line = f.line, msg = f.msg }
|
||||||
errors[#errors + 1] = { line = f.line, msg = f.msg }
|
else warnings[#warnings + 1] = { line = f.line, msg = f.msg }
|
||||||
else
|
|
||||||
warnings[#warnings + 1] = { line = f.line, msg = f.msg }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Per-source "scanned:" summary line. Includes the source basename
|
-- Per-source "scanned:" summary line. Includes the source basename
|
||||||
@@ -1410,9 +1425,8 @@ local function emit_static_analysis_txt(ctx, src, result)
|
|||||||
return out_path
|
return out_path
|
||||||
end
|
end
|
||||||
|
|
||||||
-- (Old per-source emit function above; kept for backward compat but no
|
-- (Old per-source emit function above; kept for backward compat but no longer called from M.run.
|
||||||
-- longer called from M.run. Replaced by `emit_module_static_analysis_txt`
|
-- Replaced by `emit_module_static_analysis_txt` which aggregates by directory.)
|
||||||
-- which aggregates by directory.)
|
|
||||||
|
|
||||||
--- Per-directory emit. Aggregates atoms + findings across every source
|
--- Per-directory emit. Aggregates atoms + findings across every source
|
||||||
--- in `dir_sources` and writes a single report to
|
--- in `dir_sources` and writes a single report to
|
||||||
|
|||||||
Reference in New Issue
Block a user