Skip to content
Snippets Groups Projects
Commit 2eb93b6e authored by Frederik Hennig's avatar Frederik Hennig
Browse files

split namespaces into an entity and an element part

parent 9aba6a1e
No related branches found
No related tags found
1 merge request!17Improved Source File and Code Structure Modelling
...@@ -39,9 +39,9 @@ class SfgCodeEntity: ...@@ -39,9 +39,9 @@ class SfgCodeEntity:
Each code entity has a name and an optional enclosing namespace. Each code entity has a name and an optional enclosing namespace.
""" """
def __init__(self, name: str, namespace: SfgNamespace | None) -> None: def __init__(self, name: str, parent_namespace: SfgNamespace | None) -> None:
self._name = name self._name = name
self._namespace: SfgNamespace | None = namespace self._namespace: SfgNamespace | None = parent_namespace
@property @property
def name(self) -> str: def name(self) -> str:
...@@ -57,11 +57,23 @@ class SfgCodeEntity: ...@@ -57,11 +57,23 @@ class SfgCodeEntity:
return self._name return self._name
@property @property
def namespace(self) -> SfgNamespace | None: def parent_namespace(self) -> SfgNamespace | None:
"""Parent namespace of this entity""" """Parent namespace of this entity"""
return self._namespace return self._namespace
class SfgNamespace(SfgCodeEntity):
"""A C++ namespace.
Each namespace has a `name` and a `parent`; its fully qualified name is given as
``<parent.name>::<name>``.
Args:
name: Local name of this namespace
parent: Parent namespace enclosing this namespace
"""
class SfgKernelHandle(SfgCodeEntity): class SfgKernelHandle(SfgCodeEntity):
"""Handle to a pystencils kernel.""" """Handle to a pystencils kernel."""
...@@ -100,7 +112,76 @@ class SfgKernelHandle(SfgCodeEntity): ...@@ -100,7 +112,76 @@ class SfgKernelHandle(SfgCodeEntity):
return self._kernel return self._kernel
class SfgKernelNamespace(SfgNamespace):
"""A namespace grouping together a number of kernels."""
def __init__(self, name: str, parent: SfgNamespace | None):
super().__init__(name, parent)
self._kernels: dict[str, SfgKernelHandle] = []
@property
def name(self):
return self._name
@property
def kernels(self) -> tuple[SfgKernelHandle, ...]:
return tuple(self._kernels.values())
def add(self, kernel: Kernel, name: str | None = None):
"""Adds an existing pystencils AST to this namespace.
If a name is specified, the AST's function name is changed."""
if name is None:
kernel_name = kernel.name
else:
kernel_name = name
if kernel_name in self._kernels:
raise ValueError(
f"Duplicate kernels: A kernel called {kernel_name} already exists in namespace {self.fqname}"
)
if name is not None:
kernel.name = kernel_name
khandle = SfgKernelHandle(kernel_name, self, kernel)
self._kernels[kernel_name] = khandle
# TODO: collect includes later
# for header in kernel.required_headers:
# self._ctx.add_include(
# SfgHeaderInclude(HeaderFile.parse(header), private=True)
# )
return khandle
def create(
self,
assignments,
name: str | None = None,
config: CreateKernelConfig | None = None,
):
"""Creates a new pystencils kernel from a list of assignments and a configuration.
This is a wrapper around `pystencils.create_kernel`
with a subsequent call to `add`.
"""
if config is None:
config = CreateKernelConfig()
if name is not None:
if name in self._kernels:
raise ValueError(
f"Duplicate kernels: A kernel with name {name} already exists in namespace {self.fqname}"
)
config = replace(config, function_name=name)
# type: ignore
kernel = create_kernel(assignments, config=config)
return self.add(kernel)
class SfgFunction(SfgCodeEntity): class SfgFunction(SfgCodeEntity):
"""A free function."""
__match_args__ = ("name", "tree", "parameters") __match_args__ = ("name", "tree", "parameters")
def __init__( def __init__(
...@@ -142,6 +223,8 @@ class SfgFunction(SfgCodeEntity): ...@@ -142,6 +223,8 @@ class SfgFunction(SfgCodeEntity):
class SfgVisibility(Enum): class SfgVisibility(Enum):
"""Visibility qualifiers of C++"""
DEFAULT = auto() DEFAULT = auto()
PRIVATE = auto() PRIVATE = auto()
PROTECTED = auto() PROTECTED = auto()
...@@ -160,6 +243,8 @@ class SfgVisibility(Enum): ...@@ -160,6 +243,8 @@ class SfgVisibility(Enum):
class SfgClassKeyword(Enum): class SfgClassKeyword(Enum):
"""Class keywords of C++"""
STRUCT = auto() STRUCT = auto()
CLASS = auto() CLASS = auto()
...@@ -172,6 +257,8 @@ class SfgClassKeyword(Enum): ...@@ -172,6 +257,8 @@ class SfgClassKeyword(Enum):
class SfgClassMember(ABC): class SfgClassMember(ABC):
"""Base class for class member entities"""
def __init__(self) -> None: def __init__(self) -> None:
self._cls: SfgClass | None = None self._cls: SfgClass | None = None
self._visibility: SfgVisibility | None = None self._visibility: SfgVisibility | None = None
...@@ -205,25 +292,56 @@ class SfgClassMember(ABC): ...@@ -205,25 +292,56 @@ class SfgClassMember(ABC):
class SfgMemberVariable(SfgVar, SfgClassMember): class SfgMemberVariable(SfgVar, SfgClassMember):
"""Variable that is a field of a class"""
def __init__(self, name: str, dtype: PsType): def __init__(self, name: str, dtype: PsType):
SfgVar.__init__(self, name, dtype) SfgVar.__init__(self, name, dtype)
SfgClassMember.__init__(self) SfgClassMember.__init__(self)
class SfgMethod(SfgFunction, SfgClassMember): class SfgMethod(SfgClassMember):
"""Instance method of a class"""
__match_args__ = ("name", "tree", "parameters")
def __init__( def __init__(
self, self,
name: str, name: str,
tree: SfgCallTreeNode, tree: SfgCallTreeNode,
return_type: PsType = PsCustomType("void"), return_type: PsType = void,
inline: bool = False, inline: bool = False,
const: bool = False, const: bool = False,
): ):
SfgFunction.__init__(self, name, tree, return_type=return_type, inline=inline) super().__init__()
SfgClassMember.__init__(self)
self._name = name
self._tree = tree
self._return_type = return_type
self._inline = inline
self._const = const self._const = const
self._parameters: set[SfgVar] = set()
self._parameters: set[SfgVar]
from .postprocessing import CallTreePostProcessing
param_collector = CallTreePostProcessing()
self._parameters = param_collector(self._tree).function_params
@property
def parameters(self) -> set[SfgVar]:
return self._parameters
@property
def tree(self) -> SfgCallTreeNode:
return self._tree
@property
def return_type(self) -> PsType:
return self._return_type
@property
def inline(self) -> bool:
return self._inline
@property @property
def const(self) -> bool: def const(self) -> bool:
...@@ -231,6 +349,8 @@ class SfgMethod(SfgFunction, SfgClassMember): ...@@ -231,6 +349,8 @@ class SfgMethod(SfgFunction, SfgClassMember):
class SfgConstructor(SfgClassMember): class SfgConstructor(SfgClassMember):
"""Constructor of a class"""
__match_args__ = ("parameters", "initializers", "body") __match_args__ = ("parameters", "initializers", "body")
def __init__( def __init__(
...@@ -503,7 +623,7 @@ class SfgVisibilityBlock: ...@@ -503,7 +623,7 @@ class SfgVisibilityBlock:
self._cls = cls self._cls = cls
class SfgNamespace: class SfgNamespaceDef:
"""A C++ namespace. """A C++ namespace.
Each namespace has a `name` and a `parent`; its fully qualified name is given as Each namespace has a `name` and a `parent`; its fully qualified name is given as
...@@ -514,24 +634,10 @@ class SfgNamespace: ...@@ -514,24 +634,10 @@ class SfgNamespace:
parent: Parent namespace enclosing this namespace parent: Parent namespace enclosing this namespace
""" """
def __init__(self, name: str, parent: SfgNamespace | None) -> None: def __init__(self, namespace: SfgNamespace) -> None:
self._name: str = name self._namespace = namespace
self._parent: SfgNamespace | None = parent
self._elements: list[SfgNamespaceElement] = [] self._elements: list[SfgNamespaceElement] = []
@property
def name(self) -> str:
"""The name of this namespace"""
return self._name
@property
def fqname(self) -> str:
"""The fully qualified name of this namespace"""
if self._parent is not None:
return self._parent.fqname + "::" + self._name
else:
return self._name
@property @property
def elements(self) -> list[SfgNamespaceElement]: def elements(self) -> list[SfgNamespaceElement]:
"""Sequence of source elements that make up the body of this namespace""" """Sequence of source elements that make up the body of this namespace"""
...@@ -542,74 +648,7 @@ class SfgNamespace: ...@@ -542,74 +648,7 @@ class SfgNamespace:
self._elements = list(elems) self._elements = list(elems)
class SfgKernelNamespace(SfgNamespace): SfgNamespaceElement = str | SfgNamespaceDef | SfgEntityDecl | SfgEntityDef
"""A namespace grouping together a number of kernels."""
def __init__(self, name: str, parent: SfgNamespace | None):
super().__init__(name, parent)
self._kernels: dict[str, SfgKernelHandle] = []
@property
def name(self):
return self._name
@property
def kernels(self) -> tuple[SfgKernelHandle, ...]:
return tuple(self._kernels.values())
def add(self, kernel: Kernel, name: str | None = None):
"""Adds an existing pystencils AST to this namespace.
If a name is specified, the AST's function name is changed."""
if name is None:
kernel_name = kernel.name
else:
kernel_name = name
if kernel_name in self._kernels:
raise ValueError(
f"Duplicate kernels: A kernel called {kernel_name} already exists in namespace {self.fqname}"
)
if name is not None:
kernel.name = kernel_name
khandle = SfgKernelHandle(kernel_name, self, kernel)
self._kernels[kernel_name] = khandle
# TODO: collect includes later
# for header in kernel.required_headers:
# self._ctx.add_include(
# SfgHeaderInclude(HeaderFile.parse(header), private=True)
# )
return khandle
def create(
self,
assignments,
name: str | None = None,
config: CreateKernelConfig | None = None,
):
"""Creates a new pystencils kernel from a list of assignments and a configuration.
This is a wrapper around `pystencils.create_kernel`
with a subsequent call to `add`.
"""
if config is None:
config = CreateKernelConfig()
if name is not None:
if name in self._kernels:
raise ValueError(
f"Duplicate kernels: A kernel with name {name} already exists in namespace {self.fqname}"
)
config = replace(config, function_name=name)
# type: ignore
kernel = create_kernel(assignments, config=config)
return self.add(kernel)
SfgNamespaceElement = str | SfgNamespace | SfgEntityDecl | SfgEntityDef
"""Elements that may be placed inside a namespace, including the global namespace.""" """Elements that may be placed inside a namespace, including the global namespace."""
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment