home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / sources / misc / 3919 < prev    next >
Encoding:
Text File  |  1992-09-10  |  54.9 KB  |  1,504 lines

  1. Newsgroups: comp.sources.misc
  2. Path: sparky!kent
  3. From: chongo@toad.com (Landon Curt Noll)
  4. Subject:  v32i028:  ioccc.1992 - 1992 International Obfuscated C Code Contest winners, Part01/05
  5. Message-ID: <csm-v32i028=ioccc.1992.103926@sparky.IMD.Sterling.COM>
  6. Followup-To: comp.sources.d
  7. X-Md4-Signature: fced55eeed9eefb316aacae723a465d0
  8. Keywords: ioccc
  9. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  10. Reply-To: chongo@hoptoad.UUCP (Landon C. Noll)
  11. Organization: Nebula Consultants in San Francisco
  12. Date: Thu, 10 Sep 1992 15:40:38 GMT
  13. Approved: kent@sparky.imd.sterling.com
  14. Lines: 1488
  15.  
  16. Submitted-by: chongo@toad.com (Landon Curt Noll)
  17. Posting-number: Volume 32, Issue 28
  18. Archive-name: ioccc.1992/part01
  19. Environment: C
  20.  
  21. Enclosed is the first of a 5 part shar file containing the winners of
  22. the 1992 International Obfuscated C Code Contest.
  23.  
  24. First, we congratulate the winners for doing a fine job.  Their efforts
  25. and feedback have resulted another good year for the contest.
  26.  
  27. Second, the 1993 contest will not open until early March 1993.  The
  28. rules are expected to be very similar to the 1992 rules, though the
  29. input format will change slightly.  Please wait for the 1993 rules
  30. to be posted before submitting 1993 entries.
  31.  
  32. Third, an International Obfuscated Perl contest is being considered.
  33. Larry Wall and Landon Curt Noll plan to formulate the contest rules
  34. (and a contest name) sometime this year.  Watch comp.lang.perl for
  35. details.  Send contest ideas (but not entries!) to chongo@toad.com.
  36.  
  37. Last, we would like to make an apology to the 1992 winners and to the
  38. net for the delay in posting of these results.  The poster of this
  39. article (chongo) went on vacation, held extended discussions with
  40. several of the contest winners and attempted to deal with one entry
  41. that appears to conflict with US export regulations.
  42.  
  43. If you find problems with some of the contest entries, or find typos
  44. in our notes, please send ->PATCH FILES OR COMPLETE FILES<- containing
  45. the corrections to:
  46.  
  47.     judges@toad.com   -or-   ...!{sun,uunet,utzoo,pyramid}!hoptoad!judges
  48.  
  49. chongo <Landon Curt Noll> /\cc/\        hoptoad!chongo
  50. Larry Bassel                            {uunet,ucbvax,cbosgd}|sun!lab
  51.  
  52. p.s. previous winners are available on ftp.uu.net via anonymous ftp
  53.      under the directory ~/pub/ioccc.  Any 'patches' to the 1992 winners
  54.      will be deposited there in a few months.
  55.  
  56. =-=
  57.  
  58.  Send comments, questions, bugs to: 
  59.   
  60.       judges@toad.com   -or-   ...!{sun,uunet,utzoo,pyramid}!hoptoad!judges
  61.    
  62.  You are strongly encouraged to read the new contest rules before
  63.  sending any entries.  The rules, and sometimes the contest Email
  64.  address itself, change over time.  A valid entry one year may
  65.  be rejected in a later year due to changes in the rules.  The typical
  66.  start date for a contest is early March.  The typical end date for a
  67.  contest is early May.
  68.    
  69.  The contest rules are posted to comp.unix.wizards, comp.lang.c,
  70.  misc.misc, alt.sources and comp.sources.d.  If you do not have access 
  71.  to these groups, or if you missed the early March posting, you may 
  72.  request a copy from the judges, via Email, at the address above.
  73.    
  74. ---- Cut Here and unpack ----
  75. #! /bin/sh
  76. # This is a shell archive.  Remove anything before this line, then feed it
  77. # into a shell via "sh file" or similar.  To overwrite existing files,
  78. # type "sh file -c".
  79. # Contents:  1992 1992/buzzard.2.design 1992/gson.c 1992/guidelines
  80. # Wrapped by kent@sparky on Thu Sep 10 10:21:20 1992
  81. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  82. echo If this archive is complete, you will see the following message:
  83. echo '          "shar: End of archive 1 (of 5)."'
  84. if test ! -d '1992' ; then
  85.     echo shar: Creating directory \"'1992'\"
  86.     mkdir '1992'
  87. fi
  88. if test -f '1992/buzzard.2.design' -a "${1}" != "-c" ; then 
  89.   echo shar: Will not clobber existing file \"'1992/buzzard.2.design'\"
  90. else
  91.   echo shar: Extracting \"'1992/buzzard.2.design'\" \(25773 characters\)
  92.   sed "s/^X//" >'1992/buzzard.2.design' <<'END_OF_FILE'
  93. X            FIRST & THIRD
  94. X            almost FORTH
  95. X
  96. X    FORTH is a language mostly familiar to users of "small" machines.
  97. XFORTH programs are small because they are interpreted--a function
  98. Xcall in FORTH takes two bytes.  FORTH is an extendable language--
  99. Xbuilt-in primitives are indistinguishable from user-defined
  100. X_words_.  FORTH interpreters are small because much of the system
  101. Xcan be coded in FORTH--only a small number of primitives need to
  102. Xbe implemented.  Some FORTH interpreters can also compile defined
  103. Xwords into machine code, resulting in a fast system.
  104. X
  105. X    FIRST is an incredibly small language which is sufficient for
  106. Xdefining the language THIRD, which is mostly like FORTH.  There are
  107. Xsome differences, and THIRD is probably just enough like FORTH for
  108. Xthose differences to be disturbing to regular FORTH users.
  109. X
  110. X    The only existing FIRST interpreter is written in obfuscated C,
  111. Xand rings in at under 800 bytes of source code, although through
  112. Xdeletion of whitespace and unobfuscation it can be brought to about
  113. X650 bytes.
  114. X
  115. X    This document FIRST defines the FIRST environment and primitives,
  116. Xwith relevent design decision explanations.  It secondly documents
  117. Xthe general strategies we will use to implement THIRD.  The THIRD
  118. Xsection demonstrates how the complete THIRD system is built up
  119. Xusing FIRST.
  120. X
  121. X
  122. XSection 1:  FIRST
  123. X
  124. X
  125. XEnvironment
  126. X
  127. X    FIRST implements a virtual machine.  The machine has three chunks
  128. Xof memory: "main memory", "the stack", and "string storage".  When
  129. Xthe virtual machine wishes to do random memory accesses, they come
  130. Xout of main memory--it cannot access the stack or string storage.
  131. X
  132. X    The stack is simply a standard LIFO data structure that is used
  133. Ximplicitly by most of the FIRST primitives.  The stack is made up
  134. Xof ints, whatever size they are on the host machine.
  135. X
  136. X    String storage is used to store the names of built-in and defined
  137. Xprimitives.  Separate storage is used for these because it allows
  138. Xthe C code to use C string operations, reducing C source code size.
  139. X
  140. X    Main memory is a large array of ints.  When we speak of
  141. Xaddresses, we actually mean indices into main memory.  Main memory
  142. Xis used for two things, primarily: the return stack and the dictionary.
  143. X
  144. X    The return stack is a LIFO data structure, independent of
  145. Xthe abovementioned "the stack", which is used by FIRST to keep
  146. Xtrack of function call return addresses.
  147. X
  148. X    The dictionary is a list of words.  Each word contains a header
  149. Xand a data field.  In the header is the address of the previous word,
  150. Xan index into the string storage indicating where the name of this
  151. Xword is stored, and a "code pointer".  The code pointer is simply
  152. Xan integer which names which "machine-language-primitive" implements
  153. Xthis instruction.  For example, for defined words the code pointer
  154. Xnames the "run some code" primitive, which pushes the current program
  155. Xcounter onto the return stack and sets the counter to the address of
  156. Xthe data field for this word.
  157. X
  158. X    There are several important pointers into main memory.  There is
  159. Xa pointer to the most recently defined word, which is used to start
  160. Xsearches back through memory when compiling words.  There is a pointer
  161. Xto the top of the return stack.  There is a pointer to the current
  162. Xend of the dictionary, used while compiling.
  163. X
  164. X    For the last two pointers, namely the return stack pointer and
  165. Xthe dictionary pointer, there is an important distinction: the pointers
  166. Xthemselves are stored in main memory (in FIRST's main memory).  This
  167. Xis critical, because it means FIRST programs can get at them without
  168. Xany further primitives needing to be defined.
  169. X
  170. X
  171. XInstructions
  172. X
  173. X    There are two kinds of FIRST instructions, normal instructions and
  174. Ximmediate instructions.  Immediate instructions do something significant
  175. Xwhen they are used.  Normal instructions compile a pointer to their
  176. Xexecutable part onto the end of the dictionary.  As we will see, this
  177. Xmeans that by default FIRST simply compiles things.
  178. X
  179. X  Integer Operations
  180. XSymbol    Name        Function
  181. X  -    binary minus    pop top 2 elements of stack, subtract, push
  182. X  *    multiply    pop top 2 elements of stack, multiply, push
  183. X  /    divide        pop top 2 elements of stack, divide, push
  184. X  <0    less than 0    pop top element of stack, push 1 if < 0 else 0
  185. X
  186. XNote that we can synthesize addition and negation from binary minus,
  187. Xbut we cannot synthesize a time efficient divide or multiply from it.
  188. X<0 is synthesizable, but only nonportably.
  189. X
  190. X  Memory Operations
  191. XSymbol    Name        Function
  192. X  @    fetch        pop top of stack, treat as address to push contents of
  193. X  !    store        top of stack is address, 2nd is value; store to memory
  194. X                and pop both off the stack
  195. X
  196. X  Input/Output Operations
  197. XName            Function
  198. Xecho            output top of stack through C's putchar()
  199. Xkey            push C's getchar() onto top of stack
  200. X_read            read a space-delimited word, find it in the
  201. X                dictionary, and compile a pointer to
  202. X                that word's code pointer onto the
  203. X                current end of the dictionary
  204. X
  205. XAlthough _read could be synthesized from key, we need _read to be able
  206. Xto compile words to be able to start any syntheses.
  207. X
  208. X  Execution Operations
  209. XName            Function
  210. Xexit            leave the current function: pop the return stack
  211. X                into the program counter
  212. X
  213. X  Immediate (compilation) Operations
  214. XSymbol    Name        Function
  215. X  :    define        read in the next space-delimited word, add it to
  216. X                the end of our string storage, and generate
  217. X                a header for the new word so that when it
  218. X                is typed it compiles a pointer to itself
  219. X                so that it can be executed.
  220. Ximmediate immediate    when used immediately after a name following a ':',
  221. X                makes the word being defined run whenever
  222. X                it is typed.
  223. X
  224. X: cannot be synthesized, because we could not synthesize anything.
  225. Ximmediate has to be an immediate operation, so it could not be
  226. Xsynthesized unless by default operations were immediate; but that
  227. Xwould preclude our being able to do any useful compilation.
  228. X
  229. X  Stack Operations
  230. XName            Function
  231. Xpick            pop top of stack, use as index into stack and copy up
  232. X                that element
  233. X
  234. XIf the data stack were stored in main memory, we could synthesize pick;
  235. Xbut putting the stack and stack pointer in main memory would significantly
  236. Xincrease the C source code size.
  237. X
  238. X    There are three more primitives, but they are "internal only"--
  239. Xthey have no names and no dictionary entries.  The first is
  240. X"pushint".  It takes the next integer out of the instruction stream
  241. Xand pushes it on the stack.  This could be synthesized, but probably
  242. Xnot without using integer constants.  It is generated by _read when
  243. Xthe input is not a known word.  The second is "compile me".  When
  244. Xthis instruction is executed, a pointer to the word's data field is
  245. Xappended to the dictionary.  The third is "run me"--the word's data
  246. Xfield is taken to be a stream of pointers to words, and is executed.
  247. X
  248. X    One last note about the environment: FIRST builds a very small
  249. Xword internally that it executes as its main loop.  This word calls
  250. X_read and then calls itself.  Each time it calls itself, it uses
  251. Xup a word on the return stack, so it will eventually trash things.
  252. XThis is discussed some more in section 2.
  253. X
  254. X
  255. XHere's a handy summary of all the FIRST words:
  256. X
  257. X    - * /        binary integer operations on the stack
  258. X    <0        is top of stack less than 0?
  259. X    @ !        read from or write to memory
  260. X    echo key    output or input one character
  261. X    _read        read a word from input and compile a pointer to it
  262. X    exit        stop running the current function
  263. X    :        compile the header of a definition
  264. X    immediate    modify the header to create an immediate word
  265. X
  266. X    Here is a sample FIRST program.  I'm assuming you're using
  267. Xthe ASCII character set.  FIRST does not depend upon ASCII, but
  268. Xsince FIRST has no syntax for character constants, one normally has
  269. Xto use decimal values.  This can be gotten around using getchar, though.
  270. XOh.  One other odd thing.  FIRST initially builds its symbol table
  271. Xby calling : several times, so it needs to get the names of the base
  272. Xsymbols as its first 13 words of input.  You could even name them
  273. Xdifferently if you wanted.
  274. X    These FIRST programs have FORTH comments in them: they are contained
  275. Xinside parentheses.  FIRST programs cannot have FORTH comments; but I need
  276. Xsome device to indicate what's going on.  (THIRD programs are an entirely
  277. Xdifferent subject.)
  278. X
  279. X    ( Our first line gives the symbols for the built-ins )
  280. X: immediate _read @ ! - * / <0 exit echo key _pick
  281. X
  282. X    ( now we define a simple word that will print out a couple characters )
  283. X
  284. X: L            ( define a word named 'L' )
  285. X  108 echo        ( output an ascii 'l' )
  286. X  exit
  287. X
  288. X: hello            ( define a word named 'hello')
  289. X  72 echo        ( output an ascii 'H' )
  290. X  101 echo        ( output an ascii 'e' )
  291. X  111            ( push ascii 'o' onto the stack )
  292. X  L L            ( output two ascii 'l's )
  293. X  echo            ( output the 'o' we pushed on the stack before )
  294. X  10 echo        ( print a newline )
  295. X  exit            ( stop running this routine )
  296. X
  297. X: test immediate    ( define a word named 'test' that runs whenever typed )
  298. X  hello            ( call hello )
  299. X  exit
  300. X
  301. Xtest
  302. X
  303. X( The result of running this program should be: 
  304. XHello
  305. X)
  306. X
  307. X
  308. XSection 2: Motivating THIRD
  309. X
  310. X    What is missing from FIRST?  There are a large number of
  311. Ximportant primitives that aren't implemented, but which are
  312. Xeasy to implement.  drop , which throws away the top of the
  313. Xstack, can be implemented as { 0 * + } -- that is, multiply
  314. Xthe top of the stack by 0 (which turns the top of the stack
  315. Xinto a 0), and then add the top two elements of the stack.
  316. X
  317. X    dup , which copies the top of the stack, can be easily
  318. Ximplemented using temporary storage locations.  Conveniently,
  319. XFIRST leaves memory locations 3, 4, and 5 unused.  So we can
  320. Ximplement dup by writing the top of stack into 3, and then
  321. Xreading it out twice: { 3 ! 3 @ 3 @ }.
  322. X
  323. X    we will never use the FIRST primitive 'pick' in building THIRD,
  324. Xjust to show that it can be done; 'pick' is only provided because
  325. Xpick itself cannot be built out of the rest of FIRST's building
  326. Xblocks.
  327. X
  328. X    So, instead of worrying about stack primitives and the
  329. Xlike, what else is missing from FIRST?  We get recursion, but
  330. Xno control flow--no conditional operations.  We cannot at the
  331. Xmoment write a looping routine which terminates.
  332. X
  333. X    Another glaring dissimilarity between FIRST and FORTH is
  334. Xthat there is no "command mode"--you cannot be outside of a
  335. X: definition and issue some straight commands to be executed.
  336. XAlso, as we noted above, we cannot do comments.
  337. X
  338. X    FORTH also provides a system for defining new data types,
  339. Xusing the words [in one version of FORTH] <builds and does> .
  340. XWe would like to implement these words as well.
  341. X
  342. X    As the highest priority thing, we will build control flow
  343. Xstructures first.  Once we have control structures, we can
  344. Xwrite recursive routines that terminate, and we are ready to
  345. Xtackle tasks like parsing, and the building of a command mode.
  346. X
  347. X    By the way, location 0 holds the dictionary pointer, location
  348. X1 holds the return stack pointer, and location 2 should always
  349. Xbe 0--it's a fake dictionary entry that means "pushint".
  350. X
  351. X
  352. XSection 3: Building THIRD
  353. X
  354. X        In this section, I'm going to keep my conversation
  355. X        indented to this depth, rather than using fake comments--
  356. X        because we'll have real comments eventually.
  357. X
  358. X        The first thing we have to do is give the symbols for our
  359. X        built-ins.
  360. X
  361. X: immediate _read @ ! - * / < exit echo key _pick
  362. X
  363. X        Next we want to be mildly self commenting, so we define
  364. X        the word 'r' to push the *address of the return stack
  365. X        pointer* onto the stack--NOT the value of the return 
  366. X        stack pointer.  (In fact, when we run r, the value of
  367. X        the return stack pointer is temporarily changed.)
  368. X
  369. X: r 1 exit
  370. X
  371. X        Next, we're currently executing a short loop that contains
  372. X        _read and recursion, which is slowly blowing up the return
  373. X        stack.  So let's define a new word, from which you can
  374. X        never return.  What it does is drops the top value off
  375. X        the return stack, calls _read, then calls itself.  Because
  376. X        it kills the top of the return stack, it can recurse
  377. X        indefinitely.
  378. X
  379. X: ]
  380. X  r @            Get the value of the return stack pointer
  381. X  1 -            Subtract one
  382. X  r !            Store it back into the return stack pointer
  383. X  _read            Read and compile one word
  384. X  ]            Start over
  385. X
  386. X        Notice that we don't need to exit, since we never come
  387. X        back.  Also, it's possible that an immediate word may
  388. X        get run during _read, and that _read will never return!
  389. X
  390. X        Now let's get compile running.
  391. X
  392. X: main immediate ]
  393. Xmain
  394. X
  395. X        Next off, I'm going to do this the easy but non-portable
  396. X        way, and put some character constant definitions in.
  397. X        I wanted them at the top of the file, but that would have
  398. X        burned too much of the return stack.
  399. X
  400. X: '"'    34    exit
  401. X: ')'    41    exit
  402. X: '\n'    10    exit
  403. X: 'space' 32    exit
  404. X: '0'    48    exit
  405. X: '-'    45    exit
  406. X
  407. X: cr '\n' echo exit
  408. X
  409. X        Next, we want to define some temporary variables for
  410. X        locations 3, 4, and 5, since this'll make our code look
  411. X        clearer.
  412. X: _x 3 @ exit
  413. X: _x! 3 ! exit
  414. X: _y 4 @ exit
  415. X: _y! 4 ! exit
  416. X
  417. X        Ok.  Now, we want to make THIRD look vaguely like FORTH,
  418. X        so we're going to define ';'.  What ; ought to do is
  419. X        terminate a compilation, and turn control over to the
  420. X        command-mode handler.  We don't have one, so all we want
  421. X        ';' to do for now is compile 'exit' at the end of the
  422. X        current word.  To do this we'll need several other words.
  423. X        
  424. X        Swap by writing out the top two elements into temps, and
  425. X        then reading them back in the other order.
  426. X: swap _x! _y! _x _y exit
  427. X        Take another look and make sure you see why that works,
  428. X        since it LOOKS like I'm reading them back in the same
  429. X        order--in fact, it not only looks like it, but I AM!
  430. X
  431. X        Addition might be nice to have.  To add, we need to
  432. X        negate the top element of the stack, and then subtract.
  433. X        To negate, we subtract from 0.
  434. X: +
  435. X  0 swap -
  436. X  -
  437. X  exit
  438. X
  439. X        Create a copy of the top of stack
  440. X: dup _x! _x _x exit
  441. X
  442. X        Get a mnemonic name for our dictionary pointer--we need
  443. X        to compile stuff, so it goes through this.
  444. X: h 0 exit
  445. X
  446. X        We're going to need to advance that pointer, so let's
  447. X        make a generic pointer-advancing function.
  448. X        Given a pointer to a memory location, increment the value
  449. X        at that memory location.
  450. X: inc
  451. X  dup @            Get another copy of the address, and get the value
  452. X            so now we have value, address on top of stack.
  453. X  1 +            Add one to the value
  454. X  swap            Swap to put the address on top of the stack
  455. X  ! exit        Write it to memory
  456. X
  457. X        , is a standard FORTH word.  It should write the top of 
  458. X        stack into the dictionary, and advance the pointer
  459. X: ,
  460. X  h @            Get the value of the dictionary pointer
  461. X  !            Write the top of stack there
  462. X  h inc            And increment the dictionary pointer
  463. X  exit
  464. X
  465. X        ' is a standard FORTH word.  It should push the address
  466. X        of the word that follows it onto the stack.  We could
  467. X        do this by making ' immediate, but then it'd need to
  468. X        parse the next word.  Instead, we compile the next word
  469. X        as normal.  When ' is executed, the top of the return
  470. X        stack will point into the instruction stream immediately
  471. X        after the ' .  We push the word there, and advance the
  472. X        return stack pointer so that we don't execute it.
  473. X: '
  474. X  r @            Get the address of the top of return stack
  475. X            We currently have a pointer to the top of return stack
  476. X  @            Get the value from there
  477. X            We currently have a pointer to the instruction stream
  478. X  dup            Get another copy of it--the bottom copy will stick
  479. X                around until the end of this word
  480. X  1 +            Increment the pointer, pointing to the NEXT instruction
  481. X  r @ !            Write it back onto the top of the return stack
  482. X            We currently have our first copy of the old pointer
  483. X                to the instruction stream
  484. X  @            Get the value there--the address of the "next word"
  485. X  exit
  486. X
  487. X        Now we're set.  ; should be an immediate word that pushes
  488. X        the address of exit onto the stack, then writes it out.
  489. X: ; immediate
  490. X  ' exit         Get the address of exit
  491. X  ,            Compile it
  492. X  exit            And we should return
  493. X
  494. X        Now let's test out ; by defining a useful word:
  495. X: drop 0 * + ;
  496. X
  497. X        Since we have 'inc', we ought to make 'dec':
  498. X: dec dup @ 1 - swap ! ;
  499. X
  500. X        Our next goal, now that we have ;, is to implement
  501. X        if-then.  To do this, we'll need to play fast and
  502. X        loose with the return stack, so let's make some
  503. X        words to save us some effort.
  504. X
  505. X        First we want a word that pops off the top of the normal
  506. X        stack and pushes it on top of the return stack.  We'll
  507. X        call this 'tor', for TO-Return-stack.   It sounds easy,
  508. X        but when tor is running, there's an extra value on the
  509. X        return stack--tor's return address!  So we have to pop
  510. X        that off first...  We better just bite the bullet and
  511. X        code it out--but we can't really break it into smaller
  512. X        words, because that'll trash the return stack.
  513. X: tor
  514. X  r @ @            Get the value off the top of the return stack
  515. X  swap            Bring the value to be pushed to the top of stack
  516. X  r @ !            Write it over the current top of return stack
  517. X  r @ 1 + r !        Increment the return stack pointer--but can't use inc
  518. X  r @ !            Store our return address back on the return stack
  519. X;
  520. X
  521. X        Next we want the opposite routine, which pops the top
  522. X        of the return stack, and puts it on the normal stack.
  523. X: fromr
  524. X  r @ @            Save old value
  525. X  r @ 1 - r !        Decrement pointer
  526. X  r @ @            Get value that we want off
  527. X  swap            Bring return address to top
  528. X  r @ !            Store it and return
  529. X;
  530. X
  531. X        Now, if we have a routine that's recursing, and we
  532. X        want to be polite about the return stack, right before
  533. X        we recurse we can run { fromr drop } so the stack won't
  534. X        blow up.  This means, though, that the first time we
  535. X        enter this recursive routine, we blow our *real* return
  536. X        address--so when we're done, we'll return up two levels.
  537. X        To save a little, we make 'tail' mean { fromr drop };
  538. X        however, it's more complex since there's a new value on
  539. X        top of the return stack.
  540. X: tail fromr fromr drop tor ;
  541. X
  542. X        Now, we want to do 'if'.  To do this, we need to convert
  543. X        values to boolean values.  The next few words set this
  544. X        up.    
  545. X
  546. X        minus gives us unary negation.
  547. X: minus 0 swap - ;
  548. X
  549. X        If top of stack is boolean, bnot gives us inverse
  550. X: bnot 1 swap - ;
  551. X
  552. X        To compare two numbers, subtract and compare to 0.
  553. X: < - <0 ;
  554. X
  555. X        logical turns the top of stack into either 0 or 1.
  556. X: logical
  557. X  dup            Get two copies of it
  558. X  0 <            1 if < 0, 0 otherwise
  559. X  swap minus        Swap number back up, and take negative
  560. X  0 <            1 if original was > 0, 0 otherwise
  561. X  +            Add them up--has to be 0 or 1!
  562. X;
  563. X
  564. X        not returns 1 if top of stack is 0, and 0 otherwise
  565. X: not logical bnot ;
  566. X
  567. X        We can test equality by subtracting and comparing to 0.
  568. X: = - not ;
  569. X
  570. X        Just to show how you compute a branch:  Suppose you've
  571. X        compiled a call to branch, and immediately after it is
  572. X        an integer constant with the offset of how far to branch.
  573. X        To branch, we use the return stack to read the offset, and
  574. X        add that on to the top of the return stack, and return.
  575. X: branch
  576. X  r @            Address of top of return stack
  577. X  @            Our return address
  578. X  @            Value from there: the branch offset
  579. X  r @ @            Our return address again
  580. X  +            The address we want to execute at
  581. X  r @ !            Store it back onto the return stack
  582. X;
  583. X
  584. X        For conditional branches, we want to branch by a certain
  585. X        amount if true, otherwise we want to skip over the branch
  586. X        offset constant--that is, branch by one.  Assuming that
  587. X        the top of the stack is the branch offset, and the second
  588. X        on the stack is 1 if we should branch, and 0 if not, the
  589. X        following computes the correct branch offset.
  590. X: computebranch 1 - * 1 + ;
  591. X
  592. X        Branch if the value on top of the stack is 0.
  593. X: notbranch
  594. X  not
  595. X  r @ @ @        Get the branch offset
  596. X  computebranch        Adjust as necessary
  597. X  r @ @ +        Calculate the new address
  598. X  r @ !            Store it
  599. X;
  600. X
  601. X        here is a standard FORTH word which returns a pointer to
  602. X        the current dictionary address--that is, the value of
  603. X        the dictionary pointer.
  604. X: here h @ ;
  605. X
  606. X        We're ALL SET to compile if...else...then constructs!
  607. X        Here's what we do.  When we get 'if', we compile a call
  608. X        to notbranch, and then compile a dummy offset, because
  609. X        we don't know where the 'then' will be.  On the *stack*
  610. X        we leave the address where we compiled the dummy offset.
  611. X        'then' will calculate the offset and fill it in for us.
  612. X: if immediate
  613. X  ' notbranch ,        Compile notbranch
  614. X  here            Save the current dictionary address
  615. X  0 ,            Compile a dummy value
  616. X;
  617. X
  618. X        then expects the address to fixup to be on the stack.
  619. X: then immediate
  620. X  dup            Make another copy of the address
  621. X  here            Find the current location, where to branch to
  622. X  swap -        Calculate the difference between them
  623. X  swap !        Bring the address to the top, and store it.
  624. X;
  625. X
  626. X        Now that we can do if...then statements, we can do
  627. X        some parsing!  Let's introduce real FORTH comments.
  628. X        find-) will scan the input until it finds a ), and
  629. X        exit.
  630. X: find-)
  631. X  key            Read in a character
  632. X  ')' =            Compare it to close parentheses
  633. X  not if        If it's not equal
  634. X    tail find-)        repeat (popping R stack)
  635. X  then            Otherwise branch here and exit
  636. X;
  637. X
  638. X: ( immediate
  639. X  find-)
  640. X;
  641. X
  642. X( we should be able to do FORTH-style comments now )
  643. X
  644. X( now that we've got comments, we can comment the rest of the code
  645. X  in a legitimate [self parsing] fashion.  Note that you can't
  646. X  nest parentheses... )
  647. X
  648. X: else immediate
  649. X  ' branch ,        ( compile a definite branch )
  650. X  here            ( push the backpatching address )
  651. X  0 ,            ( compile a dummy offset for branch )
  652. X  swap            ( bring old backpatch address to top )
  653. X  dup here swap -    ( calculate the offset from old address )
  654. X  swap !        ( put the address on top and store it )
  655. X;
  656. X
  657. X: over _x! _y! _y _x _y ;
  658. X
  659. X: add
  660. X  _x!            ( save the pointer in a temp variable )
  661. X  _x @            ( get the value pointed to )
  662. X  +            ( add the incremement from on top of the stack )
  663. X  _x !            ( and save it )
  664. X;
  665. X
  666. X: allot    h add ;
  667. X
  668. X: maybebranch
  669. X  logical        ( force the TOS to be 0 or 1 )
  670. X  r @ @ @        ( load the branch offset )
  671. X  computebranch        ( calculate the condition offset [either TOS or 1])
  672. X  r @ @ +        ( add it to the return address )
  673. X  r @ !            ( store it to our return address and return )
  674. X;
  675. X
  676. X: mod _x! _y!        ( get x then y off of stack )
  677. X  _y _y _x / _x *    ( y - y / x * x )
  678. X  -
  679. X;
  680. X
  681. X: printnum
  682. X  dup
  683. X  10 mod '0' +
  684. X  swap 10 / dup
  685. X  if
  686. X    printnum
  687. X    echo
  688. X  else
  689. X    drop
  690. X    echo
  691. X  then
  692. X;
  693. X
  694. X: .
  695. X  dup 0 <
  696. X  if
  697. X    '-' echo minus
  698. X  then
  699. X  printnum
  700. X  'space' echo
  701. X;
  702. X
  703. X: debugprint dup . cr ;
  704. X
  705. X( the following routine takes a pointer to a string, and prints it,
  706. X  except for the trailing quote.  returns a pointer to the next word
  707. X  after the trailing quote )
  708. X
  709. X: _print
  710. X  dup 1 +
  711. X  swap @
  712. X  dup '"' =
  713. X  if
  714. X    drop exit
  715. X  then
  716. X  echo
  717. X  tail _print
  718. X;
  719. X
  720. X: print _print ;
  721. X
  722. X  ( print the next thing from the instruction stream )
  723. X: immprint
  724. X  r @ @
  725. X  print
  726. X  r @ !
  727. X;
  728. X
  729. X: find-"
  730. X  key dup ,
  731. X  '"' =
  732. X  if
  733. X    exit
  734. X  then
  735. X  tail find-"
  736. X;
  737. X
  738. X: " immediate
  739. X  key drop
  740. X  ' immprint ,
  741. X  find-"
  742. X;
  743. X
  744. X: do immediate
  745. X  ' swap ,        ( compile 'swap' to swap the limit and start )
  746. X  ' tor ,        ( compile to push the limit onto the return stack )
  747. X  ' tor ,        ( compile to push the start on the return stack )
  748. X  here            ( save this address so we can branch back to it )
  749. X;
  750. X
  751. X: i r @ 1 - @ ;
  752. X: j r @ 3 - @ ;
  753. X
  754. X: > swap < ;
  755. X: <= 1 + < ;
  756. X: >= swap <= ;
  757. X
  758. X: inci 
  759. X  r @ 1 -     ( get the pointer to i )
  760. X  inc        ( add one to it )
  761. X  r @ 1 - @     ( find the value again )
  762. X  r @ 2 - @    ( find the limit value )
  763. X  <=
  764. X  if
  765. X    r @ @ @ r @ @ + r @ ! exit        ( branch )
  766. X  then
  767. X  fromr 1 +
  768. X  fromr drop
  769. X  fromr drop
  770. X  tor
  771. X;
  772. X
  773. X: loop immediate ' inci @ here - , ;
  774. X
  775. X: loopexit
  776. X
  777. X  fromr drop        ( pop off our return address )
  778. X  fromr drop        ( pop off i )
  779. X  fromr drop        ( pop off the limit of i )
  780. X;            ( and return to the caller's caller routine )
  781. X
  782. X: execute
  783. X  8 !
  784. X  ' exit 9 !
  785. X  8 tor
  786. X;
  787. X
  788. X: :: ;          ( :: is going to be a word that does ':' at runtime )
  789. X
  790. X: fix-:: immediate 3 ' :: ! ;
  791. Xfix-::
  792. X
  793. X        ( Override old definition of ':' with a new one that invokes ] )
  794. X: : immediate :: ] ;
  795. X
  796. X: command
  797. X  here 5 !              ( store dict pointer in temp variable )
  798. X  _read                 ( compile a word )
  799. X                        ( if we get control back: )
  800. X  here 5 @
  801. X  = if
  802. X    tail command        ( we didn't compile anything )
  803. X  then
  804. X  here 1 - h !          ( decrement the dictionary pointer )
  805. X  here 5 @              ( get the original value )
  806. X  = if
  807. X    here @              ( get the word that was compiled )
  808. X    execute             ( and run it )
  809. X  else
  810. X    here @              ( else it was an integer constant, so push it )
  811. X    here 1 - h !        ( and decrement the dictionary pointer again )
  812. X  then
  813. X  tail command
  814. X;
  815. X
  816. X: make-immediate        ( make a word just compiled immediate )
  817. X  here 1 -              ( back up a word in the dictionary )
  818. X  dup dup               ( save the pointer to here )
  819. X  h !                   ( store as the current dictionary pointer )
  820. X  @                     ( get the run-time code pointer )
  821. X  swap                  ( get the dict pointer again )
  822. X  1 -                   ( point to the compile-time code pointer )
  823. X  !                     ( write run-time code pointer on compile-time pointer )
  824. X;
  825. X
  826. X: <build immediate
  827. X  make-immediate        ( make the word compiled so far immediate )
  828. X  ' :: ,                ( compile '::', so we read next word )
  829. X  2 ,                   ( compile 'pushint' )
  830. X  here 0 ,              ( write out a 0 but save address for does> )
  831. X  ' , ,                 ( compile a push that address onto dictionary )
  832. X;
  833. X
  834. X: does> immediate
  835. X  ' command ,           ( jump back into command mode at runtime )
  836. X  here swap !           ( backpatch the build> to point to here )
  837. X  2 ,                   ( compile run-code primitive so we look like a word )
  838. X  ' fromr ,             ( compile fromr, which leaves var address on stack )
  839. X;
  840. X
  841. X
  842. X: _dump                 ( dump out the definition of a word, sort of )
  843. X  dup " (" . " , "
  844. X  dup @                 ( save the pointer and get the contents )
  845. X  dup ' exit
  846. X  = if
  847. X        " ;)" cr exit
  848. X  then
  849. X  . " ), "
  850. X  1 +
  851. X  tail _dump
  852. X;
  853. X
  854. X: dump _dump ;
  855. X
  856. X: # . cr ;
  857. X  
  858. X: var <build , does> ;
  859. X: constant <build , does> @ ;
  860. X: array <build allot does> + ;
  861. X
  862. X: [ immediate command ;
  863. X: _welcome " Welcome to THIRD.
  864. XOk.
  865. X" ;
  866. X
  867. X: ; immediate ' exit , command exit
  868. X
  869. X[
  870. X
  871. X_welcome
  872. X
  873. END_OF_FILE
  874.   if test 25773 -ne `wc -c <'1992/buzzard.2.design'`; then
  875.     echo shar: \"'1992/buzzard.2.design'\" unpacked with wrong size!
  876.   fi
  877.   # end of '1992/buzzard.2.design'
  878. fi
  879. if test -f '1992/gson.c' -a "${1}" != "-c" ; then 
  880.   echo shar: Will not clobber existing file \"'1992/gson.c'\"
  881. else
  882.   echo shar: Extracting \"'1992/gson.c'\" \(1513 characters\)
  883.   sed "s/^X//" >'1992/gson.c' <<'END_OF_FILE'
  884. X#include <stdio.h> 
  885. X
  886. Xlong a
  887. X[4],b[
  888. X4],c[4]
  889. X,d[0400],e=1;
  890. Xtypedef struct f{long g
  891. X,h,i[4]       ,j;struct f*k;}f;f g,*
  892. Xl[4096             ]; char h[256],*m,k=3;
  893. X             long n    (o, p,q)long*o,*p,*q;{
  894. X             long r          =4,s,i=0;for(;r--;s=i^
  895. X             *o^*p,                i=i&*p|(i|*p)&~*o++,*q
  896. X             ++=s,p                ++);return i;}t(i,p)long*p
  897. X             ;{*c=d          [i],n(a,c,b),n(p,b,p);}u(j)f*j;{j->h
  898. X             =(j->g    =j->i[0]|j->i[1]|j->i[2]|j->i[3])&4095;}v(
  899. Xj,s)f*             j; {int i; for(j->k->k&&v(j->k, ' '),fseek(
  900. Xstdin,       j->j, 0);i=getchar(),putchar(i-'\n'?i:s),i-
  901. X'\n';);}w(o,r,j,x,p)f*o,*j;long p;{f q;int 
  902. Xs,i=o->h;q.k=o;r>i?j=l[r=i]:r<i&&
  903. X(s=r&~i)?(s|=s>>1, s|=s
  904. X>>2,s|=s>>4,s
  905. X|=s>>8
  906. X,j=l[r
  907. X=((r&i
  908. X             |s)&~(s>>1))-1&i]):0;--x;for
  909. X         (;x&&!(p&i);p>>=1);for(;!x&&j;n(o->i,j->i,q.
  910. X        i),u(&q),q.g||(q.j=j->j,v(&q,'\n')),j=j->k);for(;x;j=x
  911. X     ?j->k:0){for(;!j&&((r=(r&i)-1&i)-i&&(r&p)?2:(x=0));j=l[r]);!
  912. X      x||(j->g&~o->g)||n                  (o->i,j->i,q.i)||(
  913. X    u(&q), q.j=j                          ->j,q.g?w(&q
  914. X   ,r,j->k,x                              ,p):v(&q,
  915. X  '\n'));                                 }}y(){f
  916. X j;char                                       *z,*p;
  917. Xfor(;m                                    ? j.j=
  918. Xftell(                                    stdin)
  919. X,7,(m=                 gets(m                    ))||w(
  920. X&g,315                 *13,l[                    4095]
  921. X ,k,64*                 64)&0:                       0;n(g
  922. X  .i,j.i,             b)||(u                    (&j),j.
  923. X   k=l[j.h],l[j.h]= &j,y())){for(z=                p=h;*z&&(
  924. X    d[*z++]||(p=0)););for(z=p?n(j.i              ,j.i,j.i)+h:"";
  925. X  *z;t(*z++,j.i));}}main(o,p)char**         p; {for(;m = *++p;)for(;*m-
  926. X'-'?*m:(k= -atoi(m))&0;d[*m]||(d[*m         ]=e,e<<=1),t(*m++,g.i)); u(&
  927. X                 g),m=h
  928. X                 ,y();}
  929. END_OF_FILE
  930.   if test 1513 -ne `wc -c <'1992/gson.c'`; then
  931.     echo shar: \"'1992/gson.c'\" unpacked with wrong size!
  932.   fi
  933.   # end of '1992/gson.c'
  934. fi
  935. if test -f '1992/guidelines' -a "${1}" != "-c" ; then 
  936.   echo shar: Will not clobber existing file \"'1992/guidelines'\"
  937. else
  938.   echo shar: Extracting \"'1992/guidelines'\" \(22215 characters\)
  939.   sed "s/^X//" >'1992/guidelines' <<'END_OF_FILE'
  940. X9th International Obfuscated C Code Contest Guidelines, Hints and Comments
  941. X
  942. X
  943. XABOUT THIS FILE:
  944. X
  945. X    This file is intended to help people who wish to submit entries to
  946. X    the International Obfuscated C Code Contest (IOCCC for short).
  947. X
  948. X    This is not the IOCCC rules, though it does contain comments about
  949. X    them.  The guidelines should be viewed as hints and suggestions.
  950. X    Entries that violate the guidelines but remain within the rules are
  951. X    allowed.  Even so, you are safer if you remain within the guidelines.
  952. X
  953. X    You should read the current IOCCC rules, prior to submitting entries.
  954. X    The rules are typically sent out with these guidelines.
  955. X
  956. X
  957. XWHAT IS NEW IN 1992:
  958. X
  959. X    The size rules are different this year.  There is a more relaxed
  960. X    rule to encourage formatting styles beyond rectangular blobs of C
  961. X    code.  The build file (how to compile) has been expanded as well.
  962. X    See the rules, and OUR LIKES AND DISLIKES for details.
  963. X
  964. X    The entry format is better (for us anyway).  The program mkentry.c
  965. X    provides a convenient way to form an entry.  See ENTRY FORMAT.
  966. X
  967. X    The original entry source, build and resulting binary should be
  968. X    treated as read-only.  There is a provision to allow entries to
  969. X    modify these files indirectly.  See ENTRY FORMAT.
  970. X
  971. X    This year, we are experimenting with a new category of programs:
  972. X    X clients.  X client entries should be as portable as possible.
  973. X    See OUR LIKES AND DISLIKES.
  974. X
  975. X
  976. XHINTS AND SUGGESTIONS:
  977. X
  978. X    You are encouraged to examine the winners of previous contests.  See
  979. X    FOR MORE INFORMATION for details on how to get previous winners.
  980. X
  981. X    Keep in mind that rules change from year to year, so some winning entries
  982. X    may not be valid entries this year.  What was unique and novel one year
  983. X    might be 'old' the next year.
  984. X
  985. X    An entry is usually examined in a number of ways.  We typically apply
  986. X    a number of tests to an entry:
  987. X
  988. X    * look at the original source
  989. X    * If it is ANSI, convert tri-graphs to ASCII
  990. X    * C pre-process the source ignoring '#include' lines
  991. X    * C pre-process the source ignoring '#define' and '#include' lines
  992. X    * run it through a C beautifier
  993. X    * examine the algorithm
  994. X    * lint it
  995. X    * compile it
  996. X    * execute it
  997. X
  998. X    You should consider how your entry looks in each of the above tests.
  999. X    You should ask yourself if your entry remains obscure after it has been
  1000. X    'cleaned up' by the C pre-processor and a C beautifier.
  1001. X
  1002. X    Your entry need not do well under all, or in most tests.  In certain
  1003. X    cases, a test is not important.  Entries that compete for the
  1004. X    'strangest/most creative source layout' need not do as well as
  1005. X    others in terms of their algorithm.  On the other hand, given
  1006. X    two such entries, we are more inclined to pick the entry that
  1007. X    does something interesting when you run it.
  1008. X
  1009. X    We try to avoid limiting creativity in our rules.  As such, we leave
  1010. X    the contest open for creative rule interpretation.  As in real life
  1011. X    programming, interpreting a requirements document or a customer request
  1012. X    is important.  For this reason, we often award 'worst abuse of the
  1013. X    rules' to an entry that illustrates this point in an ironic way.
  1014. X
  1015. X    If you do plan to abuse the rules, we suggest that you let us know
  1016. X    in the remarks section.  Please note that an invitation to abuse
  1017. X    is not an invitation to break.  We are strict when it comes to the
  1018. X    3217 byte size limit.  Also, abusing the entry format tends to
  1019. X    annoy more than amuse.
  1020. X
  1021. X    We do realize that there are holes in the rules, and invite entries
  1022. X    to attempt to exploit them.  We will award 'worst abuse of the rules'
  1023. X    and then plug the hole next year.  Even so, we will attempt to use
  1024. X    the smallest plug needed, if not smaller.  :-)
  1025. X
  1026. X    Check out your program and be sure that it works.  We sometimes make
  1027. X    the effort to debug an entry that has a slight problem, particularly
  1028. X    in or near the final round.  On the other hand, we have seen some
  1029. X    of the best entries fall down because they didn't work.
  1030. X
  1031. X    We tend to look down on a prime number printer, that claims that
  1032. X    16 is a prime number.  If you do have a bug, you are better off
  1033. X    documenting it.  Noting "this entry sometimes prints the 4th power
  1034. X    of a prime by mistake" would save the above entry.  And sometimes,
  1035. X    a strange bug/feature can even help the entry!  Of course, a correctly
  1036. X    working entry is best.
  1037. X
  1038. X
  1039. XOUR LIKES AND DISLIKES:
  1040. X
  1041. X    Doing masses of #defines to obscure the source has become 'old'.  We
  1042. X    tend to 'see thru' masses of #defines due to our pre-processor tests
  1043. X    that we apply.  Simply abusing #defines or -Dfoo=bar won't go as far
  1044. X    as a program that is more well rounded in confusion.
  1045. X
  1046. X    Many ANSI C compilers dislike the following code, and so do we:
  1047. X
  1048. X    #define d define
  1049. X    #d foo           <-- don't expect this to turn into #define foo
  1050. X
  1051. X    int i;
  1052. X    j;           <-- don't use such implicit type declarations
  1053. X    int k;
  1054. X
  1055. X    We suggest that you use ANSI C compilers if possible.  If you must
  1056. X    use non-ANSI C, such as K&R C, try to avoid areas that give ANSI C
  1057. X    compilers problems.
  1058. X
  1059. X    Small programs are best when they are short, obscure and concise.
  1060. X    While such programs are not as complex as other winners, they do
  1061. X    serve a useful purpose.  They are often the only program that people
  1062. X    attempt to completely understand.  For this reason, we look for
  1063. X    programs that are compact, and are instructional.
  1064. X
  1065. X    One line programs should be short one line programs, say around 80
  1066. X    bytes long.  Getting close to 160 bytes is a bit too long for one liners
  1067. X    in our books.
  1068. X
  1069. X    We tend to dislike programs that:
  1070. X
  1071. X    * are very hardware specific
  1072. X    * are very OS or Un*x version specific
  1073. X         (index/strchr differences are ok, but socket/streams specific
  1074. X          code is likely not to be)
  1075. X    * dump core or have compiler warnings
  1076. X         (it is ok only if you warn us in the 'remark' header item)
  1077. X    * won't compile under both BSD or SYS V Un*x
  1078. X    * abusing the build file to get around the size limit
  1079. X    * obfuscate by excessive use of ANSI tri-graphs
  1080. X    * are longer than they need to be
  1081. X    * are similar to previous winners
  1082. X    * are identical to previous losers  :-)
  1083. X
  1084. X    Unless you are cramped for space, or unless you are entering the
  1085. X    'best one liner' category, we suggest that you format your program
  1086. X    in a more creative way than simply forming excessively long lines.
  1087. X
  1088. X    The build file should not be used to try and get around the size
  1089. X    limit.  It is one thing to make use of a several -D's to help out,
  1090. X    but it is quite another to use 200+ bytes of -D's in order to
  1091. X    try and squeeze the source under the size limit.  You should feel
  1092. X    free to make use of the build file space, but you are better off
  1093. X    if you show some amount of restraint.
  1094. X
  1095. X    We allowed whitespace, and in certain cases ; { or } do not impact
  1096. X    your program size (up to a certain point), because we want to get
  1097. X    away from source that is simply a compact blob of characters.
  1098. X
  1099. X    Given two versions of the same program, one that is a compact blob
  1100. X    of code, and the other that is formatted more like a typical C
  1101. X    program, we tend to favor the second version.  Of course, a third
  1102. X    version of the same program that is formatted in an interesting
  1103. X    and/or obfuscated way, would definitely win over the first two!
  1104. X
  1105. X    We suggest that you avoid trying for the 'smallest self-replicating'
  1106. X    program.  We are amazed at the many different sizes that claim
  1107. X    to be the smallest.  There is nothing wrong with self-replicating
  1108. X    programs.  In fact, a number of winners have been self-replicating.
  1109. X    You might want to avoid the claim of 'smallest', lest we (or others)
  1110. X    know of a smaller one!
  1111. X
  1112. X    X client entries should be as portable as possible.  Entries that
  1113. X    adapt to a wide collection of environments will be favored.  Don't
  1114. X    depend on a particular type of display.  For example, don't depend
  1115. X    on color or a given size.  Don't require backing store.
  1116. X
  1117. X    X client entries should avoid using X related libraries and
  1118. X    software that is not in wide spread use.  We ask that such X client
  1119. X    entries restrict themselves to only the low level Xlib and the
  1120. X    Athena widget set (libX11.a, libXaw.a, libXmu.a and libXt.a).
  1121. X    Don't use M*tif, Xv*ew, or OpenL*ok toolkits, since not everyone
  1122. X    has them.  Avoid depending on a particular window manager.  Not
  1123. X    everyone has X11r5, and some people are stuck back in X11r3 (or
  1124. X    earlier), so try to target X11r4 without requiring X11r4.  Better
  1125. X    yet, try to make your entry run on all version 11 X Window Systems.
  1126. X
  1127. X    X client entries should not to depend on particular items on
  1128. X    .Xdefaults.  If you must do so, be sure to note the required lines
  1129. X    in the ---remark--- section.  Better yet, give an xrdb -merge
  1130. X    command as part of the build.
  1131. X
  1132. X    We like programs that:
  1133. X
  1134. X    * are as concise and small as they need to be
  1135. X    * do something at least quasi-interesting
  1136. X    * pass lint without complaint (not a requirement, but it is nice)
  1137. X    * are portable
  1138. X    * are unique or novel in their obfuscation style
  1139. X    * MAKE USE OF A NUMBER OF DIFFERENT TYPES OF OBFUSCATION
  1140. X    * make us laugh and/or throw up  :-)
  1141. X
  1142. X    Some types of programs can't excel in some areas.  Of course, your
  1143. X    program doesn't have to excel in all areas, but doing well in several
  1144. X    areas really does help.
  1145. X
  1146. X    We freely admit that interesting, creative or humorous comments in
  1147. X    the ---remark--- section helps your chance of winning.  If you had to
  1148. X    read of many twisted entries, you too would enjoy a good laugh or two.
  1149. X    We think the readers of the contest winners do as well.
  1150. X
  1151. X    Be creative!
  1152. X
  1153. X
  1154. XENTRY FORMAT:
  1155. X
  1156. X    In order to help us process the many entries, we must request your
  1157. X    assistance by formatting your entries in a certain way.  This format,
  1158. X    in addition, allows us to quickly separate information about the
  1159. X    author from the program itself.  (see JUDGING PROCESS)
  1160. X
  1161. X    We have provided the program, mkentry, as an example of how to
  1162. X    format entries.  You should be aware of the following warning that
  1163. X    is found in mkentry.c:
  1164. X
  1165. X    This program attempts to implement the IOCCC rules.  Every
  1166. X    attempt has been made to make sure that this program produces
  1167. X    an entry that conforms to the contest rules.  In all cases,
  1168. X    where this program differs from the contest rules, the
  1169. X    contest rules will be used.  Be sure to check with the
  1170. X    contest rules before submitting an entry.
  1171. X
  1172. X    You are not required to use mkentry.  It is convenient, however,
  1173. X    as it attempts to uuencode the needed files, and attempt to check
  1174. X    the entry against the size rules.
  1175. X
  1176. X    If you have any suggestions, comments, fixes or complaints about
  1177. X    the mkentry.c program, please send Email to the judges.  (see below)
  1178. X
  1179. X    The following is a sample entry:
  1180. X
  1181. X---entry---
  1182. Xrule:    1992
  1183. Xtitle:    chonglab
  1184. Xentry:    0
  1185. Xdate:    Mon Feb 17 13:58:57 1992
  1186. Xhost:    Un*x v6, pdp11/45
  1187. X    2.9BSD, pdp11/70
  1188. X---remark---
  1189. X    This is a non-obfuscated obfuscated C program.
  1190. X
  1191. X    It is likely not to win a prize.  But what do you expect from
  1192. X    a short example!  (yes, Hello world progs have become old too)
  1193. X---author---
  1194. Xname:    Landon Curt Noll
  1195. Xorg:    IOCCC Judging Group
  1196. Xaddr:    Toad Hall
  1197. X    San Francisco, CA 94101
  1198. X    USA
  1199. Xemail:    chongo@toad.com
  1200. Xanon:    n
  1201. X---author---
  1202. Xname:    Larry Bassel
  1203. Xorg:    IOCCC Judging Group
  1204. Xaddr:    Toad Hall
  1205. X    San Francisco, CA 94101
  1206. X    USA
  1207. Xemail:    hoptoad!sun!lab
  1208. X    lab@sun.com
  1209. Xanon:    n
  1210. X---info---
  1211. Xbegin 444 info.file
  1212. XM2&$A("!792!G;W0@>6]U('1O(&QO;VLA"@I4:&%T('1H870@:7,L(&ES+@I4
  1213. XM:&%T('1H870@:7,@;F]T+`H@("`@:7,@;F]T('1H870@=&AA="!N;W0@:7,N
  1214. XM"E1H870@:7,L('1H870@=&AA="!I<R!N;W0L(&ES(0H*"0DM+2!C:&]N9V\@
  1215. X%,3DW-`H@
  1216. X`
  1217. Xend
  1218. X---build---
  1219. Xbegin 444 build
  1220. X28V,@<')O9RYC("UO('!R;V<*
  1221. X`
  1222. Xend
  1223. X---program---
  1224. Xbegin 444 prog.c
  1225. XC;6%I;B@I>W!R:6YT9B@B2&5L;&\L('=O<FQD(5QN(BD[?0H`
  1226. X`
  1227. Xend
  1228. X---end---
  1229. X
  1230. X    Where build uudecodes into:
  1231. X
  1232. Xcc prog.c -o prog
  1233. X
  1234. X    and prog.c uudecodes into:
  1235. X
  1236. Xmain(){printf("Hello, world!\n");}
  1237. X
  1238. X    Typically the build file should assume that the source is prog.c
  1239. X    and will compile into prog.  If an entry wins, we will rename
  1240. X    its source and binary to avoid filename collision.  By tradition,
  1241. X    we use the name of the entry's title, followed by an optional
  1242. X    digit in case of name conflicts.
  1243. X
  1244. X    If the above entry somehow won the 'least likely to win' award,
  1245. X    we would use chonglab.c and chonglab.
  1246. X
  1247. X    If your entry depends on, or requires that your build, source
  1248. X    and/or binary files be a particular name, please say so in the
  1249. X    ---remark--- section.  If this case applies, it would be be helpful
  1250. X    if you did one of the following:
  1251. X
  1252. X    * Tell us how to change the filename(s) in your entry.
  1253. X
  1254. X    * Have the build file make copies of the files.  For example:
  1255. X
  1256. X        cc prog.c -o special_name        need special binary
  1257. X
  1258. X        or  rm -f special_src.c            need special source
  1259. X        cp prog.c special_src.c
  1260. X        cc special_src.c -o special_name
  1261. X
  1262. X        or  rm -f special_build            need special build
  1263. X        tail +4 build > special_build
  1264. X        sh < special_build
  1265. X
  1266. X    * Assume that we will use the entry title.  Send us a version of 
  1267. X      your build/program files that uses the name convention.  You 
  1268. X      should uuencode these files in ---data--- sections.
  1269. X
  1270. X    If your entry needs to modify its source, info or binary files,
  1271. X    please say so in the ---remark--- section.  You should try to avoid
  1272. X    touching your original build, source and binary files.  You should
  1273. X    arrange to make copies of the files you intend to modify.  This
  1274. X    will allow people to re-generate your entry from scratch.
  1275. X
  1276. X    Remember that your entry may be built without a build file.  We
  1277. X    typically incorporate the build lines into a Makefile.  If the
  1278. X    build file must exist, say so in the ---remark--- section.
  1279. X
  1280. X    If your entry needs special info files, you should uuencode them
  1281. X    into ---info--- sections.  In the case of multiple info files,
  1282. X    use multiple ---info--- sections.  If no info files are needed,
  1283. X    then skip the ---info--- section.
  1284. X
  1285. X    Info files are intended to be input, or detailed information that
  1286. X    does not fit well into the ---remark--- section.  For example, an
  1287. X    entry that implements a compiler might want to provide some sample
  1288. X    programs for the user to compile.  An entry might want to include a
  1289. X    lengthly design document, that might not be appropriate for a
  1290. X    'hints' file.
  1291. X
  1292. X    Info files should be used only to supplement your entry.  For
  1293. X    example, info files may provide sample input or detailed
  1294. X    information about your entry.  Because they are supplemental,
  1295. X    the entry should not require them exist.
  1296. X
  1297. X    In some cases, your info files might be renamed to avoid name
  1298. X    conflicts.  If info files should not be renamed for some reason,
  1299. X    say so in the ---remark--- section.
  1300. X
  1301. X    Info files must uudecode into the current directory.  If they
  1302. X    absolutely must be renamed, or moved into a sub-directory, say
  1303. X    so in the ---remark--- section.
  1304. X
  1305. X
  1306. XJUDGING PROCESS:
  1307. X
  1308. X    Entries are judged by Larry Bassel and Landon Curt Noll.
  1309. X
  1310. X    Entries are unpacked into individual directories.  The Email message
  1311. X    is unpacked into individual files, each containing:
  1312. X
  1313. X    ---entry--- section
  1314. X    all ---author--- sections
  1315. X    all ---info--- sections
  1316. X    ---build--- section
  1317. X    ---program--- section
  1318. X    any other text, including the Email message headers
  1319. X
  1320. X    Prior to judging, the 'any other text' file is scanned to be sure
  1321. X    it does not contain useful information (or in case the entry was
  1322. X    malformed and did not unpack correctly).  Information from the
  1323. X    ---author--- sections are not read until the judging process is
  1324. X    complete, and then only from entries that have won an award.
  1325. X
  1326. X    The above process helps keep us biased for/against any one particular
  1327. X    individual.  We are usually kept in the dark as much as you are
  1328. X    until the final awards are given.  We like the surprise of finding
  1329. X    out in the end, who won and where they were from.
  1330. X
  1331. X    We attempt to keep all entries anonymous, unless they win an award.
  1332. X    Because the main 'prize' of winning is being announced, we make all
  1333. X    attempts to send non-winners into oblivion.  We remove all non-winning
  1334. X    files, and shred all related paper.  By tradition, we do not even
  1335. X    reveal the number of entries that we received.  (for the curious,
  1336. X    we do indicate the volume of paper consumed when presenting the IOCCC
  1337. X    winners at talks)
  1338. X
  1339. X    After the Usenix announcement, we attempt to send Email to the
  1340. X    authors of the winning entries.  One reason we do this is to give
  1341. X    the authors a chance to comment on the way we have presented their
  1342. X    entry.  They are given the chance to correct mistakes, typos.  We
  1343. X    often accept their suggestions/comments about our remarks as well.
  1344. X    This is done prior to posting the winners to the wide world.
  1345. X
  1346. X    Judging consists of a number of elimination rounds.  During a round,
  1347. X    the collection of entries are divided into two roughly equal piles;
  1348. X    the pile that advances on to the next round, and the pile that does
  1349. X    not.  We also re-examine the entries that were eliminated in the
  1350. X    previous round.  Thus, an entry gets at least two readings.
  1351. X
  1352. X    A reading consists of a number of actions:
  1353. X
  1354. X    * reading the ---entry--- section
  1355. X    * reading the uudecoded ---build--- section
  1356. X    * reading the uudecoded ---program--- section
  1357. X    * reading the uudecoded ---info--- section(s), if any
  1358. X    * passing the source thru the C pre-processor
  1359. X        shipping over any #include files
  1360. X    * performing a number of C beautify/cleanup edits on the source
  1361. X    * passing the beautified source thru the C pre-processor
  1362. X        shipping over any #include files
  1363. X
  1364. X    In later rounds, other actions are performed:
  1365. X
  1366. X    * linting the source
  1367. X    * compiling/building the source
  1368. X    * running the program
  1369. X    * performing misc tests on the source and binary
  1370. X
  1371. X    Until we reduce the stack of entries down to about 25 entries, entries
  1372. X    are judged on an individual basis.  An entry is set aside because it
  1373. X    does not, in our opinion, meet the standard established by the round.
  1374. X    When the number of entries thins to about 25 entries, we begin to form
  1375. X    award categories.  Entries begin to compete with each other for awards.
  1376. X    An entry often will compete in several categories.
  1377. X
  1378. X    The actual award category list will vary depending on the types of entries
  1379. X    we receive.  A typical category list might be:
  1380. X
  1381. X    * best small one line program
  1382. X    * best small program
  1383. X    * strangest/most creative source layout
  1384. X    * most useful obfuscated program
  1385. X    * best game that is obfuscated
  1386. X    * most creatively obfuscated program
  1387. X    * most deceptive C code
  1388. X    * best X client (see OUR LIKES AND DISLIKES)
  1389. X    * best abuse of ANSI C
  1390. X    * worst abuse of the rules
  1391. X    * <anything else so strange that it deserves an award>
  1392. X
  1393. X    We do not limit ourselves to this list.  For example, a few entries are so
  1394. X    good/bad that they are declared winners at the start of the final round.
  1395. X    We will invent awards categories for them, if necessary.
  1396. X
  1397. X    In the final round process, we perform the difficult tasks of
  1398. X    reducing the remaining entries (typically about 25) down to 8 or 10
  1399. X    winners.  Often we are confident that the entries that make it into
  1400. X    the final round are definitely better than the ones that do not
  1401. X    make it.  The selection of the winners out of the final round, is
  1402. X    less clear cut.
  1403. X
  1404. X    Sometimes a final round entry good enough to win, but is beat out
  1405. X    by a similar, but slightly better entry.  For this reason, it is
  1406. X    sometimes worthwhile to re-enter an entry that failed to win on a
  1407. X    previous year.  There have been winners that lost in a previous
  1408. X    year.  Of course, in those cases, improving on the entry made
  1409. X    the difference!
  1410. X
  1411. X    More often that not, we select a small entry (usually one line), a
  1412. X    strange/creative layout entry, and an entry that abuses the contest
  1413. X    rules in some way.
  1414. X
  1415. X    In the end, we traditionally pick one entry as 'best'.  Sometimes such
  1416. X    an entry simply far exceeds any of the other entry.  More often, the
  1417. X    'best' is picked because it does well in a number of categories.
  1418. X
  1419. X
  1420. XANNOUNCEMENT OF WINNERS:
  1421. X
  1422. X    The first announcement, occurs at a Summer Usenix conference.  By 
  1423. X    tradition, this is done during the latter part of the UUNET/IOCCC BOF, 
  1424. X    just prior to the Berkeley BSD, and BSDI BOF.
  1425. X
  1426. X    Winning entries will be posted in late June to the following groups:
  1427. X
  1428. X        comp.lang.c          comp.unix.wizards    alt.sources
  1429. X
  1430. X    In addition, pointers to these postings are posted to the following
  1431. X
  1432. X        comp.sources.d      alt.sources.d        misc.misc
  1433. X        comp.sources.misc
  1434. X
  1435. X    Winning entries will be deposited into the uunet archives.  See
  1436. X    below for details.
  1437. X
  1438. X    Often, winning entries are published in magazines such as "The C Users
  1439. X    Journal".  Winners have appeared in books ("The New Hackers Dictionary")
  1440. X    and on T-Shirts.
  1441. X
  1442. X    Last, but not least, winners receive international fame and flames!  :-)
  1443. X
  1444. X
  1445. XFOR MORE INFORMATION:
  1446. X
  1447. X    You may contact the judges by sending Email to the following address:
  1448. X
  1449. X    ...!{apple,pyramid,sun,uunet}!hoptoad!judges    (not the address for
  1450. X    judges@toad.com                     submitting entries)
  1451. X
  1452. X    Questions and comments about the contest are welcome.
  1453. X
  1454. X    One may obtain a copy of the current rules, guidelines or mkentry
  1455. X    program as well.  To stream line these common requests, we request
  1456. X    that you use the following subjects when making such requests:
  1457. X
  1458. X    subject          to request
  1459. X    -------          ----------
  1460. X    send rules      to obtain the current IOCCC rules
  1461. X    send guidelines      to obtain the current IOCCC guidelines
  1462. X    send mkentry      to obtain the current IOCCC mkentry program
  1463. X    send allinfo      to obtain the current IOCCC rules,guidelines,mkentry
  1464. X
  1465. X    One may also obtain the above items, we well as winners of previous
  1466. X    contests, via anonymous ftp from:
  1467. X
  1468. X    host: ftp.uu.net    (137.39.1.9)
  1469. X    user: anonymous
  1470. X    pass: yourname@yourhost
  1471. X    dir:  pub/ioccc
  1472. X
  1473. X    Often, contest rules, guidelines and winners are available from
  1474. X    archive sites.  Check comp.sources.unix archives, for example.
  1475. X    You may also request previous winners by Email, using the judges
  1476. X    Email address, though we ask that you do this as a last resort.
  1477. X
  1478. X
  1479. Xchongo <Landon Curt Noll> /\cc/\      hoptoad!chongo
  1480. XLarry Bassel                  {uunet,ucbvax,cbosgd}|sun!lab
  1481. END_OF_FILE
  1482.   if test 22215 -ne `wc -c <'1992/guidelines'`; then
  1483.     echo shar: \"'1992/guidelines'\" unpacked with wrong size!
  1484.   fi
  1485.   # end of '1992/guidelines'
  1486. fi
  1487. echo shar: End of archive 1 \(of 5\).
  1488. cp /dev/null ark1isdone
  1489. MISSING=""
  1490. for I in 1 2 3 4 5 ; do
  1491.     if test ! -f ark${I}isdone ; then
  1492.     MISSING="${MISSING} ${I}"
  1493.     fi
  1494. done
  1495. if test "${MISSING}" = "" ; then
  1496.     echo You have unpacked all 5 archives.
  1497.     rm -f ark[1-9]isdone
  1498. else
  1499.     echo You still must unpack the following archives:
  1500.     echo "        " ${MISSING}
  1501. fi
  1502. exit 0
  1503. exit 0 # Just in case...
  1504.