]]> ]]>

Whitespacers

Реализация языка программирования Whitespace

Whitespacers — коллекция интерпретаторов языка Whitespace, собранных в Интернете. В нее входят интерпретаторы, написанные на C, C++, Haskell, Perl, Python, Rebol, Ruby и самом Whitespace. Интерпретаторы написаны разными людьми и не эквивалентны: одну и ту же программу одни выполнят, а другие выдадут различные ошибки.

Примеры:

Hello, World!:

Пример для версий Whitespacers (Ruby)

Для простоты понимания код откомментирован: буква означает, что следующий фрагмент кода добавляет в стек ASCII-код этой буквы, а после print следует команда вывода верхнего элемента стека на печать как символа. Последовательности символов, задающие ASCII-коды, заключены в фигурные скобки (за исключением перевода строки).

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

Факториал:

Пример для версий Whitespacers (Ruby)

В этом примере используется другой метод комментирования — каждая команда предваряется ее словесным описанием. Числа и метки, кроме заключительного переноса строки, заключены в скобки.

Куча используется для хранения переменных: 1 — первое число, факториал которого не нужен, 2..5 — ASCII-коды символов, используемых при выводе на печать, 6 и 7 — текущее число и его факториал. Сам факториал вычисляется итеративно: на каждой итерации печатаются ранее вычисленное число и факториал, затем вычисляются и заносятся в память новые. После этого, новое число (ячейка 6) сравнивается с ячейкой 1: если число меньше, цикл повторяется, иначе прекращается.

Интересо, что в Whitespace ноль “отрицательный”: число должно содержать в записи хотя бы один Tab, в двоичной записи нуля единиц нет, поэтому приходится задавать знаковый бит и записывать ноль как Tab-LF.

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

Числа Фибоначчи:

Пример для версий Whitespacers (Ruby)

Пример работает аналогично факториалу, но интенсивнее использует хранение данных в стеке и команду копирования верхнего элемента стека, чтобы избежать лишних обращений к памяти. Кроме того, в этом примере счетчик отрицательный и увеличивается на каждой итерации.

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:

Пример для версий 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

Комментарии

]]>

blog comments powered by Disqus

]]>

Работа программистам