mirror of https://git.sr.ht/~rabbits/uxn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
4.8 KiB
196 lines
4.8 KiB
local spairs |
|
spairs = function(t) |
|
local keys |
|
do |
|
local _accum_0 = { } |
|
local _len_0 = 1 |
|
for k in pairs(t) do |
|
_accum_0[_len_0] = k |
|
_len_0 = _len_0 + 1 |
|
end |
|
keys = _accum_0 |
|
end |
|
table.sort(keys) |
|
local i = 0 |
|
return function() |
|
i = i + 1 |
|
return keys[i], t[keys[i]] |
|
end |
|
end |
|
local trees = { |
|
['asma-opcodes'] = { } |
|
} |
|
local opcodes_in_order = { } |
|
do |
|
local wanted = false |
|
for l in assert(io.lines('src/uxnasm.c')) do |
|
if l == 'static char ops[][4] = {' then |
|
wanted = true |
|
elseif wanted then |
|
if l == '};' then |
|
break |
|
end |
|
for w in l:gmatch('[^%s",][^%s",][^%s",]') do |
|
if w ~= '---' then |
|
trees['asma-opcodes'][w] = { |
|
('"%s 00'):format(w), |
|
'' |
|
} |
|
end |
|
table.insert(opcodes_in_order, w) |
|
end |
|
end |
|
end |
|
assert(#opcodes_in_order == 32, 'didn\'t find 32 opcodes in assembler code!') |
|
end |
|
do |
|
local representation = setmetatable({ |
|
['&'] = '26 00 ( & )' |
|
}, { |
|
__index = function(self, c) |
|
return ("'%s 00"):format(c) |
|
end |
|
}) |
|
local process |
|
process = function(label, t) |
|
trees[label] = { } |
|
for k, v in pairs(t) do |
|
trees[label][('%02x'):format(k:byte())] = { |
|
representation[k], |
|
(':%s'):format(v) |
|
} |
|
end |
|
end |
|
process('asma-first-char-normal', { |
|
['%'] = 'asma-macro-define', |
|
['|'] = 'asma-pad-absolute', |
|
['$'] = 'asma-pad-relative', |
|
['@'] = 'asma-label-define', |
|
['&'] = 'asma-sublabel-define', |
|
['#'] = 'asma-literal-hex', |
|
['.'] = 'asma-literal-zero-addr', |
|
[','] = 'asma-literal-rel-addr', |
|
[';'] = 'asma-literal-abs-addr', |
|
[':'] = 'asma-abs-addr', |
|
["'"] = 'asma-raw-char', |
|
['"'] = 'asma-raw-word', |
|
['{'] = 'asma-ignore', |
|
['}'] = 'asma-ignore', |
|
['['] = 'asma-ignore', |
|
[']'] = 'asma-ignore', |
|
['('] = 'asma-comment-start', |
|
[')'] = 'asma-comment-end', |
|
['~'] = 'asma-include' |
|
}) |
|
process('asma-first-char-macro', { |
|
['('] = 'asma-comment-start', |
|
[')'] = 'asma-comment-end', |
|
['{'] = 'asma-ignore', |
|
['}'] = 'asma-macro-end' |
|
}) |
|
process('asma-first-char-comment', { |
|
['('] = 'asma-comment-more', |
|
[')'] = 'asma-comment-less' |
|
}) |
|
end |
|
local traverse_node |
|
traverse_node = function(t, min, max, lefts, rights) |
|
local i = math.ceil((min + max) / 2) |
|
if min < i then |
|
lefts[t[i]] = (':&%s'):format(traverse_node(t, min, i - 1, lefts, rights)) |
|
end |
|
if i < max then |
|
rights[t[i]] = (':&%s'):format(traverse_node(t, i + 1, max, lefts, rights)) |
|
end |
|
return t[i] |
|
end |
|
local traverse_tree |
|
traverse_tree = function(t) |
|
local lefts, rights = { }, { } |
|
local keys |
|
do |
|
local _accum_0 = { } |
|
local _len_0 = 1 |
|
for k in pairs(t) do |
|
_accum_0[_len_0] = k |
|
_len_0 = _len_0 + 1 |
|
end |
|
keys = _accum_0 |
|
end |
|
table.sort(keys) |
|
return lefts, rights, traverse_node(keys, 1, #keys, lefts, rights) |
|
end |
|
local ptr |
|
ptr = function(s) |
|
if s then |
|
return (':&%s'):format(s) |
|
end |
|
return ' $2' |
|
end |
|
local ordered_opcodes |
|
ordered_opcodes = function(t) |
|
local i = 0 |
|
return function() |
|
i = i + 1 |
|
local v = opcodes_in_order[i] |
|
if t[v] then |
|
return v, t[v] |
|
elseif v then |
|
return false, { |
|
'"--- 00', |
|
'' |
|
} |
|
end |
|
end |
|
end |
|
local printout = true |
|
local fmt |
|
fmt = function(...) |
|
return (('\t%-11s %-10s %-12s %-14s %s '):format(...):gsub(' +$', '\n')) |
|
end |
|
do |
|
local _with_0 = assert(io.open('projects/library/asma.tal.tmp', 'w')) |
|
for l in assert(io.lines('projects/library/asma.tal')) do |
|
if l:match('--- cut here ---') then |
|
break |
|
end |
|
_with_0:write(l) |
|
_with_0:write('\n') |
|
end |
|
_with_0:write('( --- 8< ------- 8< --- cut here --- 8< ------- 8< --- )\n') |
|
_with_0:write('( automatically generated code below )\n') |
|
_with_0:write('( see etc/asma.moon for instructions )\n') |
|
_with_0:write('\n(') |
|
_with_0:write(fmt('label', 'less', 'greater', 'key', 'binary')) |
|
_with_0:write(fmt('', 'than', 'than', 'string', 'data )')) |
|
_with_0:write('\n') |
|
for name, tree in spairs(trees) do |
|
_with_0:write(('@%s\n'):format(name)) |
|
local lefts, rights, entry = traverse_tree(tree) |
|
local sort_fn |
|
if name == 'asma-opcodes' then |
|
if rights[opcodes_in_order[1]] then |
|
rights[opcodes_in_order[1]] = rights[opcodes_in_order[1]] .. ' &_disasm' |
|
else |
|
rights[opcodes_in_order[1]] = ' $2 &_disasm' |
|
end |
|
sort_fn = ordered_opcodes |
|
else |
|
sort_fn = spairs |
|
end |
|
for k, v in sort_fn(tree) do |
|
local label |
|
if k == entry then |
|
label = '&_entry' |
|
elseif k then |
|
label = ('&%s'):format(k) |
|
else |
|
label = '' |
|
end |
|
_with_0:write(fmt(label, lefts[k] or ' $2', rights[k] or ' $2', unpack(v))) |
|
end |
|
_with_0:write('\n') |
|
end |
|
_with_0:close() |
|
end |
|
return os.execute('mv projects/library/asma.tal.tmp projects/library/asma.tal')
|
|
|