setting up the site generator's general document system.

This commit is contained in:
Allen Webster 2016-11-03 00:57:26 -04:00
parent de4f320e27
commit 7f559c4016
5 changed files with 301 additions and 46 deletions

View File

@ -23,7 +23,9 @@
#include <assert.h> #include <assert.h>
#include "4coder_mem.h" #include "4coder_mem.h"
#include "meta_parser.cpp"
// TODO(allen): In the end the metaprogramming base should be one sub-project, the site should be one sub-project, and this code generator should be one sub-project.
#include "site/meta_parser.cpp"
#define InvalidPath Assert(!"Invalid path of execution") #define InvalidPath Assert(!"Invalid path of execution")

Binary file not shown.

166
site/abstract_document.h Normal file
View File

@ -0,0 +1,166 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 25.02.2016
*
* File editing view for 4coder
*
*/
// TOP
#if !defined(ABSTRACT_DOCUMENT_H)
#define ABSTRACT_DOCUMENT_H
#define NotImplemented Assert(!"Not Implemented!")
// Document Declaration
struct Enriched_Text{
int32_t t;
};
enum{
Doc_Root,
Doc_Section,
Doc_Todo,
Doc_Element_List,
Doc_Full_Elements,
};
struct Document_Item{
Document_Item *next;
int32_t type;
union{
struct{
Document_Item *first_child;
Document_Item *last_child;
String name;
} section;
struct{
Meta_Unit *unit;
} unit_elements;
};
};
static Document_Item null_document_item = {0};
struct Abstract_Document{
// Document value members
Document_Item *root_item;
// Document building members
Partition *part;
Document_Item *section_stack[16];
int32_t section_top;
};
static Abstract_Document null_abstract_document = {0};
static void
begin_document_description(Abstract_Document *doc, Partition *part){
*doc = null_abstract_document;
doc->part = part;
doc->root_item = push_struct(doc->part, Document_Item);
*doc->root_item = null_document_item;
doc->section_stack[doc->section_top] = doc->root_item;
doc->root_item->type = Doc_Root;
}
static void
end_document_description(Abstract_Document *doc){
Assert(doc->section_top == 0);
}
static void
append_child(Document_Item *parent, Document_Item *item){
Assert(parent->type == Doc_Root || parent->type == Doc_Section);
if (parent->section.last_child == 0){
parent->section.first_child = item;
parent->section.last_child = item;
}
else{
parent->section.last_child->next = item;
parent->section.last_child = item;
}
}
static void
begin_section(Abstract_Document *doc, char *title){
Assert(doc->section_top+1 < ArrayCount(doc->section_stack));
Document_Item *parent = doc->section_stack[doc->section_top];
Document_Item *section = push_struct(doc->part, Document_Item);
*section = null_document_item;
doc->section_stack[++doc->section_top] = section;
section->type = Doc_Section;
int32_t title_len = str_size(title);
section->section.name = make_string_cap(push_array(doc->part, char, title_len+1), 0, title_len+1);
partition_align(doc->part, 8);
append_sc(&section->section.name, title);
append_child(parent, section);
}
static void
end_section(Abstract_Document *doc){
Assert(doc->section_top > 0);
--doc->section_top;
}
static void
add_todo(Abstract_Document *doc){
Assert(doc->section_top+1 < ArrayCount(doc->section_stack));
Document_Item *parent = doc->section_stack[doc->section_top];
Document_Item *item = push_struct(doc->part, Document_Item);
*item = null_document_item;
item->type = Doc_Todo;
append_child(parent, item);
}
static void
add_element_list(Abstract_Document *doc, Meta_Unit *unit){
Assert(doc->section_top+1 < ArrayCount(doc->section_stack));
Document_Item *parent = doc->section_stack[doc->section_top];
Document_Item *item = push_struct(doc->part, Document_Item);
*item = null_document_item;
item->type = Doc_Element_List;
item->unit_elements.unit = unit;
append_child(parent, item);
}
static void
add_full_elements(Abstract_Document *doc, Meta_Unit *unit){
Assert(doc->section_top+1 < ArrayCount(doc->section_stack));
Document_Item *parent = doc->section_stack[doc->section_top];
Document_Item *item = push_struct(doc->part, Document_Item);
*item = null_document_item;
item->type = Doc_Full_Elements;
item->unit_elements.unit = unit;
append_child(parent, item);
}
static void
add_enriched_text(Abstract_Document *doc, Enriched_Text *text){
NotImplemented;
}
// Document Generation
static void
generate_document_html(Out_Context *context, Abstract_Document *doc){
}
#endif
// BOTTOM

View File

@ -1362,6 +1362,13 @@ compile_meta_unit(Partition *part, char *code_directory, char **files, Meta_Keyw
return(unit); return(unit);
} }
static Meta_Unit
compile_meta_unit(Partition *part, char *code_directory, char *file, Meta_Keywords *keywords, int32_t key_count){
char *file_array[2] = {file, 0};
Meta_Unit unit = compile_meta_unit(part, code_directory, file_array, keywords, key_count);
return(unit);
}
#endif #endif
// BOTTOM // BOTTOM

View File

@ -22,9 +22,12 @@
#include "4coder_mem.h" #include "4coder_mem.h"
#include "meta_parser.cpp" #include "meta_parser.cpp"
#include "abstract_document.h"
#define InvalidPath Assert(!"Invalid path of execution") #define InvalidPath Assert(!"Invalid path of execution")
// TODO(allen): Move the Out_Context into it's own file.
typedef struct Out_Context{ typedef struct Out_Context{
char out_directory_space[256]; char out_directory_space[256];
String out_directory; String out_directory;
@ -856,7 +859,34 @@ allocate_app_api(Partition *part, int32_t count){
} }
static void static void
generate_custom_headers(char *code_directory, char *src_directory, char *dst_directory){ assert_files_are_equal(char *directory, char *filename1, char *filename2){
char space[256];
String name = make_fixed_width_string(space);
append_sc(&name, directory);
append_sc(&name, "\\");
append_sc(&name, filename1);
terminate_with_null(&name);
String file1 = file_dump(name.str);
name.size = 0;
append_sc(&name, directory);
append_sc(&name, "\\");
append_sc(&name, filename2);
terminate_with_null(&name);
String file2 = file_dump(name.str);
if (!match(file1, file2)){
fprintf(stderr, "Failed transitional test: %s != %s\n", filename1, filename2);
}
else{
fprintf(stderr, "Passed transitional test: %s == %s\n", filename1, filename2);
}
}
static void
generate_site(char *code_directory, char *src_directory, char *dst_directory){
#define API_DOC "4coder_API.html" #define API_DOC "4coder_API.html"
int32_t size = (512 << 20); int32_t size = (512 << 20);
@ -879,45 +909,29 @@ generate_custom_headers(char *code_directory, char *src_directory, char *dst_dir
#define ExpandArray(a) (a), (ArrayCount(a)) #define ExpandArray(a) (a), (ArrayCount(a))
// NOTE(allen): Parse the internal string file. // NOTE(allen): Parse the important code.
static char *string_files[] = { Meta_Unit custom_types_unit = compile_meta_unit(part, code_directory, "4coder_types.h", ExpandArray(meta_keywords));
"internal_4coder_string.cpp",
0
};
Meta_Unit string_unit = compile_meta_unit(part, code_directory, string_files, ExpandArray(meta_keywords)); Meta_Unit lexer_funcs_unit = compile_meta_unit(part, code_directory, "4cpp_lexer.h", ExpandArray(meta_keywords));
// NOTE(allen): Parse the lexer library Meta_Unit lexer_types_unit = compile_meta_unit(part, code_directory, "4cpp_lexer_types.h", ExpandArray(meta_keywords));
static char *lexer_types_files[] = {
"4cpp_lexer_types.h",
0
};
Meta_Unit lexer_types_unit = compile_meta_unit(part, code_directory, lexer_types_files, ExpandArray(meta_keywords)); Meta_Unit string_unit = compile_meta_unit(part, code_directory, "internal_4coder_string.cpp", ExpandArray(meta_keywords));
static char *lexer_funcs_files[] = {
"4cpp_lexer.h",
0
};
Meta_Unit lexer_funcs_unit = compile_meta_unit(part, code_directory, lexer_funcs_files, ExpandArray(meta_keywords));
// NOTE(allen): Parse the customization API files
static char *functions_files[] = { static char *functions_files[] = {
"4ed_api_implementation.cpp", "4ed_api_implementation.cpp",
"win32_api_impl.cpp", "win32_api_impl.cpp",
0 0
}; };
Meta_Unit unit_custom = compile_meta_unit(part, code_directory, functions_files, ExpandArray(meta_keywords)); Meta_Unit custom_funcs_unit = compile_meta_unit(part, code_directory, functions_files, ExpandArray(meta_keywords));
// NOTE(allen): Compute and store variations of the function names // NOTE(allen): Compute and store variations of the custom function names
App_API func_4ed_names = allocate_app_api(part, unit_custom.set.count); App_API func_4ed_names = allocate_app_api(part, custom_funcs_unit.set.count);
for (int32_t i = 0; i < unit_custom.set.count; ++i){ for (int32_t i = 0; i < custom_funcs_unit.set.count; ++i){
String name_string = unit_custom.set.items[i].name; String name_string = custom_funcs_unit.set.items[i].name;
String *macro = &func_4ed_names.names[i].macro; String *macro = &func_4ed_names.names[i].macro;
String *public_name = &func_4ed_names.names[i].public_name; String *public_name = &func_4ed_names.names[i].public_name;
@ -931,23 +945,88 @@ generate_custom_headers(char *code_directory, char *src_directory, char *dst_dir
partition_align(part, 4); partition_align(part, 4);
} }
// NOTE(allen): Parse the customization API types
static char *type_files[] = {
"4coder_types.h",
0
};
Meta_Unit unit = compile_meta_unit(part, code_directory, type_files, ExpandArray(meta_keywords)); // NOTE(allen): Put together the abstract document
Abstract_Document doc = {0};
begin_document_description(&doc, part);
begin_section(&doc, "Intro");
add_todo(&doc);
end_section(&doc);
begin_section(&doc, "4coder Systems Overview");
add_todo(&doc);
end_section(&doc);
begin_section(&doc, "Types and Functions");
{
begin_section(&doc, "Function List");
add_element_list(&doc, &custom_funcs_unit);
end_section(&doc);
begin_section(&doc, "Type List");
add_element_list(&doc, &custom_types_unit);
end_section(&doc);
begin_section(&doc, "Function Descriptions");
add_full_elements(&doc, &custom_funcs_unit);
end_section(&doc);
begin_section(&doc, "Type Descriptions");
add_full_elements(&doc, &custom_types_unit);
end_section(&doc);
}
end_section(&doc);
begin_section(&doc, "String Library");
{
begin_section(&doc, "String Library Intro");
add_todo(&doc);
end_section(&doc);
begin_section(&doc, "String Function List");
add_element_list(&doc, &string_unit);
end_section(&doc);
begin_section(&doc, "String Function Descriptions");
add_full_elements(&doc, &string_unit);
end_section(&doc);
}
end_section(&doc);
begin_section(&doc, "Lexer Library");
{
begin_section(&doc, "Lexer Intro");
add_todo(&doc);
end_section(&doc);
begin_section(&doc, "Lexer Function List");
add_element_list(&doc, &lexer_funcs_unit);
end_section(&doc);
begin_section(&doc, "Lexer Type List");
add_element_list(&doc, &lexer_types_unit);
end_section(&doc);
begin_section(&doc, "Lexer Function Descriptions");
add_full_elements(&doc, &lexer_funcs_unit);
end_section(&doc);
begin_section(&doc, "Lexer Type Descriptions");
add_full_elements(&doc, &lexer_types_unit);
end_section(&doc);
}
end_section(&doc);
end_document_description(&doc);
// NOTE(allen): Output // NOTE(allen): Output
String out = str_alloc(part, 10 << 20); String out = str_alloc(part, 10 << 20);
Out_Context context = {0}; Out_Context context = {0};
set_context_directory(&context, dst_directory); set_context_directory(&context, dst_directory);
// Output Docs // Output Docs - General Document Generator
if (begin_file_out(&context, API_DOC, &out)){ if (begin_file_out(&context, "gen-test.html", &out)){
generate_document_html(&context, &doc);
end_file_out(context);
}
else{
// TODO(allen): warning
}
// Output Docs - Direct Method
if (begin_file_out(&context, API_DOC, &out)){
Used_Links used_links = {0}; Used_Links used_links = {0};
init_used_links(part, &used_links, 4000); init_used_links(part, &used_links, 4000);
@ -1103,7 +1182,7 @@ generate_custom_headers(char *code_directory, char *src_directory, char *dst_dir
#define SECTION MAJOR_SECTION".1" #define SECTION MAJOR_SECTION".1"
append_sc(&out, "<h3>&sect;"SECTION" Function List</h3><ul>"); append_sc(&out, "<h3>&sect;"SECTION" Function List</h3><ul>");
for (int32_t i = 0; i < unit_custom.set.count; ++i){ for (int32_t i = 0; i < custom_funcs_unit.set.count; ++i){
print_item_in_list(&out, func_4ed_names.names[i].public_name, "_doc"); print_item_in_list(&out, func_4ed_names.names[i].public_name, "_doc");
} }
append_sc(&out, "</ul>"); append_sc(&out, "</ul>");
@ -1112,8 +1191,8 @@ generate_custom_headers(char *code_directory, char *src_directory, char *dst_dir
#define SECTION MAJOR_SECTION".2" #define SECTION MAJOR_SECTION".2"
append_sc(&out, "<h3>&sect;"SECTION" Type List</h3><ul>"); append_sc(&out, "<h3>&sect;"SECTION" Type List</h3><ul>");
for (int32_t i = 0; i < unit.set.count; ++i){ for (int32_t i = 0; i < custom_types_unit.set.count; ++i){
print_item_in_list(&out, unit.set.items[i].name, "_doc"); print_item_in_list(&out, custom_types_unit.set.items[i].name, "_doc");
} }
append_sc(&out, "</ul>"); append_sc(&out, "</ul>");
@ -1121,8 +1200,8 @@ generate_custom_headers(char *code_directory, char *src_directory, char *dst_dir
#define SECTION MAJOR_SECTION".3" #define SECTION MAJOR_SECTION".3"
append_sc(&out, "<h3>&sect;"SECTION" Function Descriptions</h3>"); append_sc(&out, "<h3>&sect;"SECTION" Function Descriptions</h3>");
for (int32_t i = 0; i < unit_custom.set.count; ++i){ for (int32_t i = 0; i < custom_funcs_unit.set.count; ++i){
Item_Node *item = &unit_custom.set.items[i]; Item_Node *item = &custom_funcs_unit.set.items[i];
String name = func_4ed_names.names[i].public_name; String name = func_4ed_names.names[i].public_name;
append_sc (&out, "<div id='"); append_sc (&out, "<div id='");
@ -1147,8 +1226,8 @@ generate_custom_headers(char *code_directory, char *src_directory, char *dst_dir
append_sc(&out, "<h3>&sect;"SECTION" Type Descriptions</h3>"); append_sc(&out, "<h3>&sect;"SECTION" Type Descriptions</h3>");
int32_t I = 1; int32_t I = 1;
for (int32_t i = 0; i < unit.set.count; ++i, ++I){ for (int32_t i = 0; i < custom_types_unit.set.count; ++i, ++I){
print_item(&out, part, &used_links, unit.set.items + i, "_doc", 0, SECTION, I); print_item(&out, part, &used_links, custom_types_unit.set.items + i, "_doc", 0, SECTION, I);
} }
#undef MAJOR_SECTION #undef MAJOR_SECTION
@ -1262,18 +1341,19 @@ generate_custom_headers(char *code_directory, char *src_directory, char *dst_dir
print_item(&out, part, &used_links, lexer_types_unit.set.items+i, "_doc", "", SECTION, i+1); print_item(&out, part, &used_links, lexer_types_unit.set.items+i, "_doc", "", SECTION, i+1);
} }
append_sc(&out, "</div></body></html>"); append_sc(&out, "</div></body></html>");
end_file_out(context); end_file_out(context);
} }
else{ else{
// TODO(allen): warning // TODO(allen): warning
} }
assert_files_are_equal(dst_directory, API_DOC, "gen-test.html");
} }
int main(int argc, char **argv){ int main(int argc, char **argv){
if (argc == 4){ if (argc == 4){
generate_custom_headers(argv[1], argv[2], argv[3]); generate_site(argv[1], argv[2], argv[3]);
} }
} }