aFunlang.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #include "__aFunlang.h"
  2. #include "aFunCore.h"
  3. #include "__env.h"
  4. static int runCode_(FilePath name, af_Parser *parser, int mode, FilePath save_path, af_Environment *env);
  5. void aFunInit() {
  6. aFunCoreInit();
  7. }
  8. af_Environment *creatAFunEnviroment(void) {
  9. af_Environment *env = makeEnvironment(grt_count);
  10. af_Code *code;
  11. aFunTool("base", &code, NULL, env->core->protect, env);
  12. if (code != NULL) {
  13. bool res = iterCode(code, 0, env);
  14. freeAllCode(code);
  15. if (!res) {
  16. freeEnvironment(env);
  17. return NULL;
  18. }
  19. }
  20. enableEnvironment(env);
  21. return env;
  22. }
  23. void destructAFunEnvironment(af_Environment *env) {
  24. freeEnvironment(env);
  25. }
  26. static int runCode_(FilePath name, af_Parser *parser, int mode, FilePath save_path, af_Environment *env){
  27. if (parser == NULL)
  28. return -1;
  29. af_Code *bt_code = parserCode(name, parser);
  30. freeParser(parser);
  31. if (bt_code == NULL)
  32. return -2;
  33. /* 写入文件 */
  34. if (save_path != NULL)
  35. writeAllCode(bt_code, save_path);
  36. bool res = iterCode(bt_code, mode, env);
  37. freeAllCode(bt_code);
  38. if (!res)
  39. return env->core->exit_code;
  40. return 0;
  41. }
  42. /*
  43. * 函数名: runCodeFromString
  44. * 目标: 运行字符串中的程序 (源码形式)
  45. */
  46. int runCodeFromString(char *code, char *string_name, FILE *error_file, af_Environment *env) {
  47. if (env == NULL || code == NULL)
  48. return -1;
  49. if (string_name == NULL)
  50. string_name = "string-code.aun";
  51. if (error_file == NULL)
  52. error_file = stderr;
  53. af_Parser *parser = makeParserByString(code, false, error_file);
  54. return runCode_(string_name, parser, 1, NULL, env);
  55. }
  56. /*
  57. * 函数名: runCodeFromFileSource
  58. * 目标: 运行文件中的程序 (源码形式)
  59. */
  60. int runCodeFromFileSource(FilePath file, FILE *error_file, bool save_afb, FilePath save_path, af_Environment *env) {
  61. if (env == NULL || file == NULL)
  62. return -1;
  63. if (error_file == NULL)
  64. error_file = stderr;
  65. char *sufix = getFileSurfix(file);
  66. if (sufix == NULL || !EQ_STR(".aun", sufix)) {
  67. fprintf(error_file, "Is not .aun file[%s].", (sufix == NULL ? "" : sufix));
  68. return -2;
  69. }
  70. /* 若文件不存在则自动生成 */
  71. bool free_save_path = false;
  72. if (save_afb && !save_path) {
  73. char *path = getFileNameWithPath(file);
  74. save_path = strJoin(path, ".aub", true, false);
  75. free_save_path = true;
  76. } else if (!save_afb)
  77. save_path = NULL;
  78. af_Parser *parser = makeParserByFile(file, error_file);
  79. int exit_code = runCode_(file, parser, 1, save_path, env);
  80. if (free_save_path)
  81. free(save_path);
  82. return exit_code;
  83. }
  84. /*
  85. * 函数名: runCodeFromStdin
  86. * 目标: 运行stdin的程序 (源码形式)
  87. */
  88. int runCodeFromStdin(char *name, FILE *error_file, af_Environment *env) {
  89. if (env == NULL || feof(stdin) || ferror(stdin))
  90. return -1;
  91. if (name == NULL)
  92. name = "sys-stdin.aun";
  93. if (error_file == NULL)
  94. error_file = stderr;
  95. af_Parser *parser = makeParserByStdin(error_file);
  96. return runCode_(name, parser, 0, NULL, env);
  97. }
  98. /*
  99. * 函数名: runCodeFromMemory
  100. * 目标: 运行内存中的程序 (字节码形式)
  101. */
  102. int runCodeFromMemory(af_Code *code, af_Environment *env) {
  103. bool res = iterCode(code, 0, env);
  104. if (!res)
  105. return env->core->exit_code;
  106. return 0;
  107. }
  108. /*
  109. * 函数名: runCodeFromMemoryAsImport
  110. * 目标: 采用import的方式运行内存中程序 (字节码形式)
  111. */
  112. int runCodeFromMemoryAsImport(af_Code *code, af_Environment *env) {
  113. bool res = iterCode(code, 1, env);
  114. if (!res)
  115. return env->core->exit_code;
  116. return 0;
  117. }
  118. /*
  119. * 函数名: runCodeFromFileByte
  120. * 目标: 运行文件中的程序 (字节码形式)
  121. */
  122. int runCodeFromFileByte(FilePath file, FILE *error_file, af_Environment *env) {
  123. if (env == NULL || file == NULL)
  124. return -1;
  125. if (error_file == NULL)
  126. error_file = stderr;
  127. char *sufix = getFileSurfix(file);
  128. if (sufix == NULL || !EQ_STR(".aub", sufix)) {
  129. fprintf(error_file, "Is not .aub file[%s].", (sufix == NULL ? "" : sufix));
  130. return -2;
  131. }
  132. af_Code *code;
  133. if(!readAllCode(&code, file)) {
  134. freeAllCode(code);
  135. return -2;
  136. }
  137. int exit_code = runCodeFromMemoryAsImport(code, env);
  138. freeAllCode(code);
  139. return exit_code;
  140. }
  141. /*
  142. * 函数名: runCodeFromFileByte
  143. * 目标: 运行文件中的程序 (字节码/源码形式)
  144. */
  145. int runCodeFromFile(FilePath file, FILE *error_file, bool save_afb, af_Environment *env) {
  146. if (env == NULL || file == NULL)
  147. return -1;
  148. if (error_file == NULL)
  149. error_file = stderr;
  150. char *sufix = getFileSurfix(file);
  151. if (sufix == NULL || (!EQ_STR(".aun", sufix) && EQ_STR(".aub", sufix))) { // 不是源文件或字节码文件
  152. fprintf(error_file, "Is not .aun/.aub file[%s].", (sufix == NULL ? "" : sufix));
  153. return -2;
  154. }
  155. char *path = getFileNameWithPath(file);
  156. char *path_1 = strJoin(path, ".aun", false, false);
  157. char *path_2 = strJoin(path, ".aub", true, false); // 此时释放path
  158. time_t time_1 = getFileMTime(path_1);
  159. time_t time_2 = getFileMTime(path_2);
  160. if (time_1 == 0 && time_2 == 0) {
  161. fprintf(error_file, "File not exists [%s].", file);
  162. free(path_1);
  163. free(path_2);
  164. return -3;
  165. }
  166. int exit_code;
  167. if (time_2 >= time_1)
  168. exit_code = runCodeFromFileByte(path_2, error_file, env);
  169. else
  170. exit_code = runCodeFromFileSource(path_1, error_file, save_afb, path_2, env);
  171. free(path_1);
  172. free(path_2);
  173. return exit_code;
  174. }