asma.lua (2792B)
1 local output = assert(io.open('.asma.tal', 'w')) 2 local process_subtree 3 process_subtree = function(items) 4 local middle = math.floor(#items / 2 + 1.25) 5 local node = items[middle] 6 if not node then 7 return 8 end 9 node.left = process_subtree((function() 10 local _accum_0 = { } 11 local _len_0 = 1 12 for i, item in ipairs(items) do 13 if i < middle then 14 _accum_0[_len_0] = item 15 _len_0 = _len_0 + 1 16 end 17 end 18 return _accum_0 19 end)()) 20 node.right = process_subtree((function() 21 local _accum_0 = { } 22 local _len_0 = 1 23 for i, item in ipairs(items) do 24 if i > middle then 25 _accum_0[_len_0] = item 26 _len_0 = _len_0 + 1 27 end 28 end 29 return _accum_0 30 end)()) 31 return node 32 end 33 local process_tree 34 process_tree = function(items) 35 local sorted_items 36 do 37 local _accum_0 = { } 38 local _len_0 = 1 39 for _index_0 = 1, #items do 40 local item = items[_index_0] 41 _accum_0[_len_0] = item 42 _len_0 = _len_0 + 1 43 end 44 sorted_items = _accum_0 45 end 46 table.sort(sorted_items, function(a, b) 47 return a.order < b.order 48 end); 49 (process_subtree(sorted_items)).label = '&_entry' 50 for _index_0 = 1, #items do 51 local item = items[_index_0] 52 output:write(('\t%-11s %-10s %-12s %s%s\n'):format(item.label, item.left and item.left.ref or ' $2', (item.right and item.right.ref or ' $2') .. item.extra, item.key, item.rest)) 53 end 54 end 55 local parse_tree 56 parse_tree = function(it) 57 local items = { } 58 for l in it do 59 if l == '' then 60 process_tree(items) 61 output:write('\n') 62 return 63 end 64 local item = { 65 extra = '' 66 } 67 item.key, item.rest = l:match('^%s*%S+%s+%S+%s+%S+%s+(%S+)(.*)') 68 if item.key:match('^%&') then 69 item.extra = (' %s'):format(item.key) 70 item.key, item.rest = item.rest:match('^%s+(%S+)(.*)') 71 end 72 if item.key:match('^%"') then 73 item.order = item.key:sub(2) 74 elseif item.key:match('^%x%x') then 75 item.order = string.char(tonumber(item.key, 16)) 76 else 77 error(('unknown key: %q'):format(item.key)) 78 end 79 if item.order:match('^%a') then 80 item.label = ('&%s'):format(item.order) 81 elseif item.order:match('^.$') then 82 item.label = ('&%x'):format(item.order:byte()) 83 else 84 error(('unknown label: %q'):format(item.order)) 85 end 86 item.ref = (':%s'):format(item.label) 87 table.insert(items, item) 88 end 89 end 90 local it = assert(io.lines('projects/library/asma.tal')) 91 local waiting_for_cut = true 92 for l in it do 93 output:write(l) 94 output:write('\n') 95 if l:find('--- cut here ---', 1, true) then 96 waiting_for_cut = false 97 end 98 if not waiting_for_cut and '@' == l:sub(1, 1) then 99 parse_tree(it) 100 end 101 end 102 output:close() 103 return os.execute('mv .asma.tal projects/library/asma.tal')