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