Output the Source, One Bit at a Time

Bash, 105 bytes

trap -- 'trap|xxd -b -c1|cut -d\  -f2|tr -d \\n|cut -c`x=\`cat f||echo 1\`;echo $((x+1))>f;echo $x`' EXIT

NOTE: Make sure that you don't have an important file called f in the directory you're testing this.


If you want to test this, you can use the following command:

for i in $(seq 848); do bash path/to/script.sh 2> /dev/null; done | tr -d \\n

Which should give the same output xxd -c1 -b path/to/script.sh|cut -d\ -f2|tr -d \\n.

Explanation

This is using the trap trick - calling trap inside the trap action simply prints that line. Next that output gets piped to xxd which converts it to binary (unfortunately xxd -bp doesn't work - thus the workaround with cut & tr):

xxd -c1 -b $0|cut -d\  -f2|tr -d \\n

From that we're only interested in one bit (say N) which we can select with cut -cN.

To find out what N we're using (remember that's the part that needs to be incremented after each call), simply try to set x to the content of the file f and if it doesn't exist set it to 1:

x=`cat f||echo 1`

Last thing to do, is to update the file f - writing x+1 to it:

echo $((x+1))>f

Funky, 47 41 37 bytes

Returns a number representing a bit.

f=_=>1&("%b"%("f="+f)[i//8])>>7-i++%8

This uses the quine format of f=_=>"f="+f. It takes the character at position ⌊i/8⌋, then, gets the bit by taking the pairity of n >> 7-i%8 where n is the ascii value of the current character.

This is an iterative function that increments i with each call, once it's out of source code, it will write the code for n forever.

Try it online!


TI-Basic (TI-83 series), 592 357 309 bytes

"123456789ABCDEF02A3132333435363738394142434445463004AA003FB958833404593FB9588338045A3F3230363FDA582B383F303FCE5A405A6B3232333F5A70BB0FAA002BBB0CAA002B5A2B313FB932BA32F01058713459713511BB0FAA002BBB0CAA002B597031377132722B31→Str1
iPart(X/4→Y
iPart(X/8→Z
206
IS>(X,8
0
If Z and Z<223
Z+inString(Str1,sub(Str1,Z,1
iPart(2fPart(2^(X-4Y-5)inString(Str1,sub(Str1,Y+17-2Ans,1

This table is a possible reference for the calculator's binary representation of the source code, though ultimately I just used Virtual TI's debugger.

For comparison and/or historical interest: the first quines written in TI-Basic.

How it works

Str1 stores the source code (now in glorious hexadecimal, saving lots of space over the previous binary version), leaving out the bits where the contents of Str1 itself would be represented.

We're assuming that the program starts out on a calculator whose memory has just been cleared, so X is 0. Every time through the program, we increment X.

Usually, we just figure out the half-byte we're trying to extract a bit from, read it out of Str1, convert from hexadecimal to binary, and print it. If we're on the part of the source code that's storing Str1 (which is two-thirds of the total length of the program), then we first move to the corresponding part of the string storing 31, 32, and so on.