Last active
August 29, 2015 14:13
-
-
Save r-lyeh-archived/65c78155b1b8efbb75a3 to your computer and use it in GitHub Desktop.
when/unless/go keywords
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
// when/unless go/unless keywords | |
// - rlyeh | |
#include <functional> | |
#include <iostream> | |
#define when(...) for( std::function<void()> fn; !fn && (__VA_ARGS__ +0); fn() ) fn = [&] | |
#define unless(...) , !(__VA_ARGS__) ? fn : fn = [&] | |
#define go when(true) | |
// sample | |
struct player_t { | |
int type = 0; | |
enum { BATMAN = 0, CATWOMAN = 1 }; | |
bool in_shadow = 0; | |
}; | |
struct enemy_t { | |
int type = 0; | |
int gang = 1; | |
bool something_on_fov = 1; | |
int health = 100; | |
enum { HUMAN = 0, PENGUIN = 1 }; | |
void say( const char *text ) { | |
std::cout << text << std::endl; | |
} | |
}; | |
int main() { | |
player_t player; | |
enemy_t enemy, poison_ivy; | |
// original expression : | |
auto eval = [&] { | |
when( enemy.something_on_fov ) { | |
enemy.say("guys! it's batman!!!"); | |
} | |
unless( !enemy.gang ) { enemy.say("oh no batman! please don't hurt me"); } | |
unless( enemy.type == enemy_t::PENGUIN ) { enemy.say("kwak! kwak! i think i see batman!"); } | |
unless( player.in_shadow ) { enemy.say( "hmmm... i think i see batman!"); } | |
unless( player.type == player_t::CATWOMAN ) { enemy.say("it's the kitty kat!"); } | |
unless( player.type == player_t::CATWOMAN && poison_ivy.health > 0 ) { enemy.say("hey cat, the boss wants a word with you..."); } | |
; | |
}; | |
// gets translated into: | |
auto eval1 = [&] { | |
for( std::function<void()> fn; !fn && (enemy.something_on_fov); fn() ) | |
fn = [&] { | |
enemy.say("guys! it's batman!!!"); | |
} | |
, !( !enemy.gang) ? fn : fn = [&]{ enemy.say("oh no batman! please don't hurt me"); } | |
, !( enemy.type == enemy_t::PENGUIN) ? fn : fn = [&]{ enemy.say("kwak! kwak! i think i see batman!"); } | |
, !( player.in_shadow ) ? fn : fn = [&]{ enemy.say( "hmmm... i think i see batman!"); } | |
, !( player.type == player_t::CATWOMAN) ? fn : fn = [&]{ enemy.say("it's the kitty kat!"); } | |
, !( player.type == player_t::CATWOMAN && poison_ivy.health > 0) ? fn : fn = [&]{ enemy.say("hey cat, the boss wants a word with you..."); } | |
; | |
}; | |
player = player_t(); | |
eval(); | |
player = player_t(); enemy.gang = 0; | |
eval(); | |
player = player_t(); player.in_shadow = 1; | |
eval(); | |
for( unsigned i = 1; i <= 100; ++i ) { | |
go { | |
std::cout << i << ','; | |
} | |
unless( 0 == i % 3 ) { | |
std::cout << "fizz,"; | |
} | |
unless( 0 == i % 5 ) { | |
std::cout << "buzz,"; | |
} | |
unless( 0 == i % 15 ) { | |
std::cout << "fizzbuzz,"; | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment