| rev | 
   line source | 
| 
jbe/bsw@0
 | 
     1 local digit_set = {
 | 
| 
jbe/bsw@0
 | 
     2   ["0"] = true, ["1"] = true, ["2"] = true, ["3"] = true, ["4"] = true,
 | 
| 
jbe/bsw@0
 | 
     3   ["5"] = true, ["6"] = true, ["7"] = true, ["8"] = true, ["9"] = true
 | 
| 
jbe/bsw@0
 | 
     4 }
 | 
| 
jbe/bsw@0
 | 
     5 
 | 
| 
jbe/bsw@0
 | 
     6 function parse.decimal(str, dest_type, options)
 | 
| 
jbe/bsw@0
 | 
     7   local str = parse._pre_fold(str)
 | 
| 
jbe/bsw@0
 | 
     8   local dest_type = dest_type or atom.number
 | 
| 
jbe/bsw@0
 | 
     9   local options = options or {}
 | 
| 
jbe/bsw@0
 | 
    10   if str == "" then
 | 
| 
jbe/bsw@0
 | 
    11     return nil
 | 
| 
jbe/bsw@0
 | 
    12   else
 | 
| 
jbe/bsw@0
 | 
    13     local decimal_shift = options.decimal_shift or 0
 | 
| 
jbe/bsw@0
 | 
    14     if decimal_shift == true then
 | 
| 
jbe/bsw@0
 | 
    15       decimal_shift = options.precision
 | 
| 
jbe/bsw@0
 | 
    16     end
 | 
| 
jbe/bsw@0
 | 
    17     local decimal_point = locale.get("decimal_point") or "."
 | 
| 
jbe/bsw@0
 | 
    18     local negative    = nil
 | 
| 
jbe/bsw@0
 | 
    19     local int         = 0
 | 
| 
jbe/bsw@0
 | 
    20     local frac        = 0
 | 
| 
jbe/bsw@0
 | 
    21     local precision   = 0
 | 
| 
jbe/bsw@0
 | 
    22     local after_point = false
 | 
| 
jbe/bsw@0
 | 
    23     for char in string.gmatch(str, ".") do
 | 
| 
jbe/bsw@0
 | 
    24       local skip = false
 | 
| 
jbe/bsw@0
 | 
    25       if negative == nil then
 | 
| 
jbe/bsw@0
 | 
    26         if char == "+" then
 | 
| 
jbe/bsw@0
 | 
    27           negative = false
 | 
| 
jbe/bsw@0
 | 
    28           skip = true
 | 
| 
jbe/bsw@0
 | 
    29         elseif char == "-" then  -- real minus sign already replaced by _pre_fold
 | 
| 
jbe/bsw@0
 | 
    30           negative = true
 | 
| 
jbe/bsw@0
 | 
    31           skip = true
 | 
| 
jbe/bsw@0
 | 
    32         end
 | 
| 
jbe/bsw@0
 | 
    33       end
 | 
| 
jbe/bsw@0
 | 
    34       if not skip then
 | 
| 
jbe/bsw@0
 | 
    35         if digit_set[char] then
 | 
| 
jbe/bsw@0
 | 
    36           if after_point then
 | 
| 
jbe/bsw@0
 | 
    37             if decimal_shift > 0 then
 | 
| 
jbe/bsw@0
 | 
    38               int = 10 * int + tonumber(char)
 | 
| 
jbe/bsw@0
 | 
    39               decimal_shift = decimal_shift - 1
 | 
| 
jbe/bsw@0
 | 
    40             else
 | 
| 
jbe/bsw@0
 | 
    41               frac = 10 * frac + tonumber(char)
 | 
| 
jbe/bsw@0
 | 
    42               precision = precision + 1
 | 
| 
jbe/bsw@0
 | 
    43             end
 | 
| 
jbe/bsw@0
 | 
    44           else
 | 
| 
jbe/bsw@0
 | 
    45             int = 10 * int + tonumber(char)
 | 
| 
jbe/bsw@0
 | 
    46           end
 | 
| 
jbe/bsw@0
 | 
    47         elseif char == decimal_point then
 | 
| 
jbe/bsw@0
 | 
    48           if after_point then
 | 
| 
jbe/bsw@0
 | 
    49             return dest_type.invalid
 | 
| 
jbe/bsw@0
 | 
    50           else
 | 
| 
jbe/bsw@0
 | 
    51             after_point = true
 | 
| 
jbe/bsw@0
 | 
    52           end
 | 
| 
jbe/bsw@0
 | 
    53         elseif char ~= " " then  -- TODO: ignore thousand seperator too, when supported by format.decimal
 | 
| 
jbe/bsw@0
 | 
    54           return dest_type.invalid
 | 
| 
jbe/bsw@0
 | 
    55         end
 | 
| 
jbe/bsw@0
 | 
    56       end
 | 
| 
jbe/bsw@0
 | 
    57     end
 | 
| 
jbe/bsw@0
 | 
    58     int = int * 10 ^ decimal_shift
 | 
| 
jbe/bsw@0
 | 
    59     if dest_type == atom.number or dest_type == atom.integer then
 | 
| 
jbe/bsw@0
 | 
    60       if dest_type == atom.integer and frac ~= 0 then
 | 
| 
jbe/bsw@0
 | 
    61         return atom.not_a_number
 | 
| 
jbe/bsw@0
 | 
    62       else
 | 
| 
jbe/bsw@0
 | 
    63         local f = int + frac / 10 ^ precision
 | 
| 
jbe/bsw@0
 | 
    64         if negative then
 | 
| 
jbe/bsw@0
 | 
    65           f = -f
 | 
| 
jbe/bsw@0
 | 
    66         end
 | 
| 
jbe/bsw@0
 | 
    67         return f
 | 
| 
jbe/bsw@0
 | 
    68       end
 | 
| 
jbe/bsw@0
 | 
    69     elseif dest_type == atom.fraction then
 | 
| 
jbe/bsw@0
 | 
    70       return atom.fraction(int * 10 ^ precision + frac, 10 ^ precision)
 | 
| 
jbe/bsw@0
 | 
    71     else
 | 
| 
jbe/bsw@0
 | 
    72       error("Missing or invalid destination type for parsing.")
 | 
| 
jbe/bsw@0
 | 
    73     end
 | 
| 
jbe/bsw@0
 | 
    74   end
 | 
| 
jbe/bsw@0
 | 
    75 end
 |