From d6df22d4e8eb8ba5399277bc171aa758cf9c4ed6 Mon Sep 17 00:00:00 2001
From: Eduardo Julian
Date: Mon, 26 Jan 2015 20:18:57 -0400
Subject: [Enhancement] - 'def' with 'lambda' as value now experiences a
 rewrite to eliminate the localized lambda-name and use the name of the
 global-def for the sake of making it easier to understand to
 users/programmers.

---
 src/lux/analyser.clj | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 70 insertions(+), 1 deletion(-)

(limited to 'src')

diff --git a/src/lux/analyser.clj b/src/lux/analyser.clj
index 32c2df71b..874ea9376 100644
--- a/src/lux/analyser.clj
+++ b/src/lux/analyser.clj
@@ -154,7 +154,7 @@
 
 (defn ^:private resolve [ident]
   (fn [state]
-    (prn 'resolve ident)
+    ;; (prn 'resolve ident)
     (let [[top & stack*] (::local-envs state)]
       (if-let [=bound (or (get-in top [:mappings ident])
                           (get-in top [:mappings/closure ident]))]
@@ -632,6 +632,7 @@
                    (analyse-ast ?body))]
     (return (list (annotated [::let idx ?label =value =body] (:type =body))))))
 
+(declare raise-bindings)
 (defn ^:private raise-tree-bindings [outer-scope ?tree]
   (case (:type ?tree)
     ::adt*
@@ -699,6 +700,67 @@
                     [::lambda =scope =captured (list ?arg) =body])]]
     (return (list (annotated =lambda =function)))))
 
+(declare ->def-lambda)
+(defn ^:private ->def-lambda-tree [old-scope new-scope ?tree]
+  (case (:type ?tree)
+    ::adt*
+    (update-in ?tree [:patterns]
+               #(into {} (for [[?tag ?unapply] %
+                               :let [=unapply (update-in ?unapply [:parts] (partial map (partial ->def-lambda-tree old-scope new-scope)))]]
+                           [?tag =unapply])))
+    
+    ::defaults
+    (update-in ?tree [:stores]
+               #(into {} (for [[?store ?branches] %
+                               :let [=store (->def-lambda old-scope new-scope {:form ?store :type ::&type/nothing})]]
+                           [(:form =store) ?branches])))
+    ;; else
+    (assert false (pr-str ?tree))
+    ))
+
+(defn ^:private ->def-lambda [old-scope new-scope syntax]
+  (match (:form syntax)
+    [::local ?local-scope ?idx]
+    (if (= ?local-scope old-scope)
+      {:form [::local new-scope ?idx]
+       :type (:type syntax)}
+      syntax)
+
+    [::self ?self-name ?curried]
+    (if (= ?self-name old-scope)
+      {:form [::self new-scope (mapv (partial ->def-lambda old-scope new-scope) ?curried)]
+       :type (:type syntax)}
+      syntax)
+    
+
+    [::jvm:iadd ?x ?y]
+    {:form [::iadd (->def-lambda old-scope new-scope ?x) (->def-lambda old-scope new-scope ?y)]
+     :type (:type syntax)}
+
+    [::case ?base ?variant ?registers ?mappings ?tree]
+    (let [=variant (->def-lambda old-scope new-scope ?variant)
+          =mappings (into {} (for [[idx syntax] ?mappings]
+                               [idx (->def-lambda old-scope new-scope syntax)]))
+          =tree (->def-lambda-tree old-scope new-scope ?tree)]
+      {:form [::case ?base =variant ?registers =mappings =tree]
+       :type (:type syntax)})
+
+    [::call ?func ?args]
+    {:form [::call (->def-lambda old-scope new-scope ?func)
+            (map (partial ->def-lambda old-scope new-scope) ?args)]
+     :type (:type syntax)}
+    
+    [::lambda ?scope ?captured ?args ?value]
+    {:form [::lambda ?scope
+            (into {} (for [[?name ?sub-syntax] ?captured]
+                       [?name (->def-lambda old-scope new-scope ?sub-syntax)]))
+            ?args
+            (->def-lambda old-scope new-scope ?value)]
+     :type (:type syntax)}
+    
+    _
+    (assert false (pr-str (:form syntax)))))
+
 (defn ^:private analyse-def [analyse-ast ?name ?value]
   (exec [def?? (defined? ?name)]
     (if def??
@@ -707,6 +769,13 @@
              :let [scoped-name (str "def_" ?name)]
              [=value] (with-env scoped-name
                         (analyse-ast ?value))
+             :let [;; _ (prn 'analyse-def/=value =value)
+                   =value (match (:form =value)
+                            [::lambda ?scope _ _ _]
+                            (->def-lambda ?scope scoped-name =value)
+                            
+                            _
+                            =value)]
              _ (if ann??
                  (return nil)
                  (annotate ?name ::constant ::public false (:type =value)))
-- 
cgit v1.2.3