# Whitespacers

Implementation of programming language Whitespace

Whitespacers is a collection of Whitespace interpreters, collected from various sources over Internet. It contains interpreters written in C, C++, Haskell, Perl, Python, Rebol, Ruby and Whitespace itself. The interpreters are not equivalent: some of them run certain examples perfectly while others fail with various errors.

## Examples:

### Hello, World!:

Example for versions Whitespacers (Ruby)

This code is commented to simplify understanding it: letter means that next piece of whitespace pushes on the stack ASCII-code of this letter, and print means invoking the command of printing topmost element of the stack. The numbers that correspond to ASCII-codes are contained within brackets (except for the delimiting newline which is outside of the brackets for readability).

``````H  { 	  	   }
print
e  { 		  	 	}
print
l  { 		 		  }
print
l  { 		 		  }
print
o  { 		 				}
print
,  { 	 		  }
print
space  { 	     }
print
W  { 	 	 			}
print
o  { 		 				}
print
r  { 			  	 }
print
l  { 		 		  }
print
d  { 		  	  }
print
!  { 	    	}
print
\n  { 	 	 }
print

end
``````

### Factorial:

Example for versions Whitespacers (Ruby)

This example uses a slightly different method of commenting — each command is preceded with its literal description. Numbers and labels are enclosed in brackets.

The example works as follows: heap is used to store variables (1 — index of the first factorial which doesn’t need to be calculated, 2..5 — ASCII-codes of special characters used in printing, 6 and 7 — current number and its factorial), and stack is used to run commands). Factorial is calculated iteratively, on each iteration previously calculated values are printed, and new ones are calculated and stored to memory. After this, the newly calculated number is compared with contents of cell 1: if it is less, the loop continues, otherwise it halts.

A curious thing to note is that in Whitespace numeric system zero is “negative”: a number must have at least one Tab in its notation, and binary notation of zero has no 1s, so it has to be written as Tab (only sign bit).

``````push_1  { 	}
push_17  { 	   	}
store		 push_2  { 	 }
push_33  { 	    	}
store		 push_3  { 		}
push_32  { 	     }
store		 push_4  { 	  }
push_61  { 				 	}
store		 push_5  { 	 	}
push_10  { 	 	 }
store		 push_6  { 		 }
push_0  {	 }
store		 push_7  { 			}
push_1  { 	}
store		 label
{ }
printing_block_push_6  { 		 }
retrieve			print_as_number
push_2  { 	 }
retrieve			print_as_char
push_3  { 		}
retrieve			print_as_char
push_4  { 	  }
retrieve			print_as_char
push_3  { 		}
retrieve			print_as_char
push_7  { 			}
retrieve			print_as_number
push_5  { 	 	}
retrieve			print_as_char
increase_counter_block_push_6  { 		 }
push_6  { 		 }
retrieve			push_1  { 	}
push_7  { 			}
retrieve			push_6  { 		 }
retrieve			multiply
store		 conditional_return_block_push_6  { 		 }
retrieve			push_1  { 	}
retrieve			subtract	  	jump_if_negative
{ }
quit

end
``````

### Fibonacci numbers:

Example for versions Whitespacers (Ruby)

This example is similar to factorial one, except for that it makes more use of stack data storage and duplicate command to avoid extra readings from memory cells. Also, in this case the counter is negative and increased at each iteration, as opposed to positive and compared to fixed number of iterations.

``````push_1  { 	}
push_-16  {		    }
store		 push_2  { 	 }
push_44  { 	 		  }
store		 push_3  { 		}
push_32  { 	     }
store		 push_4  { 	  }
push_0  {	 }
store		 push_5  { 	 	}
push_1  { 	}
store		 label
{ }
start_loop_push_5  { 	 	}
push_4  { 	  }
retrieve			push_4  { 	  }
duplicate
push_5  { 	 	}
retrieve			duplicate
print_as_number
push_2  { 	 }
retrieve			print_as_char
push_3  { 		}
retrieve			print_as_char
store		 retrieve			add	   store		 push_1  { 	}
duplicate
duplicate
duplicate
{ }
push_10  { 	 	 }
push_46  { 	 			 }
duplicate
duplicate
print_as_char
print_as_char
print_as_char
print_as_char
quit

end
``````

### CamelCase:

Example for versions Whitespacers (Ruby)
``````push-1  { 	}
push-1  { 	}
save		 LOOP-START.label-0
{ }
push-2  { 	 }
push-2  { 	 }
push-10  { 	 	 }
subtract	  	if-0-goto-1
{	}
CONVERT-TO-LOWERCASE.duplicate
push-A  { 	     	}
subtract	  	if-neg-goto-2
{	 }
duplicate
push-Z  { 	 		 	 }
swap
subtract	  	if-neg-goto-2
{	 }
push-32  { 	     }
{	 }
CHECK-WHETHER-IS-LETTER.duplicate
push-a  { 		    	}
subtract	  	if-neg-goto-3
{		}
duplicate
push-z  { 				 	 }
swap
subtract	  	if-neg-goto-3
{		}
ACTION-IF-LETTER.CHECK-WHETHER-LAST-WAS-SPACE.push-1  { 	}
{	  }
push-32  { 	     }
subtract	  	label-4
{	  }
print
push-1  { 	}
push-0  {	 }
save		 goto-0

{ }
label-3
{		}
ACTION-IF-NOT-LETTER.push-1  { 	}
push-1  { 	}
save		 goto-0

{ }
label-1
{	}
push-10  { 	 	 }
print

end.memory:1-was-last-space,2-currentchar
``````