aFunlang.c 7.4 KB

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