uxn/etc/asma.moon

163 lines
4.1 KiB
Plaintext

--
-- Asma tree helper script
--
-- This script updates the trees at the end of projects/library/asma.tal when
-- Uxn's opcode set changes or new runes (first character of tokens) are
-- created, so that new changes in the C assembler can be incorporated rapidly
-- into asma.
--
-- To run, you need Lua or LuaJIT, and just run etc/asma.lua from the top
-- directory of Uxn's git repository:
--
-- lua etc/asma.lua
--
-- This file is written in MoonScript, which is a language that compiles to
-- Lua, the same way as e.g. CoffeeScript compiles to JavaScript. Since
-- installing MoonScript has more dependencies than Lua, the compiled
-- etc/asma.lua is kept in Uxn's repository and will be kept updated as this
-- file changes.
--
spairs = (t) ->
keys = [ k for k in pairs t ]
table.sort keys
i = 0
->
i = i + 1
keys[i], t[keys[i]]
trees = {
['asma-opcodes']: {}
}
opcodes_in_order = {}
do -- opcodes
wanted = false
for l in assert io.lines 'src/uxnasm.c'
if l == 'static char ops[][4] = {'
wanted = true
elseif wanted
if l == '};'
break
for w in l\gmatch '[^%s",][^%s",][^%s",]'
if w != '---'
trees['asma-opcodes'][w] = {
'"%s 00'\format w
''
}
table.insert opcodes_in_order, w
assert #opcodes_in_order == 32, 'didn\'t find 32 opcodes in assembler code!'
do -- first characters
representation = setmetatable {
'&': '26 00 ( & )'
},
__index: (c) => "'%s 00"\format c
process = (label, t) ->
trees[label] = {}
for k, v in pairs t
trees[label]['%02x'\format k\byte!] = {
representation[k]
':%s'\format v
}
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'
traverse_node = (t, min, max, lefts, rights) ->
i = math.ceil (min + max) / 2
if min < i
lefts[t[i]] = ':&%s'\format traverse_node t, min, i - 1, lefts, rights
if i < max
rights[t[i]] = ':&%s'\format traverse_node t, i + 1, max, lefts, rights
return t[i]
traverse_tree = (t) ->
lefts, rights = {}, {}
keys = [ k for k in pairs t ]
table.sort keys
lefts, rights, traverse_node keys, 1, #keys, lefts, rights
ptr = (s) ->
if s
return ':&%s'\format s
return ' $2'
ordered_opcodes = (t) ->
i = 0
->
i = i + 1
v = opcodes_in_order[i]
if t[v]
return v, t[v]
elseif v
return false, { '"--- 00', '' }
printout = true
fmt = (...) ->
('\t%-11s %-10s %-12s %-14s %s '\format(...)\gsub ' +$', '\n')
with assert io.open 'projects/library/asma.tal.tmp', 'w'
for l in assert io.lines 'projects/library/asma.tal'
if l\match '--- cut here ---'
break
\write l
\write '\n'
\write '( --- 8< ------- 8< --- cut here --- 8< ------- 8< --- )\n'
\write '( automatically generated code below )\n'
\write '( see etc/asma.moon for instructions )\n'
\write '\n('
\write fmt 'label', 'less', 'greater', 'key', 'binary'
\write fmt '', 'than', 'than', 'string', 'data )'
\write '\n'
for name, tree in spairs trees
\write '@%s\n'\format name
lefts, rights, entry = traverse_tree tree
sort_fn = if name == 'asma-opcodes'
if rights[opcodes_in_order[1]]
rights[opcodes_in_order[1]] ..= ' &_disasm'
else
rights[opcodes_in_order[1]] = ' $2 &_disasm'
ordered_opcodes
else
spairs
for k, v in sort_fn tree
label = if k == entry
'&_entry'
elseif k
'&%s'\format k
else
''
\write fmt label, lefts[k] or ' $2', rights[k] or ' $2', unpack v
\write '\n'
\close!
os.execute 'mv projects/library/asma.tal.tmp projects/library/asma.tal'