|
| 1 | + |
| 2 | +; https://board.flatassembler.net/topic.php?p=241807#241807 |
| 3 | + |
| 4 | +if __SOURCE__ = __FILE__ ; self-test |
| 5 | + virtual |
| 6 | + TTT:: |
| 7 | + file __FILE__ |
| 8 | + end virtual |
| 9 | + |
| 10 | + iterate <TAG, VALUE>,\ |
| 11 | + "{{VEGE}}", "<<PEPPER>>",\ |
| 12 | + "{{ANIMAL}}", "{{VEGE}}<<BEAR>>",\ |
| 13 | + "{{COMMAND}}", "{{ANIMAL}}<<TESTING>>" |
| 14 | + |
| 15 | + define tags TAG |
| 16 | + define values VALUE |
| 17 | + end iterate |
| 18 | + |
| 19 | + MultiTagRep TTT |
| 20 | +end if |
| 21 | + |
| 22 | +macro MultiTagRep area*,limit:100 |
| 23 | + local DRAFT,now,replacements |
| 24 | + |
| 25 | + virtual area |
| 26 | + load now:$-$$ from $$ |
| 27 | + end virtual |
| 28 | + repeat limit |
| 29 | + virtual at 0 |
| 30 | + DRAFT.%:: |
| 31 | + db now |
| 32 | + end virtual |
| 33 | + |
| 34 | + virtual at 0 as 'result' |
| 35 | + TagReplaced DRAFT.%,replacements |
| 36 | + load now:$-$$ from $$ |
| 37 | + end virtual |
| 38 | + |
| 39 | + if replacements = 0 |
| 40 | + break |
| 41 | + end if |
| 42 | + |
| 43 | + repeat 1,\ |
| 44 | + M:sizeof DRAFT.%,\ |
| 45 | + N:lengthof now,\ |
| 46 | + O:replacements |
| 47 | + display 9,"area size:",9,`M,' -> ',`N,10 |
| 48 | + display 9,"replaced:",9,`O,10 |
| 49 | + end repeat |
| 50 | + end repeat |
| 51 | + |
| 52 | +end macro |
| 53 | + |
| 54 | +calminstruction TagReplaced area*,COUNT* ; parameterized templating |
| 55 | + local head,mark,tag,T,V,times |
| 56 | + compute times,0 |
| 57 | + compute head, -1 |
| 58 | +interval: |
| 59 | + compute mark, head + 1 |
| 60 | + |
| 61 | +tv: take tags,T |
| 62 | + take values,V |
| 63 | + jyes tv |
| 64 | + |
| 65 | +go: compute head, head + 1 |
| 66 | + check head < sizeof area |
| 67 | + jno done |
| 68 | + |
| 69 | + load tag, area:head, 1 |
| 70 | + check tag = '{' |
| 71 | + jno go |
| 72 | + |
| 73 | +vt: take T,tags |
| 74 | + take V,values |
| 75 | + jno tv |
| 76 | + |
| 77 | + check head + lengthof T <= sizeof area |
| 78 | + jno vt |
| 79 | + |
| 80 | + load tag, area:head, lengthof T |
| 81 | + check tag = T |
| 82 | + jno vt |
| 83 | + |
| 84 | + call AreaInterval,area,mark,head |
| 85 | + |
| 86 | + emit lengthof V, V |
| 87 | + compute head, head + lengthof T - 1 |
| 88 | + compute times,times+1 |
| 89 | + jump interval |
| 90 | + |
| 91 | +done: call AreaInterval,area,mark,head |
| 92 | + publish COUNT,times |
| 93 | +end calminstruction |
| 94 | + |
| 95 | +; Emit the half-open interval of an area, [x0,x1). |
| 96 | +calminstruction AreaInterval area*,x0*,x1* |
| 97 | + local bytes,value |
| 98 | + compute bytes,x1-x0 |
| 99 | + check bytes>0 |
| 100 | + jno skip |
| 101 | + load value,area:x0,bytes |
| 102 | + emit bytes,value |
| 103 | +skip: |
| 104 | +end calminstruction |
0 commit comments