docs: updates README to indicate updated testing results and drops mention of travis...
[luajson.git] / lua / json / decode / number.lua
blob94ed3b88961a092f8562083f594653f9c077c4f9
1 --[[
2 Licensed according to the included 'LICENSE' document
3 Author: Thomas Harning Jr <harningt@gmail.com>
4 ]]
5 local lpeg = require("lpeg")
6 local tonumber = tonumber
7 local jsonutil = require("json.util")
8 local merge = jsonutil.merge
9 local util = require("json.decode.util")
11 local _ENV = nil
13 local digit = lpeg.R("09")
14 local digits = digit^1
16 -- Illegal octal declaration
17 local illegal_octal_detect = #(lpeg.P('0') * digits) * util.denied("Octal numbers")
19 local int = (lpeg.P('-') + 0) * (lpeg.R("19") * digits + illegal_octal_detect + digit)
21 local frac = lpeg.P('.') * digits
23 local exp = lpeg.S("Ee") * (lpeg.S("-+") + 0) * digits
25 local nan = lpeg.S("Nn") * lpeg.S("Aa") * lpeg.S("Nn")
26 local inf = lpeg.S("Ii") * lpeg.P("nfinity")
27 local ninf = lpeg.P('-') * lpeg.S("Ii") * lpeg.P("nfinity")
28 local hex = (lpeg.P("0x") + lpeg.P("0X")) * lpeg.R("09","AF","af")^1
30 local defaultOptions = {
31 nan = true,
32 inf = true,
33 frac = true,
34 exp = true,
35 hex = false
38 local modeOptions = {}
40 modeOptions.strict = {
41 nan = false,
42 inf = false
45 local nan_value = 0/0
46 local inf_value = 1/0
47 local ninf_value = -1/0
49 --[[
50 Options: configuration options for number rules
51 nan: match NaN
52 inf: match Infinity
53 frac: match fraction portion (.0)
54 exp: match exponent portion (e1)
55 DEFAULT: nan, inf, frac, exp
57 local function mergeOptions(options, mode)
58 jsonutil.doOptionMerge(options, false, 'number', defaultOptions, mode and modeOptions[mode])
59 end
61 local function generateLexer(options)
62 options = options.number
63 local ret = int
64 if options.frac then
65 ret = ret * (frac + 0)
66 else
67 ret = ret * (#frac * util.denied("Fractions", "number.frac") + 0)
68 end
69 if options.exp then
70 ret = ret * (exp + 0)
71 else
72 ret = ret * (#exp * util.denied("Exponents", "number.exp") + 0)
73 end
74 if options.hex then
75 ret = hex + ret
76 else
77 ret = #hex * util.denied("Hexadecimal", "number.hex") + ret
78 end
79 -- Capture number now
80 ret = ret / tonumber
81 if options.nan then
82 ret = ret + nan / function() return nan_value end
83 else
84 ret = ret + #nan * util.denied("NaN", "number.nan")
85 end
86 if options.inf then
87 ret = ret + ninf / function() return ninf_value end + inf / function() return inf_value end
88 else
89 ret = ret + (#ninf + #inf) * util.denied("+/-Inf", "number.inf")
90 end
91 return ret
92 end
94 local number = {
95 int = int,
96 mergeOptions = mergeOptions,
97 generateLexer = generateLexer
100 return number