From 06f925afba87c457194ec94d3c3b365990f4b819 Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Fri, 19 Jun 2015 17:40:52 -0600 Subject: [PATCH] some things needed by the new compiler --- pixie/io.pxi | 44 +++++++++++-------- pixie/stdlib.pxi | 97 +++++++++++++++++++++++++----------------- pixie/streams/utf8.pxi | 4 +- 3 files changed, 86 insertions(+), 59 deletions(-) diff --git a/pixie/io.pxi b/pixie/io.pxi index a37188f6..46c38856 100644 --- a/pixie/io.pxi +++ b/pixie/io.pxi @@ -152,24 +152,32 @@ (defn spit "Writes the content to output. Output must be a file or an IOutputStream." - [output content] - (cond - (string? output) - (transduce (map identity) - (-> output - open-write - buffered-output-stream - utf8/utf8-output-stream-rf) - (str content)) - - (satisfies? IOutputStream output) - (transduce (map identity) - (-> output - buffered-output-stream - utf8/utf8-output-stream-rf) - (str content)) - - :else (throw [::Exception "Expected a string or IOutputStream"]))) + ([output content] + (spit output content true)) + ([output content dispose?] + (cond + (string? output) + (transduce (map identity) + (-> output + open-write + buffered-output-stream + utf8/utf8-output-stream-rf) + (str content)) + + (satisfies? IOutputStream output) + (transduce (map identity) + (-> output + buffered-output-stream + utf8/utf8-output-stream-rf) + (str content)) + + (satisfies? IByteOutputStream output) + (transduce (map identity) + (-> output + utf8/utf8-output-stream-rf) + (str content)) + + :else (throw [::Exception "Expected a string or IOutputStream"])))) (defn slurp "Reads in the contents of input. Input must be a filename or an IInputStream" diff --git a/pixie/stdlib.pxi b/pixie/stdlib.pxi index 2c3b9904..d6e2acd3 100644 --- a/pixie/stdlib.pxi +++ b/pixie/stdlib.pxi @@ -1253,45 +1253,6 @@ Creates new maps if the keys are not present." ~ctor ~@proto-bodies))) -(defmacro defrecord - {:doc "Define a record type. - -Similar to `deftype`, but supports construction from a map using `map->Type` -and implements IAssociative, ILookup and IObject." - :added "0.1"} - [nm fields & body] - (let [ctor-name (symbol (str "->" (name nm))) - map-ctor-name (symbol (str "map" (name ctor-name))) - fields (transduce (map (comp keyword name)) conj fields) - type-from-map `(defn ~map-ctor-name [m] - (apply ~ctor-name (map #(get m %) ~fields))) - default-bodies ['IAssociative - `(-assoc [self k v] - (let [m (reduce #(assoc %1 %2 (. self %2)) {} ~fields)] - (~map-ctor-name (assoc m k v)))) - `(-contains-key [self k] - (contains? ~(set fields) k)) - `(-dissoc [self k] - (throw [:pixie.stdlib/NotImplementedException - "dissoc is not supported on defrecords"])) - 'ILookup - `(-val-at [self k not-found] - (if (contains? ~(set fields) k) - (. self k) - not-found)) - 'IObject - `(-str [self] - (str "<" ~(name nm) " " (reduce #(assoc %1 %2 (. self %2)) {} ~fields) ">")) - `(-eq [self other] - (and (instance? ~nm other) - ~@(map (fn [field] - `(= (. self ~field) (. other ~field))) - fields))) - `(-hash [self] - (throw [:pixie.stdlib/NotImplementedException "not implemented"]))] - deftype-decl `(deftype ~nm ~fields ~@default-bodies ~@body)] - `(do ~type-from-map - ~deftype-decl))) (defn print {:doc "Prints the arguments, seperated by spaces." @@ -2454,3 +2415,61 @@ Calling this function on something that is not ISeqable returns a seq with that (fn [v] (str ""))) (extend -repr Namespace -str) + + +(defn -make-record-assoc-body [cname fields] + (let [k-sym (gensym "k") + v-sym (gensym "v") + this-sym (gensym "this") + result `(-assoc [~this-sym ~k-sym ~v-sym] + (case ~k-sym + ~@(mapcat + (fn [k] + [k `(~cname ~@(mapv (fn [x] + (if (= x k) + v-sym + `(get-field ~this-sym ~x))) + fields))]) + fields) + (throw [:pixie.stdlib/NotImplementedException + (str "Can't assoc to a unknown field: " ~k-sym)])))] + result)) + +(defmacro defrecord + {:doc "Define a record type. + +Similar to `deftype`, but supports construction from a map using `map->Type` +and implements IAssociative, ILookup and IObject." + :added "0.1"} + [nm field-syms & body] + (let [ctor-name (symbol (str "->" (name nm))) + map-ctor-name (symbol (str "map" (name ctor-name))) + fields (transduce (map (comp keyword name)) conj field-syms) + type-from-map `(defn ~map-ctor-name [m] + (apply ~ctor-name (map #(get m %) ~fields))) + default-bodies ['IAssociative + (-make-record-assoc-body ctor-name fields) + `(-contains-key [self k] + (contains? ~(set fields) k)) + `(-dissoc [self k] + (throw [:pixie.stdlib/NotImplementedException + "dissoc is not supported on defrecords"])) + 'ILookup + `(-val-at [self k not-found] + (if (contains? ~(set fields) k) + (. self k) + not-found)) + 'IObject + `(-str [self] + (str "<" ~(name nm) " " (reduce #(assoc %1 %2 (. self %2)) {} ~fields) ">")) + `(-eq [self other] + (and (instance? ~nm other) + ~@(map (fn [field] + `(= (. self ~field) (. other ~field))) + fields))) + `(-hash [self] + (hash [~@field-syms]))] + deftype-decl `(deftype ~nm ~fields ~@default-bodies ~@body)] + `(do ~type-from-map + ~deftype-decl))) + diff --git a/pixie/streams/utf8.pxi b/pixie/streams/utf8.pxi index bc9b4044..61781c54 100644 --- a/pixie/streams/utf8.pxi +++ b/pixie/streams/utf8.pxi @@ -25,7 +25,7 @@ :else (assert false (str "Cannot encode a UTF8 character of code " ch))))) IDisposable (-dispose! [this] - (dispose! out))) + nil)) (deftype UTF8InputStream [in bad-char] @@ -53,7 +53,7 @@ (char n)))))) IDisposable (-dispose! [this] - (dispose! in))) + nil)) (defn utf8-input-stream "Creates a UTF8 decoder that reads characters from the given IByteInputStream. If a bad character is found