Last active
February 13, 2022 21:17
-
-
Save Y-Less/11be190bc413e7e4b7bcf260d62108e0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if defined _INC_if_extract | |
#endinput | |
#endif | |
#define _INC_if_extract | |
/* | |
88888888888 88 | |
88 88 | |
88 88 | |
88aaaaa 8b, ,d8 ,adPPYYba, 88,dPYba,,adPYba, 8b,dPPYba, 88 ,adPPYba, ,adPPYba, | |
88""""" `Y8, ,8P' "" `Y8 88P' "88" "8a 88P' "8a 88 a8P_____88 I8[ "" | |
88 )888( ,adPPPPP88 88 88 88 88 d8 88 8PP""""""" `"Y8ba, | |
88 ,d8" "8b, 88, ,88 88 88 88 88b, ,a8" 88 "8b, ,aa aa ]8I | |
88888888888 8P' `Y8 `"8bbdP"Y8 88 88 88 88`YbbdP"' 88 `"Ybbd8"' `"YbbdP"' | |
88 | |
88 | |
*/ | |
#if 0 | |
IF_EXTRACT__ (new a, b, string:c[128]; params) | |
{ | |
// Parameters all found. | |
} | |
else | |
{ | |
// Something missing. | |
} | |
new params[54]; | |
if_extract(new a, b, string:c[45], d[5]; params) | |
{ | |
} | |
// Pre-declare variables. | |
new a, b, string:c[45], d[5]; | |
if_extract(a, b, string:c[45], d[5]; params) | |
{ | |
} | |
// Defaults. | |
if_extract(new player:ps[5], hex:e = 7; params) | |
{ | |
} | |
#endif | |
/* | |
88b d88 | |
888b d888 | |
88`8b d8'88 | |
88 `8b d8' 88 ,adPPYYba, ,adPPYba, 8b,dPPYba, ,adPPYba, | |
88 `8b d8' 88 "" `Y8 a8" "" 88P' "Y8 a8" "8a | |
88 `8b d8' 88 ,adPPPPP88 8b 88 8b d8 | |
88 `888' 88 88, ,88 "8a, ,aa 88 "8a, ,a8" | |
88 `8' 88 `"8bbdP"Y8 `"Ybbd8"' 88 `"YbbdP"' | |
*/ | |
// Not the normal `__gOnce` method here, but still works. The other is only limited by the fact | |
// that `__once` is in the middle part of the loop. We have the whole loop to play with here. | |
#define IF_EXTRACT__(%1;%0) for(EXTR@:(__gOnce=0);EXTRP:%1;!__gOnce++)if(!unformat(_:EXTRT:EXTRU:%0,#,%1,,)) | |
#define EXTRP:%9;%1) %1;) | |
#define EXTR@:%9;EXTRP:new%1;%9)if(%3(%4,#,new%5) new%1;__gOnce++;__gOnce=0)if(%3(%4,#,%5) | |
#define EXTRT:EXTRU:%0<%3>%4#,%1,%2) EXTRY:%0%4#P<%3>,|||%1|||%2) | |
#define EXTRU:%0#,%1,%2) EXTRY:%0#,|||%1|||%2) | |
/* | |
88 88 | |
88 ,d 88 | |
88 88 88 | |
88 8b,dPPYba, MM88MMM ,adPPYba, 8b,dPPYba, 8b,dPPYba, ,adPPYYba, 88 | |
88 88P' `"8a 88 a8P_____88 88P' "Y8 88P' `"8a "" `Y8 88 | |
88 88 88 88 8PP""""""" 88 88 88 ,adPPPPP88 88 | |
88 88 88 88, "8b, ,aa 88 88 88 88, ,88 88 | |
88 88 88 "Y888 `"Ybbd8"' 88 88 88 `"8bbdP"Y8 88 | |
*/ | |
// Everything below here is just useful extra stuff. It doesn't actually enable parts of the | |
// `IF_EXTRACT__` macro, just does things like fix "extract" and defines `__once`. | |
#tryinclude <sscanf2> | |
// This macro enables the `#if YSI_KEYWORD()` check below. It just looks for definitions | |
// controlling the addition of new keywords. Note that the metion of `YSI` here is just an pre- | |
// existing convention. This isn't actually part of YSI. | |
#define YSI_KEYWORD(%0) ((defined YSI_COMPATIBILITY_MODE && defined YSI_KEYWORD_%0) || (!defined YSI_COMPATIBILITY_MODE && !defined YSI_NO_KEYWORD_%0)) | |
// Fix a bug in the original `extract`. | |
#if !defined EXTR1 | |
#error Include <sscanf2> before <if_extract>. | |
#endif | |
#undef EXTR1 | |
#define EXTR1:EXTR2:EXTR3:EXTR4:%0#%1,%2|||%3[%7]|||%4) __EXTRW:%0#%1,%2|||%3[%7]|||%4) | |
// Define `if_extract` unless: | |
// | |
// 1) `YSI_COMPATIBILITY_MODE` is defined and `YSI_KEYWORD_if_extract` is NOT. | |
// 2) `YSI_COMPATIBILITY_MODE` is NOT defined and `YSI_NO_KEYWORD_if_extract` is. | |
// | |
// Otherwise only `IF_EXTRACT__` exists. | |
#if YSI_KEYWORD(if_extract) | |
#define if_extract IF_EXTRACT__ | |
#endif | |
// `__once`. A useful "variable" that ensures a `for` loop only runs once. This allows us to use | |
// the loop purely for its scoping abilities and not its repetition abilities. | |
#if !defined __once | |
#define __once%1;%0) (__gOnce++)%1;(%0),__gOnce=0) | |
#define __gOnce++)%1;(), __gOnce++)%1; | |
stock __gOnce = 1; | |
#endif | |
#define for(IF_FAIL:new|||%1;%2) for(IF_PASS:new %1=%2;%1;) | |
#define IF_FAIL:new%0|||%1;%2)%8() ;__once;)%8(new%0 %1=%2 PP_RIGHT_BRACKET<> | |
#define IF_PASS:%3;%4;%9)%8() %3;__once;)%8(%4 PP_RIGHT_BRACKET<> | |
// `if (new a = b)` and `if (new a = b; cond)`. | |
#define IF__(new%0\32;%1=%2) for(IF_FAIL:new%0|||%1;%2)if() | |
#if YSI_KEYWORD(if) | |
#define if(new%0\32;%1=%2) for(IF_FAIL:new%0|||%1;%2)if() | |
#endif | |
// `switch (new a = b)` and `switch (new a = b; cond)`. | |
#define SWITCH__(new%0\32;%1=%2) for(IF_FAIL:new%0|||%1;%2)switch() | |
#if YSI_KEYWORD(switch) | |
#define switch(new%0\32;%1=%2) for(IF_FAIL:new%0|||%1;%2)switch() | |
#endif | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Is the best 👏