#ifndef z #include #include static int x; static int instruction_start; static int program_start; enum ReturnState { kNormal, kFirstInstructionAfterBranch, kSecondInstructionAfterReturn, kFirstInstructionAfterReturn }; static int return_state = kFirstInstructionAfterBranch; static int stack[540] = {1 << 30}, sp = 0; static int length, offset; static jmp_buf j; #define min(a, b) a < b ? a : b #define z \ case __LINE__: \ (return_state & 1) \ ? /* Unconditionally move to next instruction after branch. */ \ (return_state--, \ (x = 0), \ (void)(instruction_start = __LINE__ + 1)) \ : (__LINE__ - program_start) % 9 \ ? /* Accumulate. */ \ (void)(x |= 1 << (__LINE__ - instruction_start)) \ : __LINE__ - instruction_start != 17 \ ? /* Output. */ \ (putchar(x), \ (x = 0), \ --stack[sp]) \ ? /* Keep going if there are more bytes to print. */ \ (void)(instruction_start = __LINE__ + 1) \ : /* Pop stack when we have printed enough bytes. */ \ (return_state = kFirstInstructionAfterReturn, \ (sp -= 2), \ longjmp(j, stack[sp + 1])) \ : /* Branch. */ \ ((length = (x & 0xff) + 3), \ (offset = ((x >> 9) + 3) * 9), \ return_state == kSecondInstructionAfterReturn) \ ? (stack[sp] -= length) <= 0 \ ? /* Recursive return. */ \ (return_state = kFirstInstructionAfterReturn, \ (sp -= 2), \ longjmp(j, stack[sp + 1])) \ : /* Completed return chain. */ \ ((return_state = kNormal), \ (instruction_start = __LINE__ + 1), \ (void)(x = 0)) \ : /* Initiate branch. */ \ ((stack[sp + 1] = instruction_start - 1), \ (stack[sp + 2] = min(stack[sp], length)), \ (return_state = kFirstInstructionAfterBranch), \ (sp += 2), \ longjmp(j, __LINE__ - offset)); int main(int argc, char **argv) { switch(setjmp(j)) { default: return_state--; x = 0; program_start = __LINE__ + 7; instruction_start = program_start + 1; #include __FILE__ #undef z #define z } } #endif // 1 // 2 // 3 z // 4 z // 5 // 6 z // 7 // 8 z // 0 -> "X" z // 1 // 2 // 3 z // 4 z // 5 // 6 z // 7 // 8 z // 0 -> "Y" // 1 z // 2 // 3 z // 4 // 5 // 6 // 7 // 8 z // 0 -> "\n" z // 1 // 2 // 3 z // 4 // 5 // 6 // 7 // 8 // 9 // 10 z // 11 // 12 // 13 // 14 // 15 // 16 // 17 z // 0 -> repeat 12, offset = -3 // 1 z // 2 // 3 z // 4 // 5 // 6 // 7 // 8 z // 0 -> "\n"