Short answer: stores information about the changes that occurred during NIF 
generation so that it is possible to generate exactly the same ast as it was 
before NIF generation if needed.

for example, there is a code
    
    
    using Int: int32
    proc test(Int)=
      discard
    
    
    Run

in nif it will be (if using is removed, not added as a node)
    
    
    (.nif24)
    (stmts
       (proc
          test ... (params . (param
             Int ... int32 .
          )) ...(stmts
           (discard .)
        )
      )
    )
    
    
    Run

Because of this, when applying a macro to a regular ast for example, it will 
get not nnkIdent, but nnkIdentDefs and the macro will eventually work 
incorrectly. On the other hand, it is desirable to remove using in NIF because 
it allows you to simplify code analysis with tools because it makes NIF code 
more unified and simple, which ast lacks.

Therefore, I suggest adding an info prefix, which will help the macro to get a 
bit more correct ast for the procedure. I.e. a small preprocess to change the 
ast viewed through the macro.

This by the way applies to (already proposed) types:
    
    
    proc test(): typeof(
      block:
        type A = int
        A
    ) = discard
    
    
    Run

In nif it should look like this:
    
    
    (.nif24)
    (stmts
      (type HiddenType1 ... (call typeof(block . (stmts (
        type A ... int
        ) A)
      )
      (proc test ... (params HiddenType1) .. (stmts (discard .)))
    )
    
    
    
    Run

However, when the macro is applied, it does not get the ast that the macro 
expects.

Again this is solved by the info prefix, which tells you that it was typeof 
%change, derivedTypeof%

Of course it is possible to make types not at the top level possible, but then 
the party receiving NIF in any place where it expects a type will have to add a 
typedef check and execute a typedef expression. These actions add complexity. 
It is much better in my opinion to put typedef at the top level (if the 
expression inside somehow involves the generic parameter we can just make the 
generic type) and handle it like any other type. However, in order for macros 
to be able to see ast before conversion, we just need to add an info prefix. 
Basically the algorithm is as follows: call macro -> convert to what ast was 
before using info -> edit ast with macro. Anyway, it seems to me that if we 
want NIF to simplify the code, we need to do this. And, as far as I understand, 
adding this behavior for macros is not that hard.

Reply via email to