[WIP] Move parser imports to another file#6625
Conversation
|
CC @yebblies |
andralex
left a comment
There was a problem hiding this comment.
Great start! A few course corrections within.
BTW thanks @WalterBright for the great idea with swapping entire AST families.
src/ddmd/attrib.d
Outdated
There was a problem hiding this comment.
Our convention would suggest codegen_ast_family
src/ddmd/attrib.d
Outdated
There was a problem hiding this comment.
scope p = ... to avoid stuttering
src/ddmd/codegenASTFamily.d
Outdated
There was a problem hiding this comment.
Great, but no need to tie types with the allocation method. Just this should suffice:
alias StructDeclaration = ddmd.dstruct.StructDeclaration;
alias UnionDeclaration = ddmd.dstruct.UnionDeclaration;
alias BaseClass = ddmd.dclass.BaseClass;
...Then the rest of the code could continue using new ASTFamily.StructDeclaration; etc.
If there's a need, we may factor out the allocation and construction mechanisms as well in a later pass.
src/ddmd/dmodule.d
Outdated
There was a problem hiding this comment.
as above, no need to specify the type twice
src/ddmd/parse.d
Outdated
There was a problem hiding this comment.
We should not need this import here. This is important - with the import it still means the parser depends on some specific AST family.
src/ddmd/parse.d
Outdated
There was a problem hiding this comment.
No need for a member - just use the static types. If methods are needed in some ASTFamily, they can be defined static.
In the future if we have an AST family keeping its own state (unlikely), we may go with a member.
src/ddmd/parse.d
Outdated
There was a problem hiding this comment.
So this would become a = new ASTFamily.InterfaceDeclaration(loc, id, baseclasses);.
src/ddmd/codegenASTFamily.d
Outdated
There was a problem hiding this comment.
I see you updated this as I was reviewing. Taking this one step further: move all imports inside this struct.
src/ddmd/codegenASTFamily.d
Outdated
There was a problem hiding this comment.
These forwarding constructors quickly become a lot of boilerplate so we definitely should avoid them.
|
This creates the illusion of independence. |
src/ddmd/codegen_ast_family.d
Outdated
There was a problem hiding this comment.
Have we settled on non-top-level imports implicitly being public, or is this yet another remnant of the 313/314 days?
There was a problem hiding this comment.
Good point. @RazvanN7 this is clever but let's create a unittest build with a separate AST family called e.g. ASTNull that has the ABSOLUTE MINIMAL types that make the parser build.
Then we need to parse a few files using Parser!ASTNull and place that in a unittest.
|
One thing I just want to make sure everybody is aware of is that LDC still needs a clean |
It creates independence.
The next step of the project is to create a family of simple AST nodes, devoid of any extra information and analysis. I predict that will be a rather easy undertaking. |
Fair enough. |
andralex
left a comment
There was a problem hiding this comment.
@WalterBright and I just had a pow-wow and agreed with the following:
- acceptance of this hinges on the presence of the ASTNull family that defines minimal AST nodes. The idea being that we want to make sure we don't access fields/methods in AST types that we're not supposed to.
- no underscores in file names :)
| import ddmd.dversion; | ||
| import ddmd.errors; | ||
| import ddmd.expression; | ||
| import ddmd.func; |
There was a problem hiding this comment.
ahhh, the red here is a good indicator
src/ddmd/parse.d
Outdated
src/ddmd/attrib.d
Outdated
There was a problem hiding this comment.
s/codegen_ast_family/astcodegen/g
src/ddmd/attrib.d
Outdated
There was a problem hiding this comment.
s/CodegenASTFamily/ASTCodegen/g
src/ddmd/codegen_ast_family.d
Outdated
There was a problem hiding this comment.
Good point. @RazvanN7 this is clever but let's create a unittest build with a separate AST family called e.g. ASTNull that has the ABSOLUTE MINIMAL types that make the parser build.
Then we need to parse a few files using Parser!ASTNull and place that in a unittest.
src/ddmd/parse.d
Outdated
There was a problem hiding this comment.
@RazvanN7 don't forget to s/ASTFamily/AST/g at some point, thx!
edfe014 to
eddf87e
Compare
|
@RazvanN7 I am not too happy with the naming. |
|
@UplinkCoder Well, actually the it is part of the codegen since it holds useful information for the correct code generation. On the other hand, ASTNull is Walter's choice. I have nothing against the NullAST name |
|
@RazvanN7 it is a dependency for cg, but does not do any cg on it's own. The last part is always the more significat one in english. |
|
@RazvanN7 also astnull is missing in win32 makefile while it is in the posix one |
|
@UplinkCoder @WalterBright wanted ASTCodegen which I'm also unhappy with but it's his prerogative. |
|
@UplinkCoder You are right, I updated now the win32.mak file |
7ae53f0 to
2c68802
Compare
|
@RazvanN7 the unit test in The DMD unit tests are automatically run when building DMD with |
| extern (C++) class TemplateParameter | ||
| { | ||
| final extern (D) this(A, B)(A a, B b) {} | ||
| void foo() {} |
There was a problem hiding this comment.
Is this actually a member of the real TemplateParameter class?
|
After reviewing this in more detail I've come to the conclusion that the
I do agree that such a family is useful, but the minimal AST is ASTBase, not this. For it to be a minimal AST it must by definite have some kind of use, which this does not. Making sure that no non-semantic fields are accessed is covered by ASTBase. I suspect this may have come from a mis-communication of the idea of an AST factory interface that does not actually build an AST, which is the minimal interface required for some parser tasks (syntax verification) - but this is approach is still unacceptable for that as it will unavoidably allocate memory. The minimal AST set that does involve a class hierarchy must be capable (at the very least) of representing the tree structure of parsed nodes. After all, the 'T' in AST stands for tree, and if you don't build a tree you have just allocated a bunch of useless classes. More realistically the minimal AST will contain all of the information necessary to run semantic analysis - ie everything that the parser currently generates. |
|
Is |
|
If |
|
Compare the implementation of static ssize_t write_null(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
return count;
}Typically a null implementation doesn't take thousands of lines, allocate a bunch of memory, and add a maintenance burden in the form of massive duplication. Please let me know if I've missed any uses of this that aren't covered better by the base ast or ast construction interface. |
|
The AST that just sets the instance variables that was shown in the talk would be a nice start. |
|
@yebblies "I want a parser that simply gives a yes/no on whether the code is syntactically correct, without any additional processing". Generally I'm fine with removing this if it has no use, but give it a little more time before we make that decision. |
|
This this fails that use case because it allocates a huge amount of memory. This is an easily solved problem but allocating a broken ast is not the answer. |
|
@yebblies OK. Let's give this a couple of months and then remove if not necessary. Thanks! |
|
How about instead we remove it and if it turns out it's necessary we can add it back in. That we will fix it now instead of waiting two months to revert a pull you should never have merged in the first place. Re-adding it would have very little cost, while maintaining it for two months would be a different story. |
|
I think that ASTNull serves as a good of example of what functions and variables you need to define to have a working parser. ASTBase has a lot of methods and fields which may be dropped if someone wants to implement its own AST family. I do agree that there is no situation in which ASTNull can be used per se, but it's easier to read than the enriched ASTBase. |
|
But why would anyone ever define an ast family from scratch instead of deriving from astbase? Astbase effectively is part of the api of the parser. Any fields in astbase should be required to get a valid ast out of the parser - other fields should not be in there. I'm happy to talk about improving the readability but not at the cost of this much duplication. |
The parse.d file creates AST nodes which are passed to the semantic analysis. In the current form, the parser imports 95% of the total compiler code, including semantic analysis code which it doesn't use. In order to break the import cycle and to take a step further into transforming the compiler into a library, it is necessary to offer the possibility of separation between parsing and semantic analysis. This PR is a first step in that direction, by moving the creation of AST nodes (more explicitly the "new" expressions) to a different file and transforming the Parser class into a templated class which receives its AST nodes types through a template. This way anyone can define their own AST nodes and instantiate the parser with them.
This is a work in progress. I only moved the creation of Union and Struct declaration nodes to a file called codegenASTFamily which contains a struct that implements the creation methods.
When this PR will be finished, the CodegenASTFamily struct will contain the creation expressions for all AST nodes and parse.d will have a lot less imports.