Week 7: Submodule ASR Design and Initial Implementation to link it with Parent Module

July 4, 2025

← Back to Home

Hi everyone, welcome to the seventh blog of my GSoC'25 journey. I started the week by working to create an ASR Design by which we can implement Submodules in LFortran. Of all the features of submodules, I firstly targeted its main feature which is that a submodule provides Implementation to a module Interface. Rest all features of submodules can be easily accomodated once we are ready with this main feature.

For the ASR Design of Submodules, we didn't had to create some sort of new Symbol in ASR and planned to use current machinery with some tweaks. In our current implementation, we were representing Submodules using a Module Symbol. So, first thing I did was to add a new Symbol flag in Module ASR. This flag was to used to the track Parent Module of a Submodule. For a normal module, the Parent Module flag would be nullptr. This flag also helped us to distinguish between a Module and Submodule based on whether parent module flag is nullptr or not. Then, I modified all Module generating ASR code with this new Parent Module Flag.

Rest of the things like, serialization, deserialization, ASR generation for updated Module ASR was handled by LFortran automatically and didn't take much efforts. Finally, I updated pickle.cpp file with this new Parent Module Flag for Module ASR. With this, my ASR Design step for Submodules was completed. I, then, updated all test references for this new change and added a test for this updated ASR. Link to Merged Pull Request for this ASR Design step for Submodule is here.

Then onwards, I started to work to link Parent Module interface with Submodule Implementation. This was a tricky part. It took a lot of efforts, like I started with an approach, then shift to some other approach due to a flaw in it and similarly, the cycle repeated. Firstly, I tried to directly update Parent Module Function node with Submodule Function node in asr_to_llvm phase but, in this phase, a lot of things need to changed as Parent Module Function node was spreaded all over in SubroutineCall, FunctionCall etc. and it was physically impossible to update Parent Module Function in all the places.

So, I changed my plan and tried to update Parent Module Function in ASR generation phase. But it seemed that modifying Parent Module Function node was a bad plan as it led a lot of failures due to incorrect Symbol Table and also, the idea was not efficient when compiling separate files or for Separate Compilation. Links to Pull Requests for these Approaches are :-

So, finally, I tried to link Parent Module interface to Submodule Implementation using ExternalSymbol. Here, the Idea was to convert Symbol corresponding to Parent Module Function to an ExternalSymbol pointing to Submodule Function. This way, all FunctionCalls and SubroutineCalls to Parent Module, will get directed to Submodule and things would work without any error. I have started to work on this approach and have covered most parts of it.

In the next week, I am planning to wrap up Submodule Implementation using ExternalSymbol approach and then, I will revert workarounds from stdlib that are related to Submodules. If nothings breaks after reverting these workarounds, then its good or else I will create MREs for failures and fix them to solidify the Submodule Implementation.

Overall, I worked for 30 hours this week and enjoyed the work that I did in the seventh week and would like to thank Ondrej Certik, Harshita Kalani, Pranav Goswami and all the other LFortran members for their reviews and suggestions which helped me a lot to tackle new difficulties. I am looking forward to continue my journey in the next week with the same excitement and enthusiasm and plan to complete my proposed tasks as quickly as I can.