Genetic Turmit Evolver
python
c
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

turmit.c 8.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. #include "turmit.h"
  2. TURMIT_OP(mem_sz)
  3. {
  4. turmit_int *new;
  5. turmit_int new_sz, old_sz, new_blc, old_blc;
  6. old_sz = turmit->stack_sz;
  7. old_blc = (old_sz / TURMIT_STACK_GROW) + 1;
  8. new_sz = SPOP(turmit);
  9. new_sz %= TURMIT_STACK_MAX;
  10. new_sz = new_sz<2?2:new_sz;
  11. new_blc = (new_sz / TURMIT_STACK_GROW) + 1;
  12. if(new_blc != old_blc)
  13. {
  14. new = realloc(turmit->stack,
  15. sizeof(turmit_int) * (new_blc * TURMIT_STACK_GROW));
  16. if(!new) {
  17. perror("Unable to reallocate memory for stack");
  18. return;
  19. }
  20. turmit->stack = new;
  21. }
  22. turmit->stack_sz = new_sz;
  23. turmit->stack_cur %= new_sz;
  24. if(old_sz < new_sz)
  25. {
  26. bzero(turmit->stack + old_sz,
  27. sizeof(turmit_int) * (new_sz - old_sz));
  28. }
  29. }
  30. TURMIT_OP(add)
  31. {
  32. turmit_int a = SPOP(turmit), b = SPOP(turmit);
  33. SPUSH(turmit, a+b);
  34. }
  35. TURMIT_OP(sub)
  36. {
  37. turmit_int a = SPOP(turmit), b = SPOP(turmit);
  38. if(turmit->flags & TURMIT_SIGNED)
  39. {
  40. fprintf(stderr, "Signed int not implemented\n");
  41. }
  42. else
  43. {
  44. SPUSH(turmit, a>b?(turmit->int_max - a) + b:b - a);
  45. }
  46. }
  47. TURMIT_OP(bin_and)
  48. {
  49. turmit_int a = SPOP(turmit), b = SPOP(turmit);
  50. SPUSH(turmit, b & a);
  51. }
  52. TURMIT_OP(dup)
  53. {
  54. turmit_int a = SCUR(turmit);
  55. SPUSH(turmit, a);
  56. }
  57. TURMIT_OP(lshift)
  58. {
  59. turmit_int a,b;
  60. a = SPOP(turmit); b = SPOP(turmit);
  61. SPUSH(turmit, b << a);
  62. }
  63. TURMIT_OP(mod)
  64. {
  65. turmit_int a,b;
  66. a = SPOP(turmit); b = SPOP(turmit);
  67. a = !a?0:b%a;
  68. SPUSH(turmit, a);
  69. }
  70. TURMIT_OP(mul)
  71. {
  72. turmit_int a = SPOP(turmit), b = SPOP(turmit);
  73. SPUSH(turmit, a*b);
  74. }
  75. TURMIT_OP(div)
  76. {
  77. turmit_int a, b;
  78. a = SPOP(turmit);
  79. b = SPOP(turmit);
  80. SPUSH(turmit, a==0?0:b/a);
  81. }
  82. TURMIT_OP(bin_or)
  83. {
  84. turmit_int a = SPOP(turmit), b = SPOP(turmit);
  85. SPUSH(turmit, a | b);
  86. }
  87. TURMIT_OP(bin_xor)
  88. {
  89. turmit_int a = SPOP(turmit), b = SPOP(turmit);
  90. SPUSH(turmit, a ^ b);
  91. }
  92. TURMIT_OP(pop)
  93. {
  94. SPOP(turmit);
  95. }
  96. TURMIT_OP(swp)
  97. {
  98. turmit_int a, b;
  99. a = SPOP(turmit);
  100. b = SPOP(turmit);
  101. SPUSH(turmit, a);
  102. SPUSH(turmit, b);
  103. }
  104. TURMIT_OP(jmp)
  105. {
  106. turmit_int a;
  107. a = SPOP(turmit);
  108. TURMIT_JMP(turmit, a);
  109. }
  110. TURMIT_OP(jz)
  111. {
  112. turmit_int a, b;
  113. a = SPOP(turmit);
  114. b = SPOP(turmit);
  115. if(b == 0)
  116. {
  117. TURMIT_JMP(turmit, a);
  118. }
  119. }
  120. TURMIT_OP(jcmp)
  121. {
  122. turmit_int a, b, cnd, offset;
  123. offset = SPOP(turmit);
  124. cnd = SPOP(turmit);
  125. b = SPOP(turmit);
  126. a = SPOP(turmit);
  127. if(((cnd & 7) == 0 && a != b) || (cnd > 6) || ((cnd & 1) && a == b) ||
  128. ((cnd & 7) > 2 && a < b) || ((cnd & 7) > 4 && a > b))
  129. {
  130. TURMIT_JMP(turmit, offset);
  131. }
  132. }
  133. turmit_t *turmit_alloc(ssize_t stack_sz, ssize_t int_max, const char *expr,
  134. unsigned char flags)
  135. {
  136. turmit_t *res;
  137. res = malloc(sizeof(struct turmit_s));
  138. if(!res)
  139. {
  140. perror("Unable to allocate memory for turmit");
  141. return NULL;
  142. }
  143. return turmit_init(res, stack_sz, int_max, expr, flags);
  144. }
  145. turmit_t *turmit_init(turmit_t *turmit, ssize_t stack_sz, ssize_t int_max,
  146. const char *expr, unsigned char flags)
  147. {
  148. turmit->expr = strndup(expr, TURMIT_EXPR_MAX_SZ);
  149. turmit->flags = flags;
  150. turmit->int_max = int_max;
  151. turmit->op_expr = NULL;
  152. turmit->op_expr_sz = 0;
  153. turmit->op_cur = 0;
  154. turmit->op_end = 0;
  155. turmit->stack_sz = stack_sz;
  156. turmit->stack_cur = turmit->stack_sz - 1;
  157. turmit->err = 0;
  158. turmit->err_str = NULL;
  159. turmit->stack = malloc(sizeof(turmit_int) *
  160. ((turmit->stack_sz / TURMIT_STACK_GROW)+1) * TURMIT_STACK_GROW);
  161. if(!turmit->stack)
  162. {
  163. perror("Unable to allocate turmit's stack's memory");
  164. return turmit;
  165. }
  166. bzero(turmit->stack, sizeof(turmit_int) * turmit->stack_sz);
  167. if(turmit->flags & TURMIT_AUTOCOMP)
  168. {
  169. turmit_compile(turmit);
  170. }
  171. return turmit;
  172. }
  173. turmit_t *turmit_copy(turmit_t *turmit)
  174. {
  175. turmit_t *res;
  176. turmit_int stack_blck;
  177. res = malloc(sizeof(turmit_t));
  178. if(!res)
  179. {
  180. perror("Unable to allocate memory for copy");
  181. return NULL;
  182. }
  183. memcpy(res, turmit, sizeof(turmit_t));
  184. if(turmit->expr)
  185. {
  186. res->expr = strdup(turmit->expr);
  187. }
  188. if(turmit->stack)
  189. {
  190. stack_blck = (res->stack_sz / TURMIT_STACK_GROW) + 1;
  191. res->stack = malloc(
  192. sizeof(turmit_int) * stack_blck * TURMIT_STACK_GROW);
  193. memcpy(res->stack, turmit->stack,
  194. sizeof(turmit_int) * stack_blck * TURMIT_STACK_GROW);
  195. }
  196. if(turmit->op_expr)
  197. {
  198. res->op_expr = malloc(sizeof(turmit_op_t) * res->op_expr_sz);
  199. if(!res->op_expr)
  200. {
  201. perror("Unable to allocate memory for expression");
  202. return res;
  203. }
  204. memcpy(res->op_expr, turmit->op_expr,
  205. sizeof(turmit_op_t) * res->op_expr_sz);
  206. }
  207. return res;
  208. }
  209. void turmit_clean(turmit_t *turmit)
  210. {
  211. if(turmit->stack) { free(turmit->stack); }
  212. if(turmit->err_str) { free(turmit->err_str); }
  213. if(turmit->expr) { free(turmit->expr); }
  214. if(turmit->op_expr) { free(turmit->op_expr); }
  215. }
  216. void turmit_free(turmit_t *turmit)
  217. {
  218. turmit_clean(turmit);
  219. free(turmit);
  220. }
  221. turmit_int turmit_exec(turmit_t *turmit, const turmit_int args[5])
  222. {
  223. turmit_op_t *op;
  224. turmit->op_cur = 0;
  225. turmit->op_end = 0;
  226. while(!turmit->op_end && turmit->op_cur < turmit->op_expr_sz)
  227. {
  228. op = &(turmit->op_expr[turmit->op_cur]);
  229. switch(op->value)
  230. {
  231. case TURMIT_SYM_OP:
  232. op->op.op(turmit);
  233. break;
  234. case TURMIT_SYM_VAL:
  235. SPUSH(turmit, op->op.val);
  236. break;
  237. case TURMIT_SYM_VAR:
  238. SPUSH(turmit, args[op->op.var]);
  239. break;
  240. default:
  241. // Null sym encountered. This sould NOT append
  242. fprintf(stderr, "Warning NULL sym encountered\n");
  243. turmit->op_cur = turmit->op_expr_sz;
  244. break;
  245. }
  246. //_turmit_stack_dump(turmit);
  247. turmit->op_cur++;
  248. }
  249. return SCUR(turmit);
  250. }
  251. int turmit_compile(turmit_t *turmit)
  252. {
  253. #pragma GCC diagnostic push
  254. #pragma GCC diagnostic ignored "-Wmissing-braces"
  255. turmit_sym_t tsym[] = TURMIT_OP_LST;
  256. #pragma GCC diagnostic pop
  257. char *cur, *endptr;
  258. turmit_sym_t *isym;
  259. ssize_t opcur;
  260. turmit_op_t *pret;
  261. long int iret;
  262. int err;
  263. int i;
  264. turmit->op_expr_sz = 64;
  265. turmit->op_expr = malloc(sizeof(turmit_op_t) * turmit->op_expr_sz);
  266. bzero(turmit->op_expr, sizeof(turmit_op_t) * turmit->op_expr_sz);
  267. opcur = 0;
  268. cur = turmit->expr;
  269. while(*cur != '\0')
  270. {
  271. if(opcur >= turmit->op_expr_sz - 1)
  272. { //more space needed
  273. turmit->op_expr_sz += 64;
  274. pret = realloc(turmit->op_expr,
  275. sizeof(turmit_op_t) * turmit->op_expr_sz);
  276. if(!pret)
  277. {
  278. perror("Unable to allocate memory");
  279. goto turmit_compile_err;
  280. }
  281. bzero(pret + opcur - 1,
  282. 64 * sizeof(turmit_op_t));
  283. turmit->op_expr = pret;
  284. }
  285. //Checking for separators
  286. if(*cur == ' ' || *cur == '\t' || *cur == ' ')
  287. {
  288. cur++;
  289. continue;
  290. }
  291. //Checking for variables
  292. for(i=0; TURMIT_VAR_L[i] != '\0'; i++)
  293. {
  294. if(tolower(*cur) == TURMIT_VAR_L[i])
  295. {
  296. turmit->op_expr[opcur].op.var = i;
  297. turmit->op_expr[opcur].value = TURMIT_SYM_VAR;
  298. opcur++;
  299. cur++;
  300. break;
  301. }
  302. }
  303. if(TURMIT_VAR_L[i] != '\0') { continue; }
  304. //Checking for values
  305. //hex
  306. if(strncasecmp("0x", cur, 2) == 0)
  307. {
  308. cur+= 2;
  309. errno = 0;
  310. iret = strtol(cur, &endptr, 16);
  311. err = errno;
  312. if(err || endptr == cur)
  313. {
  314. fprintf(stderr, "Invalid constant %s : %s\n",
  315. cur-2, strerror(err));
  316. goto turmit_compile_err;
  317. }
  318. turmit->op_expr[opcur].op.val = iret;
  319. turmit->op_expr[opcur].value = TURMIT_SYM_VAL;
  320. opcur++;
  321. cur = endptr;
  322. continue;
  323. }
  324. //decimal
  325. if(*cur <= '9' && *cur >= '0')
  326. {
  327. iret = strtol(cur, &endptr, 10);
  328. err = errno;
  329. if(err || endptr == cur)
  330. {
  331. fprintf(stderr, "Invalid constant %s : %s\n",
  332. cur, strerror(err));
  333. goto turmit_compile_err;
  334. }
  335. turmit->op_expr[opcur].op.val = iret;
  336. turmit->op_expr[opcur].value = TURMIT_SYM_VAL;
  337. opcur++;
  338. cur = endptr;
  339. continue;
  340. }
  341. //Checking for op
  342. isym = tsym;
  343. while(isym->str != NULL)
  344. {
  345. endptr = cur;
  346. if(strncasecmp(isym->str, cur, strlen(isym->str)) == 0)
  347. {
  348. endptr = cur+strlen(isym->str);
  349. }
  350. else if(isym->alias && strncmp(cur, isym->alias,
  351. strlen(isym->alias)) == 0)
  352. {
  353. endptr = cur+strlen(isym->alias);
  354. }
  355. if(cur != endptr)
  356. {
  357. cur = endptr;
  358. turmit->op_expr[opcur].op.op = isym->op_fun;
  359. turmit->op_expr[opcur].value = TURMIT_SYM_OP;
  360. opcur++;
  361. break;
  362. }
  363. isym++;
  364. }
  365. if(isym->str != NULL)
  366. {
  367. continue;
  368. }
  369. //unrecognized symbol :'(
  370. turmit->err = 1;
  371. if(turmit->err_str) { free(turmit->err_str); }
  372. turmit->err_str = malloc(sizeof(char) * 256);
  373. if(!turmit->err_str)
  374. {
  375. perror("Unable to allocate memory for error string");
  376. return -1;
  377. }
  378. snprintf(turmit->err_str, 256,
  379. "Error compiling prog starting at : '%s'", cur);
  380. goto turmit_compile_err;
  381. }
  382. if(!opcur)
  383. { //empty expression
  384. turmit->op_expr_sz = 0;
  385. free(turmit->op_expr);
  386. turmit->op_expr = NULL;
  387. return 0;
  388. }
  389. turmit->op_expr_sz = opcur;
  390. pret = realloc(turmit->op_expr,
  391. sizeof(turmit_op_t) * turmit->op_expr_sz);
  392. if(!pret)
  393. {
  394. perror("Unable to shrink op_expr");
  395. return 1;
  396. }
  397. else
  398. {
  399. turmit->op_expr = pret;
  400. }
  401. return 0;
  402. turmit_compile_err:
  403. free(turmit->op_expr);
  404. turmit->op_expr = NULL;
  405. turmit->op_expr_sz = 0;
  406. turmit->op_cur = 0;
  407. return 1;
  408. }
  409. void _turmit_stack_dump(turmit_t *turmit)
  410. {
  411. int i;
  412. fprintf(stderr, "Stack cur = %lu\n[", turmit->stack_cur);
  413. for(i=0; i<turmit->stack_sz; i++)
  414. {
  415. fprintf(stderr,"%llu, ", turmit->stack[i]);
  416. }
  417. fprintf(stderr, "]\n");
  418. }