;; Transform a string: replace '[' with '(' and append one ')' per '[' at end of each line.
(define (split-lines s)
(let loop ((i 0) (len (string-length s)) (cur "") (acc '()))
(if (>= i len)
(reverse (cons cur acc))
(let ((ch (string-ref s i)))
(if (char=? ch #\newline)
(loop (+ i 1) len "" (cons cur acc))
(loop (+ i 1) len (string-append cur (string ch)) acc))))))
(define (count-char s target)
(let loop ((i 0) (len (string-length s)) (cnt 0))
(if (>= i len)
cnt
(let ((ch (string-ref s i)))
(loop (+ i 1) len (if (char=? ch target) (+ cnt 1) cnt))))))
(define (replace-brackets s)
(let loop ((i 0) (len (string-length s)) (out ""))
(if (>= i len)
out
(let ((ch (string-ref s i)))
(loop (+ i 1) len
(string-append out (string (if (char=? ch #\[) #\( ch))))))))
(define (process-line line)
(let ((n (count-char line #\[))
(repl (replace-brackets line)))
(string-append repl (make-string n #\)))))
(define (join-lines lines)
(let loop ((lst lines) (out ""))
(if (null? lst)
out
(let ((next (if (string=? out "") (car lst) (string-append out "\n" (car lst)))))
(loop (cdr lst) next)))))
(define (compile s)
(join-lines (map process-line (split-lines s))))