Added basic pragma parsing

Actual contents of the pragma are currently just discarded. This
supports both #pragma and _Pragma() definitions, but the pragma must end
the line it is on and cannot be in the middle of a statement.
This commit is contained in:
Russell Joyce 2020-06-09 19:21:00 +01:00
parent a96902717c
commit 9abf00e2d3
No known key found for this signature in database
GPG key ID: 3D46BD9018AF7B72
6 changed files with 44 additions and 5 deletions

19
c-tests/pragma.c Normal file
View file

@ -0,0 +1,19 @@
int a;
#pragma test1
int b;
_Pragma( "test2" )
int main(void) {
a = 0;
#pragma test3
b = 1;
_Pragma("test4")
return a;
}

View file

@ -175,7 +175,9 @@ enum LexToken {
TokenEndOfLine, TokenEndOfLine,
TokenEndOfFunction, TokenEndOfFunction,
TokenBackSlash, TokenBackSlash,
TokenVolatileType TokenVolatileType,
TokenHashPragma,
TokenUnderscorePragma
}; };
/* used in dynamic memory allocation */ /* used in dynamic memory allocation */

6
lex.c
View file

@ -94,7 +94,9 @@ static struct ReservedWord ReservedWords[] = {
{"unsigned", TokenUnsignedType}, {"unsigned", TokenUnsignedType},
{"void", TokenVoidType}, {"void", TokenVoidType},
{"while", TokenWhile}, {"while", TokenWhile},
{"volatile", TokenVolatileType} {"volatile", TokenVolatileType},
{"#pragma", TokenHashPragma},
{"_Pragma", TokenUnderscorePragma}
}; };
@ -849,7 +851,7 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value,
#ifdef DEBUG_LEXER #ifdef DEBUG_LEXER
printf("Got token=%02x inc=%d pos=%d\n", Token, IncPos, Parser->CharacterPos); printf("Got token=%02x inc=%d pos=%d\n", Token, IncPos, Parser->CharacterPos);
#endif #endif
assert(Token >= TokenNone && Token <= TokenVolatileType); assert(Token >= TokenNone && Token <= TokenUnderscorePragma);
return Token; return Token;
} }

14
parse.c
View file

@ -12,6 +12,7 @@ static void ParseDeclarationAssignment(struct ParseState *Parser,
struct Value *NewVariable, int DoAssignment); struct Value *NewVariable, int DoAssignment);
static int ParseDeclaration(struct ParseState *Parser, enum LexToken Token); static int ParseDeclaration(struct ParseState *Parser, enum LexToken Token);
static void ParseMacroDefinition(struct ParseState *Parser); static void ParseMacroDefinition(struct ParseState *Parser);
static void ParsePragma(struct ParseState *Parser);
static void ParseFor(struct ParseState *Parser); static void ParseFor(struct ParseState *Parser);
static enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace, static enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace,
int Condition); int Condition);
@ -451,6 +452,14 @@ void ParseMacroDefinition(struct ParseState *Parser)
ProgramFail(Parser, "'%s' is already defined", MacroNameStr); ProgramFail(Parser, "'%s' is already defined", MacroNameStr);
} }
/* parse a pragma */
void ParsePragma(struct ParseState *Parser)
{
/* consume tokens until we hit the end of a line */
/* (not ideal for _Pragma() but it'll do for now) */
LexToEndOfMacro(Parser);
}
/* copy the entire parser state */ /* copy the entire parser state */
void ParserCopy(struct ParseState *To, struct ParseState *From) void ParserCopy(struct ParseState *To, struct ParseState *From)
{ {
@ -853,6 +862,11 @@ enum ParseResult ParseStatement(struct ParseState *Parser,
} }
break; break;
} }
case TokenHashPragma:
case TokenUnderscorePragma:
ParsePragma(Parser);
CheckTrailingSemicolon = false;
break;
default: default:
*Parser = PreState; *Parser = PreState;
return ParseResultError; return ParseResultError;

View file

@ -112,7 +112,9 @@ struct LexTokenStat LexTokenStats[NO_TOKENS] = {
{"TokenEndOfLine", {0, 0, 0, 0, 0, 0, 0}}, {"TokenEndOfLine", {0, 0, 0, 0, 0, 0, 0}},
{"TokenEndOfFunction", {0, 0, 0, 0, 0, 0, 0}}, {"TokenEndOfFunction", {0, 0, 0, 0, 0, 0, 0}},
{"TokenBackSlash", {0, 0, 0, 0, 0, 0, 0}}, {"TokenBackSlash", {0, 0, 0, 0, 0, 0, 0}},
{"TokenVolatileType", {0, 0, 0, 0, 0, 0, 0}} {"TokenVolatileType", {0, 0, 0, 0, 0, 0, 0}},
{"TokenHashPragma", {0, 0, 0, 0, 0, 0, 0}},
{"TokenUnderscorePragma", {0, 0, 0, 0, 0, 0, 0}}
}; };

View file

@ -8,7 +8,7 @@
#include "interpreter.h" #include "interpreter.h"
#define NO_RUN_MODES 7 #define NO_RUN_MODES 7
#define NO_TOKENS 98 #define NO_TOKENS 100
extern const char *RunModeNames[NO_RUN_MODES]; extern const char *RunModeNames[NO_RUN_MODES];