-
Notifications
You must be signed in to change notification settings - Fork 25
Add support for enums and attributes #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
80606e4
c8e32cc
bd63c99
f3811d5
0240797
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| """ | ||
| cfile core | ||
| """ | ||
| from typing import Union, Any | ||
| from typing import Any, Self | ||
|
|
||
|
|
||
| class Element: | ||
|
|
@@ -136,7 +136,7 @@ class DataType(Element): | |
| """ | ||
| Base class for all data types | ||
| """ | ||
| def __init__(self, name: str | None) -> None: | ||
| def __init__(self, name: str = "") -> None: | ||
| self.name = name | ||
|
|
||
|
|
||
|
|
@@ -145,12 +145,12 @@ class Type(DataType): | |
| Data type | ||
| """ | ||
| def __init__(self, | ||
| base_type: Union[str, "Type"], | ||
| base_type: str | Self, | ||
| const: bool = False, | ||
| pointer: bool = False, | ||
| volatile: bool = False, | ||
| array: int | None = None) -> None: # Only used for typedefs to other array types | ||
| super().__init__(None) | ||
| super().__init__("") | ||
| self.base_type = base_type | ||
| self.const = const | ||
| self.volatile = volatile | ||
|
|
@@ -168,6 +168,54 @@ def qualifier(self, name) -> bool: | |
| else: | ||
| raise KeyError(name) | ||
|
|
||
| class EnumMember(Element): | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be named EnumValue
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually not. It is like StructMember. This is also member of Enum type, which has name and value
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another point of view:
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about StructElement?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well it is up to you. But it should be usable for both cases. I am coauthor of eRPC project (similar to this) and at the beginning i was lead by USA architect who decided to use StructMember and EnumMember. Sounds good to me. https://github.com/EmbeddedRPC/erpc/tree/develop/erpcgen/src/types
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could be also StructItem and EnumItem |
||
| """ | ||
| Enum element. | ||
| """ | ||
|
|
||
| def __init__(self, | ||
| name: str, | ||
| value: int | None) -> None: | ||
| self.name = name | ||
| self.value = value | ||
|
|
||
|
|
||
| class Enum(DataType): | ||
| """ | ||
| A enum definition | ||
| """ | ||
|
|
||
| def __init__(self, name: str, members: list[EnumMember] | None = None, attributes: list[str] | None = None) -> None: | ||
| super().__init__(name) | ||
|
|
||
| if members == None: | ||
| self.members = [] | ||
| elif isinstance(members, list): | ||
| self.members = list(members) | ||
| enumValue = -1 | ||
| for enum in self.members: | ||
| if enum.value == None: | ||
| enumValue += 1 | ||
| enum.value = enumValue | ||
| else: | ||
| enumValue = enum.value | ||
| else: | ||
| raise TypeError('Invalid argument type for "members"') | ||
|
|
||
| if attributes == None: | ||
| self.attributes = [] | ||
| elif isinstance(attributes, list): | ||
| self.attributes: list[str] = list(attributes) | ||
| else: | ||
| raise TypeError('Invalid argument type for "attributes"') | ||
|
|
||
| def append(self, member: EnumMember) -> None: | ||
| """ | ||
| Appends new element to the struct definition | ||
| """ | ||
| if not isinstance(member, EnumMember): | ||
| raise TypeError(f'Invalid type, expected "EnumMember", got {str(type(member))}') | ||
| self.members.append(member) | ||
|
|
||
| class StructMember(Element): | ||
| """ | ||
|
|
@@ -197,17 +245,22 @@ class Struct(DataType): | |
| """ | ||
| A struct definition | ||
| """ | ||
| def __init__(self, name: str | None, members: StructMember | list[StructMember] | None = None) -> None: | ||
| def __init__(self, name: str = "", members: list[StructMember] | None = None, attributes: list[str] | None = None) -> None: | ||
| super().__init__(name) | ||
| self.members: list[StructMember] = [] | ||
| if members is not None: | ||
| if isinstance(members, StructMember): | ||
| self.append(members) | ||
| elif isinstance(members, list): | ||
| for member in members: | ||
| self.append(member) | ||
| else: | ||
| raise TypeError('Invalid argument type for "elements"') | ||
|
|
||
| if members == None: | ||
| self.members = [] | ||
| elif isinstance(members, list): | ||
| self.members: list[StructMember] = list(members) | ||
| else: | ||
| raise TypeError('Invalid argument type for "members"') | ||
|
|
||
| if attributes == None: | ||
| self.attributes = [] | ||
| elif isinstance(attributes, list): | ||
| self.attributes: list[str] = list(attributes) | ||
| else: | ||
| raise TypeError('Invalid argument type for "attributes"') | ||
|
|
||
| def append(self, member: StructMember) -> None: | ||
| """ | ||
|
|
@@ -231,46 +284,39 @@ def make_member(self, | |
| return member | ||
|
|
||
|
|
||
| class TypeDef(DataType): | ||
| """ | ||
| Type definition (typedef) | ||
| """ | ||
| def __init__(self, | ||
| name: str, | ||
| base_type: Union[str, "DataType", "Declaration"], | ||
| const: bool = False, | ||
| pointer: bool = False, | ||
| volatile: bool = False, | ||
| array: int | None = None) -> None: | ||
| super().__init__(name) | ||
| self.const = const | ||
| self.volatile = volatile | ||
| class UnionMember(Element): | ||
| def __init__(self, name: str, data_type: DataType, pointer: bool = False, array: int | None = None): | ||
| self.name = name | ||
| self.data_type = data_type | ||
| self.pointer = pointer | ||
| self.array = array | ||
| self.base_type: DataType | Declaration | ||
| if isinstance(base_type, DataType): | ||
| self.base_type = base_type | ||
| elif isinstance(base_type, str): | ||
| self.base_type = Type(base_type) | ||
| elif isinstance(base_type, Declaration): | ||
| if not isinstance(base_type.element, DataType): | ||
| err_msg = f'base_type: Declaration must declare a type, not {str(type(base_type.element))}' | ||
| self.base_type = base_type | ||
|
|
||
|
|
||
| class Union(DataType): | ||
| def __init__(self, name: str, members: list[UnionMember] | None = None, attributes: list[str] | None = None): | ||
| self.name = name | ||
|
|
||
| if members == None: | ||
| self.members = [] | ||
| elif isinstance(members, list): | ||
| self.members: list[UnionMember] = list(members) | ||
| else: | ||
| err_msg = 'base_type: Invalid type, expected "str" | "DataType" | "Declaration",' | ||
| err_msg += ' got {str(type(base_type))}' | ||
| raise TypeError(err_msg) | ||
| raise TypeError('Invalid argument type for "members"') | ||
|
|
||
| def qualifier(self, name) -> bool: | ||
| if attributes == None: | ||
| self.attributes = [] | ||
| elif isinstance(attributes, list): | ||
| self.attributes: list[str] = list(attributes) | ||
| else: | ||
| raise TypeError('Invalid argument type for "attributes"') | ||
|
|
||
| def append(self, member: UnionMember) -> None: | ||
| """ | ||
| Returns the status of named qualifier | ||
| Appends new element to the struct definition | ||
| """ | ||
| if name == "const": | ||
| return self.const | ||
| if name == "volatile": | ||
| return self.volatile | ||
| else: | ||
| raise KeyError(name) | ||
| if not isinstance(member, UnionMember): | ||
| raise TypeError(f'Invalid type, expected "UnionMember", got {str(type(member))}') | ||
| self.members.append(member) | ||
|
|
||
|
|
||
| class Variable(Element): | ||
|
|
@@ -322,7 +368,7 @@ def __init__(self, | |
| static: bool = False, | ||
| const: bool = False, # const function (as seen in C++) | ||
| extern: bool = False, | ||
| params: Variable | list[Variable] | None = None) -> None: | ||
| params: list[Variable] | None = None) -> None: | ||
| self.name = name | ||
| self.static = static | ||
| self.const = const | ||
|
|
@@ -335,13 +381,11 @@ def __init__(self, | |
| self.return_type = Type("void") | ||
| else: | ||
| raise TypeError(str(type(return_type))) | ||
| self.params: list[Variable] = [] | ||
| if params is not None: | ||
| if isinstance(params, Variable): | ||
| self.append(params) | ||
| elif isinstance(params, list): | ||
| for param in params: | ||
| self.append(param) | ||
|
|
||
| if isinstance(params, list): | ||
| self.params: list[Variable] = list(params) | ||
| else: | ||
| raise TypeError('Invalid argument type for "params"') | ||
|
|
||
| def append(self, param: Variable) -> "Function": | ||
| """ | ||
|
|
@@ -374,7 +418,7 @@ class Declaration(Element): | |
| - Function | ||
| """ | ||
| def __init__(self, | ||
| element: Union[Variable, Function, DataType], | ||
| element: Variable | Function | DataType, | ||
| init_value: Any | None = None) -> None: | ||
| if isinstance(element, (Variable, Function, DataType)): | ||
| self.element = element | ||
|
|
@@ -422,6 +466,8 @@ def __init__(self, | |
| self.expression = "true" if expression else "false" | ||
| elif isinstance(expression, (int, float)): | ||
| self.expression = str(expression) | ||
| elif isinstance(expression, EnumMember): | ||
| self.expression = expression.name | ||
| elif isinstance(expression, (str, Element)): | ||
| self.expression = expression | ||
| else: | ||
|
|
@@ -484,7 +530,7 @@ class Sequence: | |
| A sequence of statements, comments or whitespace | ||
| """ | ||
| def __init__(self) -> None: | ||
| self.elements: list[Union[Comment, Statement, "Sequence"]] = [] | ||
| self.elements: list[Comment | Statement | "Sequence"] = [] | ||
|
|
||
| def __len__(self) -> int: | ||
| return len(self.elements) | ||
|
|
@@ -511,3 +557,134 @@ class Block(Sequence): | |
| """ | ||
| A sequence wrapped in braces | ||
| """ | ||
|
|
||
|
|
||
| class Condition(Block): | ||
| """ | ||
| A sequence for condition wrapped in braces | ||
| """ | ||
|
|
||
| def __init__(self, condition: str): | ||
| super().__init__() | ||
| self.condition = condition | ||
|
|
||
|
|
||
| class Conditions(Element): | ||
| """ | ||
| A condition wrapped in braces | ||
| """ | ||
|
|
||
| def __init__(self, conditions: list[Condition] | None = None): | ||
| super().__init__() | ||
|
|
||
| if conditions == None: | ||
| self.conditions = [] | ||
| elif isinstance(conditions, list): | ||
| self.conditions: list[Condition] = list(conditions) | ||
| else: | ||
| raise TypeError('Invalid argument type for "conditions"') | ||
|
|
||
| def append(self, member: Condition) -> None: | ||
| """ | ||
| Appends new element to the conditions definition | ||
| """ | ||
| if not isinstance(member, Condition): | ||
| raise TypeError(f'Invalid type, expected "Condition", got {str(type(member))}') | ||
| self.conditions.append(member) | ||
|
|
||
|
|
||
| class SwitchCase(Block): | ||
| """ | ||
| A sequence for switch case wrapped in braces | ||
| """ | ||
|
|
||
| def __init__(self, cases: list[int | EnumMember | str] | None = None): | ||
| """ | ||
| Empty values means default | ||
| """ | ||
| super().__init__() | ||
|
|
||
| if cases == None: | ||
| self.cases = [] | ||
| elif isinstance(cases, list): | ||
| self.cases: list[int | EnumMember | str] = list(cases) | ||
| else: | ||
| raise TypeError('Invalid argument type for "cases"') | ||
|
|
||
|
|
||
| class Switch(Element): | ||
| """ | ||
| A sequence for switch case wrapped in braces | ||
| """ | ||
|
|
||
| def __init__(self, switchVar: str | Variable, cases: list[SwitchCase] | None = None): | ||
| super().__init__() | ||
|
|
||
| if switchVar == "" or not (isinstance(switchVar, str) or isinstance(switchVar, Variable)): | ||
| raise ValueError("switchVar cannot be empty ") | ||
|
|
||
| self.switchVar = switchVar | ||
|
|
||
| if cases == None: | ||
| self.cases = [] | ||
| elif isinstance(cases, list): | ||
| self.cases: list[SwitchCase] = list(cases) | ||
| else: | ||
| raise TypeError('Invalid argument type for "cases"') | ||
|
|
||
| def append(self, case: SwitchCase) -> None: | ||
| """ | ||
| Appends new element to the conditions definition | ||
| """ | ||
| if not isinstance(case, SwitchCase): | ||
| raise TypeError(f'Invalid type, expected "SwitchCase", got {str(type(case))}') | ||
| self.cases.append(case) | ||
|
|
||
|
|
||
| class Break(Element): | ||
| """ | ||
| Adding break into block | ||
| """ | ||
|
|
||
|
|
||
| class TypeDef(DataType): | ||
| """ | ||
| Type definition (typedef) | ||
| """ | ||
|
|
||
| def __init__(self, | ||
| name: str, | ||
| base_type: str | DataType | Declaration, | ||
| const: bool = False, | ||
| pointer: bool = False, | ||
| volatile: bool = False, | ||
| array: int | None = None) -> None: | ||
| super().__init__(name) | ||
| self.const = const | ||
| self.volatile = volatile | ||
| self.pointer = pointer | ||
| self.array = array | ||
| self.base_type: DataType | Declaration | ||
| if isinstance(base_type, DataType): | ||
| self.base_type = base_type | ||
| elif isinstance(base_type, str): | ||
| self.base_type = Type(base_type) | ||
| elif isinstance(base_type, Declaration): | ||
| if not isinstance(base_type.element, DataType): | ||
| err_msg = f'base_type: Declaration must declare a type, not {str(type(base_type.element))}' | ||
| self.base_type = base_type | ||
| else: | ||
| err_msg = 'base_type: Invalid type, expected "str" | "DataType" | "Declaration",' | ||
| err_msg += ' got {str(type(base_type))}' | ||
| raise TypeError(err_msg) | ||
|
|
||
| def qualifier(self, name) -> bool: | ||
| """ | ||
| Returns the status of named qualifier | ||
| """ | ||
| if name == "const": | ||
| return self.const | ||
| if name == "volatile": | ||
| return self.volatile | ||
| else: | ||
| raise KeyError(name) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why change this? It's off topic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Less complicated API. Because what is difference between "" or None? You are checking for None but not for "". So it is simpler and easier to check for "" then for None and ""
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So based on what you said bellow i understand why you are using None, but still i think it is redundant.