Skip to content

Commit 55fff5d

Browse files
authored
Make clojure stdlib rewrite script a bit more legible (#76)
1 parent 2299b0a commit 55fff5d

1 file changed

Lines changed: 101 additions & 50 deletions

File tree

scripts/rewrite-core/rewrite.clj

Lines changed: 101 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -86,32 +86,95 @@
8686
(omitp #(and (z/sexpr-able? %)
8787
(contains? forms (z/sexpr %)))))
8888

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+
89140
(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
92169
(sexpr-replace '(. clojure.lang.PersistentList creator) 'github.com$glojurelang$glojure$pkg$lang.NewList)
93170
(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 =====
111174
(sexpr-replace '.isNaN 'math.IsNaN)
112175
(sexpr-replace 'Double/isNaN 'math.IsNaN)
113176

114-
;; Range
177+
;; ===== Range Constructors =====
115178
(sexpr-replace '(clojure.lang.LongRange/create end)
116179
'(github.com$glojurelang$glojure$pkg$lang.NewLongRange 0 end 1))
117180
(sexpr-replace '(clojure.lang.LongRange/create start end)
@@ -127,9 +190,11 @@
127190
'(github.com$glojurelang$glojure$pkg$lang.NewRange start end step))
128191

129192

193+
;; ===== Collection Constructors =====
130194
(sexpr-replace '(. clojure.lang.PersistentHashMap (create keyvals))
131195
'(github.com$glojurelang$glojure$pkg$lang.CreatePersistentHashMap keyvals))
132196

197+
;; ===== Java Type Mappings =====
133198
;; map a bunch of java types to go equivalent
134199
;; TODO: once everything passes, see if we can replace with a blanket
135200
;; replacement of the clojure.lang prefix.
@@ -139,8 +204,6 @@
139204
(sexpr-replace 'java.io.PrintWriter
140205
'github.com$glojurelang$glojure$pkg$lang.PrintWriter)
141206

142-
(sexpr-replace 'Throwable
143-
'github.com$glojurelang$glojure$pkg$lang.Throwable)
144207

145208
(sexpr-replace 'clojure.lang.IReduce
146209
'github.com$glojurelang$glojure$pkg$lang.IReduce)
@@ -206,7 +269,7 @@
206269
'(fn instance? [t x] (github.com$glojurelang$glojure$pkg$lang.HasType t x)))
207270

208271

209-
;;;; Exceptions
272+
;; ===== Exception Handling =====
210273
(sexpr-replace 'IllegalArgumentException. 'github.com$glojurelang$glojure$pkg$lang.NewIllegalArgumentError)
211274
;; new Exception
212275
[(fn select [zloc] (and (z/list? zloc)
@@ -222,6 +285,7 @@
222285
(fn visit [zloc]
223286
(z/replace zloc 'go/any))]
224287

288+
;; ===== Metadata Operations =====
225289
;; replace .withMeta
226290
[(fn select [zloc] (and (z/list? zloc) (= '.withMeta (first (z/sexpr zloc)))))
227291
(fn visit [zloc] (z/replace zloc
@@ -230,6 +294,7 @@
230294
(throw (~'res 1))
231295
(~'res 0)))))]
232296

297+
;; ===== RT Function Replacements =====
233298
(RT-replace 'cons #(cons 'github.com$glojurelang$glojure$pkg$lang.NewCons %))
234299
(RT-replace 'first #(cons 'github.com$glojurelang$glojure$pkg$lang.First %))
235300
(RT-replace 'next #(cons 'github.com$glojurelang$glojure$pkg$lang.Next %))
@@ -252,7 +317,6 @@
252317
'github.com$glojurelang$glojure$pkg$lang.IPersistentVector)
253318
(sexpr-replace 'clojure.lang.IPersistentSet
254319
'github.com$glojurelang$glojure$pkg$lang.IPersistentSet)
255-
(sexpr-replace 'String 'go/string)
256320
(sexpr-replace 'clojure.lang.IMeta
257321
'github.com$glojurelang$glojure$pkg$lang.IMeta)
258322
(sexpr-replace 'clojure.lang.IReduceInit
@@ -265,8 +329,6 @@
265329

266330
(sexpr-replace '.assoc '.Assoc)
267331

268-
(sexpr-replace 'Integer/MIN_VALUE 'math.MinInt)
269-
(sexpr-replace 'Integer/MAX_VALUE 'math.MaxInt)
270332

271333
(sexpr-replace '(. Math (random)) '(math$rand.Float64))
272334

@@ -276,7 +338,7 @@
276338
(sexpr-replace '(. x (get)) '(. x (Get)))
277339
(sexpr-replace '(. x (set val)) '(. x (Set val)))
278340

279-
;; omit Eduction for now
341+
;; ===== Omissions and Deferrals =====
280342
(omitp #(and (z/list? %)
281343
(= 'deftype (first (z/sexpr %)))))
282344
(omitp #(and (z/list? %)
@@ -312,10 +374,11 @@
312374
(sexpr-replace '(^github.com$glojurelang$glojure$pkg$lang.IPersistentVector [^github.com$glojurelang$glojure$pkg$lang.IAtom2 atom f] (.swapVals atom f))
313375
'([atom f & args] (.swapVals atom f args)))
314376

315-
;; Agents
377+
;; ===== Agents =====
316378
(sexpr-replace '(. clojure.lang.Agent shutdown) '(github.com$glojurelang$glojure$pkg$lang.ShutdownAgents))
317379
(sexpr-replace 'clojure.lang.Agent 'github.com$glojurelang$glojure$pkg$lang.*Agent)
318380

381+
;; ===== Hashing Functions =====
319382
;; TODO: these should likely be different
320383
(sexpr-replace 'clojure.lang.Util/hash 'github.com$glojurelang$glojure$pkg$lang.Hash)
321384
(sexpr-replace '(. clojure.lang.Util (hasheq x))
@@ -331,15 +394,14 @@
331394

332395
(sexpr-replace '(. Array (set array idx val)) '(github.com$glojurelang$glojure$pkg$lang.SliceSet array idx val))
333396

397+
;; ===== Array Operations =====
334398
[(fn select [zloc] (and (z/sexpr-able? zloc) (= '.reduce (z/sexpr zloc))))
335399
(fn visit [zloc] (z/replace zloc
336400
(let [lst (z/sexpr (z/up zloc))]
337401
(if (= 3 (count lst))
338402
'.Reduce
339403
'.ReduceInit))))]
340404

341-
(sexpr-replace 'BigInteger 'math$big.*Int)
342-
(sexpr-replace 'BigDecimal 'github.com$glojurelang$glojure$pkg$lang.*BigDecimal)
343405
(sexpr-replace 'clojure.lang.BigInt/valueOf
344406
'github.com$glojurelang$glojure$pkg$lang.NewBigIntFromInt64)
345407
(sexpr-replace '(BigInteger/valueOf (long x))
@@ -460,8 +522,7 @@
460522
(sexpr-replace '.resetMeta '.ResetMeta)
461523

462524

463-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
464-
;; Multi-methods
525+
;; ===== Multi-methods =====
465526
[(fn select [zloc] (and (z/list? zloc)
466527
(let [sexpr (z/sexpr zloc)]
467528
(and
@@ -505,13 +566,13 @@
505566
(= 'isa? (second sexpr))))))
506567
(fn visit [zloc] (z/replace zloc new-node))])
507568

508-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
509569

510570
(sexpr-replace '(System/getProperty "line.separator") '"\\n")
511571
(sexpr-replace 'clojure.lang.ISeq 'github.com$glojurelang$glojure$pkg$lang.ISeq)
512572
(sexpr-replace 'clojure.lang.IEditableCollection 'github.com$glojurelang$glojure$pkg$lang.IEditableCollection)
513573
(sexpr-replace 'clojure.core/import* 'github.com$glojurelang$glojure$pkg$lang.Import)
514574

575+
;; ===== Import Omissions =====
515576
(omit-forms '#{(import '(java.lang.reflect Array))
516577
(import clojure.lang.ExceptionInfo clojure.lang.IExceptionInfo)
517578
(import '(java.util.concurrent BlockingQueue LinkedBlockingQueue))
@@ -535,7 +596,7 @@
535596
(sexpr-replace "clojure.core" "glojure.core")
536597
(sexpr-replace 'clojure.core/name 'glojure.core/name)
537598

538-
;; number checksclasses
599+
;; ===== Number Type Checks =====
539600
(sexpr-replace '(defn integer?
540601
"Returns true if n is an integer"
541602
{:added "1.0"
@@ -590,6 +651,7 @@
590651
(sexpr-replace 'Unchecked_int_divide 'UncheckedIntDivide)
591652
(sexpr-replace '(unchecked_minus x) '(Unchecked_negate x))
592653

654+
;; ===== Numeric Array Replacements =====
593655
(replace-num-array 'char)
594656
(replace-num-array 'byte)
595657
(replace-num-array 'short)
@@ -658,7 +720,7 @@
658720

659721
(sexpr-replace '.charAt 'github.com$glojurelang$glojure$pkg$lang.CharAt)
660722

661-
;;;; OMIT PARTS OF THE FILE ENTIRELY FOR NOW
723+
;; ===== File Loading and Module Omissions =====
662724
;;; TODO: implement load for embedded files!
663725
(sexpr-replace '(load "core_proxy") '(do))
664726
(sexpr-replace '(load "genclass") '(do))
@@ -759,13 +821,9 @@
759821
(sexpr-replace '(. x (getClass))
760822
'(github.com$glojurelang$glojure$pkg$lang.TypeOf x))
761823

762-
;;; core_print.clj
824+
;; ===== Core Print Replacements =====
763825

764-
(sexpr-replace 'Double 'go/float64)
765-
(sexpr-replace 'Float 'go/float32)
766-
(sexpr-replace 'Boolean 'go/bool)
767826

768-
(sexpr-replace 'Object 'github.com$glojurelang$glojure$pkg$lang.Object)
769827
(sexpr-replace '(.isArray c) false)
770828
;; (sexpr-replace '(print-method (.Name c) w) 'TODO)
771829
;; (sexpr-replace '(github.com$glojurelang$glojure$pkg$lang.WriteWriter w (.Name c)) 'TODO)
@@ -801,7 +859,6 @@
801859

802860
(omit-symbols '#{primitives-classnames})
803861

804-
(sexpr-replace 'Class 'reflect.Type)
805862
(sexpr-replace '(.getInterfaces c) nil) ;; no such concept in go
806863
(sexpr-replace '(.getSuperclass c) nil) ;; no such concept in go
807864

@@ -855,8 +912,7 @@
855912
(string/replace "clojure." "glojure.")
856913
symbol)))]
857914

858-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
859-
;; test.clj
915+
;; ===== Test.clj Replacements =====
860916

861917
(sexpr-remove '[clojure.stacktrace :as stack])
862918

@@ -865,15 +921,10 @@
865921
(first (z/sexpr zloc)))))
866922
(fn visit [zloc] (z/replace zloc '{}))]
867923

868-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
869-
;; Regular Expressions
924+
;; ===== Regular Expression Replacements =====
870925
(sexpr-replace '(.split re s)
871926
'(.split re s -1))
872927

873-
(sexpr-replace 'Character
874-
'github.com$glojurelang$glojure$pkg$lang.Char)
875-
(sexpr-replace 'Pattern '*Regexp)
876-
(sexpr-replace 'CharSequence 'go/string)
877928
(sexpr-replace '(.length s) '(count s))
878929
(sexpr-replace '(.length match) '(count match))
879930

@@ -887,7 +938,7 @@
887938
(node-replace "(.pattern ^java.util.regex.Pattern p)"
888939
"(.String ^regexp.*Regexp p)")
889940

890-
])
941+
]))
891942

892943
(defn rewrite-core [zloc]
893944
(loop [zloc (z/of-node (z/root zloc))]

0 commit comments

Comments
 (0)