{"id":311,"date":"2007-02-16T08:30:00","date_gmt":"2007-02-16T08:30:00","guid":{"rendered":"http:\/\/scientopia.org\/blogs\/goodmath\/2007\/02\/16\/crazy-stack-games-programming-in-kipple\/"},"modified":"2007-02-16T08:30:00","modified_gmt":"2007-02-16T08:30:00","slug":"crazy-stack-games-programming-in-kipple","status":"publish","type":"post","link":"http:\/\/www.goodmath.org\/blog\/2007\/02\/16\/crazy-stack-games-programming-in-kipple\/","title":{"rendered":"Crazy Stack Games: Programming in Kipple"},"content":{"rendered":"<p>Insane Stacking<\/p>\n<p> Todays pathology is playing with stacks. Lots of lots of stacks. Stacks for data. Stacks for control. Stacks out the wazoo. It&#8217;s called <a href=\"http:\/\/rune.krokodille.com\/lang\/kipple\/kipple.html\">Kipple<\/a> for no particularly good reason that I know of.<\/p>\n<p> Kipple happens to be one of the pathological languages that I highly recommend trying to write some programs in. It&#8217;s crazy enough to be a challenge, but there <em>is<\/em> a basic logic to how you program to it &#8211; which makes figuring out how to write programs rewarding rather than just frustrating.<\/p>\n<p><!--more--><\/p>\n<p> Kipple has only four operators, and one control structure. Everything is really based around the stacks. There are 26 of them, named &#8220;a&#8221; through &#8220;z&#8221;, and every<br \/>\noperator needs to specify which of the stacks it&#8217;s going to work with:<\/p>\n<ol>\n<li> <code><em>op<\/em>&lt;<em>stack<\/em><\/code> or <code><em>stack<\/em>&gt;<em>op<\/em><\/code>: push a value onto<br \/>\na stack. The value of the operand &#8220;op&#8221; is pushed onto the specified stack.<br \/>\n&#8220;&gt;&#8221; and &#8220;&lt;&#8221; are equivalent, except that the order of the operand and<br \/>\nstack are switched. An operand can be either an integer, or another stack; if<br \/>\nit&#8217;s another stack, it pops the top value from that other stack, and pops it<br \/>\nonto the target stack. <\/li>\n<li> <code><em>stack<\/em>+<em>op<\/em><\/code>: add the value of the operand to the value<br \/>\non the top of the target stack.<\/li>\n<li>  <code><em>stack<\/em>-<em>op<\/em><\/code>: subtract the value of the operand from<br \/>\nthe value on top of the target stack.<\/li>\n<li> <code><em>stack<\/em>?<\/code>: if the top of the specified stack is 0, then<br \/>\nempty the stack. Otherwise, do nothing.<\/li>\n<\/ol>\n<p> To make things confusing, you can chain things together: &#8220;<code>a&gt;b&lt;c<\/code>&#8221; is the same as &#8220;<code>a&gt;b<\/code>&#8221; followed by &#8220;<code>b&lt;c<\/code>&#8220;. <\/li>\n<p> The only control structure is a the loop. A loop is code inside of parens; the first thing in the parens is the name of the stack that controls the loop. The loop will be executed as long as the controlling stack is not empty. Just like with the operators, you can use chaining; if the first thing in the loop is an operator expression, then the first stack named in the operator expression is also the<br \/>\ncontrolling stack.<\/p>\n<p> So, for example, to copy stack a to stack b, the clear way of doing it is:<br \/>\n&#8220;<code>(a a&gt;b)<\/code>&#8221; (while a is not empty, pop a value from a and push it onto b.) It can be written more concisely as &#8220;<code>(a&gt;b)<\/code>&#8220;. <\/p>\n<p> For doing input and output, the stacks &#8220;i&#8221; and &#8220;o&#8221; are special: at the start of the program, any input to the program is put onto the &#8220;i&#8221; stack; when the program stops, anything on the &#8220;o&#8221; stack is output as a character.<\/p>\n<p> There are two convenience extensions. One  is a pseudo-stack. Pushing a number onto<br \/>\nthe stack &#8220;@&#8221; pushes  the characters needed to print the number onto  the &#8220;o&#8221; stack. So<br \/>\nif the top of  stack a was &#8220;273&#8221;, then &#8220;<code>a&gt;@<\/code>&#8221; would push  &#8220;2&#8221;, &#8220;7&#8221;, and &#8220;3&#8221;<br \/>\nonto the &#8220;o&#8221; stack. The other convenience is string literals: <code>a&lt;\"HI\"<\/code> is<br \/>\nthe  same   as  <code>a&lt;77 a&lt;78<\/code>. <\/p>\n<p> So, as usual, we start with hello world. It&#8217;s remarkably simple in Kipple:<\/p>\n<pre>\n\"Hello World!\"&gt;o\n<\/pre>\n<p> Pretty simple. It doesn&#8217;t even look pathological! Let&#8217;s try a bit harder&#8230;<\/p>\n<pre>\n#Prints \"Hello World!\"\n33&gt;o&lt;100 108&gt;o&lt;114 111&gt;o&lt;87 32&gt;o&lt;111 108&gt;o&lt;108 101&gt;o&lt;72\n<\/pre>\n<p> Now, that&#8217;s more like it.  Work it out, and you&#8217;ll see it&#8217;s pushing the characters<br \/>\nof &#8220;Hello world!&#8221; onto the o stack in the correct order.<\/p>\n<p> Let&#8217;s get a bit harder, and look at the fibonacci series.<\/p>\n<pre>\n24&gt;n\n0&gt;t\n1&gt;a\n# push fibonacci numbers onto stack t\n(n-1\na+0\nt&lt;a&gt;b+a\nc&lt;b&gt;a&lt;c\nn?\n)\n# output numbers:\n(t&gt;@\n(@&gt;o)\n32&gt;o\n)\n<\/pre>\n<p> It&#8217;s actually amazingly clear. &#8220;n&#8221; used as a loop counter. Each iteration through the loop, it pushes the last fib number onto the &#8220;t&#8221; stack; then it does an add and swap, so that &#8220;a&#8221; and &#8220;b&#8221; contain the next pair of fibonacci numbers; and then it checks if the loop index is zero &#8211; if it is, it empties the stack, ending the loop. Then it outputs the numbers on t, with spaces between them.<\/p>\n<p> Getting slightly trickier, here&#8217;s a program that squares a number taken from<br \/>\nthe input. The reason for trickiness is that it needs to do multiple nested loops to be able to do the multiplication.<\/p>\n<pre>\n#Reads a number from input, and squares it.\n#by Jannis Harder\n1&gt;j\n0&gt;n\n(i&gt;s-10\ns?\n(s-22 s?\n(s-16\nj+0\ns+0\nj&gt;t\n0&gt;u\n(t-1 u+s+0 t?)\nn+u\n10&gt;t\n0&gt;u\nj+0\n(t-1 u+j+0 t?)\n0&gt;j?\nu&gt;j\n0&gt;s?)\n)\n)\nn+0 a&lt;n&gt;b+0\n0&gt;u\n(a-1 u+b+0 a?)\nu&gt;@ 10&gt;o (@&gt;o)\n<\/pre>\n<p> And finally, as usually for pathological languages, the proof that it&#8217;s really Turing complete is a Brainfuck interpreter. It&#8217;s actually quite a nice piece of code &#8211; easier to understand than the squaring program above!<\/p>\n<pre>\n# Brainfuck interpreter. Input is separated from the source with\n# an ! character. Cell size is 8 bits.\n#\n# Brainfuck example:\n#\n#  &gt;,[&gt;,]&lt;[.&lt;]!Hello.\n#\n# This program (the part before the !) will output it's input\n# (the part after the !) in reverse\n(i&gt;a)\n1&gt;x\n# Loop that reads the source code into t, ignoring invalid\n# characters, until an ! is encountered:\n(x  #while(!x.empty())\n0&gt;b\na-43 a&gt;z? 0&gt;y (z y? 0&gt;z?) (y? a&gt;t b?) #if a.peek()=='+' t.push(a.pop())\na-44 a&gt;z? 0&gt;y (z y? 0&gt;z?) (y? a&gt;t b?)\na-45 a&gt;z? 0&gt;y (z y? 0&gt;z?) (y? a&gt;t b?)\na-46 a&gt;z? 0&gt;y (z y? 0&gt;z?) (y? a&gt;t b?)\na-60 a&gt;z? 0&gt;y (z y? 0&gt;z?) (y? a&gt;t b?)\na-62 a&gt;z? 0&gt;y (z y? 0&gt;z?) (y? a&gt;t b?)\na-91 a&gt;z? 0&gt;y (z y? 0&gt;z?) (y? a&gt;t b?)\na-93 a&gt;z? 0&gt;y (z y? 0&gt;z?) (y? a&gt;t b?)\n(b a&gt;z b?) # discard characters that aren't Brainfuck operators\n# if current character is ! then stop\na-33 a&gt;x? x&gt;y?\n(y\na+0\na&gt;x?\n0&gt;y?\n)\n#Move the source code to s\n(t&gt;s)\na&gt;z # discard the ! character\n(a&gt;b) (b&gt;i) # move the input to i\n(s\n0&gt;z? #empty z\n# +\ns-43\ns&gt;x? 0&gt;y (x y? 0&gt;x?)\n(y?\nd&gt;z+1\nz-256 z? z&gt;q #emulate 8 bit cells\nz&gt;d\n)\n# -\ns-45\ns&gt;x? 0&gt;y (x y? 0&gt;x?)\n(y?\nd&gt;z+0\nz&gt;q? 0&gt;r (q r? 0&gt;q? z-1)\n(r z+255 r?) #emulate 8 bit cells\nz&gt;d\n)\n# ,\ns-44\ns&gt;x? 0&gt;y (x y? 0&gt;x?)\n(y? d&gt;z i&gt;d)\n# .\ns-46\ns&gt;x? 0&gt;y (x y? 0&gt;x?)\n(y? d+0 d&gt;p)\n# &lt;\ns-60\ns&gt;x? 0&gt;y (x y? 0&gt;x?)\n(y? d&lt;e)\n# &gt;\ns-62\ns&gt;x? 0&gt;y (x y? 0&gt;x?)\n(y? d&gt;e)\n# [\ns-91\ns&gt;x? 0&gt;y (x y? 0&gt;x?)\n(y\nd+0 d&gt;m? 0&gt;n (m n? 0&gt;m?)\n(n\n1&gt;b\n(b\ns&gt;t\ns-91  s&gt;x? 0&gt;y (x y? 0&gt;x?)  (y? b+1)\ns-93  s&gt;x? 0&gt;y (x y? 0&gt;x?)  (y? b-1)\nb?\n)\nn?\n)\ny?\n)\n# ]\ns-93\ns&gt;x? 0&gt;y (x y? 0&gt;x?)\n(y\nd+0 d&gt;n?\n(n\n1&gt;b\n(b\ns&lt;t\ns-91  s&gt;x? 0&gt;y (x y? 0&gt;x?)  (y? b-1)\ns-93  s&gt;x? 0&gt;y (x y? 0&gt;x?)  (y? b+1)\nb?\n)\n0&gt;n?\n)\ny?\n)\ns&gt;t\n)\n(p&gt;o)\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Insane Stacking Todays pathology is playing with stacks. Lots of lots of stacks. Stacks for data. Stacks for control. Stacks out the wazoo. It&#8217;s called Kipple for no particularly good reason that I know of. Kipple happens to be one of the pathological languages that I highly recommend trying to write some programs in. It&#8217;s [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[92],"tags":[],"class_list":["post-311","post","type-post","status-publish","format-standard","hentry","category-pathological-programming"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p4lzZS-51","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/311","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/comments?post=311"}],"version-history":[{"count":0,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/311\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/media?parent=311"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/categories?post=311"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/tags?post=311"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}