From efb0329fda9f16b84e4ba75f825f08ee1cd22b49 Mon Sep 17 00:00:00 2001 From: Mike Cifelli Date: Sun, 12 Nov 2017 16:40:49 -0500 Subject: [PATCH] Implement TCO for cons cell toString --- lisp/tail/length-recursion.lisp | 11 ++++++++++ .../to-string-recursion.lisp} | 2 +- src/sexpression/Cons.java | 21 ++++++++++++------- 3 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 lisp/tail/length-recursion.lisp rename lisp/{random/problem.lisp => tail/to-string-recursion.lisp} (73%) diff --git a/lisp/tail/length-recursion.lisp b/lisp/tail/length-recursion.lisp new file mode 100644 index 0000000..fe6adeb --- /dev/null +++ b/lisp/tail/length-recursion.lisp @@ -0,0 +1,11 @@ +(load "../lang/functions.lisp") + +(defun build (n lst) + (if (= n 0) lst + (build (- n 1) (cons (car lst) lst)))) + +(defun build2 (n lst) + (if (= n 0) lst + (build2 (- n 1) (build 200 lst)))) + +(length (build2 200 (build2 200 (build2 200 (build2 200 '(1 1 1 1 0 0 0 0)))))) diff --git a/lisp/random/problem.lisp b/lisp/tail/to-string-recursion.lisp similarity index 73% rename from lisp/random/problem.lisp rename to lisp/tail/to-string-recursion.lisp index ad4b69a..f2d9c69 100644 --- a/lisp/random/problem.lisp +++ b/lisp/tail/to-string-recursion.lisp @@ -8,4 +8,4 @@ (if (= n 0) lst (build2 (- n 1) (build 200 lst)))) -(length (build2 200 (build2 200 '(1 1 1 1 0 0 0 0)))) +(build2 200 (build2 200 (build2 200 (build2 200 '(1 1 1 1 0 0 0 0))))) diff --git a/src/sexpression/Cons.java b/src/sexpression/Cons.java index 3bdbc4b..da6a243 100644 --- a/src/sexpression/Cons.java +++ b/src/sexpression/Cons.java @@ -1,5 +1,10 @@ package sexpression; +import static recursion.tail.TailCalls.done; +import static recursion.tail.TailCalls.tailCall; + +import recursion.tail.TailCall; + @DisplayName("list") public class Cons extends SExpression { @@ -34,16 +39,18 @@ public class Cons extends SExpression { @Override public String toString() { - return ("(" + toStringAux()); + return toStringTailRecursive("(").invoke(); } - private String toStringAux() { - if (rest.isNull()) - return (first.toString() + ")"); - else if (rest.isCons()) - return (first.toString() + " " + ((Cons) rest).toStringAux()); + private TailCall toStringTailRecursive(String precedingString) { + String leadingString = precedingString + first.toString(); - return (first.toString() + " . " + rest.toString() + ")"); + if (rest.isNull()) + return done(leadingString + ")"); + else if (rest.isCons()) + return tailCall(() -> ((Cons) rest).toStringTailRecursive(leadingString + " ")); + + return done(leadingString + " . " + rest.toString() + ")"); } }