From 0d97116248141602da75d79dc696b7f348dc1e09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Aradi?= Date: Mon, 13 Mar 2023 12:39:42 +0100 Subject: [PATCH] Add support for complex entries --- src/hsd/dict.py | 42 ++++++++++++++++++++++++++++++++++++------ test/test_dict.py | 9 +++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/hsd/dict.py b/src/hsd/dict.py index 87e7087..847aab0 100644 --- a/src/hsd/dict.py +++ b/src/hsd/dict.py @@ -13,24 +13,49 @@ QUOTING_CHARS, SPECIAL_CHARS from hsd.eventhandler import HsdEventHandler, HsdEventPrinter -_ItemType = Union[float, int, bool, str] +_ItemType = Union[float, complex, int, bool, str] _DataType = Union[_ItemType, List[_ItemType]] # Pattern to transform HSD string values into actual Python data types _TOKEN_PATTERN = re.compile(r""" # Integer -(?:\s*(?:^|(?<=\s))(?P[+-]?[0-9]+)(?:\s*$|\s+)) +(?: + \s*(?:^|(?<=\s)) + (?P[+-]?[0-9]+) + (?:\s*$|\s+) +) | # Floating point -(?:\s*(?:^|(?<=\s)) -(?P[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?)(?:$|(?=\s+))) +(?: + \s*(?:^|(?<=\s)) + (?P[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?) + (?:$|(?=\s+)) +) +| +# Complex value +(?: + \s*(?:^|(?<=\s)) + (?P + [-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?i + | + [-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?[-+][0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?i + ) + (?:$|(?=\s+)) +) | # Logical (Yes/No) -(?:\s*(?:^|(?<=\s))(?P[Yy][Ee][Ss]|[Nn][Oo])(?:$|(?=\s+))) +(?: + \s*(?:^|(?<=\s)) + (?P[Yy][Ee][Ss]|[Nn][Oo]) + (?:$|(?=\s+)) +) | # Quoted string -(?:\s*(?:(?P(?P['"]).*?(?P=quote)) +(?: + \s* + (?:(?P(?P['"]).*?(?P=quote) +) | # Unquoted string (?P.+?))(?:$|\s+)) @@ -148,6 +173,9 @@ def _text_to_data(self, txt: str) -> _DataType: linedata.append(int(match.group("int"))) elif match.group("float"): linedata.append(float(match.group("float"))) + elif match.group("complex"): + pycmplx = match.group("complex").replace("i", "j", 1) + linedata.append(complex(pycmplx)) elif match.group("logical"): lowlog = match.group("logical").lower() linedata.append(lowlog == "yes") @@ -246,6 +274,8 @@ def _item_to_hsd(item): return "Yes" if item else "No" if isinstance(item, (int, float)): return str(item) + if isinstance(item, complex): + return f"{item.real}{item.imag:+}i" if isinstance(item, str): return _str_to_hsd(item) msg = "Data type {} can not be converted to HSD string"\ diff --git a/test/test_dict.py b/test/test_dict.py index 8d832c4..008f505 100644 --- a/test/test_dict.py +++ b/test/test_dict.py @@ -78,6 +78,15 @@ } ) ), + ( + "Complex entries", ( + "ComplexNums = 4.0+9.0i 2.1e-12-4.5e-12i 0.32+0.45i -0.01-1.0i\n", + { + "ComplexNums.hsdattrib": {_HSD_EQUAL: True, _HSD_LINE: 0}, + "ComplexNums": [4.0+9.0j, 2.1e-12-4.5e-12j, 3.2e-1+4.5e-1j, -0.01-1.0j] + } + ) + ), ( "Duplicate node", ( "a {\n b = 1\n}\na {\n b = 2\n}\n",