X-Git-Url: https://code.kerkeslager.com/?a=blobdiff_plain;f=don%2Fstring.py;h=ee925f662b33b6ded3985b340fb43b8e1d02c176;hb=4714e340486e676ed50e8d6e08c5f2129daa4c59;hp=15ffc1027b3e744807fec97b82ac148eab857e92;hpb=d863068322ef1404cd5b95a8f21b3d2836f942bf;p=ton diff --git a/don/string.py b/don/string.py index 15ffc10..ee925f6 100644 --- a/don/string.py +++ b/don/string.py @@ -1,4 +1,5 @@ import binascii +import re from don import tags, _shared @@ -72,10 +73,81 @@ def _make_constant_parser(constant, value): return parser +def _make_integer_parser(width): + matcher = re.compile(r'(-?\d+)i' + str(width)) + + def parser(s): + match = matcher.match(s) + + if match: + # TODO Validate that the integer is in range + return _shared.ParseResult( + success = True, + value = int(match.group(1)), + remaining = s[match.end():], + ) + + return _shared._FAILED_PARSE_RESULT + + return parser + +_BINARY32_MATCHER = re.compile(r'(-?\d+\.\d+)f') +_BINARY64_MATCHER = re.compile(r'(-?\d+\.\d+)d') + +def _binary32_parser(s): + match = _BINARY32_MATCHER.match(s) + + if match: + # TODO Validate that the double is in range + return _shared.ParseResult( + success = True, + value = float(match.group(1)), + remaining = s[match.end():], + ) + + return _shared._FAILED_PARSE_RESULT + +def _binary64_parser(s): + match = _BINARY64_MATCHER.match(s) + + if match: + # TODO Validate that the double is in range + return _shared.ParseResult( + success = True, + value = float(match.group(1)), + remaining = s[match.end():], + ) + + return _shared._FAILED_PARSE_RESULT + +_BINARY_MATCHER = re.compile(r'"([\da-f]*)"b') + +def _binary_parser(s): + match = _BINARY_MATCHER.match(s) + + if match: + # TODO Validate that the double is in range + return _shared.ParseResult( + success = True, + value = binascii.unhexlify(match.group(1)), + remaining = s[match.end():], + ) + + return _shared._FAILED_PARSE_RESULT + + + _PARSERS = [ _make_constant_parser('null', None), _make_constant_parser('true', True), _make_constant_parser('false', False), + _make_integer_parser(8), + _make_integer_parser(16), + _make_integer_parser(32), + _make_integer_parser(64), + _binary32_parser, + _binary64_parser, + _binary_parser, ] def _object_parser(source): @@ -90,10 +162,13 @@ def _object_parser(source): def _parse(parser, source): result = parser(source) - if result.success and result.remaining.strip() == '': - return result.value + if result.success: + if result.remaining.strip() == '': + return result.value + + raise Exception('Unparsed trailing characters: "{}"'.format(result.remaining)) - raise Exception('Unparsed trailing characters: "{}"'.format(result.remaining)) + raise Exception('Unable to parse: "{}"'.format(source)) def deserialize(s): return _parse(_object_parser, s)