
# The contents of this file are subject to the Mozilla Public License
# (MPL) Version 1.1 (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License
# at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and
# limitations under the License.
#
# The Original Code is LEPL (http://www.acooke.org/lepl)
# The Initial Developer of the Original Code is Andrew Cooke.
# Portions created by the Initial Developer are Copyright (C) 2009-2010
# Andrew Cooke (andrew@acooke.org). All Rights Reserved.
#
# Contributor(s):
# - "magcius" / jstpierre at mecheye dot net
# Portions created by the Contributors are Copyright (C) 2010
# The Contributors.  All Rights Reserved.
#
# Alternatively, the contents of this file may be used under the terms
# of the LGPL license (the GNU Lesser General Public License,
# http://www.gnu.org/licenses/lgpl.html), in which case the provisions
# of the LGPL License are applicable instead of those above.
#
# If you wish to allow use of your version of this file only under the
# terms of the LGPL License and not to allow others to use your version
# of this file under the MPL, indicate your decision by deleting the
# provisions above and replace them with the notice and other provisions
# required by the LGPL License.  If you do not delete the provisions
# above, a recipient may use your version of this file under either the
# MPL or the LGPL License.

'''
http://www.ietf.org/rfc/rfc4627.txt
'''


from lepl import *
from lepl.support.lib import str


def Simple():
    '''
    A simple JSON parser.
    '''
    
    escapes = {'\\b': '\b', '\\f': '\f', '\\n': '\n', '\\t': '\t', '\\r': '\r'}
    
    def unescape_string(text):
        return escapes[text]
    
    def unescape_unicode(text):
        # Python 3 only
        return bytes(str(text), 'utf8').decode('unicode_escape')
    
    value          = Delayed()

    unicode_escape = ("\\u" + Digit()[4, ...])   >> unescape_unicode
    regular_escape = ("\\" + Any("bfntr"))       >> unescape_string
    escape         = (unicode_escape | regular_escape)
    string         = (Drop('"') & (AnyBut('"\\') | escape)[...] & Drop('"'))
    
    number         = Real() >> float
    
    comma          = Drop(',')
    
    with DroppedSpace():
        array          = Drop("[") & value[:, comma] & Drop("]")  > list
    
        pair           = string & Drop(":") & value               > tuple
        object_        = Drop("{") & pair[:, comma] & Drop("}")   > dict
    
    
    value         += ((Literal('true')  >= (lambda x: True)) |
                      (Literal('false') >= (lambda x: False)) |
                      (Literal('null')  >= (lambda x: None)) |
                      array | object_ | number | string)

    return value
