Skip to content

Commit

Permalink
Merging 'recur' into app.clj.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjfrisz committed Nov 2, 2012
1 parent d8752a6 commit bd08b06
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 61 deletions.
3 changes: 2 additions & 1 deletion src/ctco/core.clj
Expand Up @@ -3,7 +3,7 @@
;; Written by Chris Frisz
;;
;; Created 11 Apr 2012
;; Last modified 19 Oct 2012
;; Last modified 20 Oct 2012
;;
;; Defines the ctco macro which acts as the driver for the Clojure TCO
;; compiler. The macro parses the initial expression, and applies the
Expand Down Expand Up @@ -39,6 +39,7 @@
(let [new-expr (-> (parse/parse expr)
(proto/unrecurify nil)
apply-cps
(proto/recurify nil nil false)
proto/thunkify
(proto/load-tramp tramp)
proto/unparse)]
Expand Down
70 changes: 20 additions & 50 deletions src/ctco/expr/app.clj
Expand Up @@ -6,8 +6,7 @@
;; Last modified 20 Oct 2012
;;
;; Defines the App record type for function application in the Clojure
;; TCO compiler. Also defines the Recur record type and operations for
;; representing 'recur' expressions in the Clojure TCO compiler.
;; TCO compiler.
;;
;; It implements the following protocols:
;;
Expand Down Expand Up @@ -51,38 +50,20 @@
;; PWalkable:
;; Applies the given function to the rator and each rand*
;; and returns a new App record.
;;
;; Recur implements the following protocols:
;;
;; PLoadTrampoline:
;; Maps load-tramp over the arguments to the 'recur' form.
;;
;; PUnparse:
;; Unparses (recursively) the syntax for the expression as
;; `(loop ~bind* ~body), where bind* is the vector of
;; variables and bindings, and body is the body
;; expression of the 'loop.'
;;
;; PUnRecurify:
;; Replaces the 'recur' call with a function application.
;;
;; PWalkable:
;; Maps a function over the arguments to the 'recur' form,
;; generating a new Recur record.
;;----------------------------------------------------------------------

(ns ctco.expr.app
(:require [ctco.expr
cont thunk]
cont simple thunk]
[ctco.protocol :as proto]
[ctco.util :as util])
(:import [ctco.expr.cont
Cont AppCont]
[ctco.expr.simple
Simple]
[ctco.expr.thunk
Thunk]))

(declare make-recur)

(defrecord App [rator rand*]
proto/PCpsSrs
(cps-srs [this k]
Expand Down Expand Up @@ -112,45 +93,34 @@
rand* (:rand* this)
RAND* (mapv #(proto/recurify % nil nil false) rand*)]
(if (and (= rator name) (= (count rand*) arity))
(make-recur RAND*)
;; NB: seems like a manifest constant
;; NB: maybe fix this with the globals file
(App. (Simple. 'recur) RAND*)
(App. (proto/recurify rator nil nil false) RAND*))))

proto/PThunkify
(thunkify [this]
(Thunk. (proto/walk-expr this proto/thunkify nil)))
;; NB: seems like a manifest constant
;; NB: maybe fix this with the globals file
(let [APP (proto/walk-expr this proto/thunkify nil)]
(if (= (:rator this) (Simple. 'recur))
APP
(Thunk. APP))))

proto/PUnparse
(unparse [this]
`(~(proto/unparse (:rator this)) ~@(map proto/unparse (:rand* this))))

proto/PUnRecurify
(unrecurify [this name]
(proto/walk-expr this #(proto/unrecurify % name) nil))
;; NB: seems like a manifest constant
;; NB: maybe fix this with the globals file
(let [recur-rec (Simple. 'recur)
unrecurify #(proto/unrecurify % name)]
(if (= (:rator this) recur-rec)
(App. recur-rec (mapv unrecurify (:rand* this)))
(proto/walk-expr this unrecurify nil))))

proto/PWalkable
(walk-expr [this f _]
(App. (f (:rator this)) (mapv f (:rand* this)))))

(defrecord Recur [arg*]
proto/PLoadTrampoline
(load-tramp [this tramp]
(proto/walk-expr this #(proto/load-tramp % tramp) nil))

proto/PRecurify
(recurify [this name arity tail?]
(proto/walk-expr this #(proto/recurify % nil nil false) nil))

proto/PUnparse
(unparse [this]
(let [arg* (map proto/unparse (:arg* this))]
`(recur ~@arg*)))

proto/PUnRecurify
(unrecurify [this name]
(App. name (:arg* this)))

proto/PWalkable
(walk-expr [this f _]
(Recur. (mapv f (:arg* this)))))

(defn- make-recur [rand*] (Recur. rand*))
4 changes: 4 additions & 0 deletions src/ctco/expr/tramp.clj
Expand Up @@ -55,6 +55,10 @@
(thunkify [this]
(proto/walk-expr this proto/thunkify nil))

;; Not used in practice, but useful for debugging
proto/PUnparse
(unparse [this] (proto/unparse (:expr this)))

proto/PWalkable
(walk-expr [this f _]
(TrampMark. (f (:expr this)))))
8 changes: 1 addition & 7 deletions src/ctco/parse.clj
Expand Up @@ -16,7 +16,7 @@
[ctco.protocol :as proto]
[ctco.util :as util])
(:import [ctco.expr.app
App Recur]
App]
[ctco.expr.def
DefSrs DefTriv]
[ctco.expr.fn
Expand Down Expand Up @@ -97,11 +97,6 @@
(LetSrs. BIND* BODY)
(LetTriv. BIND* BODY))))

(defn- parse-recur
"Helper function for parse that handles 'recur' expressions."
[expr*]
(Recur. (mapv parse expr*)))

(defn- parse-core
"Takes a sequence representing a Clojure expression (generally passed from a
macro) and returns the parsed representation of the expression if it is a core
Expand All @@ -117,7 +112,6 @@
[(['fn (name :guard symbol?) & body*] :seq)] (parse-fn name body*)
[(['if test conseq alt] :seq)] (parse-if test conseq alt)
[(['let bind* body] :seq)] (parse-let bind* body)
[(['recur & expr*] :seq)] (parse-recur expr*)
:else false))

(defn- parse-defn
Expand Down
6 changes: 3 additions & 3 deletions src/ctco/util.clj
Expand Up @@ -3,7 +3,7 @@
;; Written by Chris Frisz
;;
;; Created 26 Apr 2012
;; Last modified 6 Oct 2012
;; Last modified 20 Oct 2012
;;
;; Defines miscellaneous utility functions for use in CTCO. These
;; include:
Expand All @@ -18,8 +18,8 @@
(:require [ctco.expr
simple]
[ctco.protocol :as proto])
(:import [ctco.expr.simple
Simple]))
(:import [ctco.expr.simple
Simple]))

(defn new-var
"Returns a unique variable for use in the TCO compiler either with a given
Expand Down

0 comments on commit bd08b06

Please sign in to comment.