Whitespace - kenrube/Esopoly GitHub Wiki

Whitespace - полушуточный язык программирования, исходник на котором можно встроить в любой другой: используя только символы пробела, табуляции и перевода строки, он прячется у всех на виду :) Ознакомиться с синтаксисом языка можно на официальной странице.

Алгоритм вывода фразы Whitespace program прост: заталкиваем (push) все символы, начиная с конца, в стек, затем по одному извлекаем их (pop) и выводим на печать. Удобства ради обозначим пробел как -, символ табуляции как >, а символ перевода строки как v.

  1. Вызываем --, что позволит нам затолкать идущее следом число (битовое представление символа) на вершину стека. - в числе означает 0, > - 1. Заканчивается число переводом строки v.
  2. После того, как все числа окажутся в стеке, для вывода каждого из них вызываем >v--. Согласно спецификации, эта последовательность инструкций извлекает и выводит на печать символ с вершины стека.
  3. После вывода всех символов вызываем vvv, что означает конец программы.

Пишем исходник в псевдокоде:

-- ->>->>->v       push 'm'(01101101) to stack
-- ->>---->v       push 'a'(01100001)
-- ->>>-->-v       push 'r'(01110010)
-- ->>-->>>v       push 'g'(01100111)
-- ->>->>>>v       push 'o'(01101111)
-- ->>>-->-v       push 'r'(01110010)
-- ->>>----v       push 'p'(01110000)
-- -->-----v       push ' '(00100000)
-- ->>-->->v       push 'e'(01100101)
-- ->>--->>v       push 'c'(01100011)
-- ->>---->v       push 'a'(01100001)
-- ->>>----v       push 'p'(01110000)
-- ->>>-->>v       push 's'(01110011)
-- ->>-->->v       push 'e'(01100101)
-- ->>>->--v       push 't'(01110100)
-- ->>->-->v       push 'i'(01101001)
-- ->>->---v       push 'h'(01101000)
-- ->->->>>v       push 'W'(01010111)
>v--               pop & print 'W'
>v--               pop & print 'h'
>v--               pop & print 'i'
>v--               pop & print 't'
>v--               pop & print 'e'
>v--               pop & print 's'
>v--               pop & print 'p'
>v--               pop & print 'a'
>v--               pop & print 'c'
>v--               pop & print 'e'
>v--               pop & print ' '
>v--               pop & print 'p'
>v--               pop & print 'r'
>v--               pop & print 'o'
>v--               pop & print 'g'
>v--               pop & print 'r'
>v--               pop & print 'a'
>v--               pop & print 'm'
vvv                finish

Или то же самое на настоящем Whitespace (вид после встраивания в общий исходник; отбросьте head и tail, если хотите увидеть только аналог псевдокода):

head    
head    
   		 		 	
   		    	
   			  	 
   		  			
   		 				
   			  	 
   			    
    	     
   		  	 	
   		   		
   		    	
   			    
   			  		
   		  	 	
   			 	  
   		 	  	
   		 	   
   	 	 			
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  


tail
--//--                                                   
--//--                                                   
--//--  		  
--//--  		  
--//--  		  
--//--  		  
--//--  		  
--//--  		  
--//--  		  
--//--  		  
--//--  		  
--//--   		   
--//--   		   
--//--   		   
--//--       
--//--
--//--
--//--
--//--
--//--
--//--
--//--                                            
--//--                        
--//--                    
--//--                                
--//--                    
--//--                    
--//--                        
--//--                                    
--//--
--//--
--//--
--//--                                  
--//--                          
--//--                        
--//--                          
--//--                          
--//--                      
--//--                      
--//--                              
--//--
--//--
--//--
--//--

Опробовать можно в онлайн-интерпретаторе.

Почему исходник столь сильно увеличился после встраивания? Я перебрал множество вариантов того, чтобы общий исходный код выглядел как можно более эстетично (рассчитывая, разумеется, на размер таба = 1), и в итоге пришел к тому, что неплохо в общей канве смотрится смайл X-P, воссозданный из исходного кода на Whitespace. X сформирован из кода заталкивания символов в стек, - - из кода извлечения и вывода. P добавился за компанию и, хоть и состоит тоже из смеси пробелов и табов, на самом деле не выполняет никаких действий в контексте Whitespace - наша программа уже закончила свое выполнение после 3 переводов строки подряд. Точно так же позже добавилась и надпись ESOTERIC POLYGLOT - слишком много места оставалось без граффити :)

Встраивать в общий исходник пока не будем, сделаем это на последнем этапе.