Pages: 1
  Print  
Author Topic: Re: Preprocessor Directives (The compile-time "if")  (Read 9678 times)
Offline (Male) Josh @ Dreamland
Posted on: November 06, 2010, 10:42:18 am

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
I see what you mean, Rusky. For a little bit I was thinking about doing something like that (C takes a lot of heat over the issues rising from copy-pasted macros, of course), but I don't think I should. The only reason I'm keeping any sort of macros is because of ENIGMA's C heritage. If it wasn't for that, they'd be expression based if they were in at all, but my reason for wanting preprocessors at all at this point isn't for macros. My number one concern is the #if directive. The rest are just kind of there. The reason I want #if is for altering behavior from platform to platform. I was discussing with marbs the other day the implications of ENIGMA compiling for iPhone, and he mentioned motion detecting devices.

Originally, I intended to offer controller_get_angle_x/y/z() and controller_get_shaken(). On Windows, they'd all return zero unless an applicable device was connected. On Wii, they'd all have an accurate return. On iPhone, _angle _x and _y would work, as well as _shaken (same for android). Issue is, what if that isn't enough? What if having a shake is a critical part of the game, and they would have to work around it with multiple lines of code (likely to test for a key combo instead)?

I like a number of features for Lisp's macros, but my focus is really more on preprocessors right now. Maybe we can pile on a new macro system as well, later. But for now I'm more concerned about being able to say

[[If Target_Device == eDev_iPhone]]
if (controller_get_shaken())
  earthquake();
[[else]]
if (keyboard_check(vk_control) and keyboard_check_pressed(ord("E")))
  earthquake();
[[fi]]

Granted, that's not a very good example, since a simple "or" could technically have sufficed with little overhead. But it conveys the basic idea.

Say we want our mobile game to always be oriented correctly, and which direction has the high resolution doesn't really matter.

Persistent Controller Step Event:
Code: (EDL) [Select]
[[if Target_Device == eDev_iPhone or Target_Device == eDev_Android]]
int az = controller_get_angle_z();
if (az > 45 and az < 135 or az > 225 and az < 315)
  view_wview[0] = display_get_width(),
  view_wview[0] = display_get_height%
« Last Edit: November 06, 2010, 06:38:14 pm by Josh @ Dreamland » Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) luiscubal
Reply #1 Posted on: November 06, 2010, 01:55:20 pm
Member
Joined: Jun 2009
Posts: 452

View Profile Email
I'm not entirely sure this is good enough.
However, it could be improved.

Code: [Select]
__preproc__ int x = 2;

__preproc__ if (x > 1) {
    printf("Yeah!\n");
} else {
    printf("Oh...\n");
}

__preproc__ int y = 2;
__preproc__ while (y < 10) : __maxloops__(100) { //max loops ensures there are no compile-time infinite loops.
   //__maxloops__ is, by default, MAXLOOPS_DEFAULT
   //Attempting to define __maxloops__ to be greater than MAXLOOPS_MAX is a compile error
   //MAXLOOPS_DEFAULT and MAXLOOPS_MAX would be defined in <enigma/preprocessor.h>
   //Also important is LOOPS_MAXNESTING
    printf("Wheeee!\n");
    ++y;
}


This, of course, means the compiler must be very smart.
Also, mandatory is official #pragma once support
Logged
Offline (Male) Josh @ Dreamland
Reply #2 Posted on: November 06, 2010, 02:00:43 pm

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
"__preproc__ int x = 2;"
"Also, mandatory is official #pragma once support"

wat is this i dont even
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) luiscubal
Reply #3 Posted on: November 06, 2010, 02:50:15 pm
Member
Joined: Jun 2009
Posts: 452

View Profile Email
Proper preprocessor types(instead of copy-paste)
Better syntax - well integrated into C++.
(Why #ifdef #endif when you can have if{}?)

#pragma once is also very useful, since it removes the need for all those #ifndef #define #endif in the headers). Also, IIRC gcc supports it so it shouldn't be any trouble).
Logged
Offline (Male) Josh @ Dreamland
Reply #4 Posted on: November 06, 2010, 03:14:57 pm

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
There's no point in using real types for macros... It's strictly interpreted... it'd just be more work.
#pragma once won't help us; this is for EDL in objects and scripts, which are always included once manually (they can't be included by the user...)
As for using ifdef and endif instead of {}, it's really a matter of preference. I like it text-based because you can always tell the preprocessor from the rest of the code. If we're going to be using [[]]. [[]]{} would look ugly. I'm opposed to so many _ in everything, but I suppose I'm not against using a word and {} instead of [[if]] [[fi]], if that's what everyone else wants.

Moreover, has anyone really been far as decided to use even go want to do look more like?
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) luiscubal
Reply #5 Posted on: November 06, 2010, 05:30:26 pm
Member
Joined: Jun 2009
Posts: 452

View Profile Email
Fine. Then:

Code: [Select]
preproc var x = 2;

preproc if (x > 1) {
    printf("Yeah!\n");
} else {
    printf("Oh...\n");
}

preproc var y = 2;
preproc while (y < 10) : maxloops(100) { //max loops ensures there are no compile-time infinite loops.
   //maxloops is, by default, MAXLOOPS_DEFAULT
   //Attempting to define maxloops to be greater than MAXLOOPS_MAX is a compile error
   //MAXLOOPS_DEFAULT and MAXLOOPS_MAX would be defined in <enigma/preprocessor.h>
   //Also important is LOOPS_MAXNESTING
    printf("Wheeee!\n");
    ++y;
}

maxloops(and the remaining possible indicators) would only be a keyword in the context of a preproc while, so this would work:
Code: [Select]
preproc var maxloops = 5;
preproc while (maxloops > 0) : maxloops(maxloops) {
//some code
--maxloops;
}
In the example above, maxloops would be set to 5 since that was the value when the compiler found the preproc while.
The goal here is precisely to reduce distinction of preprocessor and common code.

Which is clearer?
Code: [Select]
[[Define foo 1]]
var a = foo, b = [[if foo]]"bar"[[else]]""[[endif]]

or

preproc var foo = 1;
var a = foo, b = preproc if (foo) "bar" else ""

Also, my method only requires adding one keyword to the syntax highlighter.
Logged
Offline (Male) Rusky
Reply #6 Posted on: November 06, 2010, 05:51:08 pm

Resident Troll
Joined: Feb 2008
Posts: 954
MSN Messenger - rpjohnst@gmail.com
View Profile WWW Email
Lisp would be a good system to borrow ideas from here. While it would be rather complicated to get the full power of Lisp's tree-based syntax, the idea is to allow macros to manipulate expressions rather than strings, which is THE reason C's preprocessor smells so bad. Luis' version almost has what is needed for this (the language itself available in macros), but parameterized #define-like macros still need a syntax which would accept arbitrary expressions to be manipulated (as well as normal data types). See Lisp macros (preferably of the hygienic kind), Template Haskell and sort-of C# LINQ expression trees.
Logged
Offline (Male) Josh @ Dreamland
Reply #7 Posted on: November 06, 2010, 06:36:47 pm

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
I see what you mean, Rusky. For a little bit I was thinking about doing something like that (C takes a lot of heat over the issues rising from copy-pasted macros, of course), but I don't think I should. The only reason I'm keeping any sort of macros is because of ENIGMA's C heritage. If it wasn't for that, they'd be expression based if they were in at all, but my reason for wanting preprocessors at all at this point isn't for macros. My number one concern is the #if directive. The rest are just kind of there. The reason I want #if is for altering behavior from platform to platform. I was discussing with marbs the other day the implications of ENIGMA compiling for iPhone, and he mentioned motion detecting devices.

Originally, I intended to offer controller_get_angle_x/y/z() and controller_get_shaken(). On Windows, they'd all return zero unless an applicable device was connected. On Wii, they'd all have an accurate return. On iPhone, _angle _x and _y would work, as well as _shaken (same for android). Issue is, what if that isn't enough? What if having a shake is a critical part of the game, and they would have to work around it with multiple lines of code (likely to test for a key combo instead)?

I like a number of features for Lisp's macros, but my focus is really more on preprocessors right now. Maybe we can pile on a new macro system as well, later. But for now I'm more concerned about being able to say

[[If Target_Device == eDev_iPhone]]
if (controller_get_shaken())
  earthquake();
[[else]]
if (keyboard_check(vk_control) and keyboard_check_pressed(ord("E")))
  earthquake();
[[fi]]

Granted, that's not a very good example, since a simple "or" could technically have sufficed with little overhead. But it conveys the basic idea.

Say we want our mobile game to always be oriented correctly, and which direction has the high resolution doesn't really matter.

Persistent Controller Step Event:
Code: (EDL) [Select]
[[if Target_Device == eDev_iPhone or Target_Device == eDev_Android]]
int az = controller_get_angle_z();
if (az > 45 and az < 135 or az > 225 and az < 315)
  view_wview[0] = display_get_width(),
  view_wview[0] = display_get_height();
else
  view_wview[0] = display_get_height(),
  view_wview[0] = display_get_width();
[[fi]]

Granted, that code's kinda rough. But that's the kind of thing I'm talking about. You don't exactly want it doing that on Wii. :P
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Male) Rusky
Reply #8 Posted on: November 08, 2010, 09:38:36 am

Resident Troll
Joined: Feb 2008
Posts: 954
MSN Messenger - rpjohnst@gmail.com
View Profile WWW Email
If that's mainly what you want it for I think #if is just fine- .NET even pulled it into C# nearly as-is for that kind of stuff. Creating a new system for that isn't really worth it IMO.
Logged
Offline (Male) Josh @ Dreamland
Reply #9 Posted on: November 08, 2010, 05:13:05 pm

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
Well, yes, but I'd much prefer directives to be inside something other than ^#(.*)$. The [[ and ]] seem to make for prettier code. (Besides, I'm pretty much doing away with #include: I may steal require from other languages.)
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Male) RetroX
Reply #10 Posted on: November 08, 2010, 05:18:55 pm

Master of all things Linux
Contributor
Location: US
Joined: Apr 2008
Posts: 1055
MSN Messenger - classixretrox@gmail.com
View Profile Email
^#(.*)$
Really picky, but:
^[[:space:]]*#.*$

:P
Logged
My Box: Phenom II 3.4GHz X4 | ASUS ATI RadeonHD 5770, 1GB GDDR5 RAM | 1x4GB DDR3 SRAM | Arch Linux, x86_64 (Cube) / Windows 7 x64 (Blob)
Quote from: Fede-lasse
Why do all the pro-Microsoft people have troll avatars? :(
Offline (Unknown gender) TGMG
Reply #11 Posted on: November 09, 2010, 05:17:34 pm

Developer
Joined: Jun 2008
Posts: 107

View Profile WWW Email
Will this be able to use macros defined in c++ such as the ones provided by apple:
TARGET_IPHONE_SIMULATOR etc
Or will the user have to wait until enigma defines all of its own?
It might be useful to be able to mix macros between c++ and this so that functions can be rewritten in c++ more easily.
Logged
me
GMbed 2.0 :: Embed you gm games in websites.
Offline (Male) Josh @ Dreamland
Reply #12 Posted on: November 09, 2010, 06:43:37 pm

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
Since ENIGMA is responsible for understanding those macros to correctly parse its engine file, I would have to go out of my way to stop users from accessing macros like TARGET_IPHONE_SIMULATOR from your example. I of course have no intention of doing so.

So yes.
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) TGMG
Reply #13 Posted on: November 09, 2010, 07:13:26 pm

Developer
Joined: Jun 2008
Posts: 107

View Profile WWW Email
so:
[[if TARGET_IPHONE_SIMULATOR == 1]]
will work?
Logged
me
GMbed 2.0 :: Embed you gm games in websites.
Offline (Male) Josh @ Dreamland
Reply #14 Posted on: November 09, 2010, 07:19:56 pm

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
Yep.
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Pages: 1
  Print