Skip to content
This repository has been archived by the owner on Sep 21, 2024. It is now read-only.

Latest commit

 

History

History
41 lines (26 loc) · 4.24 KB

Prajwal S N - Milestone Report 2.md

File metadata and controls

41 lines (26 loc) · 4.24 KB

Milestone

The milestone was to completely eliminate the libdparse dependency from dfmt, and implement 4 transformations using the AST traversal.

Research work and debugging

DMD provides two implementations of the language AST - ASTBase and ASTCodegen. The compiler itself uses the latter, which is generated by the parser, and later enriched by semantic passes. The former was created as a way to provide the AST through the DMD library without requiring the unnecessary semantic information that ASTCodegen provides. While this is ideal for a formatter, the classes for many nodes in ASTBase did not contain certain key methods required to make the formatter work (notably, toChars() and toString()). The dmd.hdrgen package implements these helper methods for ASTCodegen and uses it for header generation through dmd -H. This means that using ASTCodegen largely reduces the burden of manually adding additional helper methods for each node in dfmt and maintaining it. The decision was taken to proceed with using ASTCodegen in dfmt, and replacing it with ASTBase in the future if necessary.

A non-trivial amount of time was also spent in debugging why the AST was not being built properly in the parsing phase. Certain bugs like the FuncDeclaration node having a valid declaration but no body were difficult to debug, mainly due to not being able to isolate the source of the issue. After a considerable amount of hunting, the process of initialising the frontend in DMD was fixed, and the standalone dmd.frontend.parseModule() function was used to parse the input file instead of dmd.dmodule.Module.parse(). This got rid of most bugs that were previously present.

Programming work

The driver code in main.d originally used appender!string from std.array as a buffer to write the output to. The D string type does not have an equivalent in C++, restricting us from using it with extern (C++) classes. To mitigate this, the driver code was modified to use std.file.File.LockingTextWriter instead of appender!string for writing the formatted output.

Multiple changes were introduced in the commit that added the AST into the formatter, mostly to ensure that the input file is parsed correctly. The logic for node traversal was added next, followed by the indentation logic. This provided us with a fully working implementation of dfmt that could take an input file, walk the AST, and output the formatted file. It was now possible to begin adding the transformation passes.

The following four transformations have been implemented:

  • dfmt_space_before_function_parameters: Adds a space before the opening parenthesis in function declarations, e.g. int foo (int a, int b) {}. This is disabled by default.
  • dfmt_space_after_cast: Adds a space between the cast and the value being cast, e.g. cast(int) 0. This is enabled by default.
  • dfmt_align_switch_statements: Aligns the case statements and labels inside a switch block at the same level rather than one level deeper. This is enabled by default.
  • dfmt_space_before_aa_colon: Adds a space before the colon in associative array key-value pairs, e.g. auto a = { "Hello" : "Hi" };. This used to be the old behaviour of dfmt, and is disabled by default now.

Commits

Weekly forum updates

Next milestone

The next milestone involves adding 7 more transformations using the AST.