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 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:
\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*)""); }