view interps/c-intercal/pit/continuation.i @ 12518:2d8fe55c6e65 draft default tip

<int-e> learn The password of the month is release incident pilot.
author HackEso <hackeso@esolangs.org>
date Sun, 03 Nov 2024 00:31:02 +0000
parents 859f9b4339e6
children
line wrap: on
line source

	PLEASE NOTE

Copyright (C) 2008 Alex Smith

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

	PLEASE NOTE Creating the continuation statements
	DO CREATE (8200) GET CONTINUATION IN .1 GETTING .2
	DO CREATE (8200) GET CONTINUATION IN ,1 SUB #1 GETTING .2
	DO CREATE (8200) GET CONTINUATION IN .1 GETTING ,2 SUB #2
	DO CREATE (8200) GET CONTINUATION IN ,1 SUB #1 GETTING ,2 SUB #2
	DO CREATE (8210) CONTINUE WITH .1 SENDING .2
	DO CREATE (8210) CONTINUE WITH .1 SENDING .2~#2
	DO CREATE (8210) CONTINUE WITH .1 SENDING ,2 SUB #2
	DO CREATE (8210) CONTINUE WITH .1~#1 SENDING .2
	DO CREATE (8210) CONTINUE WITH .1~#1 SENDING .2~#2
	DO CREATE (8210) CONTINUE WITH .1~#1 SENDING ,2 SUB #2
	DO CREATE (8210) CONTINUE WITH ,1 SUB #1 SENDING .2
	DO CREATE (8210) CONTINUE WITH ,1 SUB #1 SENDING .2~#2
	DO CREATE (8210) CONTINUE WITH ,1 SUB #1 SENDING ,2 SUB #2
	DO CREATE (8205) KILL ALL THREADS
	PLEASE NOTE Initialising the counting tracker thread
	PLEASE DO .1 <- #0
(8201)	DO NOTHING

	PLEASE NOTE Definitions of the continuation statements
(8200)	DO STASH .1
	PLEASE DO (8280) NEXT
	PLEASE DO (1020) NEXT
	PLEASE DO (8270) NEXT
	PLEASE NOTE It's possible for .1 to equal :1601, so we
		    have to be careful about operating on the
		    arguments while stashed. So we use the
		    temporary global variable .8200.
	DO .8200 <- .1
	DO RETRIEVE .1
	DO :1601 <- .8200
	DO (8202) NEXT
	DO RESUME #1
(8202)	PLEASE NOTE Fork threads, one dormant, one alive
	DO COME FROM (8202)
	DO RESUME #1
(8213) 	DO RESUME '?".1~.1"$#2'~#3
(8212)	DO (8213) NEXT
	DO RETRIEVE .1 PLEASE NOTE Restoring .1's stash
	DO COME FROM (8202)
	PLEASE FORGET #1
(8211)	DO COME FROM (8211)
	PLEASE NOTE We count how many threads are in 8275 using the
		    abstention count of 8214 and block until they're
		    all done.
	PLEASE DO ABSTAIN #1 FROM (8214)
	DO STASH .1
	DO (8275) NEXT
	DO REINSTATE (8214)
	DO COME FROM (8215)
(8216)	DO NOTHING
(8215)	DO NOTHING
(8214) 	DO COME FROM (8216)
	PLEASE DO REINSTATE (8211)
	PLEASE NOTE If .8200 matches .1, we activate. This uses
		    a NEXT/NEXT/RESUME-style check because it's
		    done on multiple threads at once and because
		    a computed COME FROM would slow down the
		    program even further.
	DO .1 <- '?.8200$.1'~'#0$#65535'
	DO (8212) NEXT
	PLEASE NOTE that if this point is reached, we've reached
		    the point where unfreezing the thread is
		    necessary. First receive one datum from
		    8277 so we can send something back in the
		    continuation (this involves signaling using
		    8217), then the other thread kills itself and
		    we make a new continuation numbered the same
		    as the old one, and continue by doubleresuming
		    (so that an unfreeze can be told apart from an
		    initial call). As this is a CREATEd statement,
		    it's important to unstash :1601 and :1602
		    ourselves when doubleresuming, as the runtime
		    only does it correctly on a single resume.
	PLEASE DO ABSTAIN FROM (8217)
	DO (8260) NEXT
	DO (8276) NEXT
	DO .8201 <- .1
	DO RETRIEVE .1 PLEASE NOTE Restoring .1's stash
 	DO (8202) NEXT PLEASE NOTE .8200 is still correct!
	DO :1602 <- .8201
	PLEASE DO :1601 <- .8200
	DO RETRIEVE :1601
	DO RETRIEVE :1602
	DO RESUME #2

(8210)	PLEASE NOTE Here we use the timing guarantees. Once we
		    ABSTAIN FROM 8211, all the threads looping
		    there become unblocked simultaneously, so
		    all of them abstain 8214 (which is 2-3 cycles)
		    before any of them REINSTATES 8211 (which is
		    way lower down, after the call to 8275), so
		    we can guarantee that all the threads get a
		    chance to check to see if they match.
	DO .8210 <- .1
	PLEASE DO .1 <- :1601
	DO (8250) NEXT
	DO (8270) NEXT
	PLEASE DO ABSTAIN FROM (8211)
(8217)	DO COME FROM (8217) AGAIN
	PLEASE NOTE This double assignment is actually correct,
		    because :1602 is overloaded.
	PLEASE DO .1 <- .8210
	DO .1 <- :1602
	PLEASE DO (8277) NEXT
	PLEASE GIVE UP

	PLEASE NOTE A communications channel thread.
		    This acts like one 16-bit variable, where
	       8250 stashes the variable
	       8260 retrieves the variable
	       8270 copies it from .1
	   and 8280 copies it into .1

	       8275 is a mutex version of 8280 so that multiple
		    threads can try to view .1 at once and only
		    one will get it at a time.
	       8299 is a spinlock that traps until the current
		    operation is completed, which is needed as
		    part of the implementation of this, and then
		    double-resumes

(8299)	DO COME FROM (8299) AGAIN
	PLEASE DO RESUME #2

(8250)	DO REINSTATE (8251)
	PLEASE DO (8299) NEXT

(8260)	DO REINSTATE (8261)
	PLEASE DO (8299) NEXT

(8270)	DO REINSTATE (8271)
	DO (8277) NEXT
	PLEASE DO (8299) NEXT

(8280)	DO REINSTATE (8281)
	DO (8276) NEXT
	PLEASE DO (8299) NEXT

(8275)	DO COME FROM (8274)
(8274) 	DO (8273) NEXT ONCE
(8273) 	DO (8280) NEXT
	PLEASE DO REINSTATE (8274)
	DO RESUME #2

	PLEASE NOTE main part of the communications channel thread
	DO COME FROM (8201)
	PLEASE DO COME FROM (8259)
(8252)  DO NOTHING
(8262)	DO NOTHING
(8272)	DO NOTHING
(8282)  DO NOTHING
(8259)	PLEASE DO NOTHING

(8251)	DON'T NEXT FROM (8252) AGAIN
	DO STASH .1
	PLEASE DO ABSTAIN FROM (8299)
	DO RESUME #1

(8261)	DON'T NEXT FROM (8262) AGAIN
	DO RETRIEVE .1
	DO ABSTAIN FROM (8299)
	DO RESUME #1

(8271)	DON'T NEXT FROM (8272) AGAIN
	DO (8276) NEXT
	DO ABSTAIN FROM (8299)
	PLEASE DO RESUME #1

(8281)	DON'T NEXT FROM (8282) AGAIN
	DO (8277) NEXT
	DO ABSTAIN FROM (8299)
	PLEASE DO RESUME #1


	PLEASE NOTE 16-bit communications channel
		8276 will block until data is sent
		8277 will send the data
		data transferred from .1 to .1

(8276)	DO COME FROM (8276) AGAIN
	DO .1 <- #65535
(8283)	DO .1 <- '?.1$#    1'~'#0$#65535' AGAIN
(8284)	DO .1 <- '?.1$#    2'~'#0$#65535' AGAIN
(8285)	DO .1 <- '?.1$#    4'~'#0$#65535' AGAIN
(8286)	DO .1 <- '?.1$#    8'~'#0$#65535' AGAIN
(8287)	DO .1 <- '?.1$#   16'~'#0$#65535' AGAIN
(8288)	DO .1 <- '?.1$#   32'~'#0$#65535' AGAIN
(8289)	DO .1 <- '?.1$#   64'~'#0$#65535' AGAIN
(8290)	DO .1 <- '?.1$#  128'~'#0$#65535' AGAIN
(8291)	DO .1 <- '?.1$#  256'~'#0$#65535' AGAIN
(8292)	DO .1 <- '?.1$#  512'~'#0$#65535' AGAIN
(8293)	DO .1 <- '?.1$# 1024'~'#0$#65535' AGAIN
(8294)	DO .1 <- '?.1$# 2048'~'#0$#65535' AGAIN
(8295)	DO .1 <- '?.1$# 4096'~'#0$#65535' AGAIN
(8296)	DO .1 <- '?.1$# 8192'~'#0$#65535' AGAIN
(8297)	DO .1 <- '?.1$#16384'~'#0$#65535' AGAIN
(8298)	DO .1 <- '?.1$#32768'~'#0$#65535' AGAIN
	DO ABSTAIN FROM (8278)
	DO RESUME #1

(8277)	DO ABSTAIN .1~#    1 FROM (8283)
	DO ABSTAIN .1~#    2 FROM (8284)
	DO ABSTAIN .1~#    4 FROM (8285)
	DO ABSTAIN .1~#    8 FROM (8286)
	DO ABSTAIN .1~#   16 FROM (8287)
	DO ABSTAIN .1~#   32 FROM (8288)
	DO ABSTAIN .1~#   64 FROM (8289)
	DO ABSTAIN .1~#  128 FROM (8290)
	DO ABSTAIN .1~#  256 FROM (8291)
	DO ABSTAIN .1~#  512 FROM (8292)
	DO ABSTAIN .1~# 1024 FROM (8293)
	DO ABSTAIN .1~# 2048 FROM (8294)
	DO ABSTAIN .1~# 4096 FROM (8295)
	DO ABSTAIN .1~# 8192 FROM (8296)
	DO ABSTAIN .1~#16384 FROM (8297)
	DO ABSTAIN .1~#32768 FROM (8298)
	DO ABSTAIN FROM (8276)
(8278)	PLEASE DO COME FROM (8278) AGAIN
	PLEASE DO RESUME #1

	PLEASE NOTE Code for killing all threads. This
		    is achieved by hoping none of them are
		    in syslib (which is after the end
		    of the program), and abstaining from
		    all flow control operations in the
		    program, all operations that hold up
		    execution, and all operations that
		    could error. Unfortunately, this
		    can be affected by ONCE/AGAIN, so
		    each thread will twice more repeat
		    the abstention in the hope of catching
		    other threads as it comes past to quit.
		    Not perfect, but hopefully good enough.
                    (Of course, a simple E000 would be
		    better at this job, but it's an error
		    and non-erroring solutions are better.)
	PLEASE DO REINSTATE (8205) AGAIN
	PLEASE DO REINSTATE (8206) AGAIN
(8205)	PLEASE DO ABSTAIN FROM ABSTAINING + REINSTATING +
	CALCULATING + NEXTING + COMING FROM + RESUMING +
	FORGETTING + STASHING + RETRIEVING + WRITING IN +
	READING OUT + COMMENT AGAIN
	DON'T DO ANYTHING FOR A BIT
	PLEASE NOTE THAT THIS IS MORE TIME WASTING
(8206)	PLEASE DO ABSTAIN FROM ABSTAINING + REINSTATING +
	CALCULATING + NEXTING + COMING FROM + RESUMING +
	FORGETTING + STASHING + RETRIEVING + WRITING IN +
	READING OUT + COMMENT AGAIN
	PLEASE GIVE UP

	PLEASE NOTE The main program.
	DO COME FROM (8201)
	DO .2 <- #0
	DO (8) NEXT
(9)  	DO GET CONTINUATION IN .1 GETTING .2
	DO (10) NEXT
	DO (7) NEXT
(8)	DO (9) NEXT
(7)	DO FORGET #1
	PLEASE DO READ OUT .2
	DO CONTINUE WITH .1 SENDING #3 ONCE
	DO CONTINUE WITH .1 SENDING #4 ONCE
	DO CONTINUE WITH .1 SENDING #5 ONCE
	DO CONTINUE WITH .1 SENDING #6 ONCE
	DO CONTINUE WITH .1 SENDING #7 ONCE
	DO .2 <- .1 ONCE
	DO (11) NEXT
(12)  	DO GET CONTINUATION IN .3 GETTING .2
	DO READ OUT #31 + .1 + .2 + .3
	DO CONTINUE WITH .3 SENDING .2
(11)  	DO (12) NEXT
	PLEASE DO READ OUT #30 + .1 + .2 + .3
	PLEASE DO CONTINUE WITH .2 SENDING .3
	PLEASE KILL ALL THREADS

(10)	DO .2 <- #1
	DO READ OUT #10
	DO CONTINUE WITH .1 SENDING #2
        DO RESUME #1