 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * This source file is part of SableVM.                            *
 *                                                                 *
 * See the file "LICENSE" for the copyright information and for    *
 * the terms and conditions for copying, distribution and          *
 * modification of this source file.                               *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

*** SableVM Informations about M4 macros ***

NOTE: If you're looking for general informations about the m4 macros that are
  used in SableVM code - you should look into ./src/libsablevm/macros.m4

TOPIC: m4svm_instruction_1, m4svm_instruction_2$1 and the rest of this stuff
  in ./src/libsablevm/instructions_preparation.m4.c
  [ this is NOT a FAQ but a discussion transcript ]

  The problem is that GNU indent puts a space between function and left
  parenthese, e.g. foo (arg1, arg2); Thing is that m4 requires the parentese
  to be joined to the macro name.  So, we have to play tricks. :-)

  Let's do it in steps.

  STEP 1.

  m4svm_instruction_head (NOP, SVM_INTRP_FLAG_INLINEABLE, 0);
  expands to:
  m4svm_instruction_1( (NOP, SVM_INTRP_FLAG_INLINEABLE, 0);
   << instruction body in C >>
  m4svm_instruction_tail ();

  Now, m4svm_instruction_tail expands to:
  ))m4_dnl ();
  
  This whole thing (after applying m4_dnl) becomes:
  m4svm_instruction_1( (NOP, SVM_INTRP_FLAG_INLINEABLE, 0);
    << instruction body in C >>
  ))

  STEP 2.
 
  The above result becomes a call to m4svm_instruction_1 with a single
  parameter [delimited by parentheses].  The argument is:
  (NOP, SVM_INTRP_FLAG_INLINEABLE, 0);
    << instruction body in C >>
  )

  STEP 3.
  
  m4svm_instruction_1 is expanded and we get:  
  m4svm_instruction_2(NOP, SVM_INTRP_FLAG_INLINEABLE, 0);
  Which ends with a ";", and it does not include the instruction body.
  So, we must expand m4svm_instruction_2.

  STEP 4.
  
  m4svm_instruction_2(NOP, SVM_INTRP_FLAG_INLINEABLE, 0); expands to:
  m4svm_instruction($1, $2, $3,m4_dnl
  or, more precisely:
  m4svm_instruction(NOP, SVM_INTRP_FLAG_INLINEABLE, 0,m4_dnl;
  So, after applying m4_dnl, the whole thing now looks as:
  
  m4svm_instruction(NOP, SVM_INTRP_FLAG_INLINEABLE, 0,
    << instruction body in C >>
  )

  Which also gets rid of the ";" at the end of the m4svm_instruction_head line.
  Now m4svm_instruction has all the params that we wanted it to have.

