aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/math/number.lux
blob: 3f4fe8c9e44e633204add3ec531ef4326d7dcaef (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
(.using
 [library
  [lux (.except)
   [abstract
    [codec (.only Codec)]]
   [control
    ["[0]" try (.only Try)]]
   [data
    ["[0]" text]]
   [macro
    ["^" pattern]]]]
 ["[0]" /
  ["[1][0]" nat]
  ["[1][0]" int]
  ["[1][0]" rev]
  ["[1][0]" frac]])

(def: separator
  ",")

(def: (separator_prefixed? number)
  (-> Text Bit)
  (case ("lux text index" 0 ..separator number)
    {.#Some 0}
    #1

    _
    #0))

(def: without_separators
  (-> Text Text)
  (text.replaced ..separator ""))

(template [<macro> <nat> <int> <rev> <frac> <error>]
  [(def: .public <macro>
     (macro (_ tokens state)
       (case tokens
         {.#Item [meta {.#Text repr'}] {.#End}}
         (if (..separator_prefixed? repr')
           {try.#Failure <error>}
           (let [repr (..without_separators repr')]
             (case (at <nat> decoded repr)
               {try.#Success value}
               {try.#Success [state (list [meta {.#Nat value}])]}

               (^.multi {try.#Failure _}
                        [(at <int> decoded repr)
                         {try.#Success value}])
               {try.#Success [state (list [meta {.#Int value}])]}

               (^.multi {try.#Failure _}
                        [(at <rev> decoded repr)
                         {try.#Success value}])
               {try.#Success [state (list [meta {.#Rev value}])]}

               (^.multi {try.#Failure _}
                        [(at <frac> decoded repr)
                         {try.#Success value}])
               {try.#Success [state (list [meta {.#Frac value}])]}

               _
               {try.#Failure <error>})))

         _
         {try.#Failure <error>})))]

  [bin /nat.binary /int.binary /rev.binary /frac.binary "Invalid binary syntax."]
  [oct /nat.octal  /int.octal  /rev.octal  /frac.octal  "Invalid octal syntax."]
  [hex /nat.hex    /int.hex    /rev.hex    /frac.hex    "Invalid hexadecimal syntax."]
  )