aFunlang.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. #include "aFunCore.h"
  2. #include "__aFunlang.h"
  3. #include "__env.h"
  4. static int runCode_(FilePath name, af_Parser *parser, int mode, FilePath save_path, af_Environment *env);
  5. static bool aFunInit_mark = false;
  6. bool aFunInit(aFunInitInfo *info) {
  7. if (aFunInit_mark)
  8. return false;
  9. if (info == NULL) {
  10. static aFunInitInfo info_default = {
  11. .base_dir=".",
  12. .buf=NULL,
  13. .level=log_info
  14. };
  15. info = &info_default;
  16. }
  17. aFunCoreInitInfo core_info = {.base_dir=info->base_dir,
  18. .buf=info->buf,
  19. .level=info->level};
  20. aFunInit_mark = aFunCoreInit(&core_info);
  21. if (aFunInit_mark)
  22. writeDebugLog(aFunCoreLogger, "aFun-runtime Init success");
  23. return aFunInit_mark;
  24. }
  25. af_Environment *creatAFunEnvironment(int argc, char **argv){
  26. if (!aFunInit_mark)
  27. return NULL;
  28. af_Environment *env = makeEnvironment(grt_count);
  29. af_Code *code = NULL;
  30. for(int i = 0; i < argc; i++)
  31. writeTrackLog(aFunCoreLogger, "[aFunlang] Env-arg %d. %s", i, argv[i]);
  32. env->core->argc->num = argc;
  33. for (int i = 0; i < argc; i++) {
  34. char tmp[512] = {0};
  35. snprintf(tmp, 512, ev_argvx_prefix "%d", i);
  36. setEnvVarData(tmp, argv[i], env);
  37. }
  38. runtimeTool("base", &code, NULL, env->core->protect, env);
  39. if (code != NULL) {
  40. bool res = iterCode(code, 0, env);
  41. freeAllCode(code);
  42. if (!res) {
  43. freeEnvironment(env);
  44. return NULL;
  45. }
  46. }
  47. enableEnvironment(env);
  48. return env;
  49. }
  50. void destructAFunEnvironment(af_Environment *env) {
  51. freeEnvironment(env);
  52. }
  53. static int runCode_(FilePath name, af_Parser *parser, int mode, FilePath save_path, af_Environment *env){
  54. if (parser == NULL)
  55. return -1;
  56. af_Code *bt_code = parserCode(name, parser);
  57. freeParser(parser);
  58. if (bt_code == NULL)
  59. return -2;
  60. /* 写入文件 */
  61. if (save_path != NULL) {
  62. int res = writeByteCode(bt_code, save_path);
  63. if (res != 1) {
  64. writeErrorLog(aFunCoreLogger, "Save %s bytecode error: %s", save_path, writeByteCodeError[res]);
  65. printf_stderr(0, "%s: %s\n", HT_aFunGetText(run_save_e, "Save aFun Bytecode file error"), save_path);
  66. }
  67. }
  68. bool res = iterCode(bt_code, mode, env);
  69. freeAllCode(bt_code);
  70. if (!res)
  71. return env->core->exit_code_->num;
  72. return 0;
  73. }
  74. /*
  75. * 函数名: runCodeFromString
  76. * 目标: 运行字符串中的程序 (源码形式)
  77. */
  78. int runCodeFromString(char *code, char *string_name, int mode, af_Environment *env){
  79. if (env == NULL || code == NULL || !aFunInit_mark)
  80. return -1;
  81. if (string_name == NULL)
  82. string_name = "string-code.aun";
  83. af_Parser *parser = makeParserByString(code, false);
  84. return runCode_(string_name, parser, mode, NULL, env);
  85. }
  86. /*
  87. * 函数名: runCodeFromFileSource
  88. * 目标: 运行文件中的程序 (源码形式)
  89. */
  90. int runCodeFromFileSource(FilePath file, bool save_afb, FilePath save_path, int mode, af_Environment *env){
  91. if (env == NULL || file == NULL || !aFunInit_mark)
  92. return -1;
  93. char *sufix = getFileSurfix(file);
  94. if (sufix == NULL || !EQ_STR(".aun", sufix)) {
  95. writeErrorLog(aFunCoreLogger, "Source is not .aun file: %s", (sufix == NULL ? "" : sufix));
  96. printf_stderr(0, "%s: %s\n", HT_aFunGetText(run_source_not_aub_e, "Source is not .aun file"), (sufix == NULL ? "" : sufix));
  97. return -2;
  98. }
  99. /* 若文件不存在则自动生成 */
  100. bool free_save_path = false;
  101. if (save_afb && !save_path) {
  102. char *path = getFileNameWithPath(file);
  103. save_path = strJoin(path, ".aub", true, false);
  104. free_save_path = true;
  105. } else if (!save_afb)
  106. save_path = NULL;
  107. af_Parser *parser = makeParserByFile(file);
  108. int exit_code = runCode_(file, parser, mode, save_path, env);
  109. if (free_save_path)
  110. free(save_path);
  111. return exit_code;
  112. }
  113. /*
  114. * 函数名: runCodeFromStdin
  115. * 目标: 运行stdin的程序 (源码形式)
  116. */
  117. int runCodeFromStdin(char *name, af_Environment *env){
  118. if (env == NULL || feof(stdin) || ferror(stdin) || !aFunInit_mark)
  119. return -1;
  120. if (name == NULL)
  121. name = "sys-stdin.aun";
  122. af_Parser *parser = makeParserByStdin();
  123. return runCode_(name, parser, 0, NULL, env);
  124. }
  125. /*
  126. * 函数名: runCodeFromMemory
  127. * 目标: 运行内存中的程序 (字节码形式)
  128. */
  129. int runCodeFromMemory(af_Code *code, int mode, af_Environment *env){
  130. if (!aFunInit_mark)
  131. return -1;
  132. bool res = iterCode(code, mode, env);
  133. if (!res)
  134. return env->core->exit_code_->num;
  135. return 0;
  136. }
  137. /*
  138. * 函数名: runCodeFromFileByte
  139. * 目标: 运行文件中的程序 (字节码形式)
  140. */
  141. int runCodeFromFileByte(FilePath file, int mode, af_Environment *env){
  142. if (env == NULL || file == NULL || !aFunInit_mark)
  143. return -1;
  144. char *sufix = getFileSurfix(file);
  145. if (sufix == NULL || !EQ_STR(".aub", sufix)) {
  146. writeErrorLog(aFunCoreLogger, "Bytecode not .aub file: %s", (sufix == NULL ? "" : sufix));
  147. printf_stderr(0, "%s: %s\n", HT_aFunGetText(run_bt_not_aub_e, "Bytecode not .aub file"), (sufix == NULL ? "" : sufix));
  148. return -2;
  149. }
  150. af_Code *code = NULL;
  151. int res = readByteCode(&code, file);
  152. if(res != 1) {
  153. writeErrorLog(aFunCoreLogger, "Load %s bytecode file error: %s", file, readByteCodeError[res]);
  154. printf_stderr(0, "%s: %s\n", HT_aFunGetText(run_load_bt_e, "Load bytecode file error"), file);
  155. return -2;
  156. }
  157. int exit_code = runCodeFromMemory(code, mode, env);
  158. freeAllCode(code);
  159. return exit_code;
  160. }
  161. /*
  162. * 函数名: runCodeFromFileByte
  163. * 目标: 运行文件中的程序 (字节码/源码形式)
  164. */
  165. int runCodeFromFile(FilePath file, bool save_afb, int mode, af_Environment *env){
  166. if (env == NULL || file == NULL || !aFunInit_mark)
  167. return -1;
  168. char *sufix = getFileSurfix(file);
  169. if (sufix != NULL && !EQ_STR(".aun", sufix) && !EQ_STR(".aub", sufix)) { // 不是源文件, 字节码文件或无后缀文件
  170. writeErrorLog(aFunCoreLogger, "Run file not .aun/.aub file: %s", sufix);
  171. printf_stderr(0, "%s: %s\n", HT_aFunGetText(run_file_aun_aub_e, "Run file not .aun/.aub file"), file);
  172. return -2;
  173. }
  174. char *path = getFileNameWithPath(file);
  175. char *path_1 = strJoin(path, ".aun", false, false);
  176. char *path_2 = strJoin(path, ".aub", true, false); // 此时释放path
  177. time_t time_1 = getFileMTime(path_1);
  178. time_t time_2 = getFileMTime(path_2);
  179. if (time_1 == 0 && time_2 == 0) {
  180. writeErrorLog(aFunCoreLogger, "Run file not exists: %s", file);
  181. printf_stderr(0, "%s: %s\n", HT_aFunGetText(run_file_not_exists_e, "Run file not exists"), file);
  182. free(path_1);
  183. free(path_2);
  184. return -3;
  185. }
  186. int exit_code;
  187. if (time_2 >= time_1) {
  188. exit_code = runCodeFromFileByte(path_2, mode, env);
  189. if (exit_code != 0)
  190. goto RUN_SOURCE_CODE;
  191. } else {
  192. RUN_SOURCE_CODE:
  193. exit_code = runCodeFromFileSource(path_1, save_afb, path_2, mode, env);
  194. }
  195. free(path_1);
  196. free(path_2);
  197. return exit_code;
  198. }
  199. /*
  200. * 函数名: buildFile
  201. * 目标: 生成字节码文件
  202. */
  203. int buildFile(FilePath out, FilePath in){
  204. if (out == NULL || in == NULL || !aFunInit_mark)
  205. return -1;
  206. char *suffix_in = getFileSurfix(in);
  207. char *suffix_out = getFileSurfix(out);
  208. if (suffix_in == NULL || !EQ_STR(".aun", suffix_in)) { // 不是源文件
  209. writeErrorLog(aFunCoreLogger, "Input not .aun %s", (suffix_in == NULL ? "" : suffix_in));
  210. printf_stderr("%s: %s\n", HT_aFunGetText(build_in_aun_e, "Input file is not .aun file"), (suffix_in == NULL ? "" : suffix_in));
  211. return -2;
  212. }
  213. if (suffix_out == NULL || !EQ_STR(".aub", suffix_out)) { // 不是字节码文件
  214. writeErrorLog(aFunCoreLogger, "Output not .aub %s", (suffix_out == NULL ? "" : suffix_out));
  215. printf_stderr("%s: %s\n", HT_aFunGetText(build_out_aub_e, "Output file is not .aub file"), (suffix_out == NULL ? "" : suffix_out));
  216. return -2;
  217. }
  218. af_Parser *parser = makeParserByFile(in);
  219. af_Code *code = parserCode(in, parser);
  220. freeParser(parser);
  221. if (code == NULL)
  222. return -2;
  223. int res = writeByteCode(code, out);
  224. freeAllCode(code);
  225. if (res != 1) {
  226. writeErrorLog(aFunCoreLogger, "Build %s error: %s", in, writeByteCodeError[res]);
  227. printf_stderr(0, "%s: %s\n", HT_aFunGetText(build_error_e, "Build error"), in);
  228. return -3;
  229. }
  230. return 0;
  231. }