webmcp

diff framework/env/parse/decimal.lua @ 0:9fdfb27f8e67

Version 1.0.0
author jbe/bsw
date Sun Oct 25 12:00:00 2009 +0100 (2009-10-25)
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/framework/env/parse/decimal.lua	Sun Oct 25 12:00:00 2009 +0100
     1.3 @@ -0,0 +1,75 @@
     1.4 +local digit_set = {
     1.5 +  ["0"] = true, ["1"] = true, ["2"] = true, ["3"] = true, ["4"] = true,
     1.6 +  ["5"] = true, ["6"] = true, ["7"] = true, ["8"] = true, ["9"] = true
     1.7 +}
     1.8 +
     1.9 +function parse.decimal(str, dest_type, options)
    1.10 +  local str = parse._pre_fold(str)
    1.11 +  local dest_type = dest_type or atom.number
    1.12 +  local options = options or {}
    1.13 +  if str == "" then
    1.14 +    return nil
    1.15 +  else
    1.16 +    local decimal_shift = options.decimal_shift or 0
    1.17 +    if decimal_shift == true then
    1.18 +      decimal_shift = options.precision
    1.19 +    end
    1.20 +    local decimal_point = locale.get("decimal_point") or "."
    1.21 +    local negative    = nil
    1.22 +    local int         = 0
    1.23 +    local frac        = 0
    1.24 +    local precision   = 0
    1.25 +    local after_point = false
    1.26 +    for char in string.gmatch(str, ".") do
    1.27 +      local skip = false
    1.28 +      if negative == nil then
    1.29 +        if char == "+" then
    1.30 +          negative = false
    1.31 +          skip = true
    1.32 +        elseif char == "-" then  -- real minus sign already replaced by _pre_fold
    1.33 +          negative = true
    1.34 +          skip = true
    1.35 +        end
    1.36 +      end
    1.37 +      if not skip then
    1.38 +        if digit_set[char] then
    1.39 +          if after_point then
    1.40 +            if decimal_shift > 0 then
    1.41 +              int = 10 * int + tonumber(char)
    1.42 +              decimal_shift = decimal_shift - 1
    1.43 +            else
    1.44 +              frac = 10 * frac + tonumber(char)
    1.45 +              precision = precision + 1
    1.46 +            end
    1.47 +          else
    1.48 +            int = 10 * int + tonumber(char)
    1.49 +          end
    1.50 +        elseif char == decimal_point then
    1.51 +          if after_point then
    1.52 +            return dest_type.invalid
    1.53 +          else
    1.54 +            after_point = true
    1.55 +          end
    1.56 +        elseif char ~= " " then  -- TODO: ignore thousand seperator too, when supported by format.decimal
    1.57 +          return dest_type.invalid
    1.58 +        end
    1.59 +      end
    1.60 +    end
    1.61 +    int = int * 10 ^ decimal_shift
    1.62 +    if dest_type == atom.number or dest_type == atom.integer then
    1.63 +      if dest_type == atom.integer and frac ~= 0 then
    1.64 +        return atom.not_a_number
    1.65 +      else
    1.66 +        local f = int + frac / 10 ^ precision
    1.67 +        if negative then
    1.68 +          f = -f
    1.69 +        end
    1.70 +        return f
    1.71 +      end
    1.72 +    elseif dest_type == atom.fraction then
    1.73 +      return atom.fraction(int * 10 ^ precision + frac, 10 ^ precision)
    1.74 +    else
    1.75 +      error("Missing or invalid destination type for parsing.")
    1.76 +    end
    1.77 +  end
    1.78 +end

Impressum / About Us