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.2KB

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