Skip to content

Commit

Permalink
Fix up some things per review feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
skeetsaz committed Sep 5, 2023
1 parent 643625c commit f2ddf39
Show file tree
Hide file tree
Showing 17 changed files with 144 additions and 121 deletions.
8 changes: 4 additions & 4 deletions .vscode/cmake-variants.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@
}
},
"CETL++": {
"short": "--std=cetl++",
"long": "Compile and link using the C++14 standard and use CETL.",
"short": "--std=cetl++14-17",
"long": "Compile and link using the C++14 standard and use CETL C++17 polyfill types.",
"settings": {
"NUNAVUT_VERIFICATION_LANG": "cpp",
"NUNAVUT_VERIFICATION_LANG_STANDARD": "cetl++"
"NUNAVUT_VERIFICATION_LANG_STANDARD": "cetl++14-17"
}
},
"C++17": {
Expand All @@ -75,7 +75,7 @@
},
"C++17 PMR": {
"short": "--std=c++17-pmr",
"long": "Compile and link using the C++17 standard and use polymorphic memory resources.",
"long": "Compile and link using the C++17 standard and use std polymorphic allocator.",
"settings": {
"NUNAVUT_VERIFICATION_LANG": "cpp",
"NUNAVUT_VERIFICATION_LANG_STANDARD": "c++17-pmr"
Expand Down
24 changes: 24 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,30 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: nnvg c++ (help)",
"type": "python",
"request": "launch",
"module": "nunavut",
"cwd": "${workspaceFolder}/src",
"args": ["-h"]
},
{
"name": "Python: nnvg c++ (skeets)",
"type": "python",
"request": "launch",
"module": "nunavut",
"cwd": "${workspaceFolder}/src",
"args": ["--experimental-languages",
"--verbose",
"--outdir", "${workspaceFolder}/skeets_out",
"-l", "cpp",
// "--configuration=${workspaceFolder}/skeets_in/nunavut_configuration.yaml",
// "-std=c++14",
// "-std=cetl++14-17",
"-std=c++17-pmr",
"${workspaceFolder}/skeets_in/dsdl/mymsgs"]
},
{
"name": "Python: nnvg c++",
"type": "python",
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ skip the docker invocations and use ``tox -s``.

To run the language verification build you'll need to use a different docker container::

docker pull ghcr.io/opencyphal/toolshed:ts20.4.1
docker run --rm -it -v $PWD:/workspace ghcr.io/opencyphal/toolshed:ts20.4.1
docker pull ghcr.io/opencyphal/toolshed:ts22.4.1
docker run --rm -it -v $PWD:/workspace ghcr.io/opencyphal/toolshed:ts22.4.1
cd /workspace
./.github/verify.py -l c
./.github/verify.py -l cpp
Expand Down
15 changes: 8 additions & 7 deletions docs/languages.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,18 @@ C++ (experimental)

See :ref:`template-language-guide` until this section is more complete.

==============================================
Using a Different Variable-Length Array Type
==============================================
============================================================
Using a Different Variable-Length Array Type and Allocator
============================================================

For now this tip is important for people using the experimental C++ support. To set which variable length array
implementation to use, create a properties override yaml file and pass it to nnvg. Specifying the use of an
allocator is optional (If ctor_convention is set to "default" then the allocator_include and allocator_type
properties don't need to be set.)

Alternatively, you may specify the language standard argument as -std=c++17-pmr or -std=cetl++ as short-hand for
the following configurations shown below.
Alternatively, you may specify the language standard argument as -std=c++17-pmr or -std=cetl++14-17 as short-hand for
the following configurations shown below. Note that "cetl++14-17" means target C++14 but use the CETL C++17 polyfill
types.

c++17-pmr.yaml
"""""""""""""""""
Expand All @@ -39,7 +40,7 @@ c++17-pmr.yaml
allocator_is_default_constructible: true
ctor_convention: "uses-trailing-allocator"
cetl++.yaml
cetl++14-17.yaml
"""""""""""""""""

.. code-block :: yaml
Expand All @@ -59,7 +60,7 @@ nnvg command

.. code-block :: bash
nnvg --configuration=c++17-pmr.yaml \ # or --configuration=cetl++.yaml
nnvg --configuration=c++17-pmr.yaml \ # or --configuration=cetl++14-17.yaml
-l cpp \
--experimental-languages \
-I path/to/public_regulated_data_types/uavcan \
Expand Down
1 change: 1 addition & 0 deletions src/nunavut/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ def extension_type(raw_arg: str) -> str:
ln_opt_group.add_argument(
"--language-standard",
"-std",
choices=["c11", "c++14", "cetl++14-17", "c++17", "c++17-pmr", "c++20"],
help=textwrap.dedent(
"""
Expand Down
7 changes: 1 addition & 6 deletions src/nunavut/cli/runners.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,6 @@ def _create_language_context(self) -> LanguageContext:
language_options["enable_serialization_asserts"] = self._args.enable_serialization_asserts
language_options["enable_override_variable_array_capacity"] = self._args.enable_override_variable_array_capacity
if self._args.language_standard is not None:
valid_language_standards: typing.List[str] = ["c11", "c++14", "cetl++", "c++17", "c++17-pmr", "c++20"]
if self._args.language_standard not in valid_language_standards:
raise RuntimeError(
f"'{self._args.language_standard}' language standard not found. "
f"Must be one of {', '.join(valid_language_standards)}."
)
language_options["std"] = self._args.language_standard

if self._args.configuration is None:
Expand All @@ -167,6 +161,7 @@ def _create_language_context(self) -> LanguageContext:
builder.set_target_language(target_language_name)
builder.load_default_config(self._args.language_standard)
builder.set_additional_config_files(additional_config_files)
builder.validate_langauge_options()
builder.set_target_language_extension(self._args.output_extension)
builder.set_target_language_configuration_override(
Language.WKCV_NAMESPACE_FILE_STEM, self._args.namespace_output_stem
Expand Down
11 changes: 4 additions & 7 deletions src/nunavut/lang/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@

logger = logging.getLogger(__name__)

NUNAVUT_LANG_CPP = "nunavut.lang.cpp"


class UnsupportedLanguageError(ValueError):
"""
Expand Down Expand Up @@ -223,11 +221,10 @@ def set_target_language(self, target_language: typing.Optional[str]) -> "Languag
return self

def load_default_config(self, language_standard: str) -> None:
self._ln_loader.config # Accessing this property causes the defaults to load
defaults_key = f"{language_standard}_options"
if defaults_key in self._ln_loader.config.sections()[NUNAVUT_LANG_CPP]:
defaults_data = self._ln_loader.config.get_config_value_as_dict(NUNAVUT_LANG_CPP, defaults_key)
self._ln_loader.config.update_section(NUNAVUT_LANG_CPP, {"options": defaults_data})
self._ln_loader.config.apply_defaults(language_standard)

def validate_langauge_options(self) -> None:
self._ln_loader.config.validate_language_options()

def set_additional_config_files(
self, additional_config_files: typing.List[pathlib.Path]
Expand Down
43 changes: 43 additions & 0 deletions src/nunavut/lang/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,33 @@
import types
import typing

from enum import auto, Enum

from yaml import Loader as YamlLoader
from yaml import load as yaml_loader
from nunavut._utilities import deep_update

NUNAVUT_LANG_CPP = "nunavut.lang.cpp"


class ConstructorConvention(Enum):
Default = "default"
UsesLeadingAllocator = "uses-leading-allocator"
UsesTrailingAllocator = "uses-trailing-allocator"

@staticmethod
def parse_string(s: str) -> typing.Optional[typing.Any]: # annoying mypy cheat due to returning type being defined
for e in ConstructorConvention:
if s == e.value:
return e
return None


class SpecialMethod(Enum):
DefaultConstructorWithOptionalAllocator = auto()
CopyConstructorWithAllocator = auto()
MoveConstructorWithAllocator = auto()


class LanguageConfig:
"""
Expand Down Expand Up @@ -595,6 +618,26 @@ def get_config_value_as_list(

return default_value

def apply_defaults(self, language_standard: str) -> None:
defaults_key = f"{language_standard}_options"
if defaults_key in self.sections()[NUNAVUT_LANG_CPP]:
defaults_data = self.get_config_value_as_dict(NUNAVUT_LANG_CPP, defaults_key)
self.update_section(NUNAVUT_LANG_CPP, {"options": defaults_data})

def validate_language_options(self) -> None:
options = self.get_config_value_as_dict(NUNAVUT_LANG_CPP, "options")
ctor_convention_str: str = options["ctor_convention"]
ctor_convention = ConstructorConvention.parse_string(ctor_convention_str)
if not ctor_convention:
raise RuntimeError(
f"ctor_convention property '{ctor_convention_str}' is invalid and must be one of "
+ (",".join([f"'{e.value}'" for e in ConstructorConvention]))
)
if ctor_convention != ConstructorConvention.Default and not options["allocator_type"]:
raise RuntimeError(
f"allocator_type property must be specified when ctor_convention is '{ctor_convention_str}'"
)


# +-------------------------------------------------------------------------------------------------------------------+
# | VersionReader
Expand Down
6 changes: 0 additions & 6 deletions src/nunavut/lang/_language.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,6 @@ def __init__(self, language_module_name: str, config: LanguageConfig, **kwargs:
self._tests = dict() # type: typing.Dict[str, typing.Callable]
self._uses = dict() # type: typing.Dict[str, typing.Callable]

self._validate_language_options(self._language_options)

def _validate_language_options(self, language_options: typing.Mapping[str, typing.Any]) -> None:
"""Subclasses may override this method to validate language-specific options"""
pass

def __getattr__(self, name: str) -> typing.Any:
"""
Any attribute access to a Language object will return the regular properties and
Expand Down
40 changes: 4 additions & 36 deletions src/nunavut/lang/cpp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@

import pydsdl

from enum import auto, Enum

from nunavut._dependencies import Dependencies
from nunavut._templates import (
template_environment_list_filter,
Expand All @@ -30,30 +28,12 @@
from nunavut._utilities import YesNoDefault
from nunavut.jinja.environment import Environment
from nunavut.lang._common import IncludeGenerator, TokenEncoder, UniqueNameGenerator
from nunavut.lang._config import ConstructorConvention, SpecialMethod
from nunavut.lang._language import Language as BaseLanguage
from nunavut.lang.c import _CFit
from nunavut.lang.c import filter_literal as c_filter_literal


class ConstructorConvention(Enum):
Default = "default"
UsesLeadingAllocator = "uses-leading-allocator"
UsesTrailingAllocator = "uses-trailing-allocator"

@staticmethod
def parse_string(s: str) -> typing.Optional[typing.Any]: # annoying mypy cheat due to returning type being defined
for e in ConstructorConvention:
if s == e.value:
return e
return None


class SpecialMethod(Enum):
DefaultConstructorWithOptionalAllocator = auto()
CopyConstructorWithAllocator = auto()
MoveConstructorWithAllocator = auto()


class Language(BaseLanguage):
"""
Concrete, C++-specific :class:`nunavut.lang.Language` object.
Expand Down Expand Up @@ -82,19 +62,6 @@ def _handle_stropping_or_encoding_failure(
# we couldn't help after all. raise the pending error.
raise pending_error

def _validate_language_options(self, language_options: typing.Mapping[str, typing.Any]) -> None:
ctor_convention_str: str = language_options["ctor_convention"]
ctor_convention = ConstructorConvention.parse_string(ctor_convention_str)
if not ctor_convention:
raise RuntimeError(
f"ctor_convention property '{ctor_convention_str}' is invalid and must be one of "
+ (",".join([f"'{e.value}'" for e in ConstructorConvention]))
)
if ctor_convention != ConstructorConvention.Default and not language_options["allocator_type"]:
raise RuntimeError(
f"allocator_type property must be specified when ctor_convention is '{ctor_convention_str}'"
)

@functools.lru_cache(maxsize=None)
def _get_token_encoder(self) -> TokenEncoder:
"""
Expand Down Expand Up @@ -999,6 +966,7 @@ def filter_value_initializer(language: Language, instance: pydsdl.Any, special_m
Emit an initialization expression for a C++ special method.
"""

value_initializer: str = ""
if (
isinstance(instance.data_type, pydsdl.PrimitiveType)
or isinstance(instance.data_type, pydsdl.ArrayType)
Expand Down Expand Up @@ -1032,9 +1000,9 @@ def filter_value_initializer(language: Language, instance: pydsdl.Any, special_m
if rhs:
args.append(rhs)
args = leading_args + args + trailing_args
return "{" + ", ".join(args) + "}"
value_initializer = "{" + ", ".join(args) + "}"

return ""
return value_initializer


@template_language_filter(__name__)
Expand Down
Loading

0 comments on commit f2ddf39

Please sign in to comment.