uxambly-translate.moon (3874B)
1 -- Used for porting Uxntal code for use with the old assembler 2 -- in commit 82f7103a55c21b13f898b20e5d1e174e501bc825 with the 3 -- assembler that replaced it straight afterwards. 4 5 import P, R, S, C, Ct, Cp, V from require 'lpeg' 6 7 local labels, filename 8 9 opcode_translate = 10 LDZ2: 'LDA' 11 STZ2: 'STA' 12 LDR: 'LDZ2' 13 STR: 'STZ2' 14 LDR2: 'LDA2' 15 STR2: 'STA2' 16 17 grammar = P { 18 'file' 19 file: Ct(V'ows' * (V'atom' * V'ows') ^ 0) * Cp! 20 ws: C S' \n\t' ^ 1 21 ows: C S' \n\t' ^ 0 22 atom: V'opcode' + V'comment' + V'variable' + V'addr' + V'literal' + V'setter' + V'getter' + V'short' + V'labeldef' + V'relative' + V'sublabel' + V'data' + V'macro' + V'macroref' + V'rawshort' 23 comment: C P'(' * (1-V'ws'*P')') ^ 0 * V'ws' * P')' 24 variable: (P';' / -> '@') * C(V'name') * V'ws' * (P'{' / ->'[') * V'ws' * ((P'' / -> '&') * C(V'name') * V'ws' * (P'' / -> '$') * C(V'name') * V'ws') ^ 0 * (P'}' / -> ']') / (...) -> 25 var = select 2, ... 26 r, w = if var\sub(1, 1) == var\sub(1, 1)\upper! 27 ' DEI', ' DEO' 28 else 29 ' LDZ', ' STZ' 30 for i = 7, select('#', ...), 6 31 k = select i, ... 32 rr, ww = if '2' == select i + 3, ... 33 r .. '2', w .. '2' 34 else 35 r, w 36 labels['~' .. var .. '.' .. k] = '.' .. var .. '/' .. k .. rr 37 labels['=' .. var .. '.' .. k] = '.' .. var .. '/' .. k .. ww 38 if i == 7 39 labels['~' .. var] = '.' .. var .. rr 40 labels['=' .. var] = '.' .. var .. ww 41 ... 42 name: R('az', 'AZ', '09', '__', '--', '++', '**', '//', '??') ^ 1 43 addr: C(P'|') * (C(V'hex') / (i) -> 44 if i == '0200' 45 return '0100' 46 if i\match '^01..$' 47 return i\sub 3 48 return i 49 ) 50 literal: C P'#' * V'hex' 51 hex: R('09', 'af', 'AF') ^ 1 52 setter: C(P'=' * V'label') / (s) -> 53 if not labels[s] 54 error 'label not found: %q in %s'\format s, filename 55 return labels[s] 56 getter: C(P'~' * V'label') / (s) -> 57 if not labels[s] 58 error 'label not found: %q in %s'\format s, filename 59 return labels[s] 60 label: R('az', 'AZ', '09', '__', '--', '..', '$$', ']]', '))', '@@', '""', ',,', '##', '||', '{{', '}}', '%%', ';;', '^^', '~~', '==', '//') ^ 1 61 short: (P',' / -> ';') * (C(V'label') / (s) -> (s\gsub '%$', '&')) 62 rawshort: (P'.' / -> ':') * (C(V'label') / (s) -> (s\gsub '%$', '&')) 63 opcode: (C(R'AZ' * R'AZ' * R'AZ' * P'2' ^ -1) / (s) -> opcode_translate[s] or s) * C P'r' ^ -1 * #V'ws' 64 labeldef: C P'@' * V'label' 65 relative: (P'^' / -> ',') * (C(V'label') / (s) -> (s\gsub '%$', '&')) 66 sublabel: (P'$' / -> '&') * (C(V'label') / (s) -> (s\gsub '%$', '&')) 67 data: C(P'[') * V'ws' * (V'data_item' * V'ws') ^ 0 * C(P']') 68 macro: C(P'%' * V'name' * V'ws' * P'{') * V'ws' * (V'atom' * V'ows') ^ 0 * C P'}' 69 macroref: C V'name' 70 data_item: C(V'hex' * #V'ws') + V'data_string' 71 data_string: C((1 - S' \n\t') ^ 1 - P']') / (s) -> '"', s 72 } 73 74 translate = (_filename) -> 75 filename = _filename 76 labels = {} 77 f = assert io.open filename 78 contents = f\read '*a' 79 f\close! 80 t, len = grammar\match contents 81 if len <= #contents 82 print '\027[32m%s\027[0;1m%s\027[0m'\format contents\sub(len - 100, len - 1), contents\sub(len, len + 100) 83 error 'no match' 84 filename = filename\gsub 'attic', 'auto' 85 f = assert io.open filename, 'w' 86 f\write table.concat(t) 87 f\close! 88 f = assert io.popen 'bin/assembler %s bin/boot.rom'\format filename 89 for l in f\lines! 90 print l 91 if l == 'Error: Assembly[Failed]' 92 os.exit 1 93 f\close! 94 os.exit 0 95 96 translate 'attic/software/assembler.tal' 97 os.exit 0 98 99 translate 'attic/tests/opcodes.tal' 100 translate 'attic/tests/basics.tal' 101 102 -- for k, v in pairs t 103 -- print k