-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #35 from gerlero/dictionaries
Refactor internal dictionaries module
- Loading branch information
Showing
6 changed files
with
235 additions
and
212 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
from typing import cast | ||
|
||
from pyparsing import ( | ||
Forward, | ||
Group, | ||
Keyword, | ||
Literal, | ||
Opt, | ||
QuotedString, | ||
Word, | ||
common, | ||
printables, | ||
) | ||
|
||
from ._values import FoamValue, FoamDimensionSet, FoamDimensioned | ||
|
||
|
||
_YES = Keyword("yes").set_parse_action(lambda s, loc, tks: True) | ||
_NO = Keyword("no").set_parse_action(lambda s, loc, tks: False) | ||
_DIMENSIONS = ( | ||
Literal("[").suppress() + common.number * 7 + Literal("]").suppress() | ||
).set_parse_action(lambda s, loc, tks: FoamDimensionSet(*tks)) | ||
_TOKEN = common.identifier | QuotedString('"', unquote_results=False) | ||
_ITEM = Forward() | ||
_LIST = Opt( | ||
Literal("List") + Literal("<") + common.identifier + Literal(">") | ||
).suppress() + ( | ||
( | ||
Opt(common.integer).suppress() | ||
+ Literal("(").suppress() | ||
+ Group(_ITEM[...]) | ||
+ Literal(")").suppress() | ||
) | ||
| ( | ||
common.integer + Literal("{").suppress() + _ITEM + Literal("}").suppress() | ||
).set_parse_action(lambda s, loc, tks: [tks[1]] * tks[0]) | ||
) | ||
_FIELD = (Keyword("uniform").suppress() + _ITEM) | ( | ||
Keyword("nonuniform").suppress() + _LIST | ||
) | ||
_DIMENSIONED = (Opt(common.identifier) + _DIMENSIONS + _ITEM).set_parse_action( | ||
lambda s, loc, tks: FoamDimensioned(*reversed(tks.as_list())) | ||
) | ||
_ITEM <<= ( | ||
_FIELD | _LIST | _DIMENSIONED | _DIMENSIONS | common.number | _YES | _NO | _TOKEN | ||
) | ||
|
||
_TOKENS = (QuotedString('"', unquote_results=False) | Word(printables))[ | ||
1, ... | ||
].set_parse_action(lambda s, loc, tks: " ".join(tks)) | ||
|
||
_VALUE = _ITEM ^ _TOKENS | ||
|
||
|
||
def parse(value: str) -> FoamValue: | ||
return cast(FoamValue, _VALUE.parse_string(value, parse_all=True).as_list()[0]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
from contextlib import suppress | ||
from typing import Any, Sequence | ||
|
||
try: | ||
import numpy as np | ||
except ModuleNotFoundError: | ||
numpy = False | ||
else: | ||
numpy = True | ||
|
||
from ._values import FoamDimensioned, FoamDimensionSet | ||
|
||
|
||
def _serialize_bool(value: Any) -> str: | ||
if value is True: | ||
return "yes" | ||
elif value is False: | ||
return "no" | ||
else: | ||
raise TypeError(f"Not a bool: {type(value)}") | ||
|
||
|
||
def _is_sequence(value: Any) -> bool: | ||
return ( | ||
isinstance(value, Sequence) | ||
and not isinstance(value, str) | ||
or numpy | ||
and isinstance(value, np.ndarray) | ||
) | ||
|
||
|
||
def _serialize_list(value: Any) -> str: | ||
if _is_sequence(value): | ||
return f"({' '.join(serialize(v) for v in value)})" | ||
else: | ||
raise TypeError(f"Not a valid sequence: {type(value)}") | ||
|
||
|
||
def _serialize_field(value: Any) -> str: | ||
if _is_sequence(value): | ||
try: | ||
s = _serialize_list(value) | ||
except TypeError: | ||
raise TypeError(f"Not a valid field: {type(value)}") from None | ||
else: | ||
if len(value) < 10: | ||
return f"uniform {s}" | ||
else: | ||
if isinstance(value[0], (int, float)): | ||
kind = "scalar" | ||
elif len(value[0]) == 3: | ||
kind = "vector" | ||
elif len(value[0]) == 6: | ||
kind = "symmTensor" | ||
elif len(value[0]) == 9: | ||
kind = "tensor" | ||
else: | ||
raise TypeError( | ||
f"Unsupported sequence length for field: {len(value[0])}" | ||
) | ||
return f"nonuniform List<{kind}> {len(value)}{s}" | ||
else: | ||
return f"uniform {value}" | ||
|
||
|
||
def _serialize_dimensions(value: Any) -> str: | ||
if _is_sequence(value) and len(value) == 7: | ||
return f"[{' '.join(str(v) for v in value)}]" | ||
else: | ||
raise TypeError(f"Not a valid dimension set: {type(value)}") | ||
|
||
|
||
def _serialize_dimensioned(value: Any) -> str: | ||
if isinstance(value, FoamDimensioned): | ||
if value.name is not None: | ||
return f"{value.name} {_serialize_dimensions(value.dimensions)} {serialize(value.value)}" | ||
else: | ||
return f"{_serialize_dimensions(value.dimensions)} {serialize(value.value)}" | ||
else: | ||
raise TypeError(f"Not a valid dimensioned value: {type(value)}") | ||
|
||
|
||
def serialize( | ||
value: Any, *, assume_field: bool = False, assume_dimensions: bool = False | ||
) -> str: | ||
if isinstance(value, FoamDimensionSet) or assume_dimensions: | ||
with suppress(TypeError): | ||
return _serialize_dimensions(value) | ||
|
||
if assume_field: | ||
with suppress(TypeError): | ||
return _serialize_field(value) | ||
|
||
with suppress(TypeError): | ||
return _serialize_dimensioned(value) | ||
|
||
with suppress(TypeError): | ||
return _serialize_list(value) | ||
|
||
with suppress(TypeError): | ||
return _serialize_bool(value) | ||
|
||
return str(value) |
Oops, something went wrong.