|
- proc generate_docs(String* path) -> void {
- // save the current working directory
- char* cwd = get_cwd();
- // get the direction of the exe
- char* exe_path = get_exe_dir();
- change_cwd(exe_path);
-
- defer {
- // switch back to the users directory
- change_cwd(cwd);
- free(exe_path);
- free(cwd);
- };
-
- FILE *f = fopen(Memory::get_c_str(path), "w");
- if (!f) {
- create_generic_error("The file for writing the documentation "
- "could not be opened for writing.");
- return;
- }
- defer {
- fclose(f);
- };
-
- Environment_Array_List* visited = create_Environment_array_list();
-
- std::function<void(Environment*, char* prefix)> print_this_env;
- print_this_env = [&](Environment* env, char* prefix) -> void {
- bool we_already_printed = false;
- // TODO(Felix): Make a generic array_list_contains function
- for (int i = 0; i < visited->next_index; ++i) {
- if (visited->data[i] == env) {
- we_already_printed = true;
- break;
- }
- }
- if (!we_already_printed) {
- append_to_array_list(visited, env);
- for (int i = 0; i < env->next_index; ++i) {
- fprintf(f, "\\hrule\n* =%s%s= \n"
- // " :PROPERTIES:\n"
- // " :UNNUMBERED: t\n"
- // " :END:"
- ,prefix, env->keys[i]);
- /*
- * sourcecodeLocation
- */
- if (env->values[i]->sourceCodeLocation) {
- fprintf(f, "\n - defined in :: =%s:%d:%d=",
- Memory::get_c_str(env->values[i]->sourceCodeLocation->file),
- env->values[i]->sourceCodeLocation->line,
- env->values[i]->sourceCodeLocation->column);
- }
- /*
- * type
- */
- Lisp_Object_Type type = Memory::get_type(env->values[i]);
- Lisp_Object* LOtype;
- try_void LOtype = eval_expr(Memory::create_list(
- Memory::get_or_create_lisp_object_symbol("type"),
- env->values[i]));
-
- 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(env->values[i], true, f);
- fprintf(f, "=");
- } break;
- default: break;
- }
- /*
- * if function then print arguments
- */
- if (type == Lisp_Object_Type::Function) {
- Lisp_Object* fun = env->values[i];
- bool printed_at_least_some_args = false;
- fprintf(f, "\n - arguments :: ");
- if (fun->value.function.positional_arguments->next_index != 0) {
- if (!printed_at_least_some_args)
- fprintf(f, ":");
- fprintf(f, "\n - postitional :: ");
- fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.positional_arguments->symbols[0]->value.symbol.identifier));
- for (int i = 1; i < fun->value.function.positional_arguments->next_index; ++i) {
- fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.positional_arguments->symbols[i]->value.symbol.identifier));
- }
- }
- if (fun->value.function.keyword_arguments->next_index != 0) {
- if (!printed_at_least_some_args)
- fprintf(f, ":");
- fprintf(f, "\n - keyword :: ");
- fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.keyword_arguments->keywords[0]->value.symbol.identifier));
- if (fun->value.function.keyword_arguments->values->data[0]) {
- fprintf(f, " =(");
- print(fun->value.function.keyword_arguments->values->data[0], true, f);
- fprintf(f, ")=");
- }
- for (int i = 1; i < fun->value.function.keyword_arguments->next_index; ++i) {
- fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.keyword_arguments->keywords[i]->value.symbol.identifier));
- if (fun->value.function.keyword_arguments->values->data[i]) {
- fprintf(f, " =(");
- print(fun->value.function.keyword_arguments->values->data[i], true, f);
- fprintf(f, ")=");
- }
- }
- }
- if (fun->value.function.rest_argument) {
- if (!printed_at_least_some_args)
- fprintf(f, ":");
- fprintf(f, "\n - rest :: =%s=", Memory::get_c_str(fun->value.function.rest_argument));
- }
- // if no args at all
- if (fun->value.function.positional_arguments->next_index == 0 &&
- fun->value.function.keyword_arguments->next_index == 0 &&
- !fun->value.function.rest_argument)
- {
- fprintf(f, "none.");
- }
- }
- fprintf(f, "\n - docu :: ");
- if (env->values[i]->docstring)
- fprintf(f, "\n #+BEGIN:\n%s\n #+END:\n",
- Memory::get_c_str(env->values[i]->docstring));
- else
- fprintf(f, "none\n");
-
- if (Memory::get_type(env->values[i]) == Lisp_Object_Type::Function &&
- env->values[i]->userType &&
- (string_equal(env->values[i]->userType->value.symbol.identifier, "package") ||
- string_equal(env->values[i]->userType->value.symbol.identifier, "constructor")))
- {
- char new_prefix[200];
- strcpy(new_prefix, prefix);
- strcat(new_prefix, env->keys[i]);
- strcat(new_prefix, " ");
- print_this_env(env->values[i]->value.function.parent_environment, new_prefix);
- }
- }
- }
-
- for (int i = 0; i < env->parents->next_index; ++i) {
- print_this_env(env->parents->data[i], prefix);
- }
- };
-
- print_this_env(get_current_environment(), (char*)"");
- }
|