_____________ _____________ /zZzZzZzZzZzZz/ /tTtTtTtTtTtTt/ /zZ/ /tT/ /Zz/ /Tt/ /Zz/ /tT/ /zZ/ /Tt/ /zZ/ /tT/ /Zz/ /Tt/ /Zz/________ /tT/ /ZzZzZzZzZzZz/ /Tt/ ZT Programming Language Documentation Written by Philipp Winterberg July 2002 Introduction ------------ Welcome to ZT. You have chosen to learn one of the beastiest programming languages on planet earth. Although ZT's syntax is easy to learn, it's an adventure to write even a small loop. A few structural thoughts are inspired by 4DL, Numberix and unbabtized. ZT has diagonal program flow, hugged data couples and commands defined only by program flow. All these features are most likely to eliminate the possibility of code reusability. Other languages like Brainf*ck etc. are far to user friendly. After a few hours of learning one can write small programs easily and reuse the code to create new applications even faster. If you manage to do this in a beautiful way in ZT, please let me know! By the way, the name ZT ("Zer0 Tolerance") is usually pronounced "Z", but feel free to find new ways. ;-) Basics ------ A ZT program consists of lots of little male and female persons called Romeos and Juliets. Each person, just like in real life, has a head (H), a body (XY) and feet (F): H <--- head X <--- body Y <--- body F <--- feet Figure 1: Structure of a ZT person (male) Head and feet are used to define program flow, the body contains important data. Since standard program flow is boring and all the Juliets out there want something unique, ZT programs are processed diagonally in all possible directions: _ _ |\ /| \ / +--------------+ | program flow | +--------------+ / \ |/_ _\| Figure 2: Directions of ZT program flow Because Romeo and Juliet are in love, they hugg each other often. As you probably expected they do it all the time in ZT programs. It looks somewhat like this: xyfH hFXY Figure 3: Romeo hugging Juliet Because they love each other so much, they don't even mind to kiss each others feet in a odd 69 position, as you can clearly see. They do this especially for you to make your ZT programs smaller. By the way, Juliet is on top. :-) Juliet's feet ______ v xyfH <-- Romeo's head Juliet's head --> hFXY ^------ Romeo's feet Figure 4: Romeo kissing Juliet's feet Hugging each other like this, Romeo and Juliet are a pretty handy couple. Lots of them can be placed in rows and columns. We now move away from the boring HXYF-Figures and take a first look at a real ZT program: 1st Juliet --> ZT<> <<2A <-- 1st Romeo 2nd Juliet --> XX<> <>ZT <-- 2nd Romeo Figure 5: A ZT program with two "Romeo and Juliet" couples packed together We can go on faster? Okay, fine, here is the same ZT program as in figure 5, but with quite a few more couples: ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<> <--- 7 Juliets <<2A<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT <--- 7 Romeos XX<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<> <--- 7 Juliets <>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT <--- 7 Romeos Figure 6: Lots of "Romeo and Juliet" couples Now in depth: A ZT program starts in the upper left corner with Juliet (Ladies first!). As you remember, Juliets body contains data ("ZT"). Her head ("<") and feet ("<") tell the ZT interpreter where to go next. Here is what she can do (for the sake of clarity, Romeo has been replaced by dots in this figure): ZT<. \ <... means: _\| (move down and right to next Romeo) ZT>. / <... means: |/_ (move down and left to next Romeo) _ ZT>. |\ >... means: \ (move up and left to next Romeo) _ ZT<. /| >... means: / (move up and right to next Romeo) Figure 7: Juliet's head and feet telling ZT interpreter where to go Fortunately the ZT interpreter was a psychologist in a former life, so he is able to understand the different languages of men and women. This becomes more important later, but that Romeo and Juliet are using the same words for very different things is already obvious: ...> \ .>ZT means: _\| (move down and right to next Juliet) ...> / .ZT means: / (move up and right to next Juliet) Figure 8: Romeo's head and feet telling ZT interpreter where to go Congratulations! You have just completed the first big step in becoming a professional ZT developer! You understood the structure of ZT persons, got to know the concept of "Romeo and Juliet" couples and the diagonal program flow. Now we continue with some straight action... Romeo and Juliet both can process "TALK", "JUMP", "MATH" and "SET" commands. But there are those little differences: Romeo only talks about Numbers, Juliet can not jump very far... So the experienced ZT developer chooses wisely the person that is the right one for the task. But how do you tell Romeo to JUMP? Or Juliet to TALK? Well, it's fairly easy: You tell them by program flow! Each Romeo and each Juliet has a data body, that usually contains some hex data. If for instance program flow comes from upper left side, Juliet will use the hex data to TALK about it (output the hex data as ASCII char to the screen). +--------------+ | program flow | +--------------+ \ _\| 4A<. --> TALK --> Output "J" (hex 4a) to the screen <... Figure 9: Program flow tells Juliet to talk Sometimes - well, okay, probably quite often - you do want Juliet to shut up and stop talking. This can be accomplished - not like in real life - fast and without any discussion. Simply put "ZT" in her data body and silence dawns: +--------------+ | program flow | +--------------+ \ _\| ZT<. --> DON'T TALK! <... Figure 10: With "ZT" in her data body, Juliet has to shut up, even though program flow tells her to talk [she is not very amused, but hey!] Memory & Commands ----------------- ZT offers Romeo and Juliet one thing that real couples dream of very often - at least in the first two weeks of their relationship -, they are allowed to share thoughts, memory to be precise. There are 16 (hex 0..F) memory slots that can be accessed by moving an index pointer to it or directly by data body pointer: "°[0..F]" (you may use "^", "*" or even "?" instead of "°", if you like). As you already know, a command is defined by program flow and data-body (XY). If the data body is "ZT", program flow will continue without Romeo or Juliet taking any action. Juliet's TALK action: ^^^^^^ +--------------+ | program flow | +--------------+ \ _\| XYF. H... --> TALK "XY" Figure 11: Program flow tells Juliet to talk TALK: Output XY as ASCII character to the screen (XY: hex-value), then MOVE in direction HF (defined by H, head, and F, feet. See figure 7). Examples: 5A<. \ <... --> output "Z" (hex 5A), then MOVE _\| _ °0<. /| >... --> output memory[0] as ASCII, then MOVE / _ Juliet's JUMP action: /| \ ^^^^^^ XYF. --> JUMP / , if memory[index] <> 0, else JUMP _\| F... _ /| / +--------------+ | program flow | +--------------+ Figure 12: Program flow tells Juliet to jump _ \ /| JUMP: If memory[index] = 0 jump one step _\| , else jump one step / . This command ignores all HXYF values, so put in it whatever you want (except "ZT"). _ Examples: UMP. /| \ J... --> jump / , if memory[index] <> 0, else JUMP _\| _ ???. /| \ ?... --> jump / , if memory[index] <> 0, else JUMP _\| _ ZT<. /| >... --> Don't jump, just MOVE / Juliet's SET action: ^^^^^^ +--------------+ | program flow | +--------------+ / |/_ XYF. H... --> All SET? Then quit ZT program and go party! Figure 13: Program flow tells Juliet to set SET: All SET? Then leave the building and go party! (XY <> "ZT"). This command ignores all HXYF values, so have fun filling them with whatever you like (except "ZT"). Examples: UIT. Q... --> Quit ???. ?... --> Quit _ ZT<. /| >... --> Don't Quit, just MOVE / Juliet's MATH action: ^^^^^^ XYF. H... _--> MATH XY |\ \ +--------------+ | program flow | +--------------+ Figure 14: Program flow tells Juliet to math MATH: index = (index + XY) mod 16 (X: '-' or hex-value, Y: hex-value), then MOVE in direction HF (defined by H, head, and F, feet. See figure 7). Examples: 01<. \ <... --> index = index + 1, then MOVE _\| _ -2<. /| >... --> index = index - 2, then MOVE / Romeo's TALK action: ^^^^^ +--------------+ | program flow | +--------------+ \ _\| ...H .FXY --> TALK "XY" Figure 15: Program flow tells Romeo to talk TALK: Output XY as number to the screen (XY: hex-value), then MOVE in direction HF (defined by H, head, and F, feet. See figure 8). Examples: ...> \ .>63 --> output "99" (hex 63), then MOVE _\| _ ...< /| .>°0 --> output memory[0], then MOVE / Romeo's JUMP action: ^^^^^ ...H --> JUMP "HF" .FXY _ /| / +--------------+ | program flow | +--------------+ Figure 16: Program flow tells Romeo to jump JUMP: Jump Y steps in direction HF (defined by H, head, and F, feet. See figure 8), X is recognized, but ROMEO is unable to jump that far. Examples: ...> \ .>63 --> jump 3 steps _\| [feeling heavily guilty for not being able to jump as far as requested] _ ...< /| .>°0 --> jump memory[0] steps / [but not more than 16] Romeo's SET action: ^^^^^ +--------------+ | program flow | +--------------+ / |/_ ...H .FXY --> SET memory[index] = "XY" Figure 17: Program flow tells Romeo to set SET: Set memory[index] to XY (hex-input, stored as decimal number), then MOVE in direction HF (defined by H, head, and F, feet. See figure 8). Examples: ...> \ .>63 --> set memory[index] = 99, then MOVE _\| _ ...< /| .>°0 --> set memory[index] = memory[0], then MOVE / ...> \ .>-3 --> set memory[index] = - 3 , then MOVE _\| Romeo's MATH action: ^^^^^ ...H .FXY _--> MATH XY |\ \ +--------------+ | program flow | +--------------+ Figure 18: Program flow tells Romeo to math MATH: Memory[index] = memory[index] + XY (X: '-' or hex-value, Y: hex-value), then MOVE in direction HF (defined by H, head, and F, feet. See figure 8). Examples: ...> \ .>63 --> memory[index] = memory[index] + 99, then MOVE _\| _ ...< /| .>°0 --> memory[index] = memory[index] + memory[0], then MOVE / ...> \ .>-3 --> memory[index] = memory[index] - 3, then MOVE _\| User Input ---------- I follow the wise 'unbabtized'-input-philosophy of Gerson Kurz: "There is no input. There is a philosophy behind this, you know! To my view, there are two kinds of input, user input and hardcoded input. User input sucks, and hardcoded input rules, so there." (2002.07.02, http://www.p-nand-q.com/unbabtized.htm) Examples -------- ZT offers a huge world of programming possibilities that you may explore now. To give you some help and final overview, here are some small ZT examples: 5A<>........ <>ZT........ ....65<>.... ....<>ZT.... ........72<> ...Zer0.<<00 .Tolerance.. Figure 19: ZT program that writes "Zer0" to the screen 47<>..................... <>ZT..................... ...>6F>>................. .>FF<>ZT................. ....ZT<.21<>...>ZT><..... ....>...<>ZT.....ZT><. ............<>°0....>. ................<>ZT< // Move -_> <<2A // Output 42, Move <_- NICE // Exit ZT CODE Figure 21: Shortest complete ZT program with comments The last line is only needed, because otherwise Juliet would be dead (head chopped off) and a dead Juliet can't do nothing. Obviously. You see, that the ZT interpreter is not really zero tolerant, but rather quite forgiving if you replace head and feet by letters. Even the data body of the second Romeo can be filled with other letters than "ZT", because program flow never reaches him (poor guy). 48<>>>>>ZT<>ZT<> Hello | <>ZT>>ZT<>ZT<>ZT World!| <<<<65<>6F<>6F<>6C<>>>>> >>>2<>ZT<>ZT<>ZT<>ZT<<<8 ZT<<<<<<6C<>20<>72<>64<< >ZT<>ZT<>ZT><<5 >>>>ZT><<<<<6C<>57<>ZT<< >>ZT><<<<<<7 ZT<<21<>ZT>>ZT<<<<<| >ZT><42<<<<<>ZT by| >>>>ZT><21<>>>> Philipp| >>>>>........................................................................ <>ZT.....ZT version of 99 Bottles of beer (Bottles.zt)...................... ...>ZT>..Philipp Winterberg, http://www.philipp-winterberg.de...................... .<63<....................................................................... ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>.... <>°0<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>.. ZT<>20<>62<>6F<>74<>74<>74<>6C<>65<>28<>73<>29<>20<>6F<>66<>20<>62<>65<>65<> >ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>> <>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT ZT<>72<>20<>6F<>6E<>20<>74<>68<>65<>20<>77<>61<>6C<>6C<>2C<>0D<>0A<>ZT<>ZT<> >ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>> <>°0>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT ZT<>20<>62<>6F<>74<>74<>74<>6C<>65<>28<>73<>29<>20<>6F<>66<>20<>62<>65<>65<> >ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>> <>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT ZT<>72<>2E<>0D<>0A<>54<>61<>6B<<65<>20<>6F<>6E<>65<>20<>64<>6F<>77<>6E<>2C<> >XXX>XXX>ZT>>ZT>>ZT>>ZT>>XXXXXT>>ZT<>ZT>>ZT>>ZT>>XXXXXT>>ZT>>ZT>>ZT>>ZT>>ZT<> <>ZT>>ZT>>ZT>>ZT>>ZTXXXXX>ZT>ZT>>ZT>>ZT>>ZTXXXXX>ZT>>ZT>>ZT>>ZT>>ZT<ZT<>ZT<>ZT<>ZT<>ZXX>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZXX>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<> >ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>> <>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT ZT<>20<>70<>61<>73<>73<>20<>69<>74<>20<>61<>72<>6F<>75<>6E<>64<>2C<>0D<>0A<> ><-1<ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>> <>°0>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT ZT<>20<>62<>6F<>74<>74<>74<>6C<>65<>28<>73<>29<>20<>6F<>66<>20<>62<>65<>65<> >ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>> <>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT ZT<>72<>20<>6F<>6E<>20<>74<>68<>65<>20<>77<>61<>6C<>6C<>2E<>0D<>0A<<0D<>0A<> >XXX>XXX>ZT>>ZT>>ZT>>ZTXXXT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>ZT>>XXX>ZT>>ZT>ZT>>ZT>> <>ZT<>ZT<>ZT<>ZT<>XXXXZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZXXXXT<>ZT<>ZT<ZT>>ZT<>ZT<>ZTZT<>ZT<>ZT<>ZT<>ZT<>ZXXXXX<>ZT<>ZT<ZT>>ZT<> <>ZT<>ZT<>ZT<>ZT<>ZTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX>ZT<>ZT>ZT ZT<>ZT>>ZT<>ZT<>ZT<>ZTXXXXXXXXXXXXXXXXXXXXXXXXXXXXX>ZT<>ZT<>ZT<>ZT>ZT<> <>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT<>ZT>ZT<>ZT Figure 23: Lousy "99 Bottles of Beer" version in ZT, showing that even bad ZT code can smile and look happy This lousy "99 Bottles of Beer" ZT program shows that even though the ZT programming language was designed to prevent reusage of code snippets, it is - by using ugly techniques - still possible to write reusable code. But a beautiful "99 Bottles of Beer" version probably could have been written with less than half of the commands used above. If you have the time to give it a face lift, please do so! Finish ------ Yeah! Cool! You made it all the way through this documentation in just about no time. The romantic world of ZT coding is now like an open book to you. Please don't hesitate to send me your ZT creations: philipp(at)winterbergs.de [preferred subject: "ZT Killer Application"] The ZT interpreter is open source and may be distributed freely under GNU GPL. If you write your own ZT interpreter or ZT compiler, please send me a copy. Appendix A ---------- Reading a first few comments on ZT, it seems to me, a little ZT FAQ (frequently asked questions) might be helpful. So: F: "Does '//' start a comment?" A: Nope. Sorry. That's my fault. I used '//' in some of the examples, but that was just a habit. All you have to do is write your comments to a dark area that the ZT Interpreter never passes through. F: "What happens here: 'JUMP ZT' for Romeo?" A: 'JUMP ZT' is for Romeo the same as 'JUMP 01': HF indicate the direction, XY define the size of Romeo's jump. '01' = one step. If 'ZT' is used, the JUMP command is ignored completely, but the result is the same, since it is "one step in direction HF". F: "Again the JUMP action: 111122223333 111122223333 4444..<.5555 4444>...5555 666677778888 666677778888 Juliet wants to JUMP. If memory[index] <> 0 then to 3, else to 8, or what?" A: A Juliet-JUMP is - just like normal program flow - always (see figure 7) diagonal to the next Romeo (it's NOT a diagonal jump to the next couple). Example: 111122223333 111122RA3333 4444JJ<.5555 4444>.RB5555 666677778888 666677778888 Juliet (JJ) jumps, if memory[index] <> 0, to Romeo (RA) in Block 2 (hmmm, is she cheating?), else to her own Romeo (RB). F: "Why '°'? That isn't ASCII! And it's not on my finnish keyboard!" A: Good point. I just changed specs and interpreter: One may use "^", "*" or even "?" instead of "°". These are all ASCII and probably even on finnish keyboards. :-) Appendix B ---------- + + + | Juliet | Romeo | | | | +-----+------------------+------------------+ TALK | Print data body | Print data body | | or memory[index] | or memory[index] | | as ASCII Char | as number | +-----+------------------+------------------+ JUMP | Conditional jump | Simple jump | | memory[index]=0? | in direction HF | +-----+------------------+------------------+ SET | Quit ZT program | Set value of | | | memory[index] | +-----+------------------+------------------+ MATH | Change index | Change value of | | pointer value | memory[index] | +-----+------------------+------------------+ This documentation will be updated if necessary: [ 2004-11-10 - URL updated ] [ 2002-07-29 - New feature added: "°" may be replaced by "^", "*" or "?" ] [ 2002-07-07 - Fixed buggy documentation of Juliets MATH action + FAQ ] [ 2002-07-05 - Initial release] ZT programming language, "Zer0 Tolerance" Copyright © 2002-2004 Philipp Winterberg, http://www.philipp-winterberg.de 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA [eof]