Acc!!, 129 bytes
Not bad for a fairly verbose Turing tarpit...
N
Count i while _%128-9 {
Count x while _/128%2 {
Write 40
_+128
}
Write _%128
_+128-_%128+N
}
Count j while _/256-j {
Write 41
}
(Yes, all that whitespace is mandatory.)
Note: because of the input limitations of Acc!!, it is impossible to read an arbitrary string of characters without some ending delimiter. Therefore, this program expects input (on stdin) as a string followed by a tab character.
Acc!!?
It's a language I created that only appears to be unusable. The only data type is integers, the only control flow construct is the Count x while y
loop, and the only way to store data is a single accumulator _
. Input and output are done one character at a time, using the special value N
and the Write
statement. Despite these limitations, I'm quite sure that Acc!! is Turing-complete.
Explanation
The basic strategy in Acc!! programming is to use mod %
and integer division /
to conceptually partition the accumulator, allowing it to store multiple values at once. In this program, we use three such sections: the lowest-order seven bits (_%128
) store an ASCII code from input; the next bit (_/128%2
) stores a flag value; and the remaining bits (_/256
) count the number of close-parens we will need.
Input in Acc!! comes from the special value N
, which reads a single character and evaluates to its ASCII code. Any statement that consists solely of an expression assigns the result of that expression to the accumulator. So we start by storing the first character's code in the accumulator.
_%128
will store the most recently read character. So the first loop runs while _%128-9
is nonzero--that is, until the current character is a tab.
Inside the loop, we want to print (
unless we're on the first iteration. Since Acc!! has no if statement, we have to use loops for conditionals. We use the 128's bit of the accumulator, _/128%2
, as a flag value. On the first pass, the only thing in the accumulator is an ASCII value < 128, so the flag is 0 and the loop is skipped. On every subsequent pass, we will make sure the flag is 1.
Inside the Count x
loop (whenever the flag is 1), we write an open paren (ASCII 40
) and add 128 to the accumulator, thereby setting the flag to 0 and exiting the loop. This also happens to increment the value of _/256
, which we will use as our tally of close-parens to be output.
Regardless of the flag's value, we write the most recent input char, which is simply _%128
.
The next assignment (_+128-_%128+N
) does two things. First, by adding 128, it sets the flag for the next time through the loop. Second, it zeros out the _%128
slot, reads another character, and stores it there. Then we loop.
When the Count i
loop exits, we have just read a tab character, and the accumulator value breaks down like this:
_%128
: 9
(the tab character)
_/128%2
: 1
(the flag)
_/256
: number of characters read, minus 1
(The minus 1 is because we only add 128 to the accumulator once during the first pass through the main loop.) All that we need now are the close-parens. Count j while _/256-j
loops _/256
times, writing a close-paren (ASCII 41
) each time. Voila!
You may take the input and the output in any reasonable format.
A list of characters seems perfectly reasonable to me. \$\endgroup\$