-
Notifications
You must be signed in to change notification settings - Fork 29
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
Major Refactoring of API to a clean OOP interface #10
Comments
I like the idea of prebuilt parsers, let's do this. I agree with you about making the backends tests independent of the parser. Don't bother about writing the CLibInterface for the header I use for the tests I will do it myself while working on the backends, and once I will be done I will also add a test checking that the parser does indeed produce the same result as the handwritten CLibInterface. Lets rather start with the type system (in which you will have to include a Var and MacroVar object for completeness). As soon as this is in place I will start working on the backends. |
Regarding MacroVar: I added a MacroDef() class and .macros attribute already (see gist). Did you mean this object or did you mean an additiinal class (meant for what?). Regarding Var: My intention was to handle this via the All global objs (functions and vars) are stored in the .globals Attribute. If a globale Entry points to a FunctionType, it is a Funktion, otherwise a variable. |
Looking at the gist I was under the impression that this was reserved to macro function. Having two class one for macro functions and one for macro values might make things easier to understand. My point is what do you do with a global entry referring to a lets say a structure, where do you store the members values ? The idea behind Var would be to store the type and alongside the value. |
What do you mean with compelling use case? I can create two classes for macros if you prefer, but then I propose to derive one from the other, to avoid duplication oft common code. Why do we need a value? Am I overlooking sth.? If I am correct the interface Definition only needs a Name and a type for vars (respektive respective key and value oPointe to a obale attr). Values Come into the game if you load a library. But the values of the library instances variables are currntly represented by ctype module objects. If a variable points to a structure, the idea is, that it shall look like: assert p.globals == { 'varname': TypeRef('struct structname') }
assert p.types == { 'struct structname': StructType(...) } |
Sorry about that I started my answer with something than re-wrote it ... My idea for the macros is that in the case of a function we simply keep what is needed to perform the preprocessing steps, in the case of values the user can query the actual value (as a python object) but maybe this could be reserved to the backend. (I definitively agree that those should have a common base class). I was considering the ugly case of global variables declared in a header file (which may happen in single header project). Something like : int var = 1; This is ugly and should be avoided but I am worried that this exists nonetheless. |
|
|
OK. |
…artiailh#10 (comment). Currently only c_model.py and test_c_model.py where added (and a yet empty class for the reworked parser in c_parser.py), without implications on existing code. Thus the next steps can be done independently relying on this model.
I reasoned about the "stupid corner case" Imagine we had a mod1.c which is used by mod2.c and mod3.c. mod1.c's header (which contains If you agree with me, I propose to avoid complicating the interface of CLibInterface by an attribute that is never needed. |
I agree that this is very ugly coding, so ok lets keep it out for the time being. If we find somebody stupid enough to do such a thing we can always add it later. |
While implementing #15 I figured out a relatively clean interface of the parser. Please let me know your thoughts about the API. Regarding reworking of preprocessor: My original intention was to move the macro evaluation to the CLibInterface but keeping the CParser parsing the macro definitions. This would have required a AST like structure for macro definitions. Then the backend could use the macro without need to have knowledge of the CParser (which is currently responsible for evaluation). But then I detected, that a clean macro evalution required more work, as the current implementation is not really conform to the C preprocessor spec. The reason is that macros currently are always evaluated during definition, instead of invokation. This can cause trouble. I.e.: #define Y X
#define X int
Y var; //<- var will be of type CustomType('Y') instead of BuildinType('int') Then I realized that in 99% percent the current implementation should do its job. Thus I think I will skip this job and continue with the backend. If we come back later to the preprocessor issue, it should be doable without API change (the CParser would use the Preprocessor object internally then) |
This makes perfect sense to me. Have you found a templating engine suiting your needs ? |
As noted in Issues #5, #6 and #8 the interface of version 0.2.0 has some shortcomings in the API which shall be cleaned up. PR #9 did already a careful rework that keeps compatibility. But as decided in #8 the interface shall be reworked completely.
This issue is a continuation of the discussion started in #8 (comment) and superseeds #8. Regarding the annotiation in this comment:
int
,unsigned char
,float
(What do you mean by "is not passed one in your example"? It is used in the example multiple times; i.e. https://gist.github.com/mrh1997/876070be3763733f849e#file-typesystem_proposal-py-L155)Regarding the CParser object, I have one more idea:
An application could support multiple compilers by simply instantiating multiple CParsers with slightly different different grammars. Currently the grammars may only vary in type_quals, but in future we could even implement more complex differences. I would propose to provide a submodule for every standard compiler (visual studio, gcc, ...) that only provide a single object: a prebuild CParser for the corresponding compiler.
Regarding cooperation:
I propose to change the unittests of the backend (
test_ctypes.py
): Currently the tests requireCParser
which is not a clean test design. A better approach would be to separate the header-file-model (see GIST) completely into a separate file and the backend test only rely on this file (not on cparser.py).This way the test would be a "real" unit test, testing only a single unit (the backend; not parser+backend).
If you agree with me, I would start with a first PR, where I only add a independant file with the header-file-model. Then you and me could work independently.
The text was updated successfully, but these errors were encountered: