Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

161 строка
7.1 KiB

  1. proc generate_docs(String* path) -> void {
  2. // save the current working directory
  3. char* cwd = get_cwd();
  4. // get the direction of the exe
  5. char* exe_path = get_exe_dir();
  6. change_cwd(exe_path);
  7. defer {
  8. // switch back to the users directory
  9. change_cwd(cwd);
  10. free(exe_path);
  11. free(cwd);
  12. };
  13. FILE *f = fopen(Memory::get_c_str(path), "w");
  14. if (!f) {
  15. create_generic_error("The file for writing the documentation "
  16. "could not be opened for writing.");
  17. return;
  18. }
  19. defer {
  20. fclose(f);
  21. };
  22. Environment_Array_List* visited = create_Environment_array_list();
  23. std::function<void(Environment*, char* prefix)> print_this_env;
  24. print_this_env = [&](Environment* env, char* prefix) -> void {
  25. bool we_already_printed = false;
  26. // TODO(Felix): Make a generic array_list_contains function
  27. for (int i = 0; i < visited->next_index; ++i) {
  28. if (visited->data[i] == env) {
  29. we_already_printed = true;
  30. break;
  31. }
  32. }
  33. if (!we_already_printed) {
  34. append_to_array_list(visited, env);
  35. for (int i = 0; i < env->next_index; ++i) {
  36. fprintf(f, "\\hrule\n* =%s%s= \n"
  37. // " :PROPERTIES:\n"
  38. // " :UNNUMBERED: t\n"
  39. // " :END:"
  40. ,prefix, env->keys[i]);
  41. /*
  42. * sourcecodeLocation
  43. */
  44. if (env->values[i]->sourceCodeLocation) {
  45. fprintf(f, "\n - defined in :: =%s:%d:%d=",
  46. Memory::get_c_str(env->values[i]->sourceCodeLocation->file),
  47. env->values[i]->sourceCodeLocation->line,
  48. env->values[i]->sourceCodeLocation->column);
  49. }
  50. /*
  51. * type
  52. */
  53. Lisp_Object_Type type = Memory::get_type(env->values[i]);
  54. Lisp_Object* LOtype;
  55. try_void LOtype = eval_expr(Memory::create_list(
  56. Memory::get_or_create_lisp_object_symbol("type"),
  57. env->values[i]));
  58. fprintf(f, "\n - type :: =");
  59. print(LOtype, true, f);
  60. fprintf(f, "=");
  61. /*
  62. * if printable value -> print it
  63. */
  64. switch (type) {
  65. case(Lisp_Object_Type::Nil):
  66. case(Lisp_Object_Type::T):
  67. case(Lisp_Object_Type::Number):
  68. case(Lisp_Object_Type::String):
  69. case(Lisp_Object_Type::Pair):
  70. case(Lisp_Object_Type::Symbol):
  71. case(Lisp_Object_Type::Keyword): {
  72. fprintf(f, "\n - value :: =");
  73. print(env->values[i], true, f);
  74. fprintf(f, "=");
  75. } break;
  76. default: break;
  77. }
  78. /*
  79. * if function then print arguments
  80. */
  81. if (type == Lisp_Object_Type::Function) {
  82. Lisp_Object* fun = env->values[i];
  83. bool printed_at_least_some_args = false;
  84. fprintf(f, "\n - arguments :: ");
  85. if (fun->value.function.positional_arguments->next_index != 0) {
  86. if (!printed_at_least_some_args)
  87. fprintf(f, ":");
  88. fprintf(f, "\n - postitional :: ");
  89. fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.positional_arguments->symbols[0]->value.symbol.identifier));
  90. for (int i = 1; i < fun->value.function.positional_arguments->next_index; ++i) {
  91. fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.positional_arguments->symbols[i]->value.symbol.identifier));
  92. }
  93. }
  94. if (fun->value.function.keyword_arguments->next_index != 0) {
  95. if (!printed_at_least_some_args)
  96. fprintf(f, ":");
  97. fprintf(f, "\n - keyword :: ");
  98. fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.keyword_arguments->keywords[0]->value.symbol.identifier));
  99. if (fun->value.function.keyword_arguments->values->data[0]) {
  100. fprintf(f, " =(");
  101. print(fun->value.function.keyword_arguments->values->data[0], true, f);
  102. fprintf(f, ")=");
  103. }
  104. for (int i = 1; i < fun->value.function.keyword_arguments->next_index; ++i) {
  105. fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.keyword_arguments->keywords[i]->value.symbol.identifier));
  106. if (fun->value.function.keyword_arguments->values->data[i]) {
  107. fprintf(f, " =(");
  108. print(fun->value.function.keyword_arguments->values->data[i], true, f);
  109. fprintf(f, ")=");
  110. }
  111. }
  112. }
  113. if (fun->value.function.rest_argument) {
  114. if (!printed_at_least_some_args)
  115. fprintf(f, ":");
  116. fprintf(f, "\n - rest :: =%s=", Memory::get_c_str(fun->value.function.rest_argument));
  117. }
  118. // if no args at all
  119. if (fun->value.function.positional_arguments->next_index == 0 &&
  120. fun->value.function.keyword_arguments->next_index == 0 &&
  121. !fun->value.function.rest_argument)
  122. {
  123. fprintf(f, "none.");
  124. }
  125. }
  126. fprintf(f, "\n - docu :: ");
  127. if (env->values[i]->docstring)
  128. fprintf(f, "\n #+BEGIN:\n%s\n #+END:\n",
  129. Memory::get_c_str(env->values[i]->docstring));
  130. else
  131. fprintf(f, "none\n");
  132. if (Memory::get_type(env->values[i]) == Lisp_Object_Type::Function &&
  133. env->values[i]->userType &&
  134. (string_equal(env->values[i]->userType->value.symbol.identifier, "package") ||
  135. string_equal(env->values[i]->userType->value.symbol.identifier, "constructor")))
  136. {
  137. char new_prefix[200];
  138. strcpy(new_prefix, prefix);
  139. strcat(new_prefix, env->keys[i]);
  140. strcat(new_prefix, " ");
  141. print_this_env(env->values[i]->value.function.parent_environment, new_prefix);
  142. }
  143. }
  144. }
  145. for (int i = 0; i < env->parents->next_index; ++i) {
  146. print_this_env(env->parents->data[i], prefix);
  147. }
  148. };
  149. print_this_env(get_current_environment(), (char*)"");
  150. }