非専門的シンギュラリティー研究所

無限に動き続けるシステムを表す方法を AI なども使って考えていきます。

自由モノイドのイテレーター(10)

自由モノイドプログラミング言語の作成(Python版 5)

プログラムの実行

構文解析からプログラムの実行は以下のようになります。prog.eval() によって実行することができます。

from lark import Lark
parser = Lark(grammar, parser="lalr")
custom_transformer = CustomTransformer()

src = "def fib(x, y) = x & fib(y, x + y);\nfib(0, 1)"
prog: Program = custom_transformer.transform(parser.parse(src))
count = 20
print(take(count, prog.eval()))

src の定義を zipsum を使ったバージョン

src = "def fib(x, y) = x & y & $zipsum(fib(x, y), $tail(fib(x, y)));\nfib(0, 1)"

に変更すると同様に実行することができます。

変数の値を保持するクラス

変数の値を保持するクラスは以下のようになります。最後に定義された値を使うことができるようになっています。

from typing import Generic, List, Optional, TypeVar

T = TypeVar('T')

class EnvNode(Generic[T]):
	def __init__(self, key: str, value: T, next_node: "Optional[EnvNode[T]]"):
		self.key = key
		self.value = value
		self.next_node = next_node
	def __str__(self):
		return f"key = {self.key}; value = {self.value}"
	def __repr__(self):
		return f"EnvNode(key = {repr(self.key)}; value = {repr(self.value)})"

class Env(Generic[T]):
	def __init__(self):
		self.env_node: Optional[EnvNode[T]] = None
	def __str__(self):
		return ", ".join(list(map(lambda x: str(x), self)))
	def __repr__(self):
		return "Env" + ", ".join(list(map(lambda x: repr(x), self)))
	def __iter__(self):
		# コピーして返す
		env = Env[T]()
		env.env_node = self.env_node
		return env
	def __next__(self) -> EnvNode[T]:
		if self.env_node is None:
			raise StopIteration()
		node = self.env_node
		self.env_node = self.env_node.next_node
		return node
	def define(self, key: str, value: T) -> "Env[T]":
		env: "Env[T]" = Env()
		env.env_node = EnvNode(key, value, self.env_node)
		return env
	def define_list(self, keys: List[str], values: List[T]) -> "Env[T]":
		env: "Env[T]" = self
		for key, value in zip(keys, values):
			env = env.define(key, value)
		return env
	def value(self, key: str) -> Optional[T]:
		for node in self:
			if node.key == key:
				return node.value
		return None