now using the meta unit on internal_4coder_string.cpp and 4ed_api_implementation.cpp
							parent
							
								
									46bddd14b7
								
							
						
					
					
						commit
						a1afaa0e40
					
				
							
								
								
									
										628
									
								
								4ed_metagen.cpp
								
								
								
								
							
							
						
						
									
										628
									
								
								4ed_metagen.cpp
								
								
								
								
							|  | @ -366,11 +366,14 @@ typedef struct Documentation{ | |||
| typedef enum Item_Type{ | ||||
|     Item_Null, | ||||
|     Item_Function, | ||||
|     Item_CppName, | ||||
|     Item_Macro, | ||||
|     Item_Typedef, | ||||
|     Item_Struct, | ||||
|     Item_Union, | ||||
|     Item_Enum, | ||||
|     Item_Type_Count, | ||||
| #define Item_Type_User0 Item_Type_Count | ||||
| } Item_Type; | ||||
| 
 | ||||
| typedef struct Item_Node{ | ||||
|  | @ -403,6 +406,7 @@ typedef struct Item_Set{ | |||
| typedef struct Parse{ | ||||
|     String code; | ||||
|     Cpp_Token_Stack tokens; | ||||
|     int32_t item_count; | ||||
| } Parse; | ||||
| 
 | ||||
| typedef struct Meta_Unit{ | ||||
|  | @ -939,8 +943,7 @@ struct_parse_next_member(Partition *part, Parse_Context *context){ | |||
| } | ||||
| 
 | ||||
| static int32_t | ||||
| struct_parse(Partition *part, int32_t is_struct, | ||||
|              Parse_Context *context, Item_Node *top_member){ | ||||
| struct_parse(Partition *part, int32_t is_struct, Parse_Context *context, Item_Node *top_member){ | ||||
|      | ||||
|     int32_t result = false; | ||||
|      | ||||
|  | @ -1177,116 +1180,6 @@ enum_parse(Partition *part, Parse_Context *context, Item_Node *item){ | |||
|     return(result); | ||||
| } | ||||
| 
 | ||||
| static Meta_Unit | ||||
| compile_meta_unit(Partition *part, char **files, int32_t file_count, | ||||
|                   Meta_Keywords *keywords, int32_t key_count){ | ||||
|     Meta_Unit unit = {0}; | ||||
|     int32_t i = 0; | ||||
|      | ||||
|     unit.count = file_count; | ||||
|     unit.parse = push_array(part, Parse, file_count); | ||||
|      | ||||
|     for (i = 0; i < file_count; ++i){ | ||||
|         unit.parse[i] = meta_lex(files[i]); | ||||
|     } | ||||
|      | ||||
|     // TODO(allen): This stage counts nested structs
 | ||||
|     // and unions which is not correct.  Luckily it only
 | ||||
|     // means we over allocate by a few items, but fixing it
 | ||||
|     // to be exactly correct would be nice.
 | ||||
|     for (int32_t J = 0; J < unit.count; ++J){ | ||||
|         Cpp_Token *token = 0; | ||||
|         Parse_Context context_ = setup_parse_context(unit.parse[J]); | ||||
|         Parse_Context *context = &context_; | ||||
|          | ||||
|         for (; (token = get_token(context)) != 0; get_next_token(context)){ | ||||
|             if (!(token->flags & CPP_TFLAG_PP_BODY) && | ||||
|                 ((token->flags & CPP_TFLAG_IS_KEYWORD) || | ||||
|                  token->type == CPP_TOKEN_IDENTIFIER)){ | ||||
|                  | ||||
|                 String lexeme = get_lexeme(*token, context->data); | ||||
|                 int32_t match_index = 0; | ||||
|                 if (string_set_match_table(keywords, sizeof(*keywords), key_count, lexeme, &match_index)){ | ||||
|                     switch (match_index){ | ||||
|                         case 0: //typedef
 | ||||
|                         case 1: case 2: //struct/union
 | ||||
|                         case 3: //ENUM
 | ||||
|                         ++unit.set.count; break; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     if (unit.set.count >  0){ | ||||
|         unit.set = allocate_item_set(part, unit.set.count); | ||||
|     } | ||||
|      | ||||
|     int32_t index = 0; | ||||
|      | ||||
|     for (int32_t J = 0; J < unit.count; ++J){ | ||||
|         Cpp_Token *token = 0; | ||||
|         Parse_Context context_ = setup_parse_context(unit.parse[J]); | ||||
|         Parse_Context *context = &context_; | ||||
|          | ||||
|         for (; (token = get_token(context)) != 0; get_next_token(context)){ | ||||
|             if (!(token->flags & CPP_TFLAG_PP_BODY) && | ||||
|                 ((token->flags & CPP_TFLAG_IS_KEYWORD) || | ||||
|                  token->type == CPP_TOKEN_IDENTIFIER)){ | ||||
|                  | ||||
|                 String lexeme = get_lexeme(*token, context->data); | ||||
|                 int32_t match_index = 0; | ||||
|                 if (string_set_match_table(keywords, sizeof(*keywords), key_count, lexeme, &match_index)){ | ||||
|                     switch (match_index){ | ||||
|                         case 0: //typedef
 | ||||
|                         { | ||||
|                             if (typedef_parse(context, unit.set.items + index)){ | ||||
|                                 Assert(unit.set.items[index].t == Item_Typedef); | ||||
|                                 ++index; | ||||
|                             } | ||||
|                             else{ | ||||
|                                 InvalidPath; | ||||
|                             } | ||||
|                         }break; | ||||
|                          | ||||
|                         case 1: case 2: //struct/union
 | ||||
|                         { | ||||
|                             if (struct_parse(part, (match_index == 1), | ||||
|                                              context, unit.set.items + index)){ | ||||
|                                 Assert(unit.set.items[index].t == Item_Struct || | ||||
|                                        unit.set.items[index].t == Item_Union); | ||||
|                                 ++index; | ||||
|                             } | ||||
|                             else{ | ||||
|                                 InvalidPath; | ||||
|                             } | ||||
|                         }break; | ||||
|                          | ||||
|                         case 3: //ENUM
 | ||||
|                         { | ||||
|                             if (enum_parse(part, context, unit.set.items + index)){ | ||||
|                                 Assert(unit.set.items[index].t == Item_Enum); | ||||
|                                 ++index; | ||||
|                             } | ||||
|                             else{ | ||||
|                                 InvalidPath; | ||||
|                             } | ||||
|                         }break; | ||||
|                          | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         // NOTE(allen): This is necessary for now because
 | ||||
|         // the original count is slightly overestimated thanks
 | ||||
|         // to nested structs and unions.
 | ||||
|         unit.set.count = index; | ||||
|     } | ||||
|      | ||||
|     return(unit); | ||||
| } | ||||
| 
 | ||||
| static Argument_Breakdown | ||||
| allocate_argument_breakdown(Partition *part, int32_t count){ | ||||
|     Argument_Breakdown breakdown = {0}; | ||||
|  | @ -1417,7 +1310,7 @@ function_get_doc(Parse_Context *context, char *data, String *doc_string){ | |||
| } | ||||
| 
 | ||||
| static int32_t | ||||
| parse_cpp_name(Parse_Context *context, char *data, String *name){ | ||||
| cpp_name_parse(Parse_Context *context, String *name){ | ||||
|     int32_t result = false; | ||||
|      | ||||
|     Cpp_Token *token = 0; | ||||
|  | @ -1429,7 +1322,7 @@ parse_cpp_name(Parse_Context *context, char *data, String *name){ | |||
|         if (token && token->type == CPP_TOKEN_IDENTIFIER){ | ||||
|             token = get_next_token(context); | ||||
|             if (token && token->type == CPP_TOKEN_PARENTHESE_CLOSE){ | ||||
|                 *name = get_lexeme(*(token-1), data); | ||||
|                 *name = get_lexeme(*(token-1), context->data); | ||||
|                 result = true; | ||||
|             } | ||||
|         } | ||||
|  | @ -1448,11 +1341,9 @@ Moves the context in the following way: | |||
|  ^  --------------->  ^ | ||||
| */ | ||||
| static int32_t | ||||
| function_sig_parse(Partition *part, Parse_Context *context, | ||||
|                    char *data, Item_Set item_set, int32_t sig_count, String cpp_name){ | ||||
| function_sig_parse(Partition *part, Parse_Context *context, Item_Node *item, String cpp_name){ | ||||
|     int32_t result = false; | ||||
|      | ||||
|     int32_t size = 0; | ||||
|     Cpp_Token *token = 0; | ||||
|     Cpp_Token *args_start_token = 0; | ||||
|     Cpp_Token *ret_token = get_token(context); | ||||
|  | @ -1460,11 +1351,11 @@ function_sig_parse(Partition *part, Parse_Context *context, | |||
|     if (function_parse_goto_name(context)){ | ||||
|         token = get_token(context); | ||||
|         args_start_token = token+1; | ||||
|         item_set.items[sig_count].name = get_lexeme(*token, data); | ||||
|         item->name = get_lexeme(*token, context->data); | ||||
|          | ||||
|         size = token->start - ret_token->start; | ||||
|         item_set.items[sig_count].ret = | ||||
|             chop_whitespace(make_string(data + ret_token->start, size)); | ||||
|         item->ret = chop_whitespace( | ||||
|             get_string(context->data, ret_token->start, token->start) | ||||
|             ); | ||||
|          | ||||
|         for (; (token = get_token(context)) != 0; get_next_token(context)){ | ||||
|             if (token->type == CPP_TOKEN_PARENTHESE_CLOSE){ | ||||
|  | @ -1473,13 +1364,11 @@ function_sig_parse(Partition *part, Parse_Context *context, | |||
|         } | ||||
|          | ||||
|         if (token){ | ||||
|             size = token->start + token->size - args_start_token->start;; | ||||
|             item_set.items[sig_count].args = | ||||
|                 make_string(data + args_start_token->start, size); | ||||
|             item_set.items[sig_count].t = Item_Function; | ||||
|             item_set.items[sig_count].cpp_name = cpp_name; | ||||
|             item_set.items[sig_count].breakdown = | ||||
|                 parameter_parse(part, data, args_start_token, token); | ||||
|             item->args = | ||||
|                 get_string(context->data, args_start_token->start, token->start + token->size); | ||||
|             item->t = Item_Function; | ||||
|             item->cpp_name = cpp_name; | ||||
|             item->breakdown = parameter_parse(part, context->data, args_start_token, token); | ||||
|              | ||||
|             Assert(get_token(context)->type == CPP_TOKEN_PARENTHESE_CLOSE); | ||||
|             result = true; | ||||
|  | @ -1495,22 +1384,21 @@ Moves the context in the following way: | |||
|  ^  ------------------->  ^ | ||||
| */ | ||||
| static int32_t | ||||
| function_parse(Partition *part, Parse_Context *context, | ||||
|                char *data, Item_Set item_set, int32_t sig_count, String cpp_name){ | ||||
| function_parse(Partition *part, Parse_Context *context, Item_Node *item, String cpp_name){ | ||||
|     int32_t result = false; | ||||
|      | ||||
|     String doc_string = {0}; | ||||
|     Cpp_Token *token = get_token(context); | ||||
|      | ||||
|     item_set.items[sig_count].marker = get_lexeme(*token, data); | ||||
|     item->marker = get_lexeme(*token, context->data); | ||||
|      | ||||
|     if (function_get_doc(context, data, &doc_string)){ | ||||
|         item_set.items[sig_count].doc_string = doc_string; | ||||
|     if (function_get_doc(context, context->data, &doc_string)){ | ||||
|         item->doc_string = doc_string; | ||||
|     } | ||||
|      | ||||
|     set_token(context, token); | ||||
|     if (get_next_token(context)){ | ||||
|         if (function_sig_parse(part, context, data, item_set, sig_count, cpp_name)){ | ||||
|         if (function_sig_parse(part, context, item, cpp_name)){ | ||||
|             Assert(get_token(context)->type == CPP_TOKEN_PARENTHESE_CLOSE); | ||||
|             result = true; | ||||
|         } | ||||
|  | @ -1549,8 +1437,7 @@ Moves the context in the following way: | |||
|  ^  ---------------------------->  ^ | ||||
| */ | ||||
| static int32_t | ||||
| macro_parse(Partition *part, Parse_Context *context, | ||||
|             char *data, Item_Set item_set, int32_t sig_count){ | ||||
| macro_parse(Partition *part, Parse_Context *context, Item_Node *item){ | ||||
|     int32_t result = false; | ||||
|      | ||||
|     Cpp_Token *token = 0; | ||||
|  | @ -1564,10 +1451,10 @@ macro_parse(Partition *part, Parse_Context *context, | |||
|         if (can_back_step(context)){ | ||||
|             doc_token = token-1; | ||||
|              | ||||
|             doc_string = get_lexeme(*doc_token, data); | ||||
|             doc_string = get_lexeme(*doc_token, context->data); | ||||
|              | ||||
|             if (check_and_fix_docs(&doc_string)){ | ||||
|                 item_set.items[sig_count].doc_string = doc_string; | ||||
|                 item->doc_string = doc_string; | ||||
|                  | ||||
|                 for (; (token = get_token(context)) != 0; get_next_token(context)){ | ||||
|                     if (token->type == CPP_TOKEN_IDENTIFIER){ | ||||
|  | @ -1576,7 +1463,7 @@ macro_parse(Partition *part, Parse_Context *context, | |||
|                 } | ||||
|                  | ||||
|                 if (get_token(context) && (token->flags & CPP_TFLAG_PP_BODY)){ | ||||
|                     item_set.items[sig_count].name = get_lexeme(*token, data); | ||||
|                     item->name = get_lexeme(*token, context->data); | ||||
|                      | ||||
|                     if ((token = get_next_token(context)) != 0){ | ||||
|                         args_start_token = token; | ||||
|  | @ -1587,12 +1474,10 @@ macro_parse(Partition *part, Parse_Context *context, | |||
|                         } | ||||
|                          | ||||
|                         if (token){ | ||||
|                             int32_t start = args_start_token->start; | ||||
|                             int32_t end = token->start + token->size; | ||||
|                             item_set.items[sig_count].args = make_string(data + start, end - start); | ||||
|                             item->args = get_string(context->data, args_start_token->start, | ||||
|                                                     token->start + token->size); | ||||
|                              | ||||
|                             item_set.items[sig_count].breakdown = | ||||
|                                 parameter_parse(part, data, args_start_token, token); | ||||
|                             item->breakdown = parameter_parse(part, context->data, args_start_token, token); | ||||
|                              | ||||
|                             if ((token = get_next_token(context)) != 0){ | ||||
|                                 Cpp_Token *body_start = token; | ||||
|  | @ -1606,13 +1491,13 @@ macro_parse(Partition *part, Parse_Context *context, | |||
|                                      | ||||
|                                     token = get_prev_token(context); | ||||
|                                      | ||||
|                                     start = body_start->start; | ||||
|                                     end = token->start + token->size; | ||||
|                                     item_set.items[sig_count].body = make_string(data + start, end - start); | ||||
|                                     item->body = | ||||
|                                         get_string(context->data, body_start->start, | ||||
|                                                    token->start + token->size); | ||||
|                                 } | ||||
|                             } | ||||
|                              | ||||
|                             item_set.items[sig_count].t = Item_Macro; | ||||
|                             item->t = Item_Macro; | ||||
|                             result = true; | ||||
|                         } | ||||
|                     } | ||||
|  | @ -1624,6 +1509,161 @@ macro_parse(Partition *part, Parse_Context *context, | |||
|     return(result); | ||||
| } | ||||
| 
 | ||||
| static Meta_Unit | ||||
| compile_meta_unit(Partition *part, char **files, int32_t file_count, | ||||
|                   Meta_Keywords *keywords, int32_t key_count){ | ||||
|     Meta_Unit unit = {0}; | ||||
|     int32_t i = 0; | ||||
|      | ||||
|     unit.count = file_count; | ||||
|     unit.parse = push_array(part, Parse, file_count); | ||||
|      | ||||
|     for (i = 0; i < file_count; ++i){ | ||||
|         unit.parse[i] = meta_lex(files[i]); | ||||
|     } | ||||
|      | ||||
|     // TODO(allen): This stage counts nested structs
 | ||||
|     // and unions which is not correct.  Luckily it only
 | ||||
|     // means we over allocate by a few items, but fixing it
 | ||||
|     // to be exactly correct would be nice.
 | ||||
|     for (int32_t J = 0; J < unit.count; ++J){ | ||||
|         Cpp_Token *token = 0; | ||||
|         Parse_Context context_ = setup_parse_context(unit.parse[J]); | ||||
|         Parse_Context *context = &context_; | ||||
|          | ||||
|         for (; (token = get_token(context)) != 0; get_next_token(context)){ | ||||
|             if (!(token->flags & CPP_TFLAG_PP_BODY)){ | ||||
|                  | ||||
|                 String lexeme = get_lexeme(*token, context->data); | ||||
|                 int32_t match_index = 0; | ||||
|                 if (string_set_match_table(keywords, sizeof(*keywords), key_count, lexeme, &match_index)){ | ||||
|                     Item_Type type = keywords[match_index].type; | ||||
|                      | ||||
|                     if (type > Item_Null && type < Item_Type_Count){ | ||||
|                         ++unit.set.count; | ||||
|                     } | ||||
|                     else{ | ||||
|                         // TODO(allen): Convert this to a duff's routine and return
 | ||||
|                         // this result to the user so that they may do whatever it
 | ||||
|                         // is they want to do.
 | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     if (unit.set.count >  0){ | ||||
|         unit.set = allocate_item_set(part, unit.set.count); | ||||
|     } | ||||
|      | ||||
|     int32_t index = 0; | ||||
|      | ||||
|     for (int32_t J = 0; J < unit.count; ++J){ | ||||
|         Cpp_Token *token = 0; | ||||
|         Parse_Context context_ = setup_parse_context(unit.parse[J]); | ||||
|         Parse_Context *context = &context_; | ||||
|          | ||||
|         String cpp_name = {0}; | ||||
|         int32_t has_cpp_name = 0; | ||||
|          | ||||
|         for (; (token = get_token(context)) != 0; get_next_token(context)){ | ||||
|             if (!(token->flags & CPP_TFLAG_PP_BODY)){ | ||||
|                  | ||||
|                 String lexeme = get_lexeme(*token, context->data); | ||||
|                 int32_t match_index = 0; | ||||
|                 if (string_set_match_table(keywords, sizeof(*keywords), key_count, lexeme, &match_index)){ | ||||
|                     Item_Type type = keywords[match_index].type; | ||||
|                      | ||||
|                     switch (type){ | ||||
|                         case Item_Function: | ||||
|                         { | ||||
|                             if (function_parse(part, context, unit.set.items + index, cpp_name)){ | ||||
|                                 Assert(unit.set.items[index].t == Item_Function); | ||||
|                                 ++index; | ||||
|                             } | ||||
|                             else{ | ||||
|                                 fprintf(stderr, "warning : invalid function signature\n"); | ||||
|                             } | ||||
|                         }break; | ||||
|                          | ||||
|                         case Item_CppName: | ||||
|                         { | ||||
|                             if (cpp_name_parse(context, &cpp_name)){ | ||||
|                                 has_cpp_name = 1; | ||||
|                             } | ||||
|                             else{ | ||||
|                                 // TODO(allen): warning message
 | ||||
|                             } | ||||
|                         }break; | ||||
|                          | ||||
|                         case Item_Macro: | ||||
|                         { | ||||
|                             if (macro_parse(part, context, unit.set.items + index)){ | ||||
|                                 Assert(unit.set.items[index].t == Item_Macro); | ||||
|                                 ++index; | ||||
|                             } | ||||
|                             else{ | ||||
|                                 // TODO(allen): warning message
 | ||||
|                             } | ||||
|                         }break; | ||||
|                          | ||||
|                         case Item_Typedef: //typedef
 | ||||
|                         { | ||||
|                             if (typedef_parse(context, unit.set.items + index)){ | ||||
|                                 Assert(unit.set.items[index].t == Item_Typedef); | ||||
|                                 ++index; | ||||
|                             } | ||||
|                             else{ | ||||
|                                 // TODO(allen): warning message
 | ||||
|                             } | ||||
|                         }break; | ||||
|                          | ||||
|                         case Item_Struct: case Item_Union: //struct/union
 | ||||
|                         { | ||||
|                             if (struct_parse(part, (type == Item_Struct), context, unit.set.items + index)){ | ||||
|                                 Assert(unit.set.items[index].t == Item_Struct || | ||||
|                                        unit.set.items[index].t == Item_Union); | ||||
|                                 ++index; | ||||
|                             } | ||||
|                             else{ | ||||
|                                 // TODO(allen): warning message
 | ||||
|                             } | ||||
|                         }break; | ||||
|                          | ||||
|                         case Item_Enum: //ENUM
 | ||||
|                         { | ||||
|                             if (enum_parse(part, context, unit.set.items + index)){ | ||||
|                                 Assert(unit.set.items[index].t == Item_Enum); | ||||
|                                 ++index; | ||||
|                             } | ||||
|                             else{ | ||||
|                                 // TODO(allen): warning message
 | ||||
|                             } | ||||
|                         }break; | ||||
|                          | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|              | ||||
|             if (has_cpp_name){ | ||||
|                 has_cpp_name = 0; | ||||
|             } | ||||
|             else{ | ||||
|                 cpp_name = string_zero(); | ||||
|             } | ||||
|              | ||||
|             unit.parse[J].item_count = index; | ||||
|         } | ||||
|          | ||||
|         // NOTE(allen): This is necessary for now because
 | ||||
|         // the original count is slightly overestimated thanks
 | ||||
|         // to nested structs and unions.
 | ||||
|         unit.set.count = index; | ||||
|     } | ||||
|      | ||||
|     return(unit); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| print_struct_html(FILE *file, Item_Node *member){ | ||||
|     String name = member->name; | ||||
|  | @ -1794,6 +1834,7 @@ print_see_also(FILE *file, Documentation *doc){ | |||
|     } | ||||
| } | ||||
| 
 | ||||
| #if 0 | ||||
| typedef struct String_Function_Marker{ | ||||
|     int32_t parse_function; | ||||
|     int32_t is_inline; | ||||
|  | @ -1821,6 +1862,7 @@ string_function_marker_check(String lexeme){ | |||
|      | ||||
|     return(result); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| static void | ||||
| print_str(FILE *file, String str){ | ||||
|  | @ -2130,164 +2172,40 @@ generate_custom_headers(){ | |||
|     Partition part_ = make_part(mem, size); | ||||
|     Partition *part = &part_; | ||||
|      | ||||
|     Parse string_parse = meta_lex("internal_4coder_string.cpp"); | ||||
|     static char *string_files[] = { | ||||
|         "internal_4coder_string.cpp" | ||||
|     }; | ||||
|      | ||||
|     int32_t string_function_count = 0; | ||||
|     static Meta_Keywords string_keys[] = { | ||||
|         {make_lit_string("FSTRING_INLINE") , Item_Function } , | ||||
|         {make_lit_string("FSTRING_LINK")   , Item_Function } , | ||||
|         {make_lit_string("DOC_EXPORT")     , Item_Macro    } , | ||||
|         {make_lit_string("CPP_NAME")       , Item_CppName  } , | ||||
|     }; | ||||
|      | ||||
|     { | ||||
|         char *data = string_parse.code.str; | ||||
|          | ||||
|         Cpp_Token *token = 0; | ||||
|          | ||||
|         Parse_Context context_ = setup_parse_context(data, string_parse.tokens); | ||||
|         Parse_Context *context = &context_; | ||||
|          | ||||
|         for (; (token = get_token(context)) != 0; get_next_token(context)){ | ||||
|             if (token->type == CPP_TOKEN_IDENTIFIER && !(token->flags & CPP_TFLAG_PP_BODY)){ | ||||
|                 String lexeme = get_lexeme(*token, data); | ||||
|                  | ||||
|                 String_Function_Marker marker = | ||||
|                     string_function_marker_check(lexeme); | ||||
|                  | ||||
|                 if (marker.parse_function){ | ||||
|                     if (function_parse_goto_name(context)){ | ||||
|                         ++string_function_count; | ||||
|                     } | ||||
|                 } | ||||
|                 else if (marker.parse_doc){ | ||||
|                     if (macro_parse_check(context)){ | ||||
|                         ++string_function_count; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     Item_Set string_function_set = allocate_item_set(part, string_function_count); | ||||
|     int32_t string_sig_count = 0; | ||||
|      | ||||
|     { | ||||
|         String *code = &string_parse.code; | ||||
|         Cpp_Token_Stack *token_stack = &string_parse.tokens; | ||||
|          | ||||
|         char *data = code->str; | ||||
|          | ||||
|         Parse_Context context_ = setup_parse_context(data, *token_stack); | ||||
|         Parse_Context *context = &context_; | ||||
|          | ||||
|         String cpp_name = {0}; | ||||
|         int32_t has_cpp_name = 0; | ||||
|          | ||||
|         for (; get_token(context); get_next_token(context)){ | ||||
|             Cpp_Token *token = get_token(context); | ||||
|             if (token->type == CPP_TOKEN_IDENTIFIER && !(token->flags & CPP_TFLAG_PP_BODY)){ | ||||
|                 String lexeme = make_string(data + token->start, token->size); | ||||
|                  | ||||
|                 String_Function_Marker marker = | ||||
|                     string_function_marker_check(lexeme); | ||||
|                  | ||||
|                 if (marker.cpp_name){ | ||||
|                     if (parse_cpp_name(context, data, &cpp_name)){ | ||||
|                         has_cpp_name = 1; | ||||
|                     } | ||||
|                 } | ||||
|                 else if (marker.parse_function){ | ||||
|                     if (function_parse(part, context, data, | ||||
|                                        string_function_set, string_sig_count, | ||||
|                                        cpp_name)){ | ||||
|                         ++string_sig_count; | ||||
|                     } | ||||
|                 } | ||||
|                 else if (marker.parse_doc){ | ||||
|                     if (macro_parse(part, context, data, | ||||
|                                     string_function_set, string_sig_count)){ | ||||
|                         ++string_sig_count; | ||||
|                     } | ||||
|                 } | ||||
|                  | ||||
|                 if (has_cpp_name){ | ||||
|                     has_cpp_name = 0; | ||||
|                 } | ||||
|                 else{ | ||||
|                     cpp_name = string_zero(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     Meta_Unit string_unit = compile_meta_unit(part, string_files, ArrayCount(string_files), | ||||
|                                               string_keys, ArrayCount(string_keys)); | ||||
|      | ||||
|     //
 | ||||
|     // App API parsing
 | ||||
|     //
 | ||||
|      | ||||
|     Parse parses[2]; | ||||
|     parses[0] = meta_lex("4ed_api_implementation.cpp"); | ||||
|     parses[1] = meta_lex("win32_api_impl.cpp"); | ||||
|     static char *functions_files[] = { | ||||
|         "4ed_api_implementation.cpp", | ||||
|         "win32_api_impl.cpp" | ||||
|     }; | ||||
|      | ||||
|     int32_t line_count = 0; | ||||
|     static Meta_Keywords functions_keys[] = { | ||||
|         {make_lit_string("API_EXPORT"), Item_Function}, | ||||
|     }; | ||||
|      | ||||
|     for (int32_t J = 0; J < 2; ++J){ | ||||
|         Parse *parse = &parses[J]; | ||||
|          | ||||
|         char *data = parse->code.str; | ||||
|          | ||||
|         int32_t count = parse->tokens.count; | ||||
|         Cpp_Token *tokens = parse->tokens.tokens; | ||||
|         Cpp_Token *token = tokens; | ||||
|          | ||||
|         Parse_Context context_ = setup_parse_context(data, parse->tokens); | ||||
|         Parse_Context *context = &context_; | ||||
|          | ||||
|         for (int32_t i = 0; i < count; ++i, ++token){ | ||||
|             if (token->type == CPP_TOKEN_IDENTIFIER && | ||||
|                 !(token->flags & CPP_TFLAG_PP_BODY)){ | ||||
|                 String lexeme = make_string(data + token->start, token->size); | ||||
|                 if (match_ss(lexeme, make_lit_string("API_EXPORT"))){ | ||||
|                     set_token(context, token); | ||||
|                     if (function_parse_goto_name(context)){ | ||||
|                         ++line_count; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     Meta_Unit unit_custom = compile_meta_unit(part, functions_files, ArrayCount(functions_files), | ||||
|                                               functions_keys, ArrayCount(functions_keys)); | ||||
|      | ||||
|     Item_Set function_set = allocate_item_set(part, line_count); | ||||
|     App_API func_4ed_names = allocate_app_api(part, line_count); | ||||
|     int32_t sig_count = 0; | ||||
|     int32_t sig_count_per_file[2]; | ||||
|     App_API func_4ed_names = allocate_app_api(part, unit_custom.set.count); | ||||
|      | ||||
|     for (int32_t J = 0; J < 2; ++J){ | ||||
|         Parse *parse = &parses[J]; | ||||
|          | ||||
|         char *data = parse->code.str; | ||||
|          | ||||
|         Parse_Context context_ = setup_parse_context(data, parse->tokens); | ||||
|         Parse_Context *context = &context_; | ||||
|          | ||||
|         // NOTE(allen): Header Parse
 | ||||
|         for (; get_token(context); get_next_token(context)){ | ||||
|             Cpp_Token *token = get_token(context); | ||||
|             if (token->type == CPP_TOKEN_IDENTIFIER && !(token->flags & CPP_TFLAG_PP_BODY)){ | ||||
|                 String lexeme = make_string(data + token->start, token->size); | ||||
|                 if (match_ss(lexeme, make_lit_string("API_EXPORT"))){ | ||||
|                     set_token(context, token); | ||||
|                     function_parse(part, context, data, function_set, | ||||
|                                    sig_count, string_zero()); | ||||
|                     if (function_set.items[sig_count].t == Item_Null){ | ||||
|                         function_set.items[sig_count] = null_item_node; | ||||
|                         // TODO(allen): get warning file name and line numbers
 | ||||
|                         fprintf(stderr, "generator warning : invalid function signature\n"); | ||||
|                     } | ||||
|                     ++sig_count; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         ++sig_count_per_file[J] = sig_count; | ||||
|     } | ||||
|      | ||||
|     for (int32_t i = 0; i < sig_count; ++i){ | ||||
|         String name_string = function_set.items[i].name; | ||||
|     for (int32_t i = 0; i < unit_custom.set.count; ++i){ | ||||
|         String name_string = unit_custom.set.items[i].name; | ||||
|         String *macro = &func_4ed_names.names[i].macro; | ||||
|         String *public_name = &func_4ed_names.names[i].public_name; | ||||
|          | ||||
|  | @ -2311,10 +2229,11 @@ generate_custom_headers(){ | |||
|     // NOTE(allen): Header
 | ||||
|     FILE *file = fopen(OS_API_H, "wb"); | ||||
|      | ||||
|     int32_t main_api_count = sig_count_per_file[0]; | ||||
|     for (int32_t i = main_api_count; i < sig_count; ++i){ | ||||
|         String ret_string   = function_set.items[i].ret; | ||||
|         String args_string  = function_set.items[i].args; | ||||
|     int32_t main_api_count = unit_custom.parse[0].item_count; | ||||
|     int32_t os_api_count = unit_custom.parse[1].item_count; | ||||
|     for (int32_t i = main_api_count; i < os_api_count; ++i){ | ||||
|         String ret_string   = unit_custom.set.items[i].ret; | ||||
|         String args_string  = unit_custom.set.items[i].args; | ||||
|         String macro_string = func_4ed_names.names[i].macro; | ||||
|          | ||||
|         fprintf(file, "#define %.*s(n) %.*s n%.*s\n", | ||||
|  | @ -2323,8 +2242,8 @@ generate_custom_headers(){ | |||
|                 args_string.size, args_string.str); | ||||
|     } | ||||
|      | ||||
|     for (int32_t i = main_api_count; i < sig_count; ++i){ | ||||
|         String name_string  = function_set.items[i].name; | ||||
|     for (int32_t i = main_api_count; i < os_api_count; ++i){ | ||||
|         String name_string  = unit_custom.set.items[i].name; | ||||
|         String macro_string = func_4ed_names.names[i].macro; | ||||
|          | ||||
|         fprintf(file, "typedef %.*s(%.*s_Function);\n", | ||||
|  | @ -2336,9 +2255,9 @@ generate_custom_headers(){ | |||
|      | ||||
|     file = fopen(API_H, "wb"); | ||||
|      | ||||
|     for (int32_t i = 0; i < sig_count; ++i){ | ||||
|         String ret_string   = function_set.items[i].ret; | ||||
|         String args_string  = function_set.items[i].args; | ||||
|     for (int32_t i = 0; i < unit_custom.set.count; ++i){ | ||||
|         String ret_string   = unit_custom.set.items[i].ret; | ||||
|         String args_string  = unit_custom.set.items[i].args; | ||||
|         String macro_string = func_4ed_names.names[i].macro; | ||||
|          | ||||
|         fprintf(file, "#define %.*s(n) %.*s n%.*s\n", | ||||
|  | @ -2347,8 +2266,8 @@ generate_custom_headers(){ | |||
|                 args_string.size, args_string.str); | ||||
|     } | ||||
|      | ||||
|     for (int32_t i = 0; i < sig_count; ++i){ | ||||
|         String name_string  = function_set.items[i].name; | ||||
|     for (int32_t i = 0; i < unit_custom.set.count; ++i){ | ||||
|         String name_string  = unit_custom.set.items[i].name; | ||||
|         String macro_string = func_4ed_names.names[i].macro; | ||||
|          | ||||
|         fprintf(file, "typedef %.*s(%.*s_Function);\n", | ||||
|  | @ -2361,8 +2280,8 @@ generate_custom_headers(){ | |||
|             "    void *memory;\n" | ||||
|             "    int32_t memory_size;\n" | ||||
|             ); | ||||
|     for (int32_t i = 0; i < sig_count; ++i){ | ||||
|         String name_string  = function_set.items[i].name; | ||||
|     for (int32_t i = 0; i < unit_custom.set.count; ++i){ | ||||
|         String name_string  = unit_custom.set.items[i].name; | ||||
|         String public_string = func_4ed_names.names[i].public_name; | ||||
|          | ||||
|         fprintf(file, "    %.*s_Function *%.*s;\n", | ||||
|  | @ -2378,8 +2297,8 @@ generate_custom_headers(){ | |||
|     fprintf(file, "};\n"); | ||||
|      | ||||
|     fprintf(file, "#define FillAppLinksAPI(app_links) do{"); | ||||
|     for (int32_t i = 0; i < sig_count; ++i){ | ||||
|         String name = function_set.items[i].name; | ||||
|     for (int32_t i = 0; i < unit_custom.set.count; ++i){ | ||||
|         String name = unit_custom.set.items[i].name; | ||||
|         String public_string = func_4ed_names.names[i].public_name; | ||||
|          | ||||
|         fprintf(file, | ||||
|  | @ -2416,8 +2335,8 @@ generate_custom_headers(){ | |||
|         file = fopen(STRING_H, "wb"); | ||||
|          | ||||
|         { | ||||
|             String *code = &string_parse.code; | ||||
|             Cpp_Token_Stack *token_stack = &string_parse.tokens; | ||||
|             String *code = &string_unit.parse[0].code; | ||||
|             Cpp_Token_Stack *token_stack = &string_unit.parse[0].tokens; | ||||
|              | ||||
|             int32_t start = 0; | ||||
|              | ||||
|  | @ -2460,15 +2379,17 @@ generate_custom_headers(){ | |||
| #define RETURN_PADDING 16 | ||||
| #define SIG_PADDING 30 | ||||
|                      | ||||
|                     for (int32_t j = 0; j < string_sig_count; ++j){ | ||||
|                     for (int32_t j = 0; j < string_unit.set.count; ++j){ | ||||
|                         char line_space[2048]; | ||||
|                         String line = make_fixed_width_string(line_space); | ||||
|                          | ||||
|                         if (string_function_set.items[j].t != Item_Macro){ | ||||
|                             String marker = string_function_set.items[j].marker; | ||||
|                             String ret    = string_function_set.items[j].ret; | ||||
|                             String name   = string_function_set.items[j].name; | ||||
|                             String args   = string_function_set.items[j].args; | ||||
|                         Item_Node *item = string_unit.set.items + j; | ||||
|                          | ||||
|                         if (item->t != Item_Macro){ | ||||
|                             String marker = item->marker; | ||||
|                             String ret    = item->ret; | ||||
|                             String name   = item->name; | ||||
|                             String args   = item->args; | ||||
|                                                                | ||||
|                             append_ss(&line, marker);          | ||||
|                             append_padding(&line, ' ', RETURN_PADDING); | ||||
|  | @ -2481,9 +2402,9 @@ generate_custom_headers(){ | |||
|                             fprintf(file, "%s;\n", line.str);  | ||||
|                         }                                      | ||||
|                         else{                                  | ||||
|                             String name = string_function_set.items[j].name; | ||||
|                             String args = string_function_set.items[j].args; | ||||
|                             String body = string_function_set.items[j].body; | ||||
|                             String name = item->name; | ||||
|                             String args = item->args; | ||||
|                             String body = item->body; | ||||
|                              | ||||
|                             append_ss(&line, make_lit_string("#ifndef ")); | ||||
|                             append_padding(&line, ' ', 10); | ||||
|  | @ -2514,15 +2435,17 @@ generate_custom_headers(){ | |||
|                                 "// for C++ users who can have overloaded functions.  None of\n" | ||||
|                                 "// these functions add new features.\n"); | ||||
|                          | ||||
|                         for (int32_t j = 0; j < string_sig_count; ++j){ | ||||
|                         for (int32_t j = 0; j < string_unit.set.count; ++j){ | ||||
|                             char line_space[2048]; | ||||
|                             String line = make_fixed_width_string(line_space); | ||||
|                              | ||||
|                             if (string_function_set.items[j].t != Item_Macro){ | ||||
|                                 String cpp_name = string_function_set.items[j].cpp_name; | ||||
|                             Item_Node *item = &string_unit.set.items[j]; | ||||
|                              | ||||
|                             if (item->t != Item_Macro){ | ||||
|                                 String cpp_name = item->cpp_name; | ||||
|                                 if (cpp_name.str != 0){ | ||||
|                                     String ret = string_function_set.items[j].ret; | ||||
|                                     String args = string_function_set.items[j].args; | ||||
|                                     String ret =  item->ret; | ||||
|                                     String args = item->args; | ||||
|                                      | ||||
|                                     append_ss(&line, make_lit_string("FSTRING_INLINE")); | ||||
|                                     append_padding(&line, ' ', RETURN_PADDING); | ||||
|  | @ -2545,17 +2468,19 @@ generate_custom_headers(){ | |||
|                     { | ||||
|                         fprintf(file, "\n#if !defined(FSTRING_C) && !defined(FSTRING_GUARD)\n\n"); | ||||
|                          | ||||
|                         for (int32_t j = 0; j < string_sig_count; ++j){ | ||||
|                         for (int32_t j = 0; j < string_unit.set.count; ++j){ | ||||
|                             char line_space[2048]; | ||||
|                             String line = make_fixed_width_string(line_space); | ||||
|                              | ||||
|                             if (string_function_set.items[j].t != Item_Macro){ | ||||
|                                 String cpp_name = string_function_set.items[j].cpp_name; | ||||
|                             Item_Node *item = &string_unit.set.items[j]; | ||||
|                              | ||||
|                             if (item->t != Item_Macro){ | ||||
|                                 String cpp_name = item->cpp_name; | ||||
|                                 if (cpp_name.str != 0){ | ||||
|                                     String name = string_function_set.items[j].name; | ||||
|                                     String ret  = string_function_set.items[j].ret; | ||||
|                                     String args = string_function_set.items[j].args; | ||||
|                                 Argument_Breakdown breakdown = string_function_set.items[j].breakdown; | ||||
|                                     String name                  = item->name; | ||||
|                                     String ret                   = item->ret; | ||||
|                                     String args                  = item->args; | ||||
|                                     Argument_Breakdown breakdown = item->breakdown; | ||||
|                                      | ||||
|                                     append_ss(&line, make_lit_string("FSTRING_INLINE")); | ||||
|                                     append_s_char(&line, ' '); | ||||
|  | @ -2825,7 +2750,7 @@ generate_custom_headers(){ | |||
|                     "<h3>§"SECTION" Function List</h3>\n" | ||||
|                     "<ul>\n"); | ||||
|              | ||||
|             for (int32_t i = 0; i < sig_count; ++i){ | ||||
|             for (int32_t i = 0; i < unit_custom.set.count; ++i){ | ||||
|                 String name = func_4ed_names.names[i].public_name; | ||||
|                 fprintf(file, | ||||
|                         "<li>" | ||||
|  | @ -2862,7 +2787,7 @@ generate_custom_headers(){ | |||
| #define SECTION MAJOR_SECTION".3" | ||||
|              | ||||
|             fprintf(file, "<h3>§"SECTION" Function Descriptions</h3>\n"); | ||||
|             for (int32_t i = 0; i < sig_count; ++i){ | ||||
|             for (int32_t i = 0; i < unit_custom.set.count; ++i){ | ||||
|                 String name = func_4ed_names.names[i].public_name; | ||||
|                  | ||||
|                 fprintf(file, | ||||
|  | @ -2872,10 +2797,10 @@ generate_custom_headers(){ | |||
|                         name.size, name.str, i+1, | ||||
|                         name.size, name.str | ||||
|                         ); | ||||
|                 print_function_html(file, function_set.items[i], name, "app->"); | ||||
|                 print_function_html(file, unit_custom.set.items[i], name, "app->"); | ||||
|                 fprintf(file, "</div>\n"); | ||||
|                  | ||||
|                 String doc_string = function_set.items[i].doc_string; | ||||
|                 String doc_string = unit_custom.set.items[i].doc_string; | ||||
|                 print_function_docs(file, part, name, doc_string); | ||||
|                  | ||||
|                 fprintf(file, "</div><hr>\n"); | ||||
|  | @ -2922,17 +2847,17 @@ generate_custom_headers(){ | |||
|                     "<h3>§"SECTION" String Function List</h3>\n" | ||||
|                     "<ul>\n"); | ||||
|              | ||||
|             // TODO(allen): I don't think used_strings is necessary any more
 | ||||
|             // since I have made the default names C compatible there will
 | ||||
|             // be no overloading.
 | ||||
|             String *used_strings = 0; | ||||
|             int32_t used_string_count = 0; | ||||
|              | ||||
|             { | ||||
|                 int32_t memory_size = sizeof(String)*(string_sig_count); | ||||
|                 used_strings = (String*)malloc(memory_size); | ||||
|                 memset(used_strings, 0, memory_size); | ||||
|             } | ||||
|             used_strings = push_array(part, String, string_unit.set.count); | ||||
|             memset(used_strings, 0, sizeof(String)*string_unit.set.count); | ||||
|              | ||||
|             for (int32_t i = 0; i < string_sig_count; ++i){ | ||||
|                 String name = string_function_set.items[i].name; | ||||
|             for (int32_t i = 0; i < string_unit.set.count; ++i){ | ||||
|                 String name = string_unit.set.items[i].name; | ||||
|                 int32_t index = 0; | ||||
|                 if (!string_set_match(used_strings, used_string_count, name, &index)){ | ||||
|                     fprintf(file, | ||||
|  | @ -2954,8 +2879,10 @@ generate_custom_headers(){ | |||
|                     "<h3>§"SECTION" String Function Descriptions</h3>\n" | ||||
|                     "<ul>\n"); | ||||
|              | ||||
|             for (int32_t i = 0; i < string_sig_count; ++i){ | ||||
|                 String name = string_function_set.items[i].name; | ||||
|             for (int32_t i = 0; i < string_unit.set.count; ++i){ | ||||
|                 Item_Node *item = &string_unit.set.items[i]; | ||||
|                  | ||||
|                 String name = item->name; | ||||
|                 int32_t index = 0; | ||||
|                 int32_t do_id = false; | ||||
|                 if (!string_set_match(used_strings, used_string_count, name, &index)){ | ||||
|  | @ -2978,18 +2905,17 @@ generate_custom_headers(){ | |||
|                         "<div style='"CODE_STYLE" "DESCRIPT_SECTION_STYLE"'>\n", | ||||
|                         i+1, name.size, name.str); | ||||
|                  | ||||
|                 if (string_function_set.items[i].t == Item_Macro){ | ||||
|                     print_macro_html(file, string_function_set.items[i], name); | ||||
|                 if (item->t == Item_Macro){ | ||||
|                     print_macro_html(file, *item, name); | ||||
|                 } | ||||
|                 else{ | ||||
|                     print_function_html(file, string_function_set.items[i], name, ""); | ||||
|                     print_function_html(file, *item, name, ""); | ||||
|                 } | ||||
|                  | ||||
|                 fprintf(file, "</div>\n"); | ||||
|                  | ||||
|                  | ||||
|                 String doc_string = string_function_set.items[i].doc_string; | ||||
|                 print_function_docs(file, part, name, doc_string); | ||||
|                 print_function_docs(file, part, name, item->doc_string); | ||||
|                  | ||||
|                 fprintf(file, "</div><hr>\n"); | ||||
|             } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Allen Webster
						Allen Webster