aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/math/number.lux
blob: a96c450ee3ebf3bc5e2b8fd689a26d784dcb7a6c (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
(.module:
  [lux #*
   [abstract
    [codec (#+ Codec)]]
   [control
    ["." try (#+ Try)]]
   [data
    ["." text]]]
  ["." / #_
   ["#." nat]
   ["#." int]
   ["#." rev]
   ["#." frac]])

(macro: (encoding_doc tokens state)
  (case tokens
    (^ (list [location (#.Text encoding)] example_1 example_2))
    (let [encoding ($_ "lux text concat"
                       "Given syntax for a "
                       encoding
                       " number, generates a Nat, an Int, a Rev or a Frac.")
          separators "Allows for the presence of commas among the digits."
          description [location (#.Text ($_ "lux text concat" encoding " " separators))]]
      (#try.Success [state (list (` (doc (~ description)
                                         (~ example_1)
                                         (~ example_2))))]))

    _
    (#try.Failure "Wrong syntax for 'encoding_doc'.")))

(def: separator
  ",")

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

    _
    #0))

(def: clean_separators
  (-> Text Text)
  (text.replace_all ..separator ""))

(template [<macro> <nat> <int> <rev> <frac> <error> <doc>]
  [(macro: #export (<macro> tokens state)
     {#.doc <doc>}
     (case tokens
       (#.Cons [meta (#.Text repr')] #.Nil)
       (if (..separator_prefixed? repr')
         (#try.Failure <error>)
         (let [repr (..clean_separators repr')]
           (case (\ <nat> decode repr)
             (#try.Success value)
             (#try.Success [state (list [meta (#.Nat value)])])

             (^multi (#try.Failure _)
                     [(\ <int> decode repr) (#try.Success value)])
             (#try.Success [state (list [meta (#.Int value)])])

             (^multi (#try.Failure _)
                     [(\ <rev> decode repr) (#try.Success value)])
             (#try.Success [state (list [meta (#.Rev value)])])

             (^multi (#try.Failure _)
                     [(\ <frac> decode 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."
   (encoding_doc "binary" (bin "11001001") (bin "11,00,10,01"))]
  [oct /nat.octal  /int.octal  /rev.octal  /frac.octal
   "Invalid octal syntax."
   (encoding_doc "octal" (oct "615243") (oct "615,243"))]
  [hex /nat.hex    /int.hex    /rev.hex    /frac.hex
   "Invalid hexadecimal syntax."
   (encoding_doc "hexadecimal" (hex "deadBEEF") (hex "dead,BEEF"))]
  )