Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/clojure/clojure-clr
Browse files Browse the repository at this point in the history
Conflicts:
	Clojure/Clojure/Lib/RT.cs
  • Loading branch information
aaronc committed Feb 28, 2013
2 parents 0b20f06 + d77934d commit 0782f42
Show file tree
Hide file tree
Showing 49 changed files with 2,902 additions and 251 deletions.
3 changes: 3 additions & 0 deletions Clojure/Clojure.Compile/Clojure.Compile.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,7 @@
<PostBuildEvent Condition=" '$(Runtime)' == 'Mono' ">mono "$(TargetPath)" clojure.core clojure.core.protocols clojure.main clojure.set clojure.zip clojure.walk clojure.stacktrace clojure.template clojure.test clojure.test.tap clojure.test.junit clojure.pprint clojure.clr.io clojure.repl clojure.clr.shell clojure.string clojure.data clojure.reflect</PostBuildEvent>
<PostBuildEvent Condition=" '$(Runtime)' == '.Net' ">"$(TargetPath)" clojure.core clojure.core.protocols clojure.main clojure.set clojure.zip clojure.walk clojure.stacktrace clojure.template clojure.test clojure.test.tap clojure.test.junit clojure.pprint clojure.clr.io clojure.repl clojure.clr.shell clojure.string clojure.data clojure.reflect</PostBuildEvent>
</PropertyGroup>
<PropertyGroup>
<PostBuildEvent>"$(TargetPath)" clojure.core clojure.core.protocols clojure.main clojure.set clojure.edn clojure.zip clojure.walk clojure.stacktrace clojure.template clojure.test clojure.test.tap clojure.test.junit clojure.pprint clojure.clr.io clojure.repl clojure.clr.shell clojure.string clojure.data clojure.reflect</PostBuildEvent>
</PropertyGroup>
</Project>
3 changes: 3 additions & 0 deletions Clojure/Clojure.Source/Clojure.Source.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@
<None Include="clojure\data.clj">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="clojure\edn.clj">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="clojure\gvec.clj">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
4 changes: 2 additions & 2 deletions Clojure/Clojure.Source/clojure/clr/io.clj
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@

(defprotocol ^{:added "1.2"} Coercions
"Coerce between various 'resource-namish' things."
(^{:tag FileInfo, :added "1.2"} as-file [x] "Coerce argument to a file.")
(^{:tag Uri, :added "1.2"} as-uri [x] "Coerce argument to a URI."))
(^{:tag System.IO.FileInfo, :added "1.2"} as-file [x] "Coerce argument to a file.")
(^{:tag System.Uri, :added "1.2"} as-uri [x] "Coerce argument to a URI."))

(extend-protocol Coercions
nil
Expand Down
79 changes: 63 additions & 16 deletions Clojure/Clojure.Source/clojure/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2104,6 +2104,14 @@
(.setMinHistory r (:min-history opts)))
r)))

(defn ^:private deref-future ;;; this won't get used because clojure.lang.Future implements IDeref and IBlockingDeref, but what the heck, why not do it?
([^clojure.lang.Future fut] ;;; ^java.util.concurrent.Future
(.get fut))
([^clojure.lang.Future fut timeout-ms timeout-val] ;;; ^java.util.concurrent.Future
(try (.get fut timeout-ms) ;;; (.get fut timeout-ms java.util.concurrent.TimeUnit/MILLISECONDS)
(catch clojure.lang.FutureTimeoutException e ;;; java.util.concurrent.TimeoutException
timeout-val))))

(defn deref
"Also reader macro: @ref/@agent/@var/@atom/@delay/@future/@promise. Within a transaction,
returns the in-transaction-value of ref, else returns the
Expand All @@ -2117,9 +2125,14 @@
value is available. See also - realized?."
{:added "1.0"
:static true}
([^clojure.lang.IDeref ref] (.deref ref))
([^clojure.lang.IBlockingDeref ref timeout-ms timeout-val] (.deref ref timeout-ms timeout-val)))

([ref] (if (instance? clojure.lang.IDeref ref)
(.deref ^clojure.lang.IDeref ref)
(deref-future ref)))
([ref timeout-ms timeout-val]
(if (instance? clojure.lang.IBlockingDeref ref)
(.deref ^clojure.lang.IBlockingDeref ref timeout-ms timeout-val)
(deref-future ref timeout-ms timeout-val))))

(defn atom
"Creates and returns an Atom with an initial value of x and zero or
more options (in any order):
Expand Down Expand Up @@ -3377,7 +3390,12 @@
(defn read ;;; still have an error here, probably from leftover newline causing interference with REPL
"Reads the next object from stream, which must be an instance of
java.io.PushbackReader or some derivee. stream defaults to the
current value of *in* ."
current value of *in*.
Note that read can execute code (controlled by *read-eval*),
and as such should be used only with trusted sources.
For data structure interop use clojure.edn/read"
{:added "1.0"
:static true}
([]
Expand All @@ -3399,7 +3417,12 @@
;;; (.readLine ^java.io.BufferedReader *in*)))

(defn read-string
"Reads one object from the string s"
"Reads one object from the string s.
Note that read-string can execute code (controlled by *read-eval*),
and as such should be used only with trusted sources.
For data structure interop use clojure.edn/read-string"
{:added "1.0"
:static true}
[s] (clojure.lang.RT/readString s))
Expand Down Expand Up @@ -3979,7 +4002,7 @@
gmapseq (with-meta gmap {:tag 'clojure.lang.ISeq})
defaults (:or b)]
(loop [ret (-> bvec (conj gmap) (conj v)
(conj gmap) (conj `(if (seq? ~gmap) (clojure.lang.PersistentHashMap/create ~gmapseq) ~gmap))
(conj gmap) (conj `(if (seq? ~gmap) (clojure.lang.PersistentHashMap/create (seq ~gmapseq)) ~gmap))
((fn [ret]
(if (:as b)
(conj ret (:as b) gmap)
Expand Down Expand Up @@ -5224,7 +5247,10 @@
~@(when gen-class-call (list gen-class-call))
~@(when (and (not= name 'clojure.core) (not-any? #(= :refer-clojure (first %)) references))
`((clojure.core/refer '~'clojure.core)))
~@(map process-reference references)))))
~@(map process-reference references))
(if (.Equals '~name 'clojure.core) ;;; .equals
nil
(do (dosync (commute @#'*loaded-libs* conj '~name)) nil)))))

(defmacro refer-clojure
"Same as (refer 'clojure.core <filters>)"
Expand Down Expand Up @@ -5856,11 +5882,29 @@
{:added "1.0"})

(add-doc-and-meta *read-eval*
"When set to logical false, the EvalReader (#=(...)) is disabled in the
read/load in the thread-local binding.
Example: (binding [*read-eval* false] (read-string \"#=(eval (def x 3))\"))
Defaults to true"
"Defaults to true (or value specified by system property, see below)
***This setting implies that the full power of the reader is in play,
including syntax that can cause code to execute. It should never be
used with untrusted sources. See also: clojure.end/read.***
When set to logical false in the thread-local binding,
the eval reader (#=) and record/type literal syntax are disabled in read/load.
Example (will fail): (binding [*read-eval* false] (read-string \"#=(* 2 21)\"))
The default binding can be controlled by the system property
'clojure.read.eval' System properties can be set on the command line
like this:
java -Dclojure.read.eval=false ...
The system property can also be set to 'unknown' via
-Dclojure.read.eval=unknown, in which case the default binding
is :unknown and all reads will fail in contexts where *read-eval*
has not been explicitly bound to either true or false. This setting
can be a useful diagnostic tool to ensure that all of your reads
occur in considered contexts. You can also accomplish this in a
particular scope by binding *read-eval* to :unknown
"
{:added "1.0"})

(defn future?
Expand Down Expand Up @@ -6134,6 +6178,11 @@
(clojure.core.protocols/coll-reduce coll f val)))

(extend-protocol clojure.core.protocols/IKVReduce
nil
(kv-reduce
[_ f init]
init)

;;slow path default
clojure.lang.IPersistentMap
(kv-reduce
Expand Down Expand Up @@ -6257,13 +6306,11 @@
(clojure.lang.Future. f))) ;;; fut (.submit clojure.lang.Agent/soloExecutor ^Callable f)]
;;; (reify
;;; clojure.lang.IDeref
;;; (deref [_] (.get fut))
;;; (deref [_] (deref-future fut))
;;; clojure.lang.IBlockingDeref
;;; (deref
;;; [_ timeout-ms timeout-val]
;;; (try (.get fut timeout-ms java.util.concurrent.TimeUnit/MILLISECONDS)
;;; (catch java.util.concurrent.TimeoutException e
;;; timeout-val)))
;;; (deref-future fut timeout-ms timeout-val))
;;; clojure.lang.IPending
;;; (isRealized [_] (.isDone fut))
;;; java.util.concurrent.Future
Expand Down
5 changes: 5 additions & 0 deletions Clojure/Clojure.Source/clojure/core/reducers.clj
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,11 @@
(combinef (f1) (fjjoin t2)))))))

(extend-protocol CollFold
nil
(coll-fold
[coll n combinef reducef]
(combinef))

Object
(coll-fold
[coll n combinef reducef]
Expand Down
2 changes: 1 addition & 1 deletion Clojure/Clojure.Source/clojure/core_deftype.clj
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ ditto for method impls defined with deftype, defrecord, and reify."))))
(eqhash [[i m]]
[(conj i 'clojure.lang.IHashEq)
(conj m
`(hasheq [this#] (bit-xor ~type-hash (.GetHashCode this#))) ;;; .hashCode
`(hasheq [this#] (bit-xor ~type-hash (clojure.lang.APersistentMap/mapHasheq this#))) ;;; .hashCode
`(GetHashCode [this#] (clojure.lang.APersistentMap/mapHash this#)) ;;; hashCode
`(Equals [this# ~gs] (clojure.lang.APersistentMap/mapEquals this# ~gs)))]) ;;; equals
(iobj [[i m]]
Expand Down
24 changes: 15 additions & 9 deletions Clojure/Clojure.Source/clojure/core_print.clj
Original file line number Diff line number Diff line change
Expand Up @@ -362,14 +362,19 @@


(def primitives-classnames ;; not clear what the equiv should be
{Single "Single" ;;{Float/TYPE "Float/TYPE"
Int32 "Int32" ;; Integer/TYPE "Integer/TYPE"
Int64 "Int64" ;; Long/TYPE "Long/TYPE"
Boolean "Boolean" ;; Boolean/TYPE "Boolean/TYPE"
Char "Char" ;; Character/TYPE "Character/TYPE"
Double "Double" ;; Double/TYPE "Double/TYPE"
Byte "Byte" ;; Byte/TYPE "Byte/TYPE"
Int16 "Int16"}) ;; Short/TYPE "Short/TYPE"})
{Single "System.Single" ;;{Float/TYPE "Float/TYPE"
Int32 "System.Int32" ;; Integer/TYPE "Integer/TYPE"
Int64 "System.Int64" ;; Long/TYPE "Long/TYPE"
Boolean "System.Boolean" ;; Boolean/TYPE "Boolean/TYPE"
Char "System.Char" ;; Character/TYPE "Character/TYPE"
Double "System.Double" ;; Double/TYPE "Double/TYPE"
Byte "System.Byte" ;; Byte/TYPE "Byte/TYPE"
Int16 "System.Int16" ;; Short/TYPE "Short/TYPE"})
SByte "System.SByte" ;; ADDED
UInt16 "System.UInt16" ;; ADDED
UInt32 "System.UInt32" ;; ADDED
UInt64 "System.UInt64" ;; ADDED
Decimal "System.Decimal" }) ;; ADDED

(defmethod print-method Type [^Type c, ^System.IO.TextWriter w]
(.Write w (.FullName c))) ;;; .getName => .FullName
Expand Down Expand Up @@ -433,7 +438,8 @@
(agent-error o))
" FAILED"
""))
pr-on, "", ">", (list (if (and (instance? clojure.lang.IPending o) (not (.isRealized o)))
pr-on, "", ">", (list (if (and (instance? clojure.lang.IPending o)
(not (.isRealized ^clojure.lang.IPending o)))
:pending
@o)), w))

Expand Down
46 changes: 46 additions & 0 deletions Clojure/Clojure.Source/clojure/edn.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
; Copyright (c) Rich Hickey. All rights reserved.
; The use and distribution terms for this software are covered by the
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
; which can be found in the file epl-v10.html at the root of this distribution.
; By using this software in any fashion, you are agreeing to be bound by
; the terms of this license.
; You must not remove this notice, or any other, from this software.

(ns ^{:doc "edn reading."
:author "Rich Hickey"}
clojure.edn
(:refer-clojure :exclude [read read-string]))

(defn read
"Reads the next object from stream, which must be an instance of
java.io.PushbackReader or some derivee. stream defaults to the
current value of *in*.
Reads data in the edn format (subset of Clojure data):
http://edn-format.org
opts is a map that can include the following keys:
:eof - value to return on end-of-file. When not supplied, eof throws an exception.
:readers - a map of tag symbols to data-reader functions to be considered before default-data-readers.
When not supplied, only the default-data-readers will be used.
:default - A function of two args, that will, if present and no reader is found for a tag,
be called with the tag and the value."

{:added "1.5"}
([]
(read *in*))
([stream]
(read {} stream))
([opts stream]
(clojure.lang.EdnReader/read stream opts)))

(defn read-string
"Reads one object from the string s. Returns nil when s is nil or empty.
Reads data in the edn format (subset of Clojure data):
http://edn-format.org
opts is a map as per clojure.edn/read"
{:added "1.5"}
([s] (read-string {:eof nil} s))
([opts s] (when s (clojure.lang.EdnReader/readString s opts))))
6 changes: 4 additions & 2 deletions Clojure/Clojure.Source/clojure/main.clj
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,11 @@ by default when a new command-line REPL is started."} repl-requires
read-eval-print
(fn []
(try
(let [input (read request-prompt request-exit)]
(let [read-eval *read-eval*
input (binding [*read-eval* (if (= :unknown read-eval) true read-eval)]
(read request-prompt request-exit))]
(or (#{request-prompt request-exit} input)
(let [value (eval input)]
(let [value (binding [*read-eval* read-eval] (eval input))]
(print value)
(set! *3 *2)
(set! *2 *1)
Expand Down
2 changes: 1 addition & 1 deletion Clojure/Clojure.Source/clojure/string.clj
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Design notes for clojure.string:
"Given a replacement string that you wish to be a literal
replacement for a pattern match in replace or replace-first, do the
necessary escaping of special characters in the replacement."
{:added "1.4"}
{:added "1.5"}
[^String replacement] ;;; ^CharSequence
replacement) ;;; TODO: a no-op until I figure out the CLR equivalent -- (Matcher/quoteReplacement (.toString ^CharSequence replacement)))

Expand Down
10 changes: 6 additions & 4 deletions Clojure/Clojure.Tests/clojure/test_clojure/agents.clj
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@
(is (= agt (first @err)))
(is (true? (instance? ArithmeticException (second @err))))))

(deftest fail-handler
;; TODO: make these tests deterministic (i.e. not sleep and hope)

#_(deftest fail-handler
(let [err (atom nil)
agt (agent 0 :error-mode :fail :error-handler #(reset! err %&))]
(send agt /)
Expand Down Expand Up @@ -79,7 +81,7 @@
(send failing-agent (fn [_] (throw (Exception.)))) ;;; RuntimeException
(is (.Await latch 10000)))) ;;; .await 10 TimeUnit/Seconds

(deftest restart-no-clear
#_(deftest restart-no-clear
(let [p (promise)
agt (agent 1 :error-mode :fail)]
(send agt (fn [v] @p))
Expand All @@ -95,7 +97,7 @@
(is (= 12 @agt))
(is (nil? (agent-error agt)))))

(deftest restart-clear
#_(deftest restart-clear
(let [p (promise)
agt (agent 1 :error-mode :fail)]
(send agt (fn [v] @p))
Expand All @@ -115,7 +117,7 @@
(is (= 11 @agt))
(is (nil? (agent-error agt)))))

(deftest invalid-restart
#_(deftest invalid-restart
(let [p (promise)
agt (agent 2 :error-mode :fail :validator even?)]
(is (thrown? Exception (restart-agent agt 4))) ;;; RuntimeException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,8 @@
(hash-set nil 2) #{nil 2}
(hash-set #{}) #{#{}}
(hash-set 1 #{}) #{1 #{}}
(hash-set #{} 2) #{#{} 2} ))
(hash-set #{} 2) #{#{} 2}
#_(hash-set (Integer. -1)) #_(hash-set (Long. -1))))


(deftest test-sorted-set
Expand Down
6 changes: 5 additions & 1 deletion Clojure/Clojure.Tests/clojure/test_clojure/reducers.clj
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,8 @@
(is (= 1 (reduce-kv (fn [acc k v]
(reduced (+ acc k)))
0 m))
"Sorted maps should stop reduction when asked")))
"Sorted maps should stop reduction when asked")))

(deftest test-nil
(is (= {:k :v} (reduce-kv assoc {:k :v} nil)))
(is (= 0 (r/fold + nil))))
14 changes: 14 additions & 0 deletions Clojure/Clojure.Tests/clojure/test_clojure/repl.clj
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,17 @@
(is (some #{'defmacro} (apropos 'defmacro)))
(is (some #{'defmacro} (apropos 'efmac)))
(is (= [] (apropos 'nothing-has-this-name)))))


(defmacro call-ns
"Call ns with a unique namespace name. Return the result of calling ns"
[] `(ns a#))
(defmacro call-ns-sym
"Call ns wih a unique namespace name. Return the namespace symbol."
[] `(do (ns a#) 'a#))

(deftest test-dynamic-ns
(testing "a call to ns returns nil"
(is (= nil (call-ns))))
(testing "requiring a dynamically created ns should not throw an exception"
(is (= nil (let [a (call-ns-sym)] (require a))))))
6 changes: 5 additions & 1 deletion Clojure/Clojure.Tests/clojure/test_clojure/special.clj
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@
(let [foo (fn [& {:keys [x]}] x)
bar (fn [& options] (apply foo :x :b options))]
(is (= (bar) :b))
(is (= (bar :x :a) :a))))
(is (= (bar :x :a) :a))))

(deftest empty-list-with-:as-destructuring
(let [{:as x} '()]
(is (= {} x))))
Loading

0 comments on commit 0782f42

Please sign in to comment.