|
86 | 86 | (omitp #(and (z/sexpr-able? %) |
87 | 87 | (contains? forms (z/sexpr %))))) |
88 | 88 |
|
| 89 | +;; Data structures for simple 1:1 replacements |
| 90 | +(def namespace-mappings |
| 91 | + {'clojure.core 'glojure.core |
| 92 | + 'clojure.string 'glojure.string}) |
| 93 | + |
| 94 | +(def type-mappings |
| 95 | + {;; Simple type replacements when appearing alone |
| 96 | + 'String 'go/string |
| 97 | + 'Long 'go/int64 |
| 98 | + 'java.lang.Long 'go/int64 |
| 99 | + 'java.lang.Double 'go/float64 |
| 100 | + 'Double 'go/float64 |
| 101 | + 'Float 'go/float32 |
| 102 | + 'Boolean 'go/bool |
| 103 | + 'Character 'github.com$glojurelang$glojure$pkg$lang.Char |
| 104 | + 'java.lang.Character 'github.com$glojurelang$glojure$pkg$lang.Char |
| 105 | + 'Throwable 'github.com$glojurelang$glojure$pkg$lang.Throwable |
| 106 | + 'Object 'github.com$glojurelang$glojure$pkg$lang.Object |
| 107 | + 'BigInteger 'math$big.*Int |
| 108 | + 'BigDecimal 'github.com$glojurelang$glojure$pkg$lang.*BigDecimal |
| 109 | + 'CharSequence 'go/string |
| 110 | + 'Class 'reflect.Type |
| 111 | + 'Pattern '*Regexp}) |
| 112 | + |
| 113 | +(def static-field-mappings |
| 114 | + {'Integer/MIN_VALUE 'math.MinInt |
| 115 | + 'Integer/MAX_VALUE 'math.MaxInt |
| 116 | + 'Double/POSITIVE_INFINITY '(math.Inf 1) |
| 117 | + 'Double/NEGATIVE_INFINITY '(math.Inf -1) |
| 118 | + 'Float/POSITIVE_INFINITY '(go/float32 (math.Inf 1)) |
| 119 | + 'Float/NEGATIVE_INFINITY '(go/float32 (math.Inf -1))}) |
| 120 | + |
| 121 | +(defn create-simple-replacements |
| 122 | + "Create sexpr-replace calls from a mapping" |
| 123 | + [mappings] |
| 124 | + (map (fn [[old new]] (sexpr-replace old new)) mappings)) |
| 125 | + |
| 126 | +(defn clojure-lang->glojure-pkg |
| 127 | + "Create replacement for clojure.lang.ClassName to glojure package equivalent" |
| 128 | + [class-name & {:keys [pointer? package] |
| 129 | + :or {pointer? false |
| 130 | + package "github.com$glojurelang$glojure$pkg$lang"}}] |
| 131 | + (sexpr-replace |
| 132 | + (symbol (str "clojure.lang." class-name)) |
| 133 | + (symbol (str package "." (when pointer? "*") class-name)))) |
| 134 | + |
| 135 | +(defn clojure-lang-list->glojure-pkg |
| 136 | + "Create replacements for a list of clojure.lang classes" |
| 137 | + [classes & opts] |
| 138 | + (map #(apply clojure-lang->glojure-pkg % opts) classes)) |
| 139 | + |
89 | 140 | (def replacements |
90 | | - [ |
91 | | - (sexpr-replace 'clojure.core 'glojure.core) |
| 141 | + (concat |
| 142 | + ;; Simple mappings from data structures |
| 143 | + (create-simple-replacements namespace-mappings) |
| 144 | + (create-simple-replacements type-mappings) |
| 145 | + (create-simple-replacements static-field-mappings) |
| 146 | + |
| 147 | + ;; Pattern-based clojure.lang replacements |
| 148 | + (clojure-lang-list->glojure-pkg |
| 149 | + ["IPersistentCollection" "IPersistentList" "IRecord" |
| 150 | + "NewSymbol" "IReduce" "IPending" "Volatile" "IAtom" "IMapEntry" |
| 151 | + "IPersistentMap" "IPersistentVector" "IPersistentSet" "IMeta" |
| 152 | + "IReduceInit" "IObj" "Keyword" "ISeq" "IEditableCollection" |
| 153 | + "Named" "Counted" "Sequential" "IChunkedSeq" |
| 154 | + "IDrop" "IDeref" "IBlockingDeref"] |
| 155 | + :pointer? false) |
| 156 | + |
| 157 | + (clojure-lang-list->glojure-pkg |
| 158 | + ["Symbol" "Ratio" "MultiFn" "PersistentHashMap" "PersistentHashSet" |
| 159 | + "PersistentVector" "LazySeq" "Var" "Namespace" "Ref" "Agent" |
| 160 | + "BigInt" "BigDecimal"] |
| 161 | + :pointer? true) |
| 162 | + |
| 163 | + [(clojure-lang->glojure-pkg "Fn" :pointer? true :package "github.com$glojurelang$glojure$pkg$runtime")] |
| 164 | + |
| 165 | + ;; All other replacements remain as-is |
| 166 | + [ |
| 167 | + ;; ===== Special Clojure.lang Replacements ===== |
| 168 | + ;; These don't follow the standard pattern |
92 | 169 | (sexpr-replace '(. clojure.lang.PersistentList creator) 'github.com$glojurelang$glojure$pkg$lang.NewList) |
93 | 170 | (sexpr-replace '(setMacro) '(SetMacro)) |
94 | | - (sexpr-replace 'clojure.lang.Symbol 'github.com$glojurelang$glojure$pkg$lang.*Symbol) |
95 | | - (sexpr-replace 'clojure.lang.Fn 'github.com$glojurelang$glojure$pkg$runtime.*Fn) |
96 | | - (sexpr-replace 'clojure.lang.IPersistentCollection 'github.com$glojurelang$glojure$pkg$lang.IPersistentCollection) |
97 | | - (sexpr-replace 'clojure.lang.IPersistentList 'github.com$glojurelang$glojure$pkg$lang.IPersistentList) |
98 | | - (sexpr-replace 'clojure.lang.IRecord 'github.com$glojurelang$glojure$pkg$lang.IRecord) |
99 | | - (sexpr-replace 'java.lang.Character 'github.com$glojurelang$glojure$pkg$lang.Char) |
100 | | - (sexpr-replace 'java.lang.Long 'go/int64) |
101 | | - (sexpr-replace 'Long 'go/int64) |
102 | | - (sexpr-replace 'java.lang.Double 'go/float64) |
103 | | - (sexpr-replace 'clojure.lang.Ratio 'github.com$glojurelang$glojure$pkg$lang.*Ratio) |
104 | | - |
105 | | - (sexpr-replace 'clojure.lang.NewSymbol 'github.com$glojurelang$glojure$pkg$lang.NewSymbol) |
106 | | - |
107 | | - (sexpr-replace 'Double/POSITIVE_INFINITY '(math.Inf 1)) |
108 | | - (sexpr-replace 'Double/NEGATIVE_INFINITY '(math.Inf -1)) |
109 | | - (sexpr-replace 'Float/POSITIVE_INFINITY '(go/float32 (math.Inf 1))) |
110 | | - (sexpr-replace 'Float/NEGATIVE_INFINITY '(go/float32 (math.Inf -1))) |
| 171 | + |
| 172 | + |
| 173 | + ;; ===== Math Functions ===== |
111 | 174 | (sexpr-replace '.isNaN 'math.IsNaN) |
112 | 175 | (sexpr-replace 'Double/isNaN 'math.IsNaN) |
113 | 176 |
|
114 | | - ;; Range |
| 177 | + ;; ===== Range Constructors ===== |
115 | 178 | (sexpr-replace '(clojure.lang.LongRange/create end) |
116 | 179 | '(github.com$glojurelang$glojure$pkg$lang.NewLongRange 0 end 1)) |
117 | 180 | (sexpr-replace '(clojure.lang.LongRange/create start end) |
|
127 | 190 | '(github.com$glojurelang$glojure$pkg$lang.NewRange start end step)) |
128 | 191 |
|
129 | 192 |
|
| 193 | + ;; ===== Collection Constructors ===== |
130 | 194 | (sexpr-replace '(. clojure.lang.PersistentHashMap (create keyvals)) |
131 | 195 | '(github.com$glojurelang$glojure$pkg$lang.CreatePersistentHashMap keyvals)) |
132 | 196 |
|
| 197 | + ;; ===== Java Type Mappings ===== |
133 | 198 | ;; map a bunch of java types to go equivalent |
134 | 199 | ;; TODO: once everything passes, see if we can replace with a blanket |
135 | 200 | ;; replacement of the clojure.lang prefix. |
|
139 | 204 | (sexpr-replace 'java.io.PrintWriter |
140 | 205 | 'github.com$glojurelang$glojure$pkg$lang.PrintWriter) |
141 | 206 |
|
142 | | - (sexpr-replace 'Throwable |
143 | | - 'github.com$glojurelang$glojure$pkg$lang.Throwable) |
144 | 207 |
|
145 | 208 | (sexpr-replace 'clojure.lang.IReduce |
146 | 209 | 'github.com$glojurelang$glojure$pkg$lang.IReduce) |
|
206 | 269 | '(fn instance? [t x] (github.com$glojurelang$glojure$pkg$lang.HasType t x))) |
207 | 270 |
|
208 | 271 |
|
209 | | - ;;;; Exceptions |
| 272 | + ;; ===== Exception Handling ===== |
210 | 273 | (sexpr-replace 'IllegalArgumentException. 'github.com$glojurelang$glojure$pkg$lang.NewIllegalArgumentError) |
211 | 274 | ;; new Exception |
212 | 275 | [(fn select [zloc] (and (z/list? zloc) |
|
222 | 285 | (fn visit [zloc] |
223 | 286 | (z/replace zloc 'go/any))] |
224 | 287 |
|
| 288 | + ;; ===== Metadata Operations ===== |
225 | 289 | ;; replace .withMeta |
226 | 290 | [(fn select [zloc] (and (z/list? zloc) (= '.withMeta (first (z/sexpr zloc))))) |
227 | 291 | (fn visit [zloc] (z/replace zloc |
|
230 | 294 | (throw (~'res 1)) |
231 | 295 | (~'res 0)))))] |
232 | 296 |
|
| 297 | + ;; ===== RT Function Replacements ===== |
233 | 298 | (RT-replace 'cons #(cons 'github.com$glojurelang$glojure$pkg$lang.NewCons %)) |
234 | 299 | (RT-replace 'first #(cons 'github.com$glojurelang$glojure$pkg$lang.First %)) |
235 | 300 | (RT-replace 'next #(cons 'github.com$glojurelang$glojure$pkg$lang.Next %)) |
|
252 | 317 | 'github.com$glojurelang$glojure$pkg$lang.IPersistentVector) |
253 | 318 | (sexpr-replace 'clojure.lang.IPersistentSet |
254 | 319 | 'github.com$glojurelang$glojure$pkg$lang.IPersistentSet) |
255 | | - (sexpr-replace 'String 'go/string) |
256 | 320 | (sexpr-replace 'clojure.lang.IMeta |
257 | 321 | 'github.com$glojurelang$glojure$pkg$lang.IMeta) |
258 | 322 | (sexpr-replace 'clojure.lang.IReduceInit |
|
265 | 329 |
|
266 | 330 | (sexpr-replace '.assoc '.Assoc) |
267 | 331 |
|
268 | | - (sexpr-replace 'Integer/MIN_VALUE 'math.MinInt) |
269 | | - (sexpr-replace 'Integer/MAX_VALUE 'math.MaxInt) |
270 | 332 |
|
271 | 333 | (sexpr-replace '(. Math (random)) '(math$rand.Float64)) |
272 | 334 |
|
|
276 | 338 | (sexpr-replace '(. x (get)) '(. x (Get))) |
277 | 339 | (sexpr-replace '(. x (set val)) '(. x (Set val))) |
278 | 340 |
|
279 | | - ;; omit Eduction for now |
| 341 | + ;; ===== Omissions and Deferrals ===== |
280 | 342 | (omitp #(and (z/list? %) |
281 | 343 | (= 'deftype (first (z/sexpr %))))) |
282 | 344 | (omitp #(and (z/list? %) |
|
312 | 374 | (sexpr-replace '(^github.com$glojurelang$glojure$pkg$lang.IPersistentVector [^github.com$glojurelang$glojure$pkg$lang.IAtom2 atom f] (.swapVals atom f)) |
313 | 375 | '([atom f & args] (.swapVals atom f args))) |
314 | 376 |
|
315 | | - ;; Agents |
| 377 | + ;; ===== Agents ===== |
316 | 378 | (sexpr-replace '(. clojure.lang.Agent shutdown) '(github.com$glojurelang$glojure$pkg$lang.ShutdownAgents)) |
317 | 379 | (sexpr-replace 'clojure.lang.Agent 'github.com$glojurelang$glojure$pkg$lang.*Agent) |
318 | 380 |
|
| 381 | + ;; ===== Hashing Functions ===== |
319 | 382 | ;; TODO: these should likely be different |
320 | 383 | (sexpr-replace 'clojure.lang.Util/hash 'github.com$glojurelang$glojure$pkg$lang.Hash) |
321 | 384 | (sexpr-replace '(. clojure.lang.Util (hasheq x)) |
|
331 | 394 |
|
332 | 395 | (sexpr-replace '(. Array (set array idx val)) '(github.com$glojurelang$glojure$pkg$lang.SliceSet array idx val)) |
333 | 396 |
|
| 397 | + ;; ===== Array Operations ===== |
334 | 398 | [(fn select [zloc] (and (z/sexpr-able? zloc) (= '.reduce (z/sexpr zloc)))) |
335 | 399 | (fn visit [zloc] (z/replace zloc |
336 | 400 | (let [lst (z/sexpr (z/up zloc))] |
337 | 401 | (if (= 3 (count lst)) |
338 | 402 | '.Reduce |
339 | 403 | '.ReduceInit))))] |
340 | 404 |
|
341 | | - (sexpr-replace 'BigInteger 'math$big.*Int) |
342 | | - (sexpr-replace 'BigDecimal 'github.com$glojurelang$glojure$pkg$lang.*BigDecimal) |
343 | 405 | (sexpr-replace 'clojure.lang.BigInt/valueOf |
344 | 406 | 'github.com$glojurelang$glojure$pkg$lang.NewBigIntFromInt64) |
345 | 407 | (sexpr-replace '(BigInteger/valueOf (long x)) |
|
460 | 522 | (sexpr-replace '.resetMeta '.ResetMeta) |
461 | 523 |
|
462 | 524 |
|
463 | | - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
464 | | - ;; Multi-methods |
| 525 | + ;; ===== Multi-methods ===== |
465 | 526 | [(fn select [zloc] (and (z/list? zloc) |
466 | 527 | (let [sexpr (z/sexpr zloc)] |
467 | 528 | (and |
|
505 | 566 | (= 'isa? (second sexpr)))))) |
506 | 567 | (fn visit [zloc] (z/replace zloc new-node))]) |
507 | 568 |
|
508 | | - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
509 | 569 |
|
510 | 570 | (sexpr-replace '(System/getProperty "line.separator") '"\\n") |
511 | 571 | (sexpr-replace 'clojure.lang.ISeq 'github.com$glojurelang$glojure$pkg$lang.ISeq) |
512 | 572 | (sexpr-replace 'clojure.lang.IEditableCollection 'github.com$glojurelang$glojure$pkg$lang.IEditableCollection) |
513 | 573 | (sexpr-replace 'clojure.core/import* 'github.com$glojurelang$glojure$pkg$lang.Import) |
514 | 574 |
|
| 575 | + ;; ===== Import Omissions ===== |
515 | 576 | (omit-forms '#{(import '(java.lang.reflect Array)) |
516 | 577 | (import clojure.lang.ExceptionInfo clojure.lang.IExceptionInfo) |
517 | 578 | (import '(java.util.concurrent BlockingQueue LinkedBlockingQueue)) |
|
535 | 596 | (sexpr-replace "clojure.core" "glojure.core") |
536 | 597 | (sexpr-replace 'clojure.core/name 'glojure.core/name) |
537 | 598 |
|
538 | | - ;; number checksclasses |
| 599 | + ;; ===== Number Type Checks ===== |
539 | 600 | (sexpr-replace '(defn integer? |
540 | 601 | "Returns true if n is an integer" |
541 | 602 | {:added "1.0" |
|
590 | 651 | (sexpr-replace 'Unchecked_int_divide 'UncheckedIntDivide) |
591 | 652 | (sexpr-replace '(unchecked_minus x) '(Unchecked_negate x)) |
592 | 653 |
|
| 654 | + ;; ===== Numeric Array Replacements ===== |
593 | 655 | (replace-num-array 'char) |
594 | 656 | (replace-num-array 'byte) |
595 | 657 | (replace-num-array 'short) |
|
658 | 720 |
|
659 | 721 | (sexpr-replace '.charAt 'github.com$glojurelang$glojure$pkg$lang.CharAt) |
660 | 722 |
|
661 | | - ;;;; OMIT PARTS OF THE FILE ENTIRELY FOR NOW |
| 723 | + ;; ===== File Loading and Module Omissions ===== |
662 | 724 | ;;; TODO: implement load for embedded files! |
663 | 725 | (sexpr-replace '(load "core_proxy") '(do)) |
664 | 726 | (sexpr-replace '(load "genclass") '(do)) |
|
759 | 821 | (sexpr-replace '(. x (getClass)) |
760 | 822 | '(github.com$glojurelang$glojure$pkg$lang.TypeOf x)) |
761 | 823 |
|
762 | | - ;;; core_print.clj |
| 824 | + ;; ===== Core Print Replacements ===== |
763 | 825 |
|
764 | | - (sexpr-replace 'Double 'go/float64) |
765 | | - (sexpr-replace 'Float 'go/float32) |
766 | | - (sexpr-replace 'Boolean 'go/bool) |
767 | 826 |
|
768 | | - (sexpr-replace 'Object 'github.com$glojurelang$glojure$pkg$lang.Object) |
769 | 827 | (sexpr-replace '(.isArray c) false) |
770 | 828 | ;; (sexpr-replace '(print-method (.Name c) w) 'TODO) |
771 | 829 | ;; (sexpr-replace '(github.com$glojurelang$glojure$pkg$lang.WriteWriter w (.Name c)) 'TODO) |
|
801 | 859 |
|
802 | 860 | (omit-symbols '#{primitives-classnames}) |
803 | 861 |
|
804 | | - (sexpr-replace 'Class 'reflect.Type) |
805 | 862 | (sexpr-replace '(.getInterfaces c) nil) ;; no such concept in go |
806 | 863 | (sexpr-replace '(.getSuperclass c) nil) ;; no such concept in go |
807 | 864 |
|
|
855 | 912 | (string/replace "clojure." "glojure.") |
856 | 913 | symbol)))] |
857 | 914 |
|
858 | | - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
859 | | - ;; test.clj |
| 915 | + ;; ===== Test.clj Replacements ===== |
860 | 916 |
|
861 | 917 | (sexpr-remove '[clojure.stacktrace :as stack]) |
862 | 918 |
|
|
865 | 921 | (first (z/sexpr zloc))))) |
866 | 922 | (fn visit [zloc] (z/replace zloc '{}))] |
867 | 923 |
|
868 | | - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
869 | | - ;; Regular Expressions |
| 924 | + ;; ===== Regular Expression Replacements ===== |
870 | 925 | (sexpr-replace '(.split re s) |
871 | 926 | '(.split re s -1)) |
872 | 927 |
|
873 | | - (sexpr-replace 'Character |
874 | | - 'github.com$glojurelang$glojure$pkg$lang.Char) |
875 | | - (sexpr-replace 'Pattern '*Regexp) |
876 | | - (sexpr-replace 'CharSequence 'go/string) |
877 | 928 | (sexpr-replace '(.length s) '(count s)) |
878 | 929 | (sexpr-replace '(.length match) '(count match)) |
879 | 930 |
|
|
887 | 938 | (node-replace "(.pattern ^java.util.regex.Pattern p)" |
888 | 939 | "(.String ^regexp.*Regexp p)") |
889 | 940 |
|
890 | | - ]) |
| 941 | + ])) |
891 | 942 |
|
892 | 943 | (defn rewrite-core [zloc] |
893 | 944 | (loop [zloc (z/of-node (z/root zloc))] |
|
0 commit comments