aboutsummaryrefslogtreecommitdiff
path: root/src/cljcc/util.clj
blob: 6ced120b43f9c1c5446a5901f73f85b1646ab729 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
(ns cljcc.util
  (:require [clojure.java.shell :refer [sh]]
            [clojure.string :as str]
            [cljcc.log :as log]
            [cljcc.exception :as exc]))

(def ^:private counter "Global integer counter for generating unique identifier names." (atom 0))

(defn create-identifier!
  "Returns a unique identifier. Used for generating unique identifier.

  Removes : from keywords.
  Replaces all - with _ for generating valid assembly names."
  ([]
   (create-identifier! "tmp"))
  ([identifier]
   (let [n @counter
         _ (swap! counter inc)]
     (-> identifier
         (str "." n)
         (str/replace #":" "")
         (str/replace #"-" "_")))))

(defn reset-counter! []
  (reset! counter 0))

(defn make-file-name
  ([^String filename ^String ext]
   (str filename "." ext))
  ([directory filename ext]
   (str directory "/" filename "." ext)))

(defn get-os []
  (let [os-name (.toLowerCase (System/getProperty "os.name"))]
    (cond
      (.contains os-name "mac") :mac
      (.contains os-name "linux") :linux
      :else :unsupported)))

(defn mac-aarch64? []
  (and (= :mac (get-os)) (= (System/getProperty "os.arch") "aarch64")))

(defn handle-sh
  "Preprends arch -x86_64 if running under Mac M chips."
  [command & args]
  (if (mac-aarch64?)
    (apply sh "arch" "-x86_64" command args)
    (apply sh command args)))

(defn exit
  ([status msg]
   (if (= status 0)
     (log/info msg)
     (log/error msg))
   (System/exit status))
  ([status msg e]
   (log/error (ex-data e))
   (exit status msg)))

(defn letter? [^Character ch]
  (or (= \_ ch)
      (Character/isLetter ch)))

(defn letter-digit? [^Character ch]
  (or (= \_ ch)
      (Character/isLetterOrDigit ch)))

(defn digit? [^Character ch]
  (Character/isDigit ch))

(defn newline? [ch]
  (= \newline ch))

(defn whitespace? [^Character ch]
  (Character/isWhitespace ch))

(defn- valid-long?
  "Validates string to be of form [0-9]+[lL]\b.

  Verifies that `l` or `L` occurs only once, and at the end."
  [s]
  (try
    (let [strip-l-or-L (if-let [_ (or (str/ends-with? s "l")
                                      (str/ends-with? s "L"))]
                         (subs s 0 (dec (count s)))
                         s)
          _ (-> strip-l-or-L
                Long/parseLong
                Long/toString)]
        s)
    (catch Exception _e
      false)))

(defn read-number
  "Returns number and number type tuple.

  Checks whether number is valid long. If no, checks if it valid int.
  Otherwise error."
  [s line col]
  (if-let [s (valid-long? s)]
    s
    (exc/lex-error {:line line
                    :col col})))