The Sol Programming Language!
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.

2687 lines
79 KiB

  1. #include <string.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <math.h>
  5. #include <stdint.h>
  6. #include <dlfcn.h>
  7. #include <readline/readline.h>
  8. #include <readline/history.h>
  9. #include "ast.h"
  10. #include "dsl/dsl.h"
  11. // XXX hardcoded buffer sizes
  12. #define STDIO_CHUNK_SIZE 4096
  13. static char *_itoa(int i) {
  14. int n = 33;
  15. char *s = malloc(n);
  16. snprintf(s, n, "%d", i);
  17. return s;
  18. }
  19. static char *_ftoa(double f) {
  20. int n = 65;
  21. char *s = malloc(n);
  22. snprintf(s, n, "%f", f);
  23. return s;
  24. }
  25. sol_object_t *sol_f_not_impl(sol_state_t *state, sol_object_t *args) {
  26. char buffer[64];
  27. snprintf(buffer, 64, "Undefined method (%s on %s)", state->calling_meth, state->calling_type);
  28. return sol_set_error_string(state, buffer);
  29. }
  30. sol_object_t *sol_f_default_cmp(sol_state_t *state, sol_object_t *args) {
  31. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
  32. sol_object_t *res = sol_new_int(state, a != b);
  33. sol_obj_free(a);
  34. sol_obj_free(b);
  35. return res;
  36. }
  37. sol_object_t *sol_f_default_tostring(sol_state_t *state, sol_object_t *args) {
  38. sol_object_t *obj = sol_list_get_index(state, args, 0);
  39. char s[64];
  40. snprintf(s, 64, "<%s object at %p>", obj->ops->tname, obj);
  41. sol_obj_free(obj);
  42. return sol_new_string(state, s);
  43. }
  44. sol_object_t *sol_f_default_repr(sol_state_t *state, sol_object_t *args) {
  45. sol_object_t *obj = sol_list_get_index(state, args, 0), *res = CALL_METHOD(state, obj, tostring, args);
  46. sol_obj_free(obj);
  47. return res;
  48. }
  49. sol_object_t *sol_f_tbang(sol_state_t *state, sol_object_t *args) {
  50. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
  51. int refa = a->refcnt, refb = b->refcnt;
  52. sol_object_t c = *b;
  53. *b = *a;
  54. *a = c;
  55. b->refcnt = refa;
  56. a->refcnt = refb;
  57. sol_obj_free(a);
  58. sol_obj_free(b);
  59. return sol_incref(state->None);
  60. }
  61. sol_object_t *sol_f_no_op(sol_state_t *state, sol_object_t *args) {
  62. if(state) {
  63. return sol_incref(state->None);
  64. }
  65. return NULL;
  66. }
  67. sol_object_t *sol_f_toint(sol_state_t *state, sol_object_t *args) {
  68. sol_object_t *obj = sol_list_get_index(state, args, 0);
  69. sol_object_t *res = CALL_METHOD(state, obj, toint, args);
  70. sol_obj_free(obj);
  71. return res;
  72. }
  73. sol_object_t *sol_f_tofloat(sol_state_t *state, sol_object_t *args) {
  74. sol_object_t *obj = sol_list_get_index(state, args, 0);
  75. sol_object_t *res = CALL_METHOD(state, obj, tofloat, args);
  76. sol_obj_free(obj);
  77. return res;
  78. }
  79. sol_object_t *sol_f_tostring(sol_state_t *state, sol_object_t *args) {
  80. sol_object_t *obj = sol_list_get_index(state, args, 0);
  81. sol_object_t *res = CALL_METHOD(state, obj, tostring, args);
  82. sol_obj_free(obj);
  83. return res;
  84. }
  85. sol_object_t *sol_f_try(sol_state_t *state, sol_object_t *args) {
  86. sol_object_t *func = sol_list_get_index(state, args, 0), *fargs = sol_list_sublist(state, args, 1);
  87. sol_object_t *ls = sol_new_list(state), *one = sol_new_int(state, 1);
  88. sol_object_t *res;
  89. sol_list_insert(state, fargs, 0, func);
  90. res = CALL_METHOD(state, func, call, fargs);
  91. sol_obj_free(func);
  92. sol_obj_free(fargs);
  93. if(sol_has_error(state)) {
  94. sol_object_t *err = sol_get_error(state);
  95. sol_clear_error(state);
  96. sol_object_t *zero = sol_new_int(state, 0);
  97. sol_obj_free(res);
  98. sol_obj_free(one);
  99. sol_list_insert(state, ls, 0, err);
  100. sol_obj_free(err);
  101. sol_list_insert(state, ls, 0, zero);
  102. sol_obj_free(zero);
  103. sol_list_insert(state, ls, 2, state->traceback);
  104. sol_obj_free(state->traceback);
  105. state->traceback = NULL;
  106. return ls;
  107. }
  108. sol_list_insert(state, ls, 0, res);
  109. sol_obj_free(res);
  110. sol_list_insert(state, ls, 0, one);
  111. sol_obj_free(one);
  112. return ls;
  113. }
  114. sol_object_t *sol_f_error(sol_state_t *state, sol_object_t *args) {
  115. sol_object_t *arg = sol_list_get_index(state, args, 0), *res;
  116. res = sol_set_error(state, arg);
  117. sol_obj_free(arg);
  118. return res;
  119. }
  120. sol_object_t *sol_f_type(sol_state_t *state, sol_object_t *args) {
  121. sol_object_t *obj = sol_list_get_index(state, args, 0);
  122. sol_object_t *res = sol_new_string(state, obj->ops->tname);
  123. sol_obj_free(obj);
  124. return res;
  125. }
  126. static dsl_seq *seen = NULL;
  127. int test_seen(sol_object_t *obj) {
  128. dsl_seq_iter *iter;
  129. if(seen) {
  130. iter = dsl_new_seq_iter(seen);
  131. while(!dsl_seq_iter_is_invalid(iter)) {
  132. if(dsl_seq_iter_at(iter) == obj) {
  133. return 1;
  134. }
  135. dsl_seq_iter_next(iter);
  136. }
  137. dsl_free_seq_iter(iter);
  138. dsl_seq_insert(seen, dsl_seq_len(seen), obj);
  139. }
  140. return 0;
  141. }
  142. void ob_print(sol_object_t *obj) {
  143. sol_object_t *cur;
  144. dsl_seq_iter *iter;
  145. int i;
  146. if(test_seen(obj)) {
  147. return;
  148. }
  149. switch(obj->type) {
  150. case SOL_SINGLET:
  151. printf("%s", obj->str);
  152. break;
  153. case SOL_INTEGER:
  154. printf("%ld", obj->ival);
  155. break;
  156. case SOL_FLOAT:
  157. printf("%f", obj->fval);
  158. break;
  159. case SOL_STRING:
  160. printf("\"%s\"", obj->str);
  161. break;
  162. case SOL_LIST:
  163. printf("[");
  164. iter = dsl_new_seq_iter(obj->seq);
  165. while(!dsl_seq_iter_is_invalid(iter)) {
  166. ob_print(dsl_seq_iter_at(iter));
  167. printf(", ");
  168. dsl_seq_iter_next(iter);
  169. }
  170. dsl_free_seq_iter(iter);
  171. printf("]");
  172. break;
  173. case SOL_MCELL:
  174. printf("<<");
  175. ob_print(obj->key);
  176. printf("=");
  177. ob_print(obj->val);
  178. printf(">>");
  179. case SOL_MAP:
  180. printf("{");
  181. iter = dsl_new_seq_iter(obj->seq);
  182. while(!dsl_seq_iter_is_invalid(iter)) {
  183. printf("[");
  184. ob_print(AS_OBJ(dsl_seq_iter_at(iter))->key);
  185. printf("] = ");
  186. ob_print(AS_OBJ(dsl_seq_iter_at(iter))->val);
  187. printf(", ");
  188. dsl_seq_iter_next(iter);
  189. }
  190. dsl_free_seq_iter(iter);
  191. printf("}");
  192. break;
  193. case SOL_FUNCTION:
  194. if(obj->fname) {
  195. printf("<Function %s>", obj->fname);
  196. } else {
  197. printf("<Function>");
  198. }
  199. break;
  200. case SOL_CFUNCTION:
  201. printf("<CFunction>");
  202. break;
  203. case SOL_STMT:
  204. st_print(NULL, obj->node); //TODO: FIXME
  205. break;
  206. case SOL_EXPR:
  207. ex_print(NULL, obj->node); //TODO: FIXME
  208. break;
  209. case SOL_BUFFER:
  210. if(obj->sz == -1) {
  211. printf("<Buffer @%p>", obj->buffer);
  212. } else {
  213. printf("<Buffer @%p size %ld>", obj->buffer, obj->sz);
  214. }
  215. break;
  216. case SOL_CDATA:
  217. printf("<CData>");
  218. break;
  219. /*default:
  220. cur = sol_cast_string(state, obj);
  221. printf("%s", cur->str);
  222. sol_obj_free(cur);*/
  223. }
  224. }
  225. sol_object_t *sol_f_prepr(sol_state_t *state, sol_object_t *args) {
  226. int i, sz = sol_list_len(state, args);
  227. sol_object_t *obj, *str;
  228. seen = dsl_seq_new_array(NULL, NULL);
  229. for(i = 0; i < sz; i++) {
  230. obj = sol_list_get_index(state, args, i);
  231. str = sol_cast_repr(state, obj);
  232. sol_printf(state, "%s", str->str);
  233. sol_printf(state, " ");
  234. sol_obj_free(obj);
  235. sol_obj_free(str);
  236. }
  237. sol_printf(state, "\n");
  238. printf("\n");
  239. dsl_free_seq(seen);
  240. seen = NULL;
  241. return sol_incref(state->None);
  242. }
  243. sol_object_t *sol_f_print(sol_state_t *state, sol_object_t *args) {
  244. int i, sz = sol_list_len(state, args);
  245. sol_object_t *obj, *str;
  246. seen = dsl_seq_new_array(NULL, NULL);
  247. for(i = 0; i < sz; i++) {
  248. obj = sol_list_get_index(state, args, i);
  249. str = sol_cast_string(state, obj);
  250. sol_printf(state, "%s", str->str);
  251. sol_printf(state, " ");
  252. sol_obj_free(obj);
  253. sol_obj_free(str);
  254. }
  255. sol_printf(state, "\n");
  256. dsl_free_seq(seen);
  257. seen = NULL;
  258. return sol_incref(state->None);
  259. }
  260. sol_object_t *sol_f_rawget(sol_state_t *state, sol_object_t *args) {
  261. sol_object_t *obj = sol_list_get_index(state, args, 0), *key, *res;
  262. if(!sol_is_map(obj)) {
  263. return sol_set_error_string(state, "Rawset of non-map");
  264. }
  265. key = sol_list_get_index(state, args, 1);
  266. res = sol_map_get(state, obj, key);
  267. sol_obj_free(key);
  268. sol_obj_free(obj);
  269. return res;
  270. }
  271. sol_object_t *sol_f_rawset(sol_state_t *state, sol_object_t *args) {
  272. sol_object_t *obj = sol_list_get_index(state, args, 0), *key, *val;
  273. if(!sol_is_map(obj)) {
  274. return sol_set_error_string(state, "Rawset of non-map");
  275. }
  276. key = sol_list_get_index(state, args, 1);
  277. val = sol_list_get_index(state, args, 2);
  278. sol_map_set(state, obj, key, val);
  279. sol_obj_free(val);
  280. sol_obj_free(key);
  281. sol_obj_free(obj);
  282. return sol_incref(state->None);
  283. }
  284. sol_object_t *sol_f_range(sol_state_t *state, sol_object_t *args) {
  285. sol_object_t *res = sol_new_list(state), *bound = sol_cast_int(state, sol_list_get_index(state, args, 0));
  286. int i;
  287. for(i = 0; i < bound->ival; i++) {
  288. sol_list_insert(state, res, sol_list_len(state, res), sol_new_int(state, i));
  289. }
  290. sol_obj_free(bound);
  291. return res;
  292. }
  293. sol_object_t *sol_f_exec(sol_state_t *state, sol_object_t *args) {
  294. sol_object_t *prg = sol_list_get_index(state, args, 0), *prgstr = sol_cast_string(state, prg);
  295. stmt_node *program;
  296. program = sol_compile(prgstr->str);
  297. if(!program) {
  298. return sol_set_error_string(state, "Compilation failure");
  299. }
  300. // XXX should st_free(program);
  301. sol_exec(state, program);
  302. return sol_incref(state->None);
  303. }
  304. sol_object_t *sol_f_eval(sol_state_t *state, sol_object_t *args) {
  305. sol_object_t *prg = sol_list_get_index(state, args, 0), *prgstr = sol_cast_string(state, prg);
  306. stmt_node *program;
  307. program = sol_compile(prgstr->str);
  308. if(!program) {
  309. return sol_set_error_string(state, "Compilation failure");
  310. }
  311. if(program->type != ST_LIST || program->stmtlist->stmt->type != ST_EXPR) {
  312. return sol_set_error_string(state, "Not an expression");
  313. }
  314. // XXX should st_free(program);
  315. return sol_eval(state, program->stmtlist->stmt->expr);
  316. }
  317. sol_object_t *sol_f_execfile(sol_state_t *state, sol_object_t *args) {
  318. sol_object_t *prg = sol_list_get_index(state, args, 0), *prgstr = sol_cast_string(state, prg);
  319. stmt_node *program;
  320. FILE *f = fopen(prgstr->str, "r");
  321. char *s;
  322. long sz;
  323. if(!f) {
  324. return sol_set_error_string(state, "File open failure");
  325. }
  326. fseek(f, 0, SEEK_END);
  327. sz = ftell(f);
  328. fseek(f, 0, SEEK_SET);
  329. s = malloc(sz + 1);
  330. if(!s) {
  331. fclose(f);
  332. return sol_set_error_string(state, "File memory allocation failure");
  333. }
  334. fread(s, 1, sz, f);
  335. s[sz] = 0;
  336. fclose(f);
  337. program = sol_compile(s);
  338. free(s);
  339. if(!program) {
  340. return sol_set_error_string(state, "Compilation failure");
  341. }
  342. // XXX should st_free(program);
  343. sol_exec(state, program);
  344. return sol_incref(state->None);
  345. }
  346. sol_object_t *sol_f_parse(sol_state_t *state, sol_object_t *args) {
  347. sol_object_t *prg = sol_list_get_index(state, args, 0), *prgstr = sol_cast_string(state, prg);
  348. stmt_node *program = sol_compile(prgstr->str);
  349. sol_obj_free(prg);
  350. sol_obj_free(prgstr);
  351. if(!program) {
  352. return sol_set_error_string(state, "Compilation failure");
  353. }
  354. return sol_new_stmtnode(state, program);
  355. }
  356. sol_object_t *sol_f_ord(sol_state_t *state, sol_object_t *args) {
  357. sol_object_t *arg = sol_list_get_index(state, args, 0), *str = sol_cast_string(state, arg);
  358. sol_object_t *arg2, *iarg, *res;
  359. long idx = 0;
  360. size_t len = strlen(str->str);
  361. sol_obj_free(arg);
  362. if(sol_list_len(state, args) > 1) {
  363. arg2 = sol_list_get_index(state, args, 1);
  364. iarg = sol_cast_int(state, arg2);
  365. sol_obj_free(arg2);
  366. idx = iarg->ival;
  367. sol_obj_free(iarg);
  368. }
  369. if(idx < 0) {
  370. idx += len;
  371. }
  372. if(idx < 0 || idx >= len) {
  373. sol_obj_free(str);
  374. return sol_set_error_string(state, "Compute ord of out-of-bounds index");
  375. }
  376. res = sol_new_int(state, str->str[idx]);
  377. sol_obj_free(str);
  378. return res;
  379. }
  380. sol_object_t *sol_f_chr(sol_state_t *state, sol_object_t *args) {
  381. sol_object_t *arg = sol_list_get_index(state, args, 0), *iarg = sol_cast_int(state, arg);
  382. char cbuf[2] = {iarg->ival, 0};
  383. sol_object_t *res = sol_new_string(state, cbuf);
  384. sol_obj_free(arg);
  385. sol_obj_free(iarg);
  386. return res;
  387. }
  388. sol_object_t *sol_f_debug_getref(sol_state_t *state, sol_object_t *args) {
  389. sol_object_t *obj = sol_list_get_index(state, args, 0);
  390. sol_object_t *res = sol_new_int(state, obj->refcnt - 2); // NB: We grabbed a reference, and there's one in the arglist, so account for them.
  391. sol_obj_free(obj);
  392. return res;
  393. }
  394. sol_object_t *sol_f_debug_setref(sol_state_t *state, sol_object_t *args) {
  395. sol_object_t *obj = sol_list_get_index(state, args, 0), *cnt = sol_list_get_index(state, args, 1);
  396. obj->refcnt = sol_cast_int(state, cnt)->ival + 2; // NB: As above.
  397. sol_obj_free(cnt);
  398. sol_obj_free(obj);
  399. return sol_incref(state->None);
  400. }
  401. sol_object_t *sol_f_debug_closure(sol_state_t *state, sol_object_t *args) {
  402. sol_object_t *func = sol_list_get_index(state, args, 0);
  403. sol_object_t *res = sol_incref(func->closure);
  404. sol_obj_free(func);
  405. return res;
  406. }
  407. sol_object_t *sol_f_debug_globals(sol_state_t *state, sol_object_t *args) {
  408. return sol_list_get_index(state, state->scopes, sol_list_len(state, state->scopes) - 1);
  409. }
  410. sol_object_t *sol_f_debug_locals(sol_state_t *state, sol_object_t *args) {
  411. return sol_list_get_index(state, state->scopes, 0);
  412. }
  413. sol_object_t *sol_f_debug_scopes(sol_state_t *state, sol_object_t *args) {
  414. return sol_incref(state->scopes);
  415. }
  416. sol_object_t *sol_f_readline_readline(sol_state_t *state, sol_object_t *args) {
  417. sol_object_t *obj, *objstr, *res;
  418. char *line;
  419. if(sol_list_len(state, args) > 0) {
  420. obj = sol_list_get_index(state, args, 0);
  421. objstr = sol_cast_string(state, obj);
  422. line = readline(objstr->str);
  423. sol_obj_free(obj);
  424. sol_obj_free(objstr);
  425. } else {
  426. line = readline("");
  427. }
  428. if(line) {
  429. res = sol_new_string(state, line);
  430. free(line);
  431. } else {
  432. res = sol_new_string(state, "");
  433. }
  434. return res;
  435. }
  436. sol_object_t *sol_f_readline_add_history(sol_state_t *state, sol_object_t *args) {
  437. sol_object_t *line = sol_list_get_index(state, args, 0), *linestr = sol_cast_string(state, line);
  438. add_history(linestr->str);
  439. sol_obj_free(linestr);
  440. sol_obj_free(line);
  441. return sol_incref(state->None);
  442. }
  443. void _sol_freef_seq_iter(void *iter, size_t sz) {
  444. dsl_free_seq_iter((dsl_seq_iter *) iter);
  445. }
  446. sol_object_t *sol_f_iter_str(sol_state_t *state, sol_object_t *args) {
  447. sol_object_t *obj = sol_list_get_index(state, args, 0), *local = sol_list_get_index(state, args, 1);
  448. sol_object_t *index = sol_map_get_name(state, local, "idx"), *max = sol_map_get_name(state, local, "sz"), *res;
  449. char temp[2] = {0, 0};
  450. if(sol_is_none(state, index) || sol_is_none(state, max)) {
  451. sol_obj_free(index);
  452. index = sol_new_buffer(state, (void *) 0, sizeof(void *), OWN_NONE, NULL, NULL);
  453. sol_map_set_name(state, local, "idx", index);
  454. sol_obj_free(max);
  455. max = sol_new_int(state, strlen(obj->str));
  456. sol_map_set_name(state, local, "sz", max);
  457. }
  458. if(((size_t) index->buffer) >= max->ival) {
  459. sol_obj_free(index);
  460. sol_obj_free(obj);
  461. sol_obj_free(local);
  462. return sol_incref(state->StopIteration);
  463. }
  464. temp[0] = obj->str[((size_t) index->buffer)];
  465. res = sol_new_string(state, temp);
  466. index->buffer = (void *) ((size_t) index->buffer + 1);
  467. sol_obj_free(index);
  468. sol_obj_free(local);
  469. sol_obj_free(obj);
  470. return res;
  471. }
  472. sol_object_t *sol_f_iter_list(sol_state_t *state, sol_object_t *args) {
  473. sol_object_t *obj = sol_list_get_index(state, args, 0), *local = sol_list_get_index(state, args, 1);
  474. sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
  475. if(sol_is_none(state, index)) {
  476. sol_obj_free(index);
  477. index = sol_new_buffer(state, dsl_new_seq_iter(obj->seq), sizeof(dsl_seq_iter), OWN_CALLF, _sol_freef_seq_iter, NULL);
  478. sol_map_set_name(state, local, "idx", index);
  479. sol_obj_free(index);
  480. }
  481. if(dsl_seq_iter_is_invalid(index->buffer)) {
  482. sol_obj_free(index);
  483. sol_obj_free(obj);
  484. sol_obj_free(local);
  485. return sol_incref(state->StopIteration);
  486. }
  487. res = sol_incref(AS_OBJ(dsl_seq_iter_at(index->buffer)));
  488. dsl_seq_iter_next(index->buffer);
  489. sol_obj_free(local);
  490. sol_obj_free(obj);
  491. return res;
  492. }
  493. sol_object_t *sol_f_iter_map(sol_state_t *state, sol_object_t *args) {
  494. sol_object_t *obj = sol_list_get_index(state, args, 0), *local = sol_list_get_index(state, args, 1);
  495. sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
  496. if(sol_is_none(state, index)) {
  497. sol_obj_free(index);
  498. index = sol_new_buffer(state, dsl_new_seq_iter(obj->seq), sizeof(dsl_seq_iter), OWN_CALLF, _sol_freef_seq_iter, NULL);
  499. sol_map_set_name(state, local, "idx", index);
  500. sol_obj_free(index);
  501. }
  502. if(dsl_seq_iter_is_invalid(index->buffer)) {
  503. sol_obj_free(index);
  504. sol_obj_free(obj);
  505. sol_obj_free(local);
  506. return sol_incref(state->StopIteration);
  507. }
  508. res = sol_incref(AS_OBJ(dsl_seq_iter_at(index->buffer))->key);
  509. dsl_seq_iter_next(index->buffer);
  510. sol_obj_free(local);
  511. sol_obj_free(obj);
  512. return res;
  513. }
  514. sol_object_t *sol_f_ast_print(sol_state_t *state, sol_object_t *args) {
  515. sol_object_t *obj = sol_list_get_index(state, args, 0);
  516. if(sol_is_aststmt(obj)) {
  517. st_print(state, obj->node);
  518. } else {
  519. ex_print(state, obj->node);
  520. }
  521. sol_obj_free(obj);
  522. return sol_incref(state->None);
  523. }
  524. sol_object_t *sol_f_singlet_tostring(sol_state_t *state, sol_object_t *args) {
  525. sol_object_t *obj = sol_list_get_index(state, args, 0), *res = sol_new_string(state, obj->str);
  526. sol_obj_free(obj);
  527. return res;
  528. }
  529. sol_object_t *sol_f_int_add(sol_state_t *state, sol_object_t *args) {
  530. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bint = sol_cast_int(state, b);
  531. sol_object_t *res = sol_new_int(state, a->ival + bint->ival);
  532. sol_obj_free(a);
  533. sol_obj_free(b);
  534. if(sol_has_error(state)) {
  535. sol_obj_free(res);
  536. return sol_incref(state->None);
  537. }
  538. return res;
  539. }
  540. sol_object_t *sol_f_int_sub(sol_state_t *state, sol_object_t *args) {
  541. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bint = sol_cast_int(state, b);
  542. sol_object_t *res = sol_new_int(state, a->ival - bint->ival);
  543. sol_obj_free(a);
  544. sol_obj_free(b);
  545. if(sol_has_error(state)) {
  546. sol_obj_free(res);
  547. return sol_incref(state->None);
  548. }
  549. return res;
  550. }
  551. sol_object_t *sol_f_int_mul(sol_state_t *state, sol_object_t *args) {
  552. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bint = sol_cast_int(state, b);
  553. sol_object_t *res = sol_new_int(state, a->ival * bint->ival);
  554. sol_obj_free(a);
  555. sol_obj_free(b);
  556. if(sol_has_error(state)) {
  557. sol_obj_free(res);
  558. return sol_incref(state->None);
  559. }
  560. return res;
  561. }
  562. sol_object_t *sol_f_int_div(sol_state_t *state, sol_object_t *args) {
  563. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bint = sol_cast_int(state, b);
  564. sol_object_t *res = sol_new_int(state, a->ival / bint->ival);
  565. sol_obj_free(a);
  566. sol_obj_free(b);
  567. if(sol_has_error(state)) {
  568. sol_obj_free(res);
  569. return sol_incref(state->None);
  570. }
  571. return res;
  572. }
  573. sol_object_t *sol_f_int_mod(sol_state_t *state, sol_object_t *args) {
  574. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bint = sol_cast_int(state, b);
  575. sol_object_t *res = sol_new_int(state, a->ival % bint->ival);
  576. sol_obj_free(a);
  577. sol_obj_free(b);
  578. if(sol_has_error(state)) {
  579. sol_obj_free(res);
  580. return sol_incref(state->None);
  581. }
  582. return res;
  583. }
  584. sol_object_t *sol_f_int_pow(sol_state_t *state, sol_object_t *args) {
  585. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bint = sol_cast_int(state, b);
  586. sol_object_t *res = sol_new_int(state, (long) pow((double) a->ival, bint->ival));
  587. sol_obj_free(a);
  588. sol_obj_free(b);
  589. if(sol_has_error(state)) {
  590. sol_obj_free(res);
  591. return sol_incref(state->None);
  592. }
  593. return res;
  594. }
  595. sol_object_t *sol_f_int_band(sol_state_t *state, sol_object_t *args) {
  596. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bint = sol_cast_int(state, b);
  597. sol_object_t *res = sol_new_int(state, a->ival & bint->ival);
  598. sol_obj_free(a);
  599. sol_obj_free(b);
  600. if(sol_has_error(state)) {
  601. sol_obj_free(res);
  602. return sol_incref(state->None);
  603. }
  604. return res;
  605. }
  606. sol_object_t *sol_f_int_bor(sol_state_t *state, sol_object_t *args) {
  607. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bint = sol_cast_int(state, b);
  608. sol_object_t *res = sol_new_int(state, a->ival | bint->ival);
  609. sol_obj_free(a);
  610. sol_obj_free(b);
  611. if(sol_has_error(state)) {
  612. sol_obj_free(res);
  613. return sol_incref(state->None);
  614. }
  615. return res;
  616. }
  617. sol_object_t *sol_f_int_bxor(sol_state_t *state, sol_object_t *args) {
  618. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bint = sol_cast_int(state, b);
  619. sol_object_t *res = sol_new_int(state, a->ival ^ bint->ival);
  620. sol_obj_free(a);
  621. sol_obj_free(b);
  622. if(sol_has_error(state)) {
  623. sol_obj_free(res);
  624. return sol_incref(state->None);
  625. }
  626. return res;
  627. }
  628. sol_object_t *sol_f_int_blsh(sol_state_t *state, sol_object_t *args) {
  629. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bint = sol_cast_int(state, b);
  630. sol_object_t *res = sol_new_int(state, a->ival << bint->ival);
  631. sol_obj_free(a);
  632. sol_obj_free(b);
  633. if(sol_has_error(state)) {
  634. sol_obj_free(res);
  635. return sol_incref(state->None);
  636. }
  637. return res;
  638. }
  639. sol_object_t *sol_f_int_brsh(sol_state_t *state, sol_object_t *args) {
  640. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bint = sol_cast_int(state, b);
  641. sol_object_t *res = sol_new_int(state, a->ival >> bint->ival);
  642. sol_obj_free(a);
  643. sol_obj_free(b);
  644. if(sol_has_error(state)) {
  645. sol_obj_free(res);
  646. return sol_incref(state->None);
  647. }
  648. return res;
  649. }
  650. sol_object_t *sol_f_int_bnot(sol_state_t *state, sol_object_t *args) {
  651. sol_object_t *a = sol_list_get_index(state, args, 0);
  652. sol_object_t *res = sol_new_int(state, ~a->ival);
  653. sol_obj_free(a);
  654. return res;
  655. }
  656. sol_object_t *sol_f_int_cmp(sol_state_t *state, sol_object_t *args) {
  657. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
  658. sol_object_t *res;
  659. if(sol_is_int(b)) {
  660. res = sol_new_int(state, a->ival == b->ival ? 0 : (a->ival < b->ival ? -1 : 1));
  661. } else {
  662. res = sol_new_int(state, 1);
  663. }
  664. sol_obj_free(a);
  665. sol_obj_free(b);
  666. return res;
  667. }
  668. sol_object_t *sol_f_int_toint(sol_state_t *state, sol_object_t *args) {
  669. return sol_list_get_index(state, args, 0);
  670. }
  671. sol_object_t *sol_f_int_tofloat(sol_state_t *state, sol_object_t *args) {
  672. sol_object_t *a = sol_list_get_index(state, args, 0);
  673. sol_object_t *res = sol_new_float(state, (double) a->ival);
  674. sol_obj_free(a);
  675. return res;
  676. }
  677. sol_object_t *sol_f_int_tostring(sol_state_t *state, sol_object_t *args) {
  678. sol_object_t *a = sol_list_get_index(state, args, 0);
  679. char *s = _itoa(a->ival);
  680. sol_object_t *res = sol_new_string(state, s);
  681. sol_obj_free(a);
  682. free(s);
  683. return res;
  684. }
  685. sol_object_t *sol_f_float_add(sol_state_t *state, sol_object_t *args) {
  686. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bflt = sol_cast_float(state, b);
  687. sol_object_t *res = sol_new_float(state, a->fval + bflt->fval);
  688. sol_obj_free(a);
  689. sol_obj_free(b);
  690. if(sol_has_error(state)) {
  691. sol_obj_free(res);
  692. return sol_incref(state->None);
  693. }
  694. return res;
  695. }
  696. sol_object_t *sol_f_float_sub(sol_state_t *state, sol_object_t *args) {
  697. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bflt = sol_cast_float(state, b);
  698. sol_object_t *res = sol_new_float(state, a->fval - bflt->fval);
  699. sol_obj_free(a);
  700. sol_obj_free(b);
  701. if(sol_has_error(state)) {
  702. sol_obj_free(res);
  703. return sol_incref(state->None);
  704. }
  705. return res;
  706. }
  707. sol_object_t *sol_f_float_mul(sol_state_t *state, sol_object_t *args) {
  708. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bflt = sol_cast_float(state, b);
  709. sol_object_t *res = sol_new_float(state, a->fval * bflt->fval);
  710. sol_obj_free(a);
  711. sol_obj_free(b);
  712. if(sol_has_error(state)) {
  713. sol_obj_free(res);
  714. return sol_incref(state->None);
  715. }
  716. return res;
  717. }
  718. sol_object_t *sol_f_float_div(sol_state_t *state, sol_object_t *args) {
  719. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bflt = sol_cast_float(state, b);
  720. sol_object_t *res = sol_new_float(state, a->fval / bflt->fval);
  721. sol_obj_free(a);
  722. sol_obj_free(b);
  723. if(sol_has_error(state)) {
  724. sol_obj_free(res);
  725. return sol_incref(state->None);
  726. }
  727. return res;
  728. }
  729. sol_object_t *sol_f_float_pow(sol_state_t *state, sol_object_t *args) {
  730. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bflt = sol_cast_float(state, b);
  731. sol_object_t *res = sol_new_float(state, pow(a->fval, bflt->fval));
  732. sol_obj_free(a);
  733. sol_obj_free(b);
  734. if(sol_has_error(state)) {
  735. sol_obj_free(res);
  736. return sol_incref(state->None);
  737. }
  738. return res;
  739. }
  740. sol_object_t *sol_f_float_cmp(sol_state_t *state, sol_object_t *args) {
  741. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
  742. sol_object_t *res;
  743. if(sol_is_float(b)) {
  744. res = sol_new_int(state, a->fval==b->fval? 0 : (a->fval<b->fval? -1 : 1));
  745. } else {
  746. res = sol_new_int(state, 1);
  747. }
  748. sol_obj_free(a);
  749. sol_obj_free(b);
  750. return res;
  751. }
  752. sol_object_t *sol_f_float_toint(sol_state_t *state, sol_object_t *args) {
  753. sol_object_t *a = sol_list_get_index(state, args, 0);
  754. sol_object_t *res = sol_new_int(state, (int) a->fval);
  755. sol_obj_free(a);
  756. return res;
  757. }
  758. sol_object_t *sol_f_float_tofloat(sol_state_t *state, sol_object_t *args) {
  759. return sol_list_get_index(state, args, 0);
  760. }
  761. sol_object_t *sol_f_float_tostring(sol_state_t *state, sol_object_t *args) {
  762. sol_object_t *a = sol_list_get_index(state, args, 0);
  763. char *s = _ftoa(a->fval);
  764. sol_object_t *res = sol_new_string(state, s);
  765. sol_obj_free(a);
  766. free(s);
  767. return res;
  768. }
  769. sol_object_t *sol_f_str_add(sol_state_t *state, sol_object_t *args) {
  770. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bstr = sol_cast_string(state, b);
  771. sol_object_t *res = sol_string_concat(state, a, bstr);
  772. sol_obj_free(a);
  773. sol_obj_free(b);
  774. if(sol_has_error(state)) {
  775. sol_obj_free(res);
  776. return sol_incref(state->None);
  777. }
  778. return res;
  779. }
  780. sol_object_t *sol_f_str_mul(sol_state_t *state, sol_object_t *args) {
  781. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bint = sol_cast_int(state, b);
  782. int n = strlen(a->str) * bint->ival + 1;
  783. char *s = malloc(n);
  784. int i;
  785. s[0] = '\0';
  786. for(i = 0; i < b->ival; i++) {
  787. strncat(s, a->str, n);
  788. }
  789. sol_object_t *res = sol_new_string(state, s);
  790. sol_obj_free(a);
  791. sol_obj_free(b);
  792. sol_obj_free(bint);
  793. free(s);
  794. if(sol_has_error(state)) {
  795. sol_obj_free(res);
  796. return sol_incref(state->None);
  797. }
  798. return res;
  799. }
  800. sol_object_t *sol_f_str_cmp(sol_state_t *state, sol_object_t *args) {
  801. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
  802. sol_object_t *res;
  803. if(sol_is_string(b)) {
  804. res = sol_new_int(state, strcmp(a->str, b->str));
  805. } else {
  806. res = sol_new_int(state, 1);
  807. }
  808. sol_obj_free(a);
  809. sol_obj_free(b);
  810. return res;
  811. }
  812. sol_object_t *sol_f_str_len(sol_state_t *state, sol_object_t *args) {
  813. sol_object_t *a = sol_list_get_index(state, args, 0);
  814. sol_object_t *res = sol_new_int(state, strlen(a->str));
  815. sol_obj_free(a);
  816. return res;
  817. }
  818. sol_object_t *sol_f_str_index(sol_state_t *state, sol_object_t *args) {
  819. sol_object_t *str = sol_list_get_index(state, args, 0), *key = sol_list_get_index(state, args, 1), *idx, *funcs, *res;
  820. char buf[2] = {0, 0};
  821. if(sol_is_string(key)) {
  822. funcs = sol_get_methods_name(state, "string");
  823. res = sol_map_get(state, funcs, key);
  824. sol_obj_free(funcs);
  825. return res;
  826. }
  827. idx = sol_cast_int(state, key);
  828. if(idx->ival >= 0 && idx->ival < strlen(str->str)) {
  829. buf[0] = str->str[idx->ival];
  830. }
  831. sol_obj_free(str);
  832. sol_obj_free(key);
  833. sol_obj_free(idx);
  834. return sol_new_string(state, buf);
  835. }
  836. sol_object_t *sol_f_str_iter(sol_state_t *state, sol_object_t *args) {
  837. return sol_new_cfunc(state, sol_f_iter_str);
  838. }
  839. sol_object_t *sol_f_str_toint(sol_state_t *state, sol_object_t *args) {
  840. sol_object_t *a = sol_list_get_index(state, args, 0);
  841. sol_object_t *res = sol_new_int(state, atoi(a->str));
  842. sol_obj_free(a);
  843. return res;
  844. }
  845. sol_object_t *sol_f_str_tofloat(sol_state_t *state, sol_object_t *args) {
  846. sol_object_t *a = sol_list_get_index(state, args, 0);
  847. sol_object_t *res = sol_new_float(state, atof(a->str));
  848. sol_obj_free(a);
  849. return res;
  850. }
  851. sol_object_t *sol_f_str_tostring(sol_state_t *state, sol_object_t *args) {
  852. return sol_list_get_index(state, args, 0);
  853. }
  854. sol_object_t *sol_f_str_repr(sol_state_t *state, sol_object_t *args) {
  855. sol_object_t *obj = sol_list_get_index(state, args, 0), *cur = sol_new_string(state, "\""), *next = sol_string_concat(state, cur, obj);
  856. sol_obj_free(cur);
  857. cur = next;
  858. next = sol_string_concat_cstr(state, cur, "\"");
  859. sol_obj_free(cur);
  860. return next;
  861. }
  862. sol_object_t *sol_f_str_sub(sol_state_t *state, sol_object_t *args) {
  863. sol_object_t *str = sol_list_get_index(state, args, 0), *low = sol_list_get_index(state, args, 1), *high = sol_list_get_index(state, args, 2);
  864. sol_object_t *ilow, *ihigh;
  865. long l, h;
  866. size_t len = strlen(str->str), i;
  867. char *s;
  868. if(sol_is_none(state, low)) {
  869. ilow = sol_new_int(state, 0);
  870. } else {
  871. ilow = sol_cast_int(state, low);
  872. }
  873. if(sol_is_none(state, high)) {
  874. ihigh = sol_new_int(state, len);
  875. } else {
  876. ihigh = sol_cast_int(state, high);
  877. }
  878. sol_obj_free(low);
  879. sol_obj_free(high);
  880. l = ilow->ival;
  881. h = ihigh->ival;
  882. sol_obj_free(ihigh);
  883. sol_obj_free(ilow);
  884. if(l < 0) {
  885. l += len;
  886. if(l < 0) {
  887. l = 0;
  888. }
  889. }
  890. if(l > len) {
  891. l = len;
  892. }
  893. if(h < 0) {
  894. h += len;
  895. if(h < 0) {
  896. h = 0;
  897. }
  898. }
  899. if(h > len) {
  900. h = len;
  901. }
  902. if(l >= h) {
  903. sol_obj_free(str);
  904. return sol_new_string(state, "");
  905. }
  906. s = malloc(h - l + 1);
  907. for(i = l; i < h; i++) {
  908. s[i - l] = str->str[i];
  909. }
  910. s[h - l] = '\0';
  911. sol_obj_free(str);
  912. return sol_new_string(state, s);
  913. }
  914. sol_object_t *sol_f_str_split(sol_state_t *state, sol_object_t *args) {
  915. sol_object_t *str = sol_list_get_index(state, args, 0), *tok = sol_list_get_index(state, args, 1), *stok = sol_cast_string(state, tok);
  916. sol_object_t *res = sol_new_list(state), *opart;
  917. char *s = strdup(str->str);
  918. char *part = strtok(s, stok->str);
  919. sol_obj_free(tok);
  920. sol_obj_free(str);
  921. if(!part) {
  922. sol_obj_free(res);
  923. sol_obj_free(stok);
  924. return sol_incref(state->None);
  925. }
  926. opart = sol_new_string(state, part);
  927. sol_list_insert(state, res, 0, opart);
  928. sol_obj_free(opart);
  929. while(part = strtok(NULL, stok->str)) {
  930. opart = sol_new_string(state, part);
  931. sol_list_insert(state, res, sol_list_len(state, res), opart);
  932. sol_obj_free(opart);
  933. }
  934. sol_obj_free(stok);
  935. return res;
  936. }
  937. sol_object_t *sol_f_str_find(sol_state_t *state, sol_object_t *args) {
  938. sol_object_t *str = sol_list_get_index(state, args, 0), *substr = sol_list_get_index(state, args, 1), *ssubstr = sol_cast_string(state, substr);
  939. char *ptr = strstr(str->str, ssubstr->str);
  940. sol_object_t *res = sol_new_int(state, ptr ? ptr - str->str : -1);
  941. sol_obj_free(str);
  942. sol_obj_free(substr);
  943. sol_obj_free(ssubstr);
  944. return res;
  945. }
  946. sol_object_t *sol_f_list_add(sol_state_t *state, sol_object_t *args) {
  947. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *ls;
  948. if(!sol_is_list(b)) {
  949. sol_obj_free(a);
  950. sol_obj_free(b);
  951. return sol_set_error_string(state, "Adding list to non-list");
  952. }
  953. ls = sol_list_copy(state, a);
  954. sol_list_append(state, ls, b);
  955. sol_obj_free(a);
  956. sol_obj_free(b);
  957. return ls;
  958. }
  959. sol_object_t *sol_f_list_mul(sol_state_t *state, sol_object_t *args) {
  960. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bint = sol_cast_int(state, b), *ls;
  961. int i;
  962. if(sol_has_error(state)) {
  963. sol_obj_free(a);
  964. sol_obj_free(b);
  965. sol_obj_free(bint);
  966. return sol_incref(state->None);
  967. }
  968. ls = sol_new_list(state);
  969. for(i = 0; i < b->ival; i++) {
  970. sol_list_append(state, ls, a);
  971. if(sol_has_error(state)) {
  972. sol_obj_free(a);
  973. sol_obj_free(b);
  974. sol_obj_free(bint);
  975. return sol_incref(state->None);
  976. }
  977. }
  978. return ls;
  979. }
  980. sol_object_t *sol_f_list_index(sol_state_t *state, sol_object_t *args) {
  981. sol_object_t *ls = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *ival;
  982. sol_object_t *res, *funcs;
  983. if(sol_is_string(b)) {
  984. funcs = sol_get_methods_name(state, "list");
  985. res = sol_map_get(state, funcs, b);
  986. sol_obj_free(funcs);
  987. } else {
  988. ival = sol_cast_int(state, b);
  989. res = sol_list_get_index(state, ls, ival->ival);
  990. sol_obj_free(ival);
  991. }
  992. sol_obj_free(ls);
  993. sol_obj_free(b);
  994. return res;
  995. }
  996. sol_object_t *sol_f_list_setindex(sol_state_t *state, sol_object_t *args) {
  997. sol_object_t *ls = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args ,1), *bint = sol_cast_int(state, b);
  998. sol_object_t *val = sol_list_get_index(state, args, 2);
  999. sol_list_set_index(state, ls, bint->ival, val);
  1000. sol_obj_free(ls);
  1001. sol_obj_free(b);
  1002. sol_obj_free(bint);
  1003. sol_obj_free(val);
  1004. return sol_incref(state->None);
  1005. }
  1006. sol_object_t *sol_f_list_len(sol_state_t *state, sol_object_t *args) {
  1007. sol_object_t *ls = sol_list_get_index(state, args, 0);
  1008. sol_object_t *res = sol_new_int(state, sol_list_len(state, ls));
  1009. sol_obj_free(ls);
  1010. return res;
  1011. }
  1012. sol_object_t *sol_f_list_iter(sol_state_t *state, sol_object_t *args) {
  1013. return sol_new_cfunc(state, sol_f_iter_list);
  1014. }
  1015. sol_object_t *sol_f_list_tostring(sol_state_t *state, sol_object_t *args) {
  1016. sol_object_t *cur = sol_new_string(state, "["), *next, *str, *obj = sol_list_get_index(state, args, 0), *item;
  1017. dsl_seq_iter *iter = dsl_new_seq_iter(obj->seq);
  1018. char s[64];
  1019. while(!dsl_seq_iter_is_invalid(iter)) {
  1020. item = AS_OBJ(dsl_seq_iter_at(iter));
  1021. if(test_seen(item)) {
  1022. snprintf(s, 64, "... (%p)", item);
  1023. next = sol_string_concat_cstr(state, cur, s);
  1024. } else {
  1025. str = sol_cast_repr(state, item);
  1026. next = sol_string_concat(state, cur, str);
  1027. sol_obj_free(str);
  1028. }
  1029. sol_obj_free(cur);
  1030. cur = next;
  1031. if(!dsl_seq_iter_at_end(iter)) {
  1032. next = sol_string_concat_cstr(state, cur, ", ");
  1033. sol_obj_free(cur);
  1034. cur = next;
  1035. }
  1036. dsl_seq_iter_next(iter);
  1037. }
  1038. next = sol_string_concat_cstr(state, cur, "]");
  1039. sol_obj_free(cur);
  1040. dsl_free_seq_iter(iter);
  1041. return next;
  1042. }
  1043. sol_object_t *sol_f_list_copy(sol_state_t *state, sol_object_t *args) {
  1044. sol_object_t *list = sol_list_get_index(state, args, 0);
  1045. sol_object_t *res = sol_list_copy(state, list);
  1046. sol_obj_free(list);
  1047. return res;
  1048. }
  1049. sol_object_t *sol_f_list_insert(sol_state_t *state, sol_object_t *args) {
  1050. sol_object_t *list = sol_list_get_index(state, args, 0), *idx = sol_list_get_index(state, args, 1), *iidx = sol_cast_int(state, idx), *obj = sol_list_get_index(state, args, 2);
  1051. sol_list_insert(state, list, iidx->ival, obj);
  1052. sol_obj_free(list);
  1053. sol_obj_free(idx);
  1054. sol_obj_free(iidx);
  1055. sol_obj_free(obj);
  1056. return sol_incref(state->None);
  1057. }
  1058. sol_object_t *sol_f_list_remove(sol_state_t *state, sol_object_t *args) {
  1059. sol_object_t *list = sol_list_get_index(state, args, 0), *idx = sol_list_get_index(state, args, 1), *iidx = sol_cast_int(state, idx);
  1060. sol_object_t *res = sol_list_remove(state, list, iidx->ival);
  1061. sol_obj_free(list);
  1062. sol_obj_free(idx);
  1063. sol_obj_free(iidx);
  1064. return res;
  1065. }
  1066. sol_object_t *sol_f_list_truncate(sol_state_t *state, sol_object_t *args) {
  1067. sol_object_t *list = sol_list_get_index(state, args, 0), *idx = sol_list_get_index(state, args, 1), *iidx = sol_cast_int(state, idx);
  1068. sol_object_t *res = sol_list_truncate(state, list, iidx->ival);
  1069. sol_obj_free(list);
  1070. sol_obj_free(idx);
  1071. sol_obj_free(iidx);
  1072. return res;
  1073. }
  1074. sol_object_t *sol_f_list_map(sol_state_t *state, sol_object_t *args) {
  1075. sol_object_t *list = sol_list_get_index(state, args, 0), *func = sol_list_get_index(state, args, 1);
  1076. sol_object_t *fargs = sol_new_list(state), *item;
  1077. int idx = 0, len = sol_list_len(state, list);
  1078. sol_list_insert(state, fargs, 0, func);
  1079. while(idx < len) {
  1080. item = sol_list_get_index(state, list, idx);
  1081. sol_list_insert(state, fargs, 1, item);
  1082. sol_obj_free(item);
  1083. item = CALL_METHOD(state, func, call, fargs);
  1084. if(sol_has_error(state)) {
  1085. return list;
  1086. }
  1087. sol_list_remove(state, fargs, 1);
  1088. sol_list_set_index(state, list, idx, item);
  1089. sol_obj_free(item);
  1090. idx++;
  1091. }
  1092. sol_obj_free(fargs);
  1093. sol_obj_free(func);
  1094. return list;
  1095. }
  1096. sol_object_t *sol_f_list_filter(sol_state_t *state, sol_object_t *args) {
  1097. sol_object_t *list = sol_list_get_index(state, args, 0), *func = sol_list_get_index(state, args, 1);
  1098. sol_object_t *fargs = sol_new_list(state), *item, *ival;
  1099. int idx = 0, len = sol_list_len(state, list);
  1100. sol_list_insert(state, fargs, 0, func);
  1101. while(idx < len) {
  1102. item = sol_list_get_index(state, list, idx);
  1103. sol_list_insert(state, fargs, 1, item);