Conversation
Refactored structs Signed-off-by: Cervenka Dusan <cervenka@acrios.com>
Signed-off-by: Cervenka Dusan <cervenka@acrios.com>
Signed-off-by: Cervenka Dusan <cervenka@acrios.com>
cogu
left a comment
There was a problem hiding this comment.
I cannot approve this pull request as the code is not up to standard for the following reasons:
- Contains unrelated and off-topic changes
- Use of empty lists as default values in functions
- Introduction of attributes is compiler-dependent and needs further consideration
- Most importantly, it doesn't have any unit tests
If you make a new PR containing just the Enum with passing unit tests I might approve it. Other changes needs to come later.
| Base class for all data types | ||
| """ | ||
| def __init__(self, name: str | None) -> None: | ||
| def __init__(self, name: str = "") -> None: |
There was a problem hiding this comment.
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.
So based on what you said bellow i understand why you are using None, but still i think it is redundant.
| else: | ||
| raise KeyError(name) | ||
|
|
||
| class EnumMember(Element): |
There was a problem hiding this comment.
Actually not. It is like StructMember. This is also member of Enum type, which has name and value
There was a problem hiding this comment.
Another point of view:
If this should be EnumValue, then StructMember should be StructVariable.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Could be also StructItem and EnumItem
src/cfile/core.py
Outdated
| A enum definition | ||
| """ | ||
|
|
||
| def __init__(self, name: str, members: list[EnumMember] = [], attributes: list[str] = []) -> None: |
There was a problem hiding this comment.
You must never use empty list as default value in functions. It's dangerous.
There was a problem hiding this comment.
Why? It is valid case, where you have no members.
There was a problem hiding this comment.
t's a very common mistake among newcomers to Python. Google it, there are great explanations on the internet.
There was a problem hiding this comment.
That just sad.
Ok we can use None. But i wouldn't use one membert type as an option.
so list[EnumMember] | None = None
in a code bellow:
self.members = list(working_list) if working_list else []
There was a problem hiding this comment.
It's safer to do a proper check against None.
def __init__(self, name: str, elements: list[EnumElement] | None = None):
self.elements: list[EnumElement] = []
if elements is not None:
self.elements = list(elements)
These days however I always take it one step further and double-check that each individual element in the given argument list is of expected type. I usually do this by calling a helper function (usually called append or append_<something> that does the actual check.
src/cfile/core.py
Outdated
| A struct definition | ||
| """ | ||
| def __init__(self, name: str | None, members: StructMember | list[StructMember] | None = None) -> None: | ||
| def __init__(self, name: str = "", members: list[StructMember] = [], attributes: list[str] = []) -> None: |
There was a problem hiding this comment.
Never use empty list as initializer.
Introducing attributes here needs some further design considerations. Attributes are compiler-specific for GCC. What if we are using MSVC? We should introduce the attribute mechanism separately.
There was a problem hiding this comment.
I agree, i just need this one so i implemented them this way. But i was thinking to have something like cfiles attribute class
There was a problem hiding this comment.
I agree, i just need this one so i implemented them this way. But i was thinking to have something like cfiles attribute class
src/cfile/core.py
Outdated
| self.members: list[StructMember] = members.copy() | ||
| else: | ||
| raise TypeError('Invalid argument type for "elements"') | ||
| self.attributes = attributes.copy() |
There was a problem hiding this comment.
Don't use copy. If you want to create a new list which is a copy of another, write it as list(attributes).
But as stated above, we should introduce attribute-mechanism later anyway.
src/cfile/writer.py
Outdated
| Writes typedef usage | ||
| """ | ||
| if not elem.name: | ||
| if elem.name == "": |
There was a problem hiding this comment.
This is making it worse. if not elem.name works equally well if name is an empty string or None. Comparing it to empty string is not the Python way.
src/cfile/writer.py
Outdated
| Writes function usage (name of the function) | ||
| """ | ||
| if not elem.name: | ||
| if elem.name == "": |
There was a problem hiding this comment.
Don't change this. It's making it worse.
| """ | ||
| Writes enum declaration | ||
| """ | ||
| self._write(f"enum{" ".join([' __attribute__(('+attribute+'))' for attribute in elem.attributes])} {elem.name}") |
There was a problem hiding this comment.
This change only works for GCC-like compilers. Needs some more consideration and design (for example how to specify compiler family).
src/cfile/writer.py
Outdated
| Writes struct usage | ||
| """ | ||
| if not elem.name: | ||
| if elem.name == "": |
| Writes struct declaration | ||
| """ | ||
| self._write(f"struct {elem.name}") | ||
| self._write(f"struct{" ".join([' __attribute__(('+attribute+'))' for attribute in elem.attributes])} {elem.name}") |
There was a problem hiding this comment.
Same as before. Needs some further consideration.
src/cfile/writer.py
Outdated
| self._write("static ") | ||
| if isinstance(elem.return_type, core.Type): | ||
| self._write_type_declaration(elem.return_type) | ||
| if isinstance(elem.return_type, core.TypeDef): |
There was a problem hiding this comment.
Not sure if this is supposed to be here without having a unit test that proves it. Nevertheless it should say elif here and not if.
There was a problem hiding this comment.
I can chage it to elif. But should work similary.
Well i need it here otherwise i cannot generate my code :D
There was a problem hiding this comment.
I am doing something like this. Maybe it is not optional. Byt i would like to have function which will return STRING from declaration instead of this hack for cfile.Writer(cfile.StyleOptions()).write_str:
"sizeof({cfile.Writer(cfile.StyleOptions()).write_str(self.cF.sequence().append(self.paramsTypes[param["data"].type]["C"]))})"
There was a problem hiding this comment.
Ok this change is not necessary as i should use self.cF.func_call("sizeof", [self.paramsTypes[param["data"].type]["C"]]) instead of what i mentioned. I am developing under pressure a bit and lack of documentation is not helping :D
Signed-off-by: Cervenka Dusan <cervenka@acrios.com>
src/cfile/core.py
Outdated
| ELSE = 2 | ||
|
|
||
|
|
||
| class Condition(Block): |
There was a problem hiding this comment.
Now you're taking shortcuts. Not all if-statements are wrapped in braces.
In C you can declare statements like this:
if(condition) ++x; else ++y;
src/cfile/writer.py
Outdated
|
|
||
| def _write_condition(self, elem:core.Condition) -> None: | ||
| if elem.type == core.ConditionType.IF: | ||
| self._write(f"if ({elem.condition})") |
There was a problem hiding this comment.
You need to add support for new formatting styles in style.py then support it in writer.py
- Space after if but before parenthesis?
if(vs.if ( - Space around the condition?
(condition)vs.( condition )
|
You're taking too many shortcuts in the design. You don't add style formatting options in the writer and don't do any unit testing. I think you should continue working directly on your fork. I'm sure you can repurpose the code to fit your specific needs. |
|
Hi @cogu , i convert PR to draft. Of course i am taking shortcuts as there are too many missing features. I think you shouldn't close PR yet. You can update your code base on this in correct way. After then i would close this branch. Otherwise i would keep it here as an inspiration for people who would miss same features... Later i can provide better PRs divided by features. E.g. adding enums, fix blank line, ... |
93d296f to
9decef9
Compare
8da198e to
5c3c3c1
Compare
Signed-off-by: Cervenka Dusan <cervenka@acrios.com>
5c3c3c1 to
0240797
Compare
Refactored structs