day 4 golf again
[aoc_eblake.git] / 2018 / day21.m4
blobfe53366b27772b82e94c889dfbf2d1b409008cfd
1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day21.input] day21.m4
4 include(`common.m4')ifelse(common(21), `ok', `',
5 `errprint(`Missing common initialization
6 ')m4exit(1)')
8 define(`input', translit(include(defn(`file')), nl`#', `;'))
9 define(`ip', `r'substr(defn(`input'), 3, 1))
10 define(`list', substr(defn(`input'), 5))
11 define(`cnt', 0)
12 define(`visit', `_$0(cnt, translit(`$1', ` ', `,'))')
13 define(`_visit', `define(`i$1', `$2')define(`a$1', `$3,$4,$5')define(
14   `cnt', incr($1))')
15 ifdef(`__gnu__', `
16   patsubst(defn(`list'), `\([^;]*\);', `visit(`\1')')
17 ', `
18   define(`_chew', `visit(substr(`$1', 0, index(`$1', `;')))define(`tail',
19     substr(`$1', incr(index(`$1', `;'))))ifelse(index(
20     defn(`tail'), `;'), -1, `', `$0(defn(`tail'))')')
21   define(`chew', `ifelse(eval(`$1 < 20'), 1, `_$0(`$2')', `$0(eval(`$1/2'),
22     substr(`$2', 0, eval(`$1/2')))$0(eval(len(defn(`tail'))` + $1 - $1/2'),
23     defn(`tail')substr(`$2', eval(`$1/2')))')')
24   chew(len(defn(`list')), defn(`list'))
26 forloop(0, 5, `define(`r'', `, 0)')
27 define(`addr_', `define(`r$3', eval(r$1+r$2))')
28 define(`addi_', `define(`r$3', eval(r$1+$2))')
29 define(`mulr_', `define(`r$3', eval(r$1*r$2))')
30 # Peephole optimization: rather than loop by 1 until one register * 256 is
31 # greater than another, just perform the truncating division on the first pass
32 define(`muli_', `define(`r$3', eval(r$1*$2))ifelse($2, 256, `hack(decr(ip),
33   incr(ip))')')
34 define(`hack', `ifelse(defn(`i$1')defn(`i$2'), `addigtrr', `_$0(a$1, a$2)')')
35 define(`_hack', `define(`r$1', eval(r$5>>8))define(`r$4', incr(r$5))')
36 define(`banr_', `define(`r$3', eval(r$1&r$2))')
37 define(`bani_', `define(`r$3', eval(r$1&$2))')
38 define(`borr_', `define(`r$3', eval(r$1|r$2))')
39 define(`bori_', `define(`r$3', eval(r$1|$2))')
40 define(`setr_', `define(`r$3', r$1)')
41 define(`seti_', `define(`r$3', $1)')
42 define(`gtir_', `define(`r$3', eval($1>r$2))')
43 define(`gtri_', `define(`r$3', eval(r$1>$2))')
44 define(`gtrr_', `define(`r$3', eval(r$1>r$2))')
45 define(`eqir_', `define(`r$3', eval($1==r$2))')
46 define(`eqri_', `define(`r$3', eval(r$1==$2))')
47 # Peephole optimization: instead of trying different r0 starting values,
48 # see what value r0 is expected to have, and pretend it did.
49 define(`eqrr_', `define(`r$3', eval(r$1==r$2))ifelse($2, 0, `hack2(r$1, $3)')')
50 define(`hack2', `ifdef(`part1', `ifdef(`h$1', `define(`r$2', 1)', `define(
51   `part2', $1)define(`h$1')')', `define(`part1', $1)')')
52 define(`run', `_$0(ip)')
53 define(`_run', `ifdef(`i$1', `i$1()_(a$1)define(defn(`ip'), incr(ip))$0(ip)')')
54 run()
56 divert`'part1
57 part2