base: fixes regression test lua path
[luajson.git] / lua / json / decode / array.lua
blob2d4f12d14b7d0e67749352cc53a29b4944b69bda
1 --[[
2 Licensed according to the included 'LICENSE' document
3 Author: Thomas Harning Jr <harningt@gmail.com>
4 ]]
5 local lpeg = require("lpeg")
7 local util = require("json.decode.util")
8 local jsonutil = require("json.util")
10 local ipairs = ipairs
11 local unpack = unpack
13 module("json.decode.array")
15 -- Utility function to help manage slighly sparse arrays
16 local function processArray(array)
17 array.n = #array
18 for i,v in ipairs(array) do
19 if v == jsonutil.null then
20 array[i] = nil
21 end
22 end
23 if #array == array.n then
24 array.n = nil
25 end
26 if jsonutil.InitArray then
27 array = jsonutil.InitArray(array) or array
28 end
29 return array
30 end
32 local defaultOptions = {
33 trailingComma = true
36 default = nil -- Let the buildCapture optimization take place
37 strict = {
38 trailingComma = false
41 local function buildCapture(options, global_options, state)
42 local ignored = global_options.ignored
43 -- arrayItem == element
44 local arrayItem = lpeg.V(util.types.VALUE)
45 -- If match-time capture supported, use it to remove stack limit for JSON
46 if lpeg.Cmt then
47 arrayItem = lpeg.Cmt(lpeg.Cp(), function(str, i)
48 -- Decode one value then return
49 local END_MARKER = {}
50 local pattern =
51 -- Found empty segment
52 #lpeg.P(']' * lpeg.Cc(END_MARKER) * lpeg.Cp())
53 -- Found a value + captured, check for required , or ] + capture next pos
54 + state.VALUE_MATCH * #(lpeg.P(',') + lpeg.P(']')) * lpeg.Cp()
55 local capture, i = pattern:match(str, i)
56 if END_MARKER == capture then
57 return i
58 elseif (i == nil and capture == nil) then
59 return false
60 else
61 return i, capture
62 end
63 end)
64 end
65 local arrayElements = lpeg.Ct(arrayItem * (ignored * lpeg.P(',') * ignored * arrayItem)^0 + 0) / processArray
67 options = options and jsonutil.merge({}, defaultOptions, options) or defaultOptions
68 local capture = lpeg.P("[")
69 capture = capture * ignored
70 * arrayElements * ignored
71 if options.trailingComma then
72 capture = capture * (lpeg.P(",") + 0) * ignored
73 end
74 capture = capture * lpeg.P("]")
75 return capture
76 end
78 function register_types()
79 util.register_type("ARRAY")
80 end
82 function load_types(options, global_options, grammar, state)
83 local capture = buildCapture(options, global_options, state)
84 local array_id = util.types.ARRAY
85 grammar[array_id] = capture
86 util.append_grammar_item(grammar, "VALUE", lpeg.V(array_id))
87 end