nim-lang / nif

NIF is a text based data format designed for compiler frontend/backend communication or communication between different programming languages.
MIT License
44 stars 4 forks source link

Dialect directive #65

Closed karbiv closed 1 month ago

karbiv commented 1 month ago

An observation on having read NIF spec. No mentions of macros. The closest part to source transformations is .dialect directive. But its name is somewhat misleading, what it represents in the spec could be named phase(of source analysis and transformations).

Function inlining and destructor injection are the same transformation, i.e. replacing a node with a subtree.

Macro expansion and code optimizations usually replace/rewrite existing nodes. It might suggest that some original source code nodes could contain subtrees reflecting different phases.

Only first phase nodes contain relevant info about lines/columns. Injected code may reference its original module and position. Optimized code nodes rewrite original nodes and may hint which original lines are affected.

Programmers that explore some code sometimes need/want to see macro expansion(like in Emacs toggling expand-macro), and only compiler can provide such information reliably.

A loose elaboration of missing or overlooked information in the spec.

Araq commented 1 month ago

No mentions of macros.

There is nothing to say about macros. You can model them with an wasExpandedFrom/comesfrom node.

But its name is somewhat misleading, what it represents in the spec could be named phase(of source analysis and transformations).

The .dialect directive is really used for dialects and it just so happens that ideally a compiler phase produces a well defined language dialect.

Function inlining and destructor injection are the same transformation, i.e. replacing a node with a subtree.

They are different phases in the Nim compiler and what you describe is overly broad anyway, "replacing a node with a subtree" is what every transformation comes down to.

Only first phase nodes contain relevant info about lines/columns.

No, the compiler carries precise line information around all compilation phases.

Injected code may reference its original module and position. Optimized code nodes rewrite original nodes and may hint which original lines are affected.

As I said, can be done with comesfrom. But it's not as necessary as you might think as the compiler keeps line information up to date.

Programmers that explore some code sometimes need/want to see macro expansion(like in Emacs toggling expand-macro), and only compiler can provide such information reliably.

That would be the output of "nim-gear2". The editor should use the line information to see a particular expansion.

karbiv commented 1 month ago

The .dialect directive is really used for dialects and it just so happens that ideally a compiler phase produces a well defined language dialect.

Best example of dialects is FreePascal where they are called modes that are switched in source code by module level directive {$MODE } or -M option: FPC, OBJFPC, TP(Turbo Pascal), DELPHI, DELPHIUNICODE, MACPAS, ISO, ExtendedPascal. These are proper dialects, compiler understands them in one project. It saved all historical codebases, I guess a lot of software that was used in businesses written in 1990s-2000s.

C++ users sometimes call standard's revision a dialect: C++98, C++11, C++17, C++20. D language is not called a dialect but some say that D was created to push C++ Committee to adopt new features. Python 2 and 3 can be thought of as dialects, there's an automated translator 2to3.

Compiler phases are derivations, but dialects deviate.

Araq commented 1 month ago

I've already explained to you how "dialect" is a perfectly fine term for what it is. I have no desire to continue this pointless discussion.

karbiv commented 1 month ago

There is nothing to say about macros. You can model them with an wasExpandedFrom/comesfrom node.

If it makes macros and templates a first class formal objects then okay.

In a text editor given a macro call node: 1) find a subnode containing its expansion, AST subtree. 2) convert AST subtree back to source code and paste in place as an uneditable text. 3) do syntax coloring and formatting of inserted expansion using predefined map of node types. 4) then it's possible to launch jump to definition from that expansion 5) toggle this expansion off

Currently nimsuggest can't jump to definition from template definitions.

karbiv commented 1 month ago

I've already explained to you how "dialect" is a perfectly fine term for what it is. I have no desire to continue this pointless discussion.

You explained it to yourself and that's enough. I don't care that much even if it's called mondaard.

Exposing AST of a compiler is already an achievement after Richard Stallman's veto on it in GCC for a decade which led to Apple acquiring LLVM for that purpose.