Skip to content
This repository has been archived by the owner on Mar 15, 2024. It is now read-only.

Commit

Permalink
Various bits and pieces. Mega bug in lambda with outer scope shadowin…
Browse files Browse the repository at this point in the history
…g args. Pcase is still holding out
  • Loading branch information
Håkan Råberg committed Mar 10, 2013
1 parent 44d350a commit 9b45b25
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 43 deletions.
7 changes: 6 additions & 1 deletion src/deuce-loadup.el
Expand Up @@ -159,7 +159,12 @@
;; (Running properly is another matter altogether.)
;; The pcase issue is not really solved, but autoloads are now delayed until actually called.
;; Pcase is pretty new in Emacs terms, seems to be more of it in 24.3.
; (load "pcasehack")
;; This enters a never ending loop in pcase.clj, works in pcase.el, something with and:
;; Emacs Lisp:
;; (pcase '(current-time . 1) (`(,(and (pred functionp) x) . ,_) (funcall x)))
;; Same in Clojure:
;; (pcase '(current-time . 1) ((#el/sym "\\`" ((#el/sym "\\," (and (pred functionp) x)) . (#el/sym "\\," _))) (funcall x)))
;; Pcase currently fails with Don't know how to create ISeq from: clojure.lang.Symbol in an odd way.
(load "minibuffer")
;; DEUCE: abbrev mode, referenced by simple below (to turn it off at times)
(load "abbrev") ;lisp-mode.el and simple.el use define-abbrev-table.
Expand Down
13 changes: 9 additions & 4 deletions src/deuce/emacs/data.clj
Expand Up @@ -229,9 +229,10 @@
(defun eq (obj1 obj2)
"Return t if the two args are the same Lisp object."
(cond
(null obj1) (null obj2)
(symbol? obj1) (c/= obj1 obj2)
:else (identical? obj1 obj2)))
(null obj1) (null obj2)
;; Macros can get confused by the exact namespace
(and (symbol? obj1) (symbol? obj2)) (c/= (name obj1) (name obj2))
:else (identical? obj1 obj2)))

(defun * (&rest numbers-or-markers)
"Return product of any number of arguments, which are numbers or markers."
Expand Down Expand Up @@ -542,7 +543,11 @@
(-> f meta :doc)
(-> definition meta :doc))))
(alter-meta! (el/fun symbol) assoc :alias true)
(when-not lambda? (.setMacro (el/fun symbol))))
(when-not lambda? (.setMacro (el/fun symbol)))
;; We want this, but it currently wrecks havoc due to backquote
;; (when (and lambda? (-> definition meta :macro)))
;; (.setMacro (el/fun symbol))))
)
definition))

(defun setplist (symbol newplist)
Expand Down
14 changes: 8 additions & 6 deletions src/deuce/emacs/fns.clj
Expand Up @@ -531,12 +531,14 @@
Numbers are compared by value, but integers cannot equal floats.
(Use `=' if you want integers and floats to be able to be equal.)
Symbols must match exactly."
(if (and (seq? o1) (seq? o2))
(every? true? (map equal o1 o2))
(if (and (data/numberp o1) (data/numberp o2))
(and (= (data/floatp o1) (data/floatp o2))
(data/= o1 o2))
(Objects/deepEquals o1 o2))))
(or (data/eq o1 o2)
(if (and (seq? o1) (seq? o2))
(c/and (equal (car o1) (car o2))
(equal (cdr o1) (cdr o2)))
(if (and (data/numberp o1) (data/numberp o2))
(and (= (data/floatp o1) (data/floatp o2))
(data/= o1 o2))
(Objects/deepEquals o1 o2)))))

(declare reverse)

Expand Down
22 changes: 13 additions & 9 deletions src/deuce/emacs_lisp.clj
Expand Up @@ -175,15 +175,18 @@
(.setAccessible true)))

(defn syntax-quote* [form]
(el->clj (.invoke clojure-syntax-quote nil (into-array [form]))))
(.invoke clojure-syntax-quote nil (into-array [form])))

;; There's a version of this already defined as macro in backquote.el, use it / override it?
;; What's their relationship?
(defn emacs-lisp-backquote [form]
(w/postwalk #(c/cond
(c/and (seq? %) (= '#el/sym "\\`" (first %)))
(w/postwalk cons/maybe-seq (syntax-quote* (second %)))
(= '#el/sym "\\," %) `unquote
(= '#el/sym "\\,@" %) `unquote-splicing
:else %) form))
(w/postwalk
#(c/cond
(c/and (seq? %) (= '#el/sym "\\`" (first %)))
(w/postwalk cons/maybe-seq (el->clj (syntax-quote* (second %))))
(= '#el/sym "\\," %) `unquote
(= '#el/sym "\\,@" %) `unquote-splicing
:else %) form))

;; Explore to either get rid of or just using the macro, not both el->clj and it
;; (c/defmacro #el/sym "\\`" [form]
Expand Down Expand Up @@ -288,7 +291,8 @@
(c/let [[args & body] cdr
[docstring body] (parse-doc-string body)
doc (apply str docstring)
vars (vec (keys &env))]
vars (remove #(re-find #"__\d+" (name %)) (keys &env))
vars (vec (remove (c/set args) vars))]
;; This is wrong as it won't share updates between original definition and the lambda var.
;; Yet to see if this ends up being a real issue.
`(c/let [closure# (zipmap '~vars
Expand All @@ -297,7 +301,7 @@
(with-meta
(def-helper* fn nil lambda ~args
(binding [*dynamic-vars* (if (dynamic-binding?) (merge *dynamic-vars* closure#) {})]
(c/let [{:syms ~(vec (keys &env))} closure#]
(c/let [{:syms ~vars} closure#]
(progn ~@body))))
{:doc ~doc}))))

Expand Down
41 changes: 18 additions & 23 deletions src/deuce/emacs_lisp/cons.clj
@@ -1,4 +1,5 @@
(ns deuce.emacs-lisp.cons
(:require [clojure.core :as c])
(:refer-clojure :exclude [list cons])
(:import [clojure.lang Seqable Sequential
IPersistentCollection ISeq Cons
Expand All @@ -23,8 +24,12 @@
(and (seq? x) (= '. (last (butlast x)))
(satisfies? IList (last x))))

(defn dotted-list-ending-in-pair? [x]
(and (seq? x) (= '. (last (butlast x)))
(not (satisfies? IList (last x)))))

(defn dotted-pair? [x]
(and (seq? x) (= '. (last (butlast x))) (= 3 (count x))))
(and (seq? x) (= 3 (count x)) (= '. (last (butlast x)))))

(extend-type IPersistentCollection
IList
Expand Down Expand Up @@ -58,7 +63,7 @@
(if (dotted-pair? this)
(setcar (rest (rest this)) val)
(do
(.set l_rest this (clojure.core/list '. val))
(.set l_rest this (c/list '. val))
(.set l_count this (int 3)))))
val))

Expand All @@ -84,18 +89,17 @@
(recur (cdr c) (inc idx)))
:else (.write w ")"))))))

(defmethod print-method PersistentList [c ^Writer w]
(print-list c w))
;; (defmethod print-method PersistentList [c ^Writer w]
;; (print-list c w))

(defmethod print-method Cons [c ^Writer w]
(print-list c w))
;; (defmethod print-method Cons [c ^Writer w]
;; (print-list c w))

(defn pair [car cdr]
(if (satisfies? IList cdr)
(let [l (clojure.core/list car)]
(setcdr l cdr)
l)
(clojure.core/list car '. cdr)))
(doto (c/list car)
(setcdr cdr))
(c/list car '. cdr)))

;; Fix uses of (apply cons/list ...) to something saner
(defn list [& objects]
Expand All @@ -106,21 +110,12 @@
(defn last-cons [l]
(if (not (satisfies? ICons (cdr l))) l (recur (cdr l))))

(defn cons-expand [form]
(let [c (apply list (drop-last 2 form))]
(setcdr (last-cons c) (last form))
c))

;; Figure out where this is actually needed.
(defn maybe-seq [x]
(if (and (seq? x)
(not (dotted-pair? x))
(not (instance? PersistentList x)))
(if (dotted-pair? x)
x
(apply list x)
;; Be smarter here? Many types of seqs.
;; (if (or (dotted-list? x) (instance? LazySeq))
;; (apply list x)
;; x)
)
(if (dotted-list-ending-in-pair? x)
(apply c/list x)
(apply list x))
x))

0 comments on commit 9b45b25

Please sign in to comment.