Skip to content

Instantly share code, notes, and snippets.

@greggman
Created January 10, 2013 19:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save greggman/4504831 to your computer and use it in GitHub Desktop.
Save greggman/4504831 to your computer and use it in GitHub Desktop.
D.R.Y. people should love macro lists
// Seems like anyone who follows the "Don't Repeat Yourself" principle
// should be into macro lists
#define COMMANDS(OP) \
OP(Jump) \
OP(Call) \
OP(Return) \
OP(Noop) \
OP(Add) \
// Make enum
#define COMMAND_OP(name) name,
enum CommandId
{
Commands(MAKE_ENUM)
LAST_COMMAND,
};
#undef COMMAND_OP
// For debugging, make a command to string function.
const char* GetCommandString(CommandId command)
{
#define COMMAND_OP(name) #name,
static const char* command_names[] = {
COMMANDS(COMMAND_OP)
};
#undef COMMAND_OP
return (command >= 0 && command < LAST_COMMAND)
? command_names[command]
: "**unknown command**"
}
typedef bool (*CommandFn)(ExecutionContext*);
// pre-declare functions
#define COMMAND_OP(name) \
extern bool Handle ## name(E)(ExecutionContext* ec);
COMMANDS(COMMAND_OP)
#undef COMMAND_OP
bool ProcessCommand(CommandId command, ExecutionContext* ec)
{
// Make jump table
#define COMMAND_OP(name) Handle ## name,
static CommandFn command_jump_table[] =
{
COMMANDS(COMMAND_OP)
};
#undef COMMAND_OP
if (g_debug)
{
Logf("%s\n", GetCommandString(command));
}
ASSERT(command >= 0 && command < LAST_COMMAND);
return command_jump_table[command](ec);
}
// Now all you need to do is implement each command.
// Adding a command you only have to edit 1 place, the
// COMMANDS macro and then add a function 'HandleNameOfCommand'
// where as without the COMMANDS macro you'd have to repeat
// yourself in 4 places.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment