From: Simon Forman Date: Mon, 4 Apr 2022 14:58:22 +0000 (-0700) Subject: Expression? X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=1da997fbbffbc4696aabb796e41a3722fd874253;p=joypy%2FThun.git Expression? --- diff --git a/implementations/Python/joy/expr.py b/implementations/Python/joy/expr.py new file mode 100644 index 0000000..bf30811 --- /dev/null +++ b/implementations/Python/joy/expr.py @@ -0,0 +1,25 @@ + + +class Expression: + + def __init__(self, initial_expression=()): + self.current = initial_expression + self.stack = [] + + def __next__(self): + if self.current: + item, self.current = self.current + return item + if self.stack: + self.current = self.stack.pop() + return self.__next__() + raise StopIteration + + def prepend(self, quoted_program): + if self.current: + self.stack.append(self.current) + self.current = quoted_program + + +from parser import text_to_expression as j +e = Expression(j('23 18')) diff --git a/implementations/expr.py b/implementations/expr.py new file mode 100644 index 0000000..4ba0be5 --- /dev/null +++ b/implementations/expr.py @@ -0,0 +1,62 @@ +from itertools import chain +from joy.utils.stack import _s, iter_stack + + +class Expression: + ''' + As elegant as it is to model the expression as a stack, it's not very + efficient, as concatenating definitions and other quoted programs to + the expression is a common and expensive operation. + + Instead, let's keep a stack of sub-expressions, reading from them + one-by-one, and prepending new sub-expressions to the stack rather than + concatenating them. + ''' + + def __init__(self, initial_expression=()): + self.current = initial_expression + self.stack = [] + + def __iter__(self): + return self + + def __next__(self): + if self.current: (item, self.current) = self.current + elif self.stack: (item, self.current) = self.stack.pop() + else: raise StopIteration + return item + + def prepend(self, quoted_program): + if not quoted_program: return + if self.current: self.stack.append(self.current) + self.current = quoted_program + + def __str__(self): + return ' '.join( + map( + _s, + chain.from_iterable( + map( + iter_stack, + reversed(self.stack + [self.current]) + ) + ) + ) + ) + + +if __name__ == '__main__': + from joy.parser import text_to_expression as j + + e = Expression(j('23 18')) + e.prepend(j('88 19')) + e.prepend(j('foo fie feum')) + print(e) + for i in e: + print(i, e.stack, e.current) + if i == 88: + print('prepending "hello world"') + e.prepend(j('hello world')) + if i == 19: + print('prepending "good bye"') + e.prepend(j('good bye'))