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;`
|
- Only parses `typedef struct { ... } type_name;`
|
||||||
- Will generate colliding definitions in case of types with the same 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
|
## Quick start
|
||||||
|
|
||||||
|
|||||||
27
cmeta.h
27
cmeta.h
@@ -15,6 +15,15 @@ typedef struct {
|
|||||||
} Struct_Info;
|
} Struct_Info;
|
||||||
|
|
||||||
// AUTO GENERATED CODE //
|
// 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 //
|
// AUTO GENERATED CODE //
|
||||||
|
|
||||||
#ifdef CMETA_COMPTIME
|
#ifdef CMETA_COMPTIME
|
||||||
@@ -229,7 +238,6 @@ char* sv_to_string(String_View sv) {
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TOKEN_IDENT,
|
TOKEN_IDENT,
|
||||||
TOKEN_DQUOTE,
|
|
||||||
TOKEN_OPAREN,
|
TOKEN_OPAREN,
|
||||||
TOKEN_CPAREN,
|
TOKEN_CPAREN,
|
||||||
TOKEN_OCURLY,
|
TOKEN_OCURLY,
|
||||||
@@ -242,9 +250,9 @@ typedef enum {
|
|||||||
} Token_Kind;
|
} Token_Kind;
|
||||||
|
|
||||||
const char* token_kind_to_str(Token_Kind token) {
|
const char* token_kind_to_str(Token_Kind token) {
|
||||||
|
static_assert(__token_kind_count == 9, "Update the token_kind_to_str table");
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case TOKEN_IDENT: return "identifier";
|
case TOKEN_IDENT: return "identifier";
|
||||||
case TOKEN_DQUOTE: return "\"";
|
|
||||||
case TOKEN_OPAREN: return "(";
|
case TOKEN_OPAREN: return "(";
|
||||||
case TOKEN_CPAREN: return ")";
|
case TOKEN_CPAREN: return ")";
|
||||||
case TOKEN_OCURLY: return "{";
|
case TOKEN_OCURLY: return "{";
|
||||||
@@ -255,7 +263,6 @@ const char* token_kind_to_str(Token_Kind token) {
|
|||||||
case TOKEN_EOF: return "EOF";
|
case TOKEN_EOF: return "EOF";
|
||||||
default: assert(false && "Unreachable");
|
default: assert(false && "Unreachable");
|
||||||
}
|
}
|
||||||
static_assert(__token_kind_count == 10, "Update the token_kind_to_str table");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -299,9 +306,19 @@ bool lexer_next(Lexer* lexer, Token* token) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static_assert(__token_kind_count == 9, "Update lexer_next");
|
||||||
switch (lexer->text.data[0]) {
|
switch (lexer->text.data[0]) {
|
||||||
// TODO: while in string, keep calling next
|
// we don't want to parse type definitions in strings
|
||||||
case '"': *token = lexer_make_token(lexer, TOKEN_DQUOTE, 1); return true;
|
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_STAR, 1); return true;
|
||||||
case '(': *token = lexer_make_token(lexer, TOKEN_OPAREN, 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;
|
case ')': *token = lexer_make_token(lexer, TOKEN_CPAREN, 1); return true;
|
||||||
|
|||||||
@@ -15,15 +15,15 @@ typedef struct {
|
|||||||
} Struct_Info;
|
} Struct_Info;
|
||||||
|
|
||||||
// AUTO GENERATED CODE //
|
// AUTO GENERATED CODE //
|
||||||
Struct_Info foo_struct_info = { // cmeta.h:470
|
Struct_Info foo_struct_info = { // cmeta.h:478
|
||||||
.name = "Foo_Struct", // cmeta.h:471
|
.name = "Foo_Struct", // cmeta.h:479
|
||||||
.fields_count = 3, // cmeta.h:472
|
.fields_count = 3, // cmeta.h:480
|
||||||
.fields = (Field_Info[3]) { // cmeta.h:473
|
.fields = (Field_Info[3]) { // cmeta.h:481
|
||||||
{ .type = "int ", .name = "int_field" }, // cmeta.h:475
|
{ .type = "int ", .name = "int_field" }, // cmeta.h:483
|
||||||
{ .type = "char* ", .name = "char_star_field" }, // cmeta.h:475
|
{ .type = "char* ", .name = "char_star_field" }, // cmeta.h:483
|
||||||
{ .type = "const char* ", .name = "const_char_star_field" }, // cmeta.h:475
|
{ .type = "const char* ", .name = "const_char_star_field" }, // cmeta.h:483
|
||||||
}, // cmeta.h:477
|
}, // cmeta.h:485
|
||||||
}; // cmeta.h:478
|
}; // cmeta.h:486
|
||||||
// AUTO GENERATED CODE //
|
// AUTO GENERATED CODE //
|
||||||
|
|
||||||
#ifdef CMETA_COMPTIME
|
#ifdef CMETA_COMPTIME
|
||||||
@@ -238,7 +238,6 @@ char* sv_to_string(String_View sv) {
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TOKEN_IDENT,
|
TOKEN_IDENT,
|
||||||
TOKEN_DQUOTE,
|
|
||||||
TOKEN_OPAREN,
|
TOKEN_OPAREN,
|
||||||
TOKEN_CPAREN,
|
TOKEN_CPAREN,
|
||||||
TOKEN_OCURLY,
|
TOKEN_OCURLY,
|
||||||
@@ -251,9 +250,9 @@ typedef enum {
|
|||||||
} Token_Kind;
|
} Token_Kind;
|
||||||
|
|
||||||
const char* token_kind_to_str(Token_Kind token) {
|
const char* token_kind_to_str(Token_Kind token) {
|
||||||
|
static_assert(__token_kind_count == 9, "Update the token_kind_to_str table");
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case TOKEN_IDENT: return "identifier";
|
case TOKEN_IDENT: return "identifier";
|
||||||
case TOKEN_DQUOTE: return "\"";
|
|
||||||
case TOKEN_OPAREN: return "(";
|
case TOKEN_OPAREN: return "(";
|
||||||
case TOKEN_CPAREN: return ")";
|
case TOKEN_CPAREN: return ")";
|
||||||
case TOKEN_OCURLY: return "{";
|
case TOKEN_OCURLY: return "{";
|
||||||
@@ -264,7 +263,6 @@ const char* token_kind_to_str(Token_Kind token) {
|
|||||||
case TOKEN_EOF: return "EOF";
|
case TOKEN_EOF: return "EOF";
|
||||||
default: assert(false && "Unreachable");
|
default: assert(false && "Unreachable");
|
||||||
}
|
}
|
||||||
static_assert(__token_kind_count == 10, "Update the token_kind_to_str table");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -308,9 +306,19 @@ bool lexer_next(Lexer* lexer, Token* token) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static_assert(__token_kind_count == 9, "Update lexer_next");
|
||||||
switch (lexer->text.data[0]) {
|
switch (lexer->text.data[0]) {
|
||||||
// TODO: while in string, keep calling next
|
// we don't want to parse type definitions in strings
|
||||||
case '"': *token = lexer_make_token(lexer, TOKEN_DQUOTE, 1); return true;
|
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_STAR, 1); return true;
|
||||||
case '(': *token = lexer_make_token(lexer, TOKEN_OPAREN, 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;
|
case ')': *token = lexer_make_token(lexer, TOKEN_CPAREN, 1); return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user