mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-02-17 09:02:25 +00:00
Parsing noref-pragma
This commit is contained in:
parent
ea08d16c06
commit
88a4721de7
2 changed files with 78 additions and 0 deletions
2
lexer.c
2
lexer.c
|
@ -492,6 +492,7 @@ unroll:
|
||||||
vec_pop(command);
|
vec_pop(command);
|
||||||
}
|
}
|
||||||
vec_free(command);
|
vec_free(command);
|
||||||
|
lex_ungetch(lex, ' ');
|
||||||
}
|
}
|
||||||
if (command) {
|
if (command) {
|
||||||
vec_pop(command);
|
vec_pop(command);
|
||||||
|
@ -500,6 +501,7 @@ unroll:
|
||||||
vec_pop(command);
|
vec_pop(command);
|
||||||
}
|
}
|
||||||
vec_free(command);
|
vec_free(command);
|
||||||
|
lex_ungetch(lex, ' ');
|
||||||
}
|
}
|
||||||
if (pragma) {
|
if (pragma) {
|
||||||
vec_pop(pragma);
|
vec_pop(pragma);
|
||||||
|
|
76
parser.c
76
parser.c
|
@ -93,6 +93,9 @@ typedef struct {
|
||||||
* we shall trigger -Wternary-precedence.
|
* we shall trigger -Wternary-precedence.
|
||||||
*/
|
*/
|
||||||
enum { POT_PAREN, POT_TERNARY1, POT_TERNARY2 } *pot;
|
enum { POT_PAREN, POT_TERNARY1, POT_TERNARY2 } *pot;
|
||||||
|
|
||||||
|
/* pragma flags */
|
||||||
|
bool noref;
|
||||||
} parser_t;
|
} parser_t;
|
||||||
|
|
||||||
static void parser_enterblock(parser_t *parser);
|
static void parser_enterblock(parser_t *parser);
|
||||||
|
@ -2398,6 +2401,75 @@ static bool parse_goto(parser_t *parser, ast_expression **out)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool parse_skipwhite(parser_t *parser)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
if (!parser_next(parser))
|
||||||
|
return false;
|
||||||
|
} while (parser->tok == TOKEN_WHITE && parser->tok < TOKEN_ERROR);
|
||||||
|
return parser->tok < TOKEN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool parse_eol(parser_t *parser)
|
||||||
|
{
|
||||||
|
if (!parse_skipwhite(parser))
|
||||||
|
return false;
|
||||||
|
return parser->tok == TOKEN_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool parse_pragma_do(parser_t *parser)
|
||||||
|
{
|
||||||
|
if (!parser_next(parser) ||
|
||||||
|
parser->tok != TOKEN_IDENT ||
|
||||||
|
strcmp(parser_tokval(parser), "pragma"))
|
||||||
|
{
|
||||||
|
parseerror(parser, "expected `pragma` keyword after `#`, got `%s`", parser_tokval(parser));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!parse_skipwhite(parser) || parser->tok != TOKEN_IDENT) {
|
||||||
|
parseerror(parser, "expected pragma, got `%s`", parser_tokval(parser));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(parser_tokval(parser), "noref")) {
|
||||||
|
if (!parse_skipwhite(parser) || parser->tok != TOKEN_INTCONST) {
|
||||||
|
parseerror(parser, "`noref` pragma requires an argument: 0 or 1");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
parser->noref = !!parser_token(parser)->constval.i;
|
||||||
|
if (!parse_eol(parser)) {
|
||||||
|
parseerror(parser, "parse error after `noref` pragma");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parseerror(parser, "unrecognized hash-keyword: `%s`", parser_tokval(parser));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool parse_pragma(parser_t *parser)
|
||||||
|
{
|
||||||
|
bool rv;
|
||||||
|
parser->lex->flags.preprocessing = true;
|
||||||
|
parser->lex->flags.mergelines = true;
|
||||||
|
rv = parse_pragma_do(parser);
|
||||||
|
if (parser->tok != TOKEN_EOL) {
|
||||||
|
parseerror(parser, "junk after pragma");
|
||||||
|
rv = false;
|
||||||
|
}
|
||||||
|
parser->lex->flags.preprocessing = false;
|
||||||
|
parser->lex->flags.mergelines = false;
|
||||||
|
if (!parser_next(parser)) {
|
||||||
|
parseerror(parser, "parse error after pragma");
|
||||||
|
rv = false;
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out, bool allow_cases)
|
static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out, bool allow_cases)
|
||||||
{
|
{
|
||||||
int cvq;
|
int cvq;
|
||||||
|
@ -4266,6 +4338,10 @@ static bool parser_global_statement(parser_t *parser)
|
||||||
parseerror(parser, "unrecognized keyword `%s`", parser_tokval(parser));
|
parseerror(parser, "unrecognized keyword `%s`", parser_tokval(parser));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (parser->tok == '#')
|
||||||
|
{
|
||||||
|
return parse_pragma(parser);
|
||||||
|
}
|
||||||
else if (parser->tok == '$')
|
else if (parser->tok == '$')
|
||||||
{
|
{
|
||||||
if (!parser_next(parser)) {
|
if (!parser_next(parser)) {
|
||||||
|
|
Loading…
Reference in a new issue