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.

802 lines
26 KiB

  1. #include <string.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <math.h>
  5. #include "sol.h"
  6. // XXX hardcoded buffer sizes
  7. static char *_itoa(int i) {
  8. int n = 33;
  9. char *s = malloc(n);
  10. snprintf(s, n, "%d", i);
  11. return s;
  12. }
  13. static char *_ftoa(double f) {
  14. int n = 65;
  15. char *s = malloc(n);
  16. snprintf(s, n, "%f", f);
  17. return s;
  18. }
  19. sol_object_t *sol_f_not_impl(sol_state_t *state, sol_object_t *args) {
  20. return sol_set_error_string(state, "Undefined method");
  21. }
  22. sol_object_t *sol_f_default_cmp(sol_state_t *state, sol_object_t *args) {
  23. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
  24. sol_object_t *res = sol_new_int(state, a!=b);
  25. sol_obj_free(a);
  26. sol_obj_free(b);
  27. return res;
  28. }
  29. sol_object_t *sol_f_no_op(sol_state_t *state, sol_object_t *args) {
  30. if(state) return sol_incref(state->None);
  31. return NULL;
  32. }
  33. sol_object_t *sol_f_toint(sol_state_t *state, sol_object_t *args) {
  34. sol_object_t *obj = sol_list_get_index(state, args, 0);
  35. sol_object_t *res = obj->ops->toint(state, args);
  36. sol_obj_free(obj);
  37. return res;
  38. }
  39. sol_object_t *sol_f_tofloat(sol_state_t *state, sol_object_t *args) {
  40. sol_object_t *obj = sol_list_get_index(state, args, 0);
  41. sol_object_t *res = obj->ops->tofloat(state, args);
  42. sol_obj_free(obj);
  43. return res;
  44. }
  45. sol_object_t *sol_f_tostring(sol_state_t *state, sol_object_t *args) {
  46. sol_object_t *obj = sol_list_get_index(state, args, 0);
  47. sol_object_t *res = obj->ops->tostring(state, args);
  48. sol_obj_free(obj);
  49. return res;
  50. }
  51. sol_object_t *sol_f_try(sol_state_t *state, sol_object_t *args) {
  52. sol_object_t *func = sol_list_get_index(state, args, 0), *fargs = sol_list_sublist(state, args, 1);
  53. sol_object_t *ls = sol_new_list(state), *one = sol_new_int(state, 1);
  54. sol_object_t *res = func->ops->call(state, fargs);
  55. sol_obj_free(func);
  56. sol_obj_free(fargs);
  57. if(sol_has_error(state)) {
  58. sol_object_t *err = sol_get_error(state);
  59. sol_object_t *zero = sol_new_int(state, 0);
  60. sol_obj_free(res);
  61. sol_obj_free(one);
  62. sol_clear_error(state);
  63. sol_list_insert(state, ls, 0, err);
  64. sol_obj_free(err);
  65. sol_list_insert(state, ls, 0, zero);
  66. sol_obj_free(zero);
  67. return ls;
  68. }
  69. sol_list_insert(state, ls, 0, res);
  70. sol_obj_free(res);
  71. sol_list_insert(state, ls, 0, one);
  72. sol_obj_free(one);
  73. return ls;
  74. }
  75. static char *sol_TypeNames[] = {"singlet", "integer", "float", "string", "list", "listcell", "map", "mapcell", "function", "cfunction", "cdata"};
  76. sol_object_t *sol_f_type(sol_state_t *state, sol_object_t *args) {
  77. sol_object_t *obj = sol_list_get_index(state, args, 0);
  78. sol_object_t *res = sol_new_string(state, sol_TypeNames[obj->type]);
  79. sol_obj_free(obj);
  80. return res;
  81. }
  82. sol_object_t *p_seen[1024] = {0};
  83. void ob_print(sol_object_t *obj) {
  84. sol_object_t *cur;
  85. int i;
  86. for(i=0; i<1024; i++) {
  87. if(!p_seen[i]) {
  88. p_seen[i] = obj;
  89. break;
  90. }
  91. if(p_seen[i] == obj) {
  92. printf("... (%p)", obj);
  93. return;
  94. }
  95. }
  96. switch(obj->type) {
  97. case SOL_SINGLET:
  98. printf("<Singlet>");
  99. break;
  100. case SOL_INTEGER:
  101. printf("%ld", obj->ival);
  102. break;
  103. case SOL_FLOAT:
  104. printf("%f", obj->fval);
  105. break;
  106. case SOL_STRING:
  107. printf("\"%s\"", obj->str);
  108. break;
  109. case SOL_LCELL:
  110. printf("<<");
  111. /* fall through */
  112. case SOL_LIST:
  113. printf("[");
  114. cur = obj;
  115. while(cur) {
  116. if(cur->lvalue) {
  117. ob_print(cur->lvalue);
  118. }
  119. if(cur->lnext) {
  120. printf(", ");
  121. }
  122. cur = cur->lnext;
  123. }
  124. printf("]");
  125. break;
  126. case SOL_MCELL:
  127. printf("<<");
  128. /* fall through */
  129. case SOL_MAP:
  130. printf("{");
  131. cur = obj;
  132. while(cur) {
  133. if(cur->mkey) {
  134. printf("[");
  135. ob_print(cur->mkey);
  136. printf("] = ");
  137. ob_print(cur->mval);
  138. }
  139. if(cur->mnext) printf(", ");
  140. cur = cur->mnext;
  141. }
  142. printf("}");
  143. break;
  144. case SOL_FUNCTION:
  145. if(obj->fname) {
  146. printf("<Function %s>", obj->fname);
  147. } else {
  148. printf("<Function>");
  149. }
  150. break;
  151. case SOL_CFUNCTION:
  152. printf("<CFunction>");
  153. break;
  154. case SOL_CDATA:
  155. printf("<CData>");
  156. break;
  157. }
  158. }
  159. sol_object_t *sol_f_prepr(sol_state_t *state, sol_object_t *args) {
  160. int i, sz = sol_list_len(state, args);
  161. sol_object_t *obj;
  162. for(i=0; i<1024; i++) p_seen[i] = NULL;
  163. for(i=0; i<sz; i++) {
  164. obj = sol_list_get_index(state, args, i);
  165. ob_print(obj);
  166. printf(" ");
  167. sol_obj_free(obj);
  168. }
  169. printf("\n");
  170. return sol_incref(state->None);
  171. }
  172. sol_object_t *sol_f_print(sol_state_t *state, sol_object_t *args) {
  173. int i, sz = sol_list_len(state, args);
  174. sol_object_t *obj;
  175. for(i=0; i<1024; i++) p_seen[i] = NULL;
  176. for(i=0; i<sz; i++) {
  177. obj = sol_list_get_index(state, args, i);
  178. if(sol_is_string(obj)) {
  179. printf("%s", obj->str);
  180. } else {
  181. ob_print(obj);
  182. }
  183. printf(" ");
  184. sol_obj_free(obj);
  185. }
  186. printf("\n");
  187. return sol_incref(state->None);
  188. }
  189. sol_object_t *sol_f_rawget(sol_state_t *state, sol_object_t *args) {
  190. sol_object_t *obj = sol_list_get_index(state, args, 0), *key, *res;
  191. if(!sol_is_map(obj)) return sol_set_error_string(state, "Rawset of non-map");
  192. key = sol_list_get_index(state, args, 1);
  193. res = sol_map_get(state, obj, key);
  194. sol_obj_free(key);
  195. sol_obj_free(obj);
  196. return sol_incref(state->None);
  197. }
  198. sol_object_t *sol_f_rawset(sol_state_t *state, sol_object_t *args) {
  199. sol_object_t *obj = sol_list_get_index(state, args, 0), *key, *val;
  200. if(!sol_is_map(obj)) return sol_set_error_string(state, "Rawset of non-map");
  201. key = sol_list_get_index(state, args, 1);
  202. val = sol_list_get_index(state, args, 2);
  203. sol_map_set(state, obj, key, val);
  204. sol_obj_free(val);
  205. sol_obj_free(key);
  206. sol_obj_free(obj);
  207. return sol_incref(state->None);
  208. }
  209. sol_object_t *sol_f_range(sol_state_t *state, sol_object_t *args) {
  210. sol_object_t *res = sol_new_list(state), *bound = sol_cast_int(state, sol_list_get_index(state, args, 0));
  211. int i;
  212. for(i=0; i<bound->ival; i++) {
  213. sol_list_insert(state, res, sol_list_len(state, res), sol_new_int(state, i));
  214. }
  215. sol_obj_free(bound);
  216. return res;
  217. }
  218. sol_object_t *sol_f_debug_getref(sol_state_t *state, sol_object_t *args) {
  219. sol_object_t *obj = sol_list_get_index(state, args, 0);
  220. 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.
  221. sol_obj_free(obj);
  222. return res;
  223. }
  224. sol_object_t *sol_f_debug_setref(sol_state_t *state, sol_object_t *args) {
  225. sol_object_t *obj = sol_list_get_index(state, args, 0), *cnt = sol_list_get_index(state, args, 1);
  226. obj->refcnt = sol_cast_int(state, cnt)->ival + 2; // NB: As above.
  227. sol_obj_free(cnt);
  228. sol_obj_free(obj);
  229. return sol_incref(state->None);
  230. }
  231. sol_object_t *sol_f_debug_closure(sol_state_t *state, sol_object_t *args) {
  232. sol_object_t *func = sol_list_get_index(state, args, 0);
  233. sol_object_t *res = sol_incref(func->closure);
  234. sol_obj_free(func);
  235. return res;
  236. }
  237. sol_object_t *sol_f_debug_globals(sol_state_t *state, sol_object_t *args) {
  238. return sol_list_get_index(state, state->scopes, sol_list_len(state, state->scopes)-1);
  239. }
  240. sol_object_t *sol_f_debug_locals(sol_state_t *state, sol_object_t *args) {
  241. return sol_list_get_index(state, state->scopes, 0);
  242. }
  243. sol_object_t *sol_f_iter_str(sol_state_t *state, sol_object_t *args) {
  244. sol_object_t *obj = sol_list_get_index(state, args, 0), *local = sol_list_get_index(state, args, 1);
  245. sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
  246. char temp[2] = {0, 0};
  247. if(sol_is_none(state, index)) {
  248. sol_obj_free(index);
  249. index = sol_new_int(state, 0);
  250. sol_map_set_name(state, local, "idx", index);
  251. }
  252. if(index->ival >= strlen(obj->str)) {
  253. sol_obj_free(index);
  254. sol_obj_free(obj);
  255. sol_obj_free(local);
  256. return sol_incref(state->StopIteration);
  257. }
  258. temp[0] = obj->str[index->ival];
  259. res = sol_new_string(state, temp);
  260. index->ival++;
  261. sol_obj_free(index);
  262. sol_obj_free(local);
  263. sol_obj_free(obj);
  264. return res;
  265. }
  266. sol_object_t *sol_f_iter_list(sol_state_t *state, sol_object_t *args) {
  267. sol_object_t *obj = sol_list_get_index(state, args, 0), *local = sol_list_get_index(state, args, 1);
  268. sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
  269. if(sol_is_none(state, index)) {
  270. sol_obj_free(index);
  271. index = sol_new_int(state, 0);
  272. sol_map_set_name(state, local, "idx", index);
  273. }
  274. if(index->ival >= sol_list_len(state, obj)) {
  275. sol_obj_free(index);
  276. sol_obj_free(obj);
  277. sol_obj_free(local);
  278. return sol_incref(state->StopIteration);
  279. }
  280. res = sol_list_get_index(state, obj, index->ival);
  281. index->ival++;
  282. sol_obj_free(index);
  283. sol_obj_free(local);
  284. sol_obj_free(obj);
  285. return res;
  286. }
  287. sol_object_t *sol_f_iter_map(sol_state_t *state, sol_object_t *args) {
  288. sol_object_t *obj = sol_list_get_index(state, args, 0), *local = sol_list_get_index(state, args, 1);
  289. sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
  290. if(sol_is_none(state, index)) {
  291. sol_obj_free(index);
  292. index = obj;
  293. sol_map_set_name(state, local, "idx", index);
  294. }
  295. while(index && !index->mkey) index = index->mnext;
  296. if(!index || !index->mnext) {
  297. sol_obj_free(index);
  298. sol_obj_free(obj);
  299. sol_obj_free(local);
  300. return sol_incref(state->StopIteration);
  301. }
  302. res = sol_incref(index->mkey);
  303. index = index->mnext;
  304. sol_map_set_name(state, local, "idx", index);
  305. sol_obj_free(index);
  306. sol_obj_free(local);
  307. sol_obj_free(obj);
  308. return res;
  309. }
  310. sol_object_t *sol_f_int_add(sol_state_t *state, sol_object_t *args) {
  311. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  312. sol_object_t *res = sol_new_int(state, a->ival + b->ival);
  313. sol_obj_free(a);
  314. sol_obj_free(b);
  315. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  316. return res;
  317. }
  318. sol_object_t *sol_f_int_sub(sol_state_t *state, sol_object_t *args) {
  319. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  320. sol_object_t *res = sol_new_int(state, a->ival - b->ival);
  321. sol_obj_free(a);
  322. sol_obj_free(b);
  323. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  324. return res;
  325. }
  326. sol_object_t *sol_f_int_mul(sol_state_t *state, sol_object_t *args) {
  327. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  328. sol_object_t *res = sol_new_int(state, a->ival * b->ival);
  329. sol_obj_free(a);
  330. sol_obj_free(b);
  331. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  332. return res;
  333. }
  334. sol_object_t *sol_f_int_div(sol_state_t *state, sol_object_t *args) {
  335. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  336. sol_object_t *res = sol_new_int(state, a->ival / b->ival);
  337. sol_obj_free(a);
  338. sol_obj_free(b);
  339. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  340. return res;
  341. }
  342. sol_object_t *sol_f_int_pow(sol_state_t *state, sol_object_t *args) {
  343. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  344. sol_object_t *res = sol_new_int(state, (long) pow((double) a->ival, b->ival));
  345. sol_obj_free(a);
  346. sol_obj_free(b);
  347. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  348. return res;
  349. }
  350. sol_object_t *sol_f_int_band(sol_state_t *state, sol_object_t *args) {
  351. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  352. sol_object_t *res = sol_new_int(state, a->ival & b->ival);
  353. sol_obj_free(a);
  354. sol_obj_free(b);
  355. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  356. return res;
  357. }
  358. sol_object_t *sol_f_int_bor(sol_state_t *state, sol_object_t *args) {
  359. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  360. sol_object_t *res = sol_new_int(state, a->ival | b->ival);
  361. sol_obj_free(a);
  362. sol_obj_free(b);
  363. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  364. return res;
  365. }
  366. sol_object_t *sol_f_int_bxor(sol_state_t *state, sol_object_t *args) {
  367. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  368. sol_object_t *res = sol_new_int(state, a->ival ^ b->ival);
  369. sol_obj_free(a);
  370. sol_obj_free(b);
  371. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  372. return res;
  373. }
  374. sol_object_t *sol_f_int_blsh(sol_state_t *state, sol_object_t *args) {
  375. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  376. sol_object_t *res = sol_new_int(state, a->ival << b->ival);
  377. sol_obj_free(a);
  378. sol_obj_free(b);
  379. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  380. return res;
  381. }
  382. sol_object_t *sol_f_int_brsh(sol_state_t *state, sol_object_t *args) {
  383. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  384. sol_object_t *res = sol_new_int(state, a->ival >> b->ival);
  385. sol_obj_free(a);
  386. sol_obj_free(b);
  387. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  388. return res;
  389. }
  390. sol_object_t *sol_f_int_bnot(sol_state_t *state, sol_object_t *args) {
  391. sol_object_t *a = sol_list_get_index(state, args, 0);
  392. sol_object_t *res = sol_new_int(state, ~a->ival);
  393. sol_obj_free(a);
  394. return res;
  395. }
  396. sol_object_t *sol_f_int_cmp(sol_state_t *state, sol_object_t *args) {
  397. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  398. sol_object_t *res = sol_new_int(state, a->ival==b->ival? 0 : (a->ival<b->ival? -1 : 1));
  399. sol_obj_free(a);
  400. sol_obj_free(b);
  401. return res;
  402. }
  403. sol_object_t *sol_f_int_toint(sol_state_t *state, sol_object_t *args) {
  404. return sol_list_get_index(state, args, 0);
  405. }
  406. sol_object_t *sol_f_int_tofloat(sol_state_t *state, sol_object_t *args) {
  407. sol_object_t *a = sol_list_get_index(state, args, 0);
  408. sol_object_t *res = sol_new_float(state, (double) a->ival);
  409. sol_obj_free(a);
  410. return res;
  411. }
  412. sol_object_t *sol_f_int_tostring(sol_state_t *state, sol_object_t *args) {
  413. sol_object_t *a = sol_list_get_index(state, args, 0);
  414. char *s = _itoa(a->ival);
  415. sol_object_t *res = sol_new_string(state, s);
  416. sol_obj_free(a);
  417. free(s);
  418. return res;
  419. }
  420. sol_object_t *sol_f_float_add(sol_state_t *state, sol_object_t *args) {
  421. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_float(state, sol_list_get_index(state, args, 1));
  422. sol_object_t *res = sol_new_float(state, a->fval + b->fval);
  423. sol_obj_free(a);
  424. sol_obj_free(b);
  425. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  426. return res;
  427. }
  428. sol_object_t *sol_f_float_sub(sol_state_t *state, sol_object_t *args) {
  429. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_float(state, sol_list_get_index(state, args, 1));
  430. sol_object_t *res = sol_new_float(state, a->fval - b->fval);
  431. sol_obj_free(a);
  432. sol_obj_free(b);
  433. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  434. return res;
  435. }
  436. sol_object_t *sol_f_float_mul(sol_state_t *state, sol_object_t *args) {
  437. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_float(state, sol_list_get_index(state, args, 1));
  438. sol_object_t *res = sol_new_float(state, a->fval * b->fval);
  439. sol_obj_free(a);
  440. sol_obj_free(b);
  441. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  442. return res;
  443. }
  444. sol_object_t *sol_f_float_div(sol_state_t *state, sol_object_t *args) {
  445. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_float(state, sol_list_get_index(state, args, 1));
  446. sol_object_t *res = sol_new_float(state, a->fval / b->fval);
  447. sol_obj_free(a);
  448. sol_obj_free(b);
  449. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  450. return res;
  451. }
  452. sol_object_t *sol_f_float_pow(sol_state_t *state, sol_object_t *args) {
  453. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_float(state, sol_list_get_index(state, args, 1));
  454. sol_object_t *res = sol_new_float(state, pow(a->fval, b->fval));
  455. sol_obj_free(a);
  456. sol_obj_free(b);
  457. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  458. return res;
  459. }
  460. sol_object_t *sol_f_float_cmp(sol_state_t *state, sol_object_t *args) {
  461. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_float(state, sol_list_get_index(state, args, 1));
  462. sol_object_t *res = sol_new_int(state, a->fval==b->fval? 0 : (a->fval<b->fval? -1 : 1));
  463. sol_obj_free(a);
  464. sol_obj_free(b);
  465. return res;
  466. }
  467. sol_object_t *sol_f_float_toint(sol_state_t *state, sol_object_t *args) {
  468. sol_object_t *a = sol_list_get_index(state, args, 0);
  469. sol_object_t *res = sol_new_int(state, (int) a->fval);
  470. sol_obj_free(a);
  471. return res;
  472. }
  473. sol_object_t *sol_f_float_tofloat(sol_state_t *state, sol_object_t *args) {
  474. return sol_list_get_index(state, args, 0);
  475. }
  476. sol_object_t *sol_f_float_tostring(sol_state_t *state, sol_object_t *args) {
  477. sol_object_t *a = sol_list_get_index(state, args, 0);
  478. char *s = _ftoa(a->fval);
  479. sol_object_t *res = sol_new_string(state, s);
  480. sol_obj_free(a);
  481. free(s);
  482. return res;
  483. }
  484. sol_object_t *sol_f_str_add(sol_state_t *state, sol_object_t *args) {
  485. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_string(state, sol_list_get_index(state, args, 1));
  486. int n = strlen(a->str) + strlen(b->str) + 1;
  487. char *s = malloc(n);
  488. sol_object_t *res = sol_new_string(state, strncat(strncpy(s, a->str, n), b->str, n));
  489. sol_obj_free(a);
  490. sol_obj_free(b);
  491. free(s);
  492. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  493. return res;
  494. }
  495. sol_object_t *sol_f_str_mul(sol_state_t *state, sol_object_t *args) {
  496. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  497. int n = strlen(a->str) * b->ival + 1;
  498. char *s = malloc(n);
  499. int i;
  500. s[0]='\0';
  501. for(i = 0; i < b->ival; i++) strncat(s, a->str, n);
  502. sol_object_t *res = sol_new_string(state, s);
  503. sol_obj_free(a);
  504. sol_obj_free(b);
  505. free(s);
  506. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  507. return res;
  508. }
  509. sol_object_t *sol_f_str_cmp(sol_state_t *state, sol_object_t *args) {
  510. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_string(state, sol_list_get_index(state, args, 1));
  511. sol_object_t *res = sol_new_int(state, strcmp(a->str, b->str));
  512. sol_obj_free(a);
  513. sol_obj_free(b);
  514. return res;
  515. }
  516. sol_object_t *sol_f_str_len(sol_state_t *state, sol_object_t *args) {
  517. sol_object_t *a = sol_list_get_index(state, args, 0);
  518. sol_object_t *res = sol_new_int(state, strlen(a->str));
  519. sol_obj_free(a);
  520. return res;
  521. }
  522. sol_object_t *sol_f_str_iter(sol_state_t *state, sol_object_t *args) {
  523. return sol_new_cfunc(state, sol_f_iter_str);
  524. }
  525. sol_object_t *sol_f_str_toint(sol_state_t *state, sol_object_t *args) {
  526. sol_object_t *a = sol_list_get_index(state, args, 0);
  527. sol_object_t *res = sol_new_int(state, atoi(a->str));
  528. sol_obj_free(a);
  529. return res;
  530. }
  531. sol_object_t *sol_f_str_tofloat(sol_state_t *state, sol_object_t *args) {
  532. sol_object_t *a = sol_list_get_index(state, args, 0);
  533. sol_object_t *res = sol_new_float(state, atof(a->str));
  534. sol_obj_free(a);
  535. return res;
  536. }
  537. sol_object_t *sol_f_str_tostring(sol_state_t *state, sol_object_t *args) {
  538. return sol_list_get_index(state, args, 0);
  539. }
  540. sol_object_t *sol_f_list_add(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), *ls;
  542. if(!sol_is_list(b)) {
  543. sol_obj_free(a);
  544. sol_obj_free(b);
  545. return sol_set_error_string(state, "Adding list to non-list");
  546. }
  547. ls = sol_list_copy(state, a);
  548. sol_list_append(state, ls, b);
  549. sol_obj_free(a);
  550. sol_obj_free(b);
  551. return ls;
  552. }
  553. sol_object_t *sol_f_list_mul(sol_state_t *state, sol_object_t *args) {
  554. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1)), *ls;
  555. int i;
  556. if(sol_has_error(state)) {
  557. sol_obj_free(a);
  558. sol_obj_free(b);
  559. return sol_incref(state->None);
  560. }
  561. ls = sol_new_list(state);
  562. for(i = 0; i < b->ival; i++) {
  563. sol_list_append(state, ls, a);
  564. if(sol_has_error(state)) {
  565. sol_obj_free(a);
  566. sol_obj_free(b);
  567. return sol_incref(state->None);
  568. }
  569. }
  570. return ls;
  571. }
  572. sol_object_t *sol_f_list_index(sol_state_t *state, sol_object_t *args) {
  573. sol_object_t *ls = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  574. sol_object_t *res = sol_list_get_index(state, ls, b->ival);
  575. sol_obj_free(ls);
  576. sol_obj_free(b);
  577. return res;
  578. }
  579. sol_object_t *sol_f_list_setindex(sol_state_t *state, sol_object_t *args) {
  580. sol_object_t *ls = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args ,1));
  581. sol_object_t *val = sol_list_get_index(state, args, 2);
  582. sol_list_set_index(state, ls, b->ival, val);
  583. sol_obj_free(ls);
  584. sol_obj_free(b);
  585. sol_obj_free(val);
  586. return sol_incref(state->None);
  587. }
  588. sol_object_t *sol_f_list_len(sol_state_t *state, sol_object_t *args) {
  589. sol_object_t *ls = sol_list_get_index(state, args, 0);
  590. sol_object_t *res = sol_new_int(state, sol_list_len(state, ls));
  591. sol_obj_free(ls);
  592. return res;
  593. }
  594. sol_object_t *sol_f_list_iter(sol_state_t *state, sol_object_t *args) {
  595. return sol_new_cfunc(state, sol_f_iter_list);
  596. }
  597. sol_object_t *sol_f_list_tostring(sol_state_t *state, sol_object_t *args) {
  598. return sol_new_string(state, "<List>");
  599. }
  600. sol_object_t *sol_f_map_add(sol_state_t *state, sol_object_t *args) {
  601. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *map;
  602. if(!sol_is_map(b)) {
  603. sol_obj_free(a);
  604. sol_obj_free(b);
  605. return sol_set_error_string(state, "Adding map to non-map");
  606. }
  607. map = sol_map_copy(state, a);
  608. sol_map_merge(state, map, b);
  609. sol_obj_free(a);
  610. sol_obj_free(b);
  611. return map;
  612. }
  613. sol_object_t *sol_f_map_index(sol_state_t *state, sol_object_t *args) {
  614. sol_object_t *map = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
  615. sol_object_t *indexf = sol_map_get_name(state, map, "__index");
  616. sol_object_t *res = NULL, *newls;
  617. if(!sol_is_none(state, indexf)) {
  618. if(indexf->ops->call && indexf->ops->call != sol_f_not_impl) {
  619. newls = sol_new_list(state);
  620. sol_list_insert(state, newls, 0, indexf);
  621. sol_list_append(state, newls, args);
  622. res = indexf->ops->call(state, newls);
  623. sol_obj_free(newls);
  624. } else if(indexf->ops->index && indexf->ops->index != sol_f_not_impl) {
  625. res = indexf->ops->index(state, args);
  626. }
  627. }
  628. if(!res) res = sol_map_get(state, map, b);
  629. sol_obj_free(indexf);
  630. sol_obj_free(map);
  631. sol_obj_free(b);
  632. return res;
  633. }
  634. sol_object_t *sol_f_map_setindex(sol_state_t *state, sol_object_t *args) {
  635. sol_object_t *map = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
  636. sol_object_t *val = sol_list_get_index(state, args, 2);
  637. sol_object_t *setindexf = sol_map_get_name(state, map, "__setindex"), *newls;
  638. if(!sol_is_none(state, setindexf)) {
  639. if(setindexf->ops->call && setindexf->ops->call != sol_f_not_impl) {
  640. newls = sol_new_list(state);
  641. sol_list_insert(state, newls, 0, setindexf);
  642. sol_list_append(state, newls, args);
  643. sol_obj_free(setindexf->ops->call(state, newls));
  644. sol_obj_free(newls);
  645. return sol_incref(state->None);
  646. } else if(setindexf->ops->setindex && setindexf->ops->setindex != sol_f_not_impl) {
  647. setindexf->ops->setindex(state, args);
  648. return sol_incref(state->None);
  649. }
  650. }
  651. sol_obj_free(setindexf);
  652. sol_map_set(state, map, b, val);
  653. sol_obj_free(map);
  654. sol_obj_free(b);
  655. sol_obj_free(val);
  656. return sol_incref(state->None);
  657. }
  658. sol_object_t *sol_f_map_call(sol_state_t *state, sol_object_t *args) {
  659. sol_object_t *map = sol_list_get_index(state, args, 0), *fargs = sol_list_sublist(state, args, 1);
  660. sol_object_t *callf = sol_map_get_name(state, map, "__call"), *res = NULL;
  661. if(!sol_is_none(state, callf)) {
  662. if(callf->ops->call) {
  663. sol_list_insert(state, fargs, 0, callf);
  664. sol_list_insert(state, fargs, 1, map);
  665. res = callf->ops->call(state, fargs);
  666. }
  667. }
  668. sol_obj_free(map);
  669. sol_obj_free(fargs);
  670. sol_obj_free(callf);
  671. if(res) return res;
  672. return sol_set_error_string(state, "Call map without call method");
  673. }
  674. sol_object_t *sol_f_map_len(sol_state_t *state, sol_object_t *args) {
  675. sol_object_t *map = sol_list_get_index(state, args, 0);
  676. sol_object_t *res = sol_new_int(state, sol_map_len(state, map));
  677. sol_obj_free(map);
  678. return res;
  679. }
  680. sol_object_t *sol_f_map_iter(sol_state_t *state, sol_object_t *args) {
  681. return sol_new_cfunc(state, sol_f_iter_map);
  682. }
  683. sol_object_t *sol_f_map_tostring(sol_state_t *state, sol_object_t *args) {
  684. return sol_new_string(state, "<Map>");
  685. }
  686. sol_object_t *sol_f_func_index(sol_state_t *state, sol_object_t *args) {
  687. sol_object_t *func = sol_list_get_index(state, args, 0), *key = sol_list_get_index(state, args, 1), *res;
  688. res = sol_map_get(state, func->closure, key);
  689. sol_obj_free(func);
  690. sol_obj_free(key);
  691. return res;
  692. }
  693. sol_object_t *sol_f_func_setindex(sol_state_t *state, sol_object_t *args) {
  694. sol_object_t *func = sol_list_get_index(state, args, 0), *key = sol_list_get_index(state, args, 1), *val = sol_list_get_index(state, args, 2);
  695. sol_map_set(state, func->closure, key, val);
  696. sol_obj_free(func);
  697. sol_obj_free(key);
  698. sol_obj_free(val);
  699. return sol_incref(state->None);
  700. }
  701. sol_object_t *sol_f_func_tostring(sol_state_t *state, sol_object_t *args) {
  702. return sol_new_string(state, "<Function>");
  703. }
  704. sol_object_t *sol_f_cfunc_call(sol_state_t *state, sol_object_t *args) {
  705. sol_object_t *func = sol_list_get_index(state, args, 0), *fargs = sol_list_sublist(state, args, 1);
  706. sol_object_t *res = func->cfunc(state, fargs);
  707. sol_obj_free(func);
  708. sol_obj_free(fargs);
  709. return res;
  710. }
  711. sol_object_t *sol_f_cfunc_tostring(sol_state_t *state, sol_object_t *args) {
  712. return sol_new_string(state, "<CFunction>");
  713. }