~rabbits/uxn

uxn/etc/asma.lua -rw-r--r-- 4.8 KiB
5496712aneauoire (controller.tal) Made buttons visible in monochromatic 5 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
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')