feat: skip strings
This commit is contained in:
@@ -9,6 +9,7 @@ Single Heaer Meta Programming Header Library for C. The same header for both cod
|
||||
|
||||
- Only parses `typedef struct { ... } type_name;`
|
||||
- Will generate colliding definitions in case of types with the same name
|
||||
- Parsing expects more or less correct code, if you forget a semi it will generating bad code
|
||||
|
||||
## Quick start
|
||||
|
||||
|
||||
27
cmeta.h
27
cmeta.h
@@ -15,6 +15,15 @@ typedef struct {
|
||||
} Struct_Info;
|
||||
|
||||
// AUTO GENERATED CODE //
|
||||
Struct_Info foo_struct_info = { // cmeta.h:478
|
||||
.name = "Foo_Struct", // cmeta.h:479
|
||||
.fields_count = 3, // cmeta.h:480
|
||||
.fields = (Field_Info[3]) { // cmeta.h:481
|
||||
{ .type = "int ", .name = "int_field" }, // cmeta.h:483
|
||||
{ .type = "char* ", .name = "char_star_field" }, // cmeta.h:483
|
||||
{ .type = "const char* ", .name = "const_char_star_field" }, // cmeta.h:483
|
||||
}, // cmeta.h:485
|
||||
}; // cmeta.h:486
|
||||
// AUTO GENERATED CODE //
|
||||
|
||||
#ifdef CMETA_COMPTIME
|
||||
@@ -229,7 +238,6 @@ char* sv_to_string(String_View sv) {
|
||||
|
||||
typedef enum {
|
||||
TOKEN_IDENT,
|
||||
TOKEN_DQUOTE,
|
||||
TOKEN_OPAREN,
|
||||
TOKEN_CPAREN,
|
||||
TOKEN_OCURLY,
|
||||
@@ -242,9 +250,9 @@ typedef enum {
|
||||
} Token_Kind;
|
||||
|
||||
const char* token_kind_to_str(Token_Kind token) {
|
||||
static_assert(__token_kind_count == 9, "Update the token_kind_to_str table");
|
||||
switch (token) {
|
||||
case TOKEN_IDENT: return "identifier";
|
||||
case TOKEN_DQUOTE: return "\"";
|
||||
case TOKEN_OPAREN: return "(";
|
||||
case TOKEN_CPAREN: return ")";
|
||||
case TOKEN_OCURLY: return "{";
|
||||
@@ -255,7 +263,6 @@ const char* token_kind_to_str(Token_Kind token) {
|
||||
case TOKEN_EOF: return "EOF";
|
||||
default: assert(false && "Unreachable");
|
||||
}
|
||||
static_assert(__token_kind_count == 10, "Update the token_kind_to_str table");
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@@ -299,9 +306,19 @@ bool lexer_next(Lexer* lexer, Token* token) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static_assert(__token_kind_count == 9, "Update lexer_next");
|
||||
switch (lexer->text.data[0]) {
|
||||
// TODO: while in string, keep calling next
|
||||
case '"': *token = lexer_make_token(lexer, TOKEN_DQUOTE, 1); return true;
|
||||
// we don't want to parse type definitions in strings
|
||||
case '"': {
|
||||
do {
|
||||
String_View ch = sv_shift(&lexer->text, 1);
|
||||
if (sv_eq_cstr(ch, "\\")) sv_shift(&lexer->text, 1);
|
||||
}
|
||||
while (lexer->text.len > 0 && lexer->text.data[0] != '"');
|
||||
sv_shift(&lexer->text, 1);
|
||||
|
||||
return lexer_next(lexer, token);
|
||||
}
|
||||
case '*': *token = lexer_make_token(lexer, TOKEN_STAR, 1); return true;
|
||||
case '(': *token = lexer_make_token(lexer, TOKEN_OPAREN, 1); return true;
|
||||
case ')': *token = lexer_make_token(lexer, TOKEN_CPAREN, 1); return true;
|
||||
|
||||
@@ -15,15 +15,15 @@ typedef struct {
|
||||
} Struct_Info;
|
||||
|
||||
// AUTO GENERATED CODE //
|
||||
Struct_Info foo_struct_info = { // cmeta.h:470
|
||||
.name = "Foo_Struct", // cmeta.h:471
|
||||
.fields_count = 3, // cmeta.h:472
|
||||
.fields = (Field_Info[3]) { // cmeta.h:473
|
||||
{ .type = "int ", .name = "int_field" }, // cmeta.h:475
|
||||
{ .type = "char* ", .name = "char_star_field" }, // cmeta.h:475
|
||||
{ .type = "const char* ", .name = "const_char_star_field" }, // cmeta.h:475
|
||||
}, // cmeta.h:477
|
||||
}; // cmeta.h:478
|
||||
Struct_Info foo_struct_info = { // cmeta.h:478
|
||||
.name = "Foo_Struct", // cmeta.h:479
|
||||
.fields_count = 3, // cmeta.h:480
|
||||
.fields = (Field_Info[3]) { // cmeta.h:481
|
||||
{ .type = "int ", .name = "int_field" }, // cmeta.h:483
|
||||
{ .type = "char* ", .name = "char_star_field" }, // cmeta.h:483
|
||||
{ .type = "const char* ", .name = "const_char_star_field" }, // cmeta.h:483
|
||||
}, // cmeta.h:485
|
||||
}; // cmeta.h:486
|
||||
// AUTO GENERATED CODE //
|
||||
|
||||
#ifdef CMETA_COMPTIME
|
||||
@@ -238,7 +238,6 @@ char* sv_to_string(String_View sv) {
|
||||
|
||||
typedef enum {
|
||||
TOKEN_IDENT,
|
||||
TOKEN_DQUOTE,
|
||||
TOKEN_OPAREN,
|
||||
TOKEN_CPAREN,
|
||||
TOKEN_OCURLY,
|
||||
@@ -251,9 +250,9 @@ typedef enum {
|
||||
} Token_Kind;
|
||||
|
||||
const char* token_kind_to_str(Token_Kind token) {
|
||||
static_assert(__token_kind_count == 9, "Update the token_kind_to_str table");
|
||||
switch (token) {
|
||||
case TOKEN_IDENT: return "identifier";
|
||||
case TOKEN_DQUOTE: return "\"";
|
||||
case TOKEN_OPAREN: return "(";
|
||||
case TOKEN_CPAREN: return ")";
|
||||
case TOKEN_OCURLY: return "{";
|
||||
@@ -264,7 +263,6 @@ const char* token_kind_to_str(Token_Kind token) {
|
||||
case TOKEN_EOF: return "EOF";
|
||||
default: assert(false && "Unreachable");
|
||||
}
|
||||
static_assert(__token_kind_count == 10, "Update the token_kind_to_str table");
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@@ -308,9 +306,19 @@ bool lexer_next(Lexer* lexer, Token* token) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static_assert(__token_kind_count == 9, "Update lexer_next");
|
||||
switch (lexer->text.data[0]) {
|
||||
// TODO: while in string, keep calling next
|
||||
case '"': *token = lexer_make_token(lexer, TOKEN_DQUOTE, 1); return true;
|
||||
// we don't want to parse type definitions in strings
|
||||
case '"': {
|
||||
do {
|
||||
String_View ch = sv_shift(&lexer->text, 1);
|
||||
if (sv_eq_cstr(ch, "\\")) sv_shift(&lexer->text, 1);
|
||||
}
|
||||
while (lexer->text.len > 0 && lexer->text.data[0] != '"');
|
||||
sv_shift(&lexer->text, 1);
|
||||
|
||||
return lexer_next(lexer, token);
|
||||
}
|
||||
case '*': *token = lexer_make_token(lexer, TOKEN_STAR, 1); return true;
|
||||
case '(': *token = lexer_make_token(lexer, TOKEN_OPAREN, 1); return true;
|
||||
case ')': *token = lexer_make_token(lexer, TOKEN_CPAREN, 1); return true;
|
||||
|
||||
Reference in New Issue
Block a user