Skip to content

Instantly share code, notes, and snippets.

@Y-Less
Last active February 13, 2022 21:17
Show Gist options
  • Save Y-Less/11be190bc413e7e4b7bcf260d62108e0 to your computer and use it in GitHub Desktop.
Save Y-Less/11be190bc413e7e4b7bcf260d62108e0 to your computer and use it in GitHub Desktop.
#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
@Y-Less
Copy link
Author

Y-Less commented Sep 29, 2019

Is updated 👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment