From e59af856b025d82e63cd9f4e0242b88c63da8c36 Mon Sep 17 00:00:00 2001 From: Rahul Arya Date: Mon, 15 Apr 2019 04:28:19 -0700 Subject: [PATCH] Made some recursive procedures iterative. (#156) --- editor/datamodel.py | 41 ++++++++++++----------------------------- editor/helper.py | 7 ++++--- editor/lists.py | 19 +++++++------------ 3 files changed, 23 insertions(+), 44 deletions(-) diff --git a/editor/datamodel.py b/editor/datamodel.py index d5549b10..f9f70541 100644 --- a/editor/datamodel.py +++ b/editor/datamodel.py @@ -48,36 +48,19 @@ def __init__(self, first: Expression, rest: Expression): f"Unable to construct a Pair with a cdr of {rest}, expected a Pair, Nil, or Promise.") self.rest = rest - # def __str__(self): - # if isinstance(self.first, Symbol): - # if isinstance(self.rest, Pair) and self.rest.rest == Nil: - # if self.first.value == "quote": - # return f"'{str(self.rest.first)}" - # elif self.first.value == "unquote": - # return f",{str(self.rest.first)}" - # elif self.first.value == "unquote-splicing": - # return f",@{str(self.rest.first)}" - # elif self.first.value == "quasiquote": - # return f"`{str(self.rest.first)}" - # - # if isinstance(self.rest, Pair): - # rest_str = str(self.rest) - # if rest_str[0] == "(" and rest_str[-1] == ")": - # return f"({self.first} {rest_str[1:-1]})" - # else: - # return f"({self.first} . {rest_str})" - # elif self.rest is Nil: - # return f"({self.first})" - # - # return f"({str(self.first)} . {str(self.rest)})" - def __repr__(self): - if isinstance(self.rest, Pair): - return f"({repr(self.first)} {repr(self.rest)[1:-1]})" - elif self.rest is Nil: - return f"({repr(self.first)})" - else: - return f"({repr(self.first)} . {repr(self.rest)})" + pos = self + out = [] + while True: + if isinstance(pos, Pair): + out.append(repr(pos.first)) + pos = pos.rest + elif isinstance(pos, NilType): + break + else: + out.append(f". {repr(pos)}") + break + return "(" + " ".join(out) + ")" class NilType(Expression): diff --git a/editor/helper.py b/editor/helper.py index 6c96b639..6b6ad455 100644 --- a/editor/helper.py +++ b/editor/helper.py @@ -43,6 +43,7 @@ def verify_min_callable_length(operator: Expression, expected: int, actual: int) def make_list(exprs: List[Expression], last: Expression = Nil) -> Union[Pair, NilType]: - if len(exprs) == 0: - return last - return Pair(exprs[0], make_list(exprs[1:], last)) + out = last + for expr in reversed(exprs): + out = Pair(expr, out) + return out diff --git a/editor/lists.py b/editor/lists.py index d1815e46..d98c06ba 100644 --- a/editor/lists.py +++ b/editor/lists.py @@ -14,21 +14,16 @@ class Append(BuiltIn): def execute_evaluated(self, operands: List[Expression], frame: Frame) -> Expression: if len(operands) == 0: return Nil - out = [] + exprs = [] for operand in operands[:-1]: if not isinstance(operand, Pair) and operand is not Nil: raise OperandDeduceError(f"Expected operand to be valid list, not {operand}") - out.extend(pair_to_list(operand)) - try: - last = operands[-1] - if not isinstance(last, Pair): - raise OperandDeduceError() - last = pair_to_list(last) - except OperandDeduceError: - return make_list(out, operands[-1]) - else: - out.extend(last) - return make_list(out) + exprs.extend(pair_to_list(operand)) + out = operands[-1] + for expr in reversed(exprs): + out = Pair(expr, out) + return out + @global_attr("car")