benchmark                                        time (avg)             (min … max)       p75       p99      p995
----------------------------------------------------------------------------------- -----------------------------
transform                                     53.55 µs/iter    (40.47 µs … 3.71 ms)  49.03 µs 221.54 µs 332.98 µs
transformBlock                                11.67 µs/iter   (9.46 µs … 869.33 µs)   10.8 µs  33.09 µs  36.68 µs
transformVariableDecl                        612.18 ns/iter  (531.9 ns … 960.45 ns) 615.87 ns 960.45 ns 960.45 ns
transformExpr :: `20 / ((5 + a) ^ (a + b))`  509.35 ns/iter (466.79 ns … 773.72 ns) 515.96 ns 756.48 ns 773.72 ns
transformBlockCallExpr :: `print(a + b)`        451 ns/iter  (403.7 ns … 772.28 ns) 462.06 ns  700.4 ns 772.28 ns

[+] check if string contains escapable characters before 
    replacing

transform                                     36.27 µs/iter    (29.66 µs … 1.42 ms)   33.1 µs 104.82 µs 247.19 µs
transformBlock                                 5.72 µs/iter     (5.63 µs … 6.17 µs)   5.71 µs   6.17 µs   6.17 µs
transformVariableDecl                        312.97 ns/iter (289.81 ns … 432.07 ns)  319.6 ns 389.74 ns 432.07 ns
transformExpr :: `20 / ((5 + a) ^ (a + b))`  453.37 ns/iter (429.78 ns … 523.84 ns) 459.99 ns 495.72 ns 523.84 ns
transformBlockCallExpr :: `print(a + b)`     194.72 ns/iter (184.87 ns … 239.98 ns) 198.91 ns 227.68 ns 239.71 ns

[-] move idents into TransformState, had to change
    benchmarks slightly

transform                                     37.73 µs/iter    (29.89 µs … 1.74 ms)  34.41 µs 147.62 µs 244.81 µs
transformBlock                                 6.17 µs/iter   (5.36 µs … 660.08 µs)   6.28 µs   8.71 µs  11.31 µs
transformVariableDecl                        329.67 ns/iter (300.06 ns … 503.69 ns) 332.52 ns 492.28 ns 503.69 ns
transformExpr :: `20 / ((5 + a) ^ (a + b))`  473.44 ns/iter (431.62 ns … 637.82 ns) 479.82 ns 582.41 ns 637.82 ns
transformBlockCallExpr :: `print(a + b)`     197.26 ns/iter  (179.65 ns … 319.4 ns) 202.18 ns 241.29 ns 244.67 ns

[-] switch back to using strings as types

transform                                     37.13 µs/iter    (31.27 µs … 2.54 ms)  33.76 µs 112.42 µs 226.41 µs
transformBlock                                 7.41 µs/iter   (6.83 µs … 576.56 µs)   7.19 µs  10.87 µs  21.64 µs
transformVariableDecl                        523.43 ns/iter (503.78 ns … 672.13 ns) 525.52 ns 628.98 ns 672.13 ns
transformExpr :: `20 / ((5 + a) ^ (a + b))`   450.4 ns/iter (430.57 ns … 542.85 ns)  455.2 ns 514.45 ns 542.85 ns
transformBlockCallExpr :: `print(a + b)`     189.01 ns/iter (180.33 ns … 286.61 ns) 192.17 ns 219.97 ns 248.98 ns

[+] iterate through typeNames instead of Object.entries()
    in transformVariableDecl()

transform                                     36.18 µs/iter    (29.69 µs … 3.26 ms)  32.74 µs  94.19 µs 242.39 µs
transformBlock                                 5.93 µs/iter   (5.44 µs … 832.39 µs)   5.85 µs    8.3 µs   9.77 µs
transformVariableDecl                        333.23 ns/iter (316.84 ns … 426.59 ns) 336.35 ns 412.75 ns 426.59 ns
transformExpr :: `20 / ((5 + a) ^ (a + b))`  445.46 ns/iter (426.16 ns … 512.61 ns) 450.72 ns 501.26 ns 512.61 ns
transformBlockCallExpr :: `print(a + b)`     191.11 ns/iter (183.08 ns … 240.99 ns) 194.36 ns    216 ns 223.62 ns

[+] made indent a string in state, add indent string
    before statement instead of passing it

transform                                     34.06 µs/iter    (28.41 µs … 1.44 ms)  30.99 µs 110.45 µs 222.66 µs
transformBlock                                 5.62 µs/iter     (5.01 µs … 1.08 ms)   5.58 µs    6.8 µs   8.48 µs
transformVariableDecl                        306.54 ns/iter (291.54 ns … 392.86 ns) 309.48 ns 344.42 ns 392.86 ns
transformExpr :: `20 / ((5 + a) ^ (a + b))`  457.71 ns/iter (431.29 ns … 581.16 ns) 461.86 ns 526.14 ns 581.16 ns
transformBlockCallExpr :: `print(a + b)`     184.39 ns/iter (172.76 ns … 208.97 ns) 188.07 ns 200.83 ns 201.95 ns

[-] dammit turns out that the regex escape thing wasn't
    even matching

transform                                     42.14 µs/iter    (35.64 µs … 1.48 ms)  38.14 µs 148.44 µs 270.71 µs
transformBlock                                 7.67 µs/iter   (7.17 µs … 533.04 µs)   7.57 µs   9.11 µs  10.88 µs
transformVariableDecl                        305.22 ns/iter (291.67 ns … 367.68 ns) 308.55 ns  348.5 ns 367.68 ns
transformExpr :: `20 / ((5 + a) ^ (a + b))`  442.14 ns/iter (425.39 ns … 481.67 ns) 446.63 ns 479.34 ns 481.67 ns
transformBlockCallExpr :: `print(a + b)`     173.47 ns/iter  (166.02 ns … 210.7 ns) 177.27 ns 190.81 ns 198.78 ns

[-] added if statement support, longer benchtest.ts

transform                                     50.17 µs/iter     (41.6 µs … 2.42 ms)  44.86 µs 200.54 µs 320.54 µs
transformBlock                                10.34 µs/iter   (9.74 µs … 548.07 µs)  10.14 µs  14.01 µs  20.94 µs
transformVariableDecl                         302.8 ns/iter (290.01 ns … 361.69 ns) 305.75 ns 338.17 ns 361.69 ns
transformExpr :: `20 / ((5 + a) ^ (a + b))`  468.38 ns/iter  (451.07 ns … 499.1 ns) 472.42 ns 497.34 ns  499.1 ns
transformBlockCallExpr :: `print(a + b)`     180.34 ns/iter  (173.4 ns … 205.18 ns) 183.79 ns 196.68 ns 204.69 ns
transformIfStmt                                1.56 µs/iter     (1.53 µs … 1.67 µs)   1.58 µs   1.67 µs   1.67 µs

? try making each type declaration group a string and directly append to it?

