自由モノイドプログラミング言語の作成(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





