AGS 3.4.0.13 allows macros inside macros : Templates much?

Started by Monsieur OUXX, Sat 10/12/2016 14:44:11

Previous topic - Next topic

Monsieur OUXX

How about producing a proof of concept of a template for a basic data structure, like let's say a List, that would rely on a type not know in advance, provided it provides a few basic methods (Compare and stuff)
I've done that in the past but it was very clunky because there could be only one macro. But with macros inside macros, I guess that gives access to a whole new world of fun.
 

Monsieur OUXX

#1
My cunning plan exploded into a giant ball of fire approximately 3 seconds after I tried to execute it.

Indeed, it's not possible to #undef , #undefine or even redefine an existing macro.
Oh well. ;-D (roll)


BULLSHIT, #undef does work :-D
 

Crimson Wizard

I was more concerned about lack of line wrap command that would let one write multiline macros (AGS may have limitations to what can be written in one line).

Monsieur OUXX

#3
Quote from: Crimson Wizard on Tue 17/01/2017 21:37:24
I was more concerned about lack of line wrap command that would let one write multiline macros (AGS may have limitations to what can be written in one line).
Well I was planning on testing that. But since it's C syntax, with { } and ; it should be alright.

However I'm having issues with this :

(with AGS 3.4.0-RC2 zipped version, which, if I understood correctly, is the current release version, also known as 3.4.0.14)
This works
Spoiler

Module header
Code: ags

struct Array
{
    import static void TestFunc();
};

import int a1[];
import int a2[];
import int a3[];



Module body
Code: ags

#define NAME a1
#define INDEX 1
#define WORKWITH_a1 else if (which == INDEX) { 

int NAME[];
export NAME;

#undef NAME
#undef INDEX

#define NAME a2
#define INDEX 2
#define WORKWITH_a2 else if (which == INDEX) { 

int NAME[];
export NAME;


#define STARTSWITCH if (which==0) {int zzz=0; }
#define ENDWORKWITH }

int a3[];
export a3;

void init(int which,  int size)
{
    STARTSWITCH
     WORKWITH_a1 a1 = new int[size]; ENDWORKWITH
     WORKWITH_a2 a2 = new int[size]; ENDWORKWITH
    
    a3 = new int[10];
}

static void Array::TestFunc()
{
  init(1,  10);
  init(2, 10);
    Display("a3(0)=%d", a3[0]);
    Display("a2(0)=%d", a2[0]);
    Display("a1(0)=%d", a1[0]);
}




[close]



This does NOT works . At execution, a1 is null in global script. a3 is fine, a2 is fine.
Spoiler

Module header
Code: ags

//UNCHANGED
(...)



Module body
Code: ags

#define NAME a1
#define INDEX 1
//MODIFIED
#define WORKWITH_a1 else if (which == INDEX) { NAME 

int NAME[];
export NAME;

#undef NAME
#undef INDEX

#define NAME a2
#define INDEX 2
//MODIFIED
#define WORKWITH_a2 else if (which == INDEX) { NAME 

int NAME[];
export NAME;


#define STARTSWITCH if (which==0) {int zzz=0; }
#define ENDWORKWITH }

int a3[];
export a3;

void init(int which,  int size)
{
    STARTSWITCH
    //MODIFIED
     WORKWITH_a1 = new int[size]; ENDWORKWITH
    //MODIFIED
     WORKWITH_a2 = new int[size]; ENDWORKWITH
    
    a3 = new int[10];
}

static void Array::TestFunc()
{
  //UNCHANGED
  ( ...)
}


[close]

The only difference is in macro WORKWITH_a1 and WORKWITH_a2.
- In the working script, the macro does not include the name of the array (a1 or a2) as "NAME". a1 and a2 are written explicitly in function "init"
- In the working script, the macro DOES include "NAME" directly.

What's wrong?

 

Gurok

Quote from: Monsieur OUXX on Tue 17/01/2017 22:24:06
Spoiler

Module header
Code: ags

//UNCHANGED
(...)



Module body
Code: ags

#define NAME a1
#define INDEX 1
//MODIFIED
#define WORKWITH_a1 else if (which == INDEX) { NAME 

int NAME[];
export NAME;

#undef NAME
#undef INDEX

#define NAME a2
#define INDEX 2
//MODIFIED
#define WORKWITH_a2 else if (which == INDEX) { NAME 

int NAME[];
export NAME;


#define STARTSWITCH if (which==0) {int zzz=0; }
#define ENDWORKWITH }

int a3[];
export a3;

void init(int which,  int size)
{
    STARTSWITCH
    //MODIFIED
     WORKWITH_a1 = new int[size]; ENDWORKWITH
    //MODIFIED
     WORKWITH_a2 = new int[size]; ENDWORKWITH
    
    a3 = new int[10];
}

static void Array::TestFunc()
{
  //UNCHANGED
  ( ...)
}


[close]

The only difference is in macro WORKWITH_a1 and WORKWITH_a2.
- In the working script, the macro does not include the name of the array (a1 or a2) as "NAME". a1 and a2 are written explicitly in function "init"
- In the working script, the macro DOES include "NAME" directly.

What's wrong?


When WORKWITH_a1 is parsed, NAME and INDEX are a2 and 2, respectively. AGS uses the value of macros at the time of reference to determine what it should replace the macro with.

Something like this (just a simple example to demonstrate) would work:

Code: ags
#define TEMPLATE if(INDEX == 1) Display("Hi %d", INDEX);

void init()
{
  #define INDEX 0
  TEMPLATE
  #undef INDEX
  #define INDEX 1
  TEMPLATE
  #undef INDEX
  #define INDEX 2
  TEMPLATE
  #undef INDEX
}
[img]http://7d4iqnx.gif;rWRLUuw.gi

Crimson Wizard

#5
Quote from: Monsieur OUXX on Tue 17/01/2017 22:24:06
(with AGS 3.4.0-RC2 zipped version, which, if I understood correctly, is the current release version, also known as 3.4.0.14)
There was not a version 3.4.0.14 yet. 3.4.0-RC2 is "release candidate 2" which is prior to final and patched releases which are latest.
If you are looking into this forum section -
http://www.adventuregamestudio.co.uk/forums/index.php?board=28.0
- the latest versions are unlocked and stickied, while obsolete version threads are locked.

Monsieur OUXX

@CW thanks for the clarifications, that will help me not using a wrong version by mistake.
@Gurok of course! Stupid me. Getting confused by replaced macros when I was trying to exploit them in the first place.  :-D Thanks.
 

SMF spam blocked by CleanTalk