Expression?
This commit is contained in:
parent
6eff23b191
commit
1da997fbbf
|
|
@ -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'))
|
||||
|
|
@ -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'))
|
||||
Loading…
Reference in New Issue