Skip to content

Commit 0912982

Browse files
committed
implement ParsePragma for pragma pack
1 parent e8d9bc3 commit 0912982

File tree

3 files changed

+86
-36
lines changed

3 files changed

+86
-36
lines changed

parser/metac_parser.c

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -215,39 +215,6 @@ void AddDefine(metac_parser_t* self, metac_token_t* token, uint32_t nParameters)
215215
}
216216
}
217217
*/
218-
/**
219-
* @param self A pointer to the `metac_parser_t` instance, which holds the current state
220-
* of the parser.
221-
* @param IdentifierKeys An array of uint32_t identifier keys to match against.
222-
* The array must be terminated with a zero (`0`) to indicate its end.
223-
* For example: {0x12345678, 0x87654321, 0xabcdef00, 0}.
224-
*
225-
* @return A pointer to the current `metac_token_t` if a match is found. The parser
226-
* advances to the next token in this case. Returns `NULL` if no match is found
227-
* or if the current token is not an identifier.
228-
*
229-
* @note This function only matches tokens of type `tok_identifier`. If the current token
230-
* is not of this type, the function will return `NULL`.
231-
**/
232-
metac_token_t* MetaCParser_MatchOneOfIdentifierIds(metac_parser_t* self, uint32_t IdentifierKeys[]) {
233-
metac_token_t* currentToken = MetaCParser_PeekToken(self, 1);
234-
235-
if (currentToken && currentToken->TokenType == tok_identifier) {
236-
// Retrieve the current token's identifier key
237-
uint32_t currentIdentifierKey = currentToken->IdentifierKey;
238-
239-
// Iterate over the provided keys and check for a match
240-
for (uint32_t i = 0; IdentifierKeys[i] != 0; i++) {
241-
if (currentIdentifierKey == IdentifierKeys[i]) {
242-
// If a match is found, advance the parser to the next token and return the current token
243-
MetaCParser_Advance(self);
244-
return currentToken;
245-
}
246-
}
247-
}
248-
// If no match is found, return NULL
249-
return NULL;
250-
}
251218

252219
/// checks if the next token is expectedType
253220
/// returns true if it is
@@ -604,6 +571,39 @@ metac_token_t* MetaCParser_NextToken(metac_parser_t* self)
604571
#undef PeekMatch
605572
#undef NextToken
606573

574+
/**
575+
* @param self A pointer to the `metac_parser_t` instance, which holds the current state
576+
* of the parser.
577+
* @param IdentifierKeys An array of uint32_t identifier keys to match against.
578+
* The array must be terminated with a zero (`0`) to indicate its end.
579+
* For example: {0x12345678, 0x87654321, 0xabcdef00, 0}.
580+
*
581+
* @return A pointer to the current `metac_token_t` if a match is found. The parser
582+
* advances to the next token in this case. Returns `NULL` if no match is found
583+
* or if the current token is not an identifier.
584+
*
585+
* @note This function only matches tokens of type `tok_identifier`. If the current token
586+
* is not of this type, the function will return `NULL`.
587+
**/
588+
metac_token_t* MetaCParser_MatchOneOfIdentifierKeys(metac_parser_t* self, uint32_t IdentifierKeys[]) {
589+
metac_token_t* currentToken = MetaCParser_PeekToken(self, 1);
590+
591+
if (currentToken && currentToken->TokenType == tok_identifier) {
592+
uint32_t currentIdentifierKey = currentToken->IdentifierKey;
593+
594+
// Iterate over the provided keys and check for a match
595+
for (uint32_t i = 0; IdentifierKeys[i] != 0; i++) {
596+
if (currentIdentifierKey == IdentifierKeys[i]) {
597+
// If a match is found, advance the parser to the next token and return the current token
598+
MetaCParser_Advance(self);
599+
return currentToken;
600+
}
601+
}
602+
}
603+
// If no match is found, return NULL
604+
return NULL;
605+
}
606+
607607
uint32_t MetaCParser_HowMuchLookahead(metac_parser_t* self)
608608
{
609609
return (self->Lexer->TokenCount - self->CurrentTokenIndex);

parser/metac_preproc.c

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,45 @@ metac_preprocessor_pragma_t MetaCPreProcessor_ParsePragma(metac_preprocessor_t*
911911
metac_token_t* currentToken = 0;
912912

913913
currentToken = MetaCParser_PeekToken(parser, 1);
914-
assert(!"Not Implemented");
914+
currentToken = MetaCParser_PeekToken(parser, 1);
915+
if (currentToken->TokenType == tok_identifier)
916+
{
917+
switch (currentToken->IdentifierKey)
918+
{
919+
case pack_key: {
920+
MetaCParser_Match(parser, tok_identifier);
921+
MetaCParser_Match(parser, tok_lParen);
922+
result.KnownPragma = metac_pragma_pack;
923+
result.PragmaPack.Push = false;
924+
result.PragmaPack.PackN = -1;
925+
uint32_t follow_ids[] = {push_key, pop_key, 0};
926+
if (currentToken = MetaCParser_MatchOneOfIdentifierKeys(parser, follow_ids))
927+
{
928+
switch (currentToken->IdentifierKey)
929+
{
930+
case push_key: {
931+
result.PragmaPack.Push = true;
932+
if (MetaCParser_PeekMatch(parser, tok_comma, true))
933+
{
934+
MetaCParser_Match(parser, tok_comma);
935+
metac_token_t* packSize = MetaCParser_Match(parser, tok_uint);
936+
result.PragmaPack.PackN = cast(int16_t) packSize->ValueU32;
937+
}
938+
} break;
939+
case pop_key : {
940+
} break;
941+
}
942+
} else if (currentToken->TokenType == tok_uint)
943+
{
944+
// assert (0);
945+
}
946+
MetaCParser_Match(parser, tok_rParen);
947+
} break;
948+
}
949+
} else {
950+
assert(!"Not Implemented");
951+
}
952+
915953

916954
return result;
917955
}

parser/metac_preproc.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
#define eval_key 0x45758c
1515
#define va_args_key 0xbc18fc
1616

17-
#define pack_key 0x4b121c
18-
#define push_key 0x42c9f9
17+
#define pack_key 0x4b121c
18+
#define push_key 0x42c9f9
19+
#define pop_key 0x352134
1920

2021
#ifndef _METAC_PREPROC_H_
2122
#define _METAC_PREPROC_H_
@@ -118,10 +119,21 @@ typedef enum metac_preprocessor_pragma_enum_t
118119

119120
#undef WITH_COMMA
120121

122+
typedef struct metac_pragma_pack_t
123+
{
124+
bool Push; // True if new a align is to be pushed
125+
int16_t PackN; // Positive number new align
126+
// 0 means default
127+
// -1 means pop
128+
} metac_pragma_pack_t;
121129

122130
typedef struct metac_preprocessor_pragma_t
123131
{
124132
metac_preprocessor_pragma_enum_t KnownPragma;
133+
union
134+
{
135+
metac_pragma_pack_t PragmaPack;
136+
};
125137
} metac_preprocessor_pragma_t;
126138

127139
typedef struct metac_preprocessor_define_ptr_t

0 commit comments

Comments
 (0)