+static bool parse_directive_or_pragma_do(parser_t *parser, bool *pragma) {
+
+ size_t type = PARSE_DIRECTIVE_COUNT;
+
+ if (!parser_next(parser) || parser->tok != TOKEN_IDENT) {
+ parseerror(parser, "expected `pragma, error, message, warning` after `#`, got `%s`",
+ parser_tokval(parser));
+
+ return false;
+ }
+
+ if (!strcmp(parser_tokval(parser), "pragma" )) {
+ *pragma = true;
+
+ return parse_pragma_do(parser);
+ }
+
+ if (!strcmp(parser_tokval(parser), "error" )) type = PARSE_DIRECTIVE_ERROR;
+ if (!strcmp(parser_tokval(parser), "message")) type = PARSE_DIRECTIVE_MESSAGE;
+ if (!strcmp(parser_tokval(parser), "warning")) type = PARSE_DIRECTIVE_WARNING;
+
+ switch (type) {
+ case PARSE_DIRECTIVE_ERROR:
+ case PARSE_DIRECTIVE_MESSAGE:
+ case PARSE_DIRECTIVE_WARNING:
+ *pragma = false;
+
+ if (!parse_skipwhite(parser) || parser->tok != TOKEN_STRINGCONST) {
+ parseerror(parser, "expected %s, got `%`", parser_directives[type], parser_tokval(parser));
+ return false;
+ }
+
+ switch (type) {
+ case PARSE_DIRECTIVE_ERROR:
+ con_cprintmsg(&parser->lex->tok.ctx, LVL_ERROR, "error", parser_tokval(parser));
+ compile_errors ++; /* hack */
+ break;
+ /*break;*/
+
+ case PARSE_DIRECTIVE_MESSAGE:
+ con_cprintmsg(&parser->lex->tok.ctx, LVL_MSG, "message", parser_tokval(parser));
+ break;
+
+ case PARSE_DIRECTIVE_WARNING:
+ con_cprintmsg(&parser->lex->tok.ctx, LVL_WARNING, "warning", parser_tokval(parser));
+ break;
+ }
+
+ if (!parse_eol(parser)) {
+ parseerror(parser, "parse error after `%` directive", parser_directives[type]);
+ return false;
+ }
+
+ return (type != PARSE_DIRECTIVE_ERROR);
+ }
+
+ parseerror(parser, "invalid directive `%s`", parser_tokval(parser));
+ return false;
+}
+
+static bool parse_directive_or_pragma(parser_t *parser)