| 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 |