|
- proc generate_docs(String* path) -> void {
- FILE *f = fopen(Memory::get_c_str(path), "w");
- if (!f) {
- create_generic_error("The file for writing the documentation (%s) "
- "could not be opened for writing.", Memory::get_c_str(path));
- return;
- }
- defer {
- fclose(f);
- };
-
- Array_List<Environment*> visited;
-
- const auto print_this_env = [&](const auto& rec, Environment* env, char* prefix) -> void {
- bool we_already_printed = false;
- // TODO(Felix): Make a generic array_list_contains function
- for(auto it : visited) {
- if (it == env) {
- we_already_printed = true;
- break;
- }
- }
- if (!we_already_printed) {
- // printf("Working on env::::");
- // print_environment(env);
- // printf("\n--------------------------------\n");
- visited.append(env);
-
- push_environment(env);
- defer {
- pop_environment();
- };
-
- for_hash_map(env->hm) {
- try_void fprintf(f,
- "#+latex: \\hrule\n"
- "#+html: <hr/>\n"
- "* =%s%s= \n"
- " :PROPERTIES:\n"
- " :UNNUMBERED: t\n"
- " :END:"
- ,prefix, Memory::get_c_str(((Lisp_Object*)key)->value.symbol));
- /*
- * sourcecodeLocation
- */
- if (value->sourceCodeLocation) {
- try_void fprintf(f, "\n - defined in :: =%s:%d:%d=",
- Memory::get_c_str(value->sourceCodeLocation->file),
- value->sourceCodeLocation->line,
- value->sourceCodeLocation->column);
- }
- /*
- * type
- */
- Lisp_Object_Type type = Memory::get_type(value);
- Lisp_Object* LOtype;
- Lisp_Object* type_expr = Memory::create_list(
- Memory::get_or_create_lisp_object_symbol("type"),
- value);
- try_void LOtype = eval_expr(type_expr);
-
- fprintf(f, "\n - type :: =");
- print(LOtype, true, f);
- fprintf(f, "=");
-
-
- /*
- * if printable value -> print it
- */
- switch (type) {
- case(Lisp_Object_Type::Nil):
- case(Lisp_Object_Type::T):
- case(Lisp_Object_Type::Number):
- case(Lisp_Object_Type::String):
- case(Lisp_Object_Type::Pair):
- case(Lisp_Object_Type::Symbol):
- case(Lisp_Object_Type::Keyword): {
- fprintf(f, "\n - value :: =");
- print(value, true, f);
- fprintf(f, "=");
- } break;
- default: break;
- }
- /*
- * if function then print arguments
- */
- if (type == Lisp_Object_Type::Function ||
- type == Lisp_Object_Type::CFunction)
- {
- Arguments* args =
- (type == Lisp_Object_Type::Function)
- ? &value->value.function->args
- : &value->value.cFunction->args;
- fprintf(f, "\n - arguments :: ");
- // if no args at all
- if (args->positional.symbols.next_index == 0 &&
- args->keyword.values.next_index == 0 &&
- !args->rest)
- {
- fprintf(f, "none.");
- } else {
- if (args->positional.symbols.next_index != 0) {
- fprintf(f, "\n - postitional :: ");
- fprintf(f, "=%s=", Memory::get_c_str(args->positional.symbols.data[0]->value.symbol));
- for (int i = 1; i < args->positional.symbols.next_index; ++i) {
- fprintf(f, ", =%s=", Memory::get_c_str(args->positional.symbols.data[i]->value.symbol));
- }
- }
- if (args->keyword.values.next_index != 0) {
- fprintf(f, "\n - keyword :: ");
- fprintf(f, "=%s=", Memory::get_c_str(args->keyword.keywords.data[0]->value.symbol));
- if (args->keyword.values.data[0]) {
- fprintf(f, " =(");
- print(args->keyword.values.data[0], true, f);
- fprintf(f, ")=");
- }
- for (int i = 1; i < args->keyword.values.next_index; ++i) {
- fprintf(f, ", =%s=", Memory::get_c_str(args->keyword.keywords.data[i]->value.symbol));
- if (args->keyword.values.data[i]) {
- fprintf(f, " =(");
- print(args->keyword.values.data[i], true, f);
- fprintf(f, ")=");
- }
- }
- }
- if (args->rest) {
- fprintf(f, "\n - rest :: =%s=", Memory::get_c_str(args->rest->value.symbol));
- }
- }
- }
- fprintf(f, "\n - docu :: ");
- if (value->docstring)
- fprintf(f, "\n #+BEGIN:\n%s\n #+END:\n",
- Memory::get_c_str(value->docstring));
- else
- fprintf(f, "none\n");
- }
- }
-
- for (int i = 0; i < env->parents.next_index; ++i) {
- try_void rec(rec, env->parents.data[i], prefix);
- }
- };
-
- print_this_env(print_this_env, get_current_environment(), (char*)"");
- }
|