Whitespacers
Implementation of programming language WhitespaceWhitespacers 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 { }
add store calculate_next_factorial_block_push_7 { }
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
retrieve add store retrieve jump_if_negative
{ }
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 { }
readchar
push-2 { }
load CHECK-WHETHER-IS-EOL.duplicate
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 { }
add label-2
{ }
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 { }
load if-0-goto-4
{ }
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
Comments
]]>blog comments powered by Disqus
]]>