Implement integer parsing
[ton] / don / string.py
index c791387..c7d810b 100644 (file)
@@ -1,4 +1,5 @@
 import binascii
+import re
 
 from don import tags, _shared
 
@@ -58,5 +59,66 @@ def serialize(o):
     
     return _STRING_SERIALIZERS[o.tag](o.value)
 
+def _make_constant_parser(constant, value):
+    def parser(s):
+        if s.startswith(constant):
+            result = _shared.ParseResult(
+                success = True,
+                value = value,
+                remaining = s[len(constant):],
+            )
+            return result
+
+        return _shared._FAILED_PARSE_RESULT
+
+    return parser
+
+def _make_integer_parser(width):
+    matcher = re.compile(r'(-?\d+)i' + str(width))
+
+    def parser(s):
+        match = matcher.match(s)
+
+        if match:
+            return _shared.ParseResult(
+                success = True,
+                value = int(match.group(1)),
+                remaining = s[match.end():],
+            )
+
+        return _shared._FAILED_PARSE_RESULT
+
+    return parser
+
+_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),
+]
+
+def _object_parser(source):
+    for parser in _PARSERS:
+        result = parser(source)
+
+        if result.success:
+            return result
+
+    return _shared._FAILED_PARSE_RESULT
+
+def _parse(parser, source):
+    result = parser(source)
+
+    if result.success:
+        if result.remaining.strip() == '':
+            return result.value
+
+        raise Exception('Unparsed trailing characters: "{}"'.format(result.remaining))
+
+    raise Exception('Unable to parse: "{}"'.format(source))
+
 def deserialize(s):
-    pass
+    return _parse(_object_parser, s)