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.

builtins.c 73KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385
  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 "ast.h"
  8. #include "dsl/dsl.h"
  9. // XXX hardcoded buffer sizes
  10. #define STDIO_CHUNK_SIZE 4096
  11. static char *_itoa(int i) {
  12. int n = 33;
  13. char *s = malloc(n);
  14. snprintf(s, n, "%d", i);
  15. return s;
  16. }
  17. static char *_ftoa(double f) {
  18. int n = 65;
  19. char *s = malloc(n);
  20. snprintf(s, n, "%f", f);
  21. return s;
  22. }
  23. sol_object_t *sol_f_not_impl(sol_state_t *state, sol_object_t *args) {
  24. return sol_set_error_string(state, "Undefined method");
  25. }
  26. sol_object_t *sol_f_default_cmp(sol_state_t *state, sol_object_t *args) {
  27. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
  28. sol_object_t *res = sol_new_int(state, a!=b);
  29. sol_obj_free(a);
  30. sol_obj_free(b);
  31. return res;
  32. }
  33. sol_object_t *sol_f_default_tostring(sol_state_t *state, sol_object_t *args) {
  34. sol_object_t *obj = sol_list_get_index(state, args, 0);
  35. char s[64];
  36. snprintf(s, 64, "<%s object at %p>", obj->ops->tname, obj);
  37. sol_obj_free(obj);
  38. return sol_new_string(state, s);
  39. }
  40. sol_object_t *sol_f_default_repr(sol_state_t *state, sol_object_t *args) {
  41. sol_object_t *obj = sol_list_get_index(state, args, 0), *res = obj->ops->tostring(state, args);
  42. sol_obj_free(obj);
  43. return res;
  44. }
  45. sol_object_t *sol_f_no_op(sol_state_t *state, sol_object_t *args) {
  46. if(state) return sol_incref(state->None);
  47. return NULL;
  48. }
  49. sol_object_t *sol_f_toint(sol_state_t *state, sol_object_t *args) {
  50. sol_object_t *obj = sol_list_get_index(state, args, 0);
  51. sol_object_t *res = obj->ops->toint(state, args);
  52. sol_obj_free(obj);
  53. return res;
  54. }
  55. sol_object_t *sol_f_tofloat(sol_state_t *state, sol_object_t *args) {
  56. sol_object_t *obj = sol_list_get_index(state, args, 0);
  57. sol_object_t *res = obj->ops->tofloat(state, args);
  58. sol_obj_free(obj);
  59. return res;
  60. }
  61. sol_object_t *sol_f_tostring(sol_state_t *state, sol_object_t *args) {
  62. sol_object_t *obj = sol_list_get_index(state, args, 0);
  63. sol_object_t *res = obj->ops->tostring(state, args);
  64. sol_obj_free(obj);
  65. return res;
  66. }
  67. sol_object_t *sol_f_try(sol_state_t *state, sol_object_t *args) {
  68. sol_object_t *func = sol_list_get_index(state, args, 0), *fargs = sol_list_sublist(state, args, 1);
  69. sol_object_t *ls = sol_new_list(state), *one = sol_new_int(state, 1);
  70. sol_object_t *res;
  71. sol_list_insert(state, fargs, 0, func);
  72. res = func->ops->call(state, fargs);
  73. sol_obj_free(func);
  74. sol_obj_free(fargs);
  75. if(sol_has_error(state)) {
  76. sol_object_t *err = sol_get_error(state);
  77. sol_clear_error(state);
  78. sol_object_t *zero = sol_new_int(state, 0);
  79. sol_obj_free(res);
  80. sol_obj_free(one);
  81. sol_list_insert(state, ls, 0, err);
  82. sol_obj_free(err);
  83. sol_list_insert(state, ls, 0, zero);
  84. sol_obj_free(zero);
  85. sol_list_insert(state, ls, 2, state->traceback);
  86. return ls;
  87. }
  88. sol_list_insert(state, ls, 0, res);
  89. sol_obj_free(res);
  90. sol_list_insert(state, ls, 0, one);
  91. sol_obj_free(one);
  92. return ls;
  93. }
  94. sol_object_t *sol_f_error(sol_state_t *state, sol_object_t *args) {
  95. sol_object_t *arg = sol_list_get_index(state, args, 0), *res;
  96. res = sol_set_error(state, arg);
  97. sol_obj_free(arg);
  98. return res;
  99. }
  100. sol_object_t *sol_f_type(sol_state_t *state, sol_object_t *args) {
  101. sol_object_t *obj = sol_list_get_index(state, args, 0);
  102. sol_object_t *res = sol_new_string(state, obj->ops->tname);
  103. sol_obj_free(obj);
  104. return res;
  105. }
  106. static dsl_seq *seen=NULL;
  107. int test_seen(sol_object_t *obj) {
  108. dsl_seq_iter *iter;
  109. if(seen) {
  110. iter = dsl_new_seq_iter(seen);
  111. while(!dsl_seq_iter_is_invalid(iter)) {
  112. if(dsl_seq_iter_at(iter) == obj) {
  113. return 1;
  114. }
  115. dsl_seq_iter_next(iter);
  116. }
  117. dsl_free_seq_iter(iter);
  118. dsl_seq_insert(seen, dsl_seq_len(seen), obj);
  119. }
  120. return 0;
  121. }
  122. void ob_print(sol_object_t *obj) {
  123. sol_object_t *cur;
  124. dsl_seq_iter *iter;
  125. int i;
  126. if(test_seen(obj)) {
  127. return;
  128. }
  129. switch(obj->type) {
  130. case SOL_SINGLET:
  131. printf("%s", obj->str);
  132. break;
  133. case SOL_INTEGER:
  134. printf("%ld", obj->ival);
  135. break;
  136. case SOL_FLOAT:
  137. printf("%f", obj->fval);
  138. break;
  139. case SOL_STRING:
  140. printf("\"%s\"", obj->str);
  141. break;
  142. case SOL_LIST:
  143. printf("[");
  144. iter = dsl_new_seq_iter(obj->seq);
  145. while(!dsl_seq_iter_is_invalid(iter)) {
  146. ob_print(dsl_seq_iter_at(iter));
  147. printf(", ");
  148. dsl_seq_iter_next(iter);
  149. }
  150. dsl_free_seq_iter(iter);
  151. printf("]");
  152. break;
  153. case SOL_MCELL:
  154. printf("<<");
  155. ob_print(obj->key);
  156. printf("=");
  157. ob_print(obj->val);
  158. printf(">>");
  159. case SOL_MAP:
  160. printf("{");
  161. iter = dsl_new_seq_iter(obj->seq);
  162. while(!dsl_seq_iter_is_invalid(iter)) {
  163. printf("[");
  164. ob_print(AS_OBJ(dsl_seq_iter_at(iter))->key);
  165. printf("] = ");
  166. ob_print(AS_OBJ(dsl_seq_iter_at(iter))->val);
  167. printf(", ");
  168. dsl_seq_iter_next(iter);
  169. }
  170. dsl_free_seq_iter(iter);
  171. printf("}");
  172. break;
  173. case SOL_FUNCTION:
  174. if(obj->fname) {
  175. printf("<Function %s>", obj->fname);
  176. } else {
  177. printf("<Function>");
  178. }
  179. break;
  180. case SOL_CFUNCTION:
  181. printf("<CFunction>");
  182. break;
  183. case SOL_STMT:
  184. st_print(NULL, obj->node); //TODO: FIXME
  185. break;
  186. case SOL_EXPR:
  187. ex_print(NULL, obj->node); //TODO: FIXME
  188. break;
  189. case SOL_BUFFER:
  190. if(obj->sz == -1) {
  191. printf("<Buffer @%p>", obj->buffer);
  192. } else {
  193. printf("<Buffer @%p size %ld>", obj->buffer, obj->sz);
  194. }
  195. break;
  196. case SOL_CDATA:
  197. printf("<CData>");
  198. break;
  199. /*default:
  200. cur = sol_cast_string(state, obj);
  201. printf("%s", cur->str);
  202. sol_obj_free(cur);*/
  203. }
  204. }
  205. sol_object_t *sol_f_prepr(sol_state_t *state, sol_object_t *args) {
  206. int i, sz = sol_list_len(state, args);
  207. sol_object_t *obj, *str;
  208. seen = dsl_seq_new_array(NULL, NULL);
  209. for(i=0; i<sz; i++) {
  210. obj = sol_list_get_index(state, args, i);
  211. str = sol_cast_repr(state, obj);
  212. sol_printf(state, "%s", str->str);
  213. sol_printf(state, " ");
  214. sol_obj_free(obj);
  215. sol_obj_free(str);
  216. }
  217. sol_printf(state, "\n");
  218. printf("\n");
  219. dsl_free_seq(seen);
  220. seen = NULL;
  221. return sol_incref(state->None);
  222. }
  223. sol_object_t *sol_f_print(sol_state_t *state, sol_object_t *args) {
  224. int i, sz = sol_list_len(state, args);
  225. sol_object_t *obj, *str;
  226. seen = dsl_seq_new_array(NULL, NULL);
  227. for(i=0; i<sz; i++) {
  228. obj = sol_list_get_index(state, args, i);
  229. str = sol_cast_string(state, obj);
  230. sol_printf(state, "%s", str->str);
  231. sol_printf(state, " ");
  232. sol_obj_free(obj);
  233. sol_obj_free(str);
  234. }
  235. sol_printf(state, "\n");
  236. dsl_free_seq(seen);
  237. seen = NULL;
  238. return sol_incref(state->None);
  239. }
  240. sol_object_t *sol_f_rawget(sol_state_t *state, sol_object_t *args) {
  241. sol_object_t *obj = sol_list_get_index(state, args, 0), *key, *res;
  242. if(!sol_is_map(obj)) return sol_set_error_string(state, "Rawset of non-map");
  243. key = sol_list_get_index(state, args, 1);
  244. res = sol_map_get(state, obj, key);
  245. sol_obj_free(key);
  246. sol_obj_free(obj);
  247. return res;
  248. }
  249. sol_object_t *sol_f_rawset(sol_state_t *state, sol_object_t *args) {
  250. sol_object_t *obj = sol_list_get_index(state, args, 0), *key, *val;
  251. if(!sol_is_map(obj)) return sol_set_error_string(state, "Rawset of non-map");
  252. key = sol_list_get_index(state, args, 1);
  253. val = sol_list_get_index(state, args, 2);
  254. sol_map_set(state, obj, key, val);
  255. sol_obj_free(val);
  256. sol_obj_free(key);
  257. sol_obj_free(obj);
  258. return sol_incref(state->None);
  259. }
  260. sol_object_t *sol_f_range(sol_state_t *state, sol_object_t *args) {
  261. sol_object_t *res = sol_new_list(state), *bound = sol_cast_int(state, sol_list_get_index(state, args, 0));
  262. int i;
  263. for(i=0; i<bound->ival; i++) {
  264. sol_list_insert(state, res, sol_list_len(state, res), sol_new_int(state, i));
  265. }
  266. sol_obj_free(bound);
  267. return res;
  268. }
  269. sol_object_t *sol_f_exec(sol_state_t *state, sol_object_t *args) {
  270. sol_object_t *prg = sol_list_get_index(state, args, 0), *prgstr = sol_cast_string(state, prg);
  271. stmt_node *program;
  272. program = sol_compile(prgstr->str);
  273. if(!program) {
  274. return sol_set_error_string(state, "Compilation failure");
  275. }
  276. // XXX should st_free(program);
  277. sol_exec(state, program);
  278. return sol_incref(state->None);
  279. }
  280. sol_object_t *sol_f_eval(sol_state_t *state, sol_object_t *args) {
  281. sol_object_t *prg = sol_list_get_index(state, args, 0), *prgstr = sol_cast_string(state, prg);
  282. stmt_node *program;
  283. program = sol_compile(prgstr->str);
  284. if(!program) {
  285. return sol_set_error_string(state, "Compilation failure");
  286. }
  287. if(program->type != ST_LIST || program->stmtlist->stmt->type != ST_EXPR) {
  288. return sol_set_error_string(state, "Not an expression");
  289. }
  290. // XXX should st_free(program);
  291. return sol_eval(state, program->stmtlist->stmt->expr);
  292. }
  293. sol_object_t *sol_f_execfile(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. FILE *f = fopen(prgstr->str, "r");
  297. char *s;
  298. long sz;
  299. if(!f) {
  300. return sol_set_error_string(state, "File open failure");
  301. }
  302. fseek(f, 0, SEEK_END);
  303. sz = ftell(f);
  304. fseek(f, 0, SEEK_SET);
  305. s = malloc(sz+1);
  306. if(!s) {
  307. fclose(f);
  308. return sol_set_error_string(state, "File memory allocation failure");
  309. }
  310. fread(s, 1, sz, f);
  311. s[sz]=0;
  312. fclose(f);
  313. program = sol_compile(s);
  314. free(s);
  315. if(!program) {
  316. return sol_set_error_string(state, "Compilation failure");
  317. }
  318. // XXX should st_free(program);
  319. sol_exec(state, program);
  320. return sol_incref(state->None);
  321. }
  322. sol_object_t *sol_f_parse(sol_state_t *state, sol_object_t *args) {
  323. sol_object_t *prg = sol_list_get_index(state, args, 0), *prgstr = sol_cast_string(state, prg);
  324. stmt_node *program = sol_compile(prgstr->str);
  325. sol_obj_free(prg);
  326. sol_obj_free(prgstr);
  327. if(!program) {
  328. return sol_set_error_string(state, "Compilation failure");
  329. }
  330. return sol_new_stmtnode(state, program);
  331. }
  332. sol_object_t *sol_f_ord(sol_state_t *state, sol_object_t *args) {
  333. sol_object_t *arg = sol_list_get_index(state, args, 0), *str = sol_cast_string(state, arg);
  334. sol_object_t *idx = sol_new_int(state, 0), *arg2, *iarg, *res;
  335. size_t len = strlen(str->str);
  336. sol_obj_free(arg);
  337. if(sol_list_len(state, args)>1) {
  338. arg2 = sol_list_get_index(state, args, 1);
  339. iarg = sol_cast_int(state, arg2);
  340. sol_obj_free(arg2);
  341. idx->ival = iarg->ival;
  342. sol_obj_free(iarg);
  343. }
  344. if(idx->ival < 0 || idx->ival >= len) {
  345. sol_obj_free(str);
  346. sol_obj_free(idx);
  347. return sol_set_error_string(state, "Compute ord of out-of-bounds index");
  348. }
  349. res = sol_new_int(state, str->str[idx->ival]);
  350. sol_obj_free(str);
  351. sol_obj_free(idx);
  352. return res;
  353. }
  354. sol_object_t *sol_f_chr(sol_state_t *state, sol_object_t *args) {
  355. sol_object_t *arg = sol_list_get_index(state, args, 0), *iarg = sol_cast_int(state, arg);
  356. char cbuf[2]={iarg->ival, 0};
  357. sol_object_t *res = sol_new_string(state, cbuf);
  358. sol_obj_free(arg);
  359. sol_obj_free(iarg);
  360. return res;
  361. }
  362. sol_object_t *sol_f_debug_getref(sol_state_t *state, sol_object_t *args) {
  363. sol_object_t *obj = sol_list_get_index(state, args, 0);
  364. 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.
  365. sol_obj_free(obj);
  366. return res;
  367. }
  368. sol_object_t *sol_f_debug_setref(sol_state_t *state, sol_object_t *args) {
  369. sol_object_t *obj = sol_list_get_index(state, args, 0), *cnt = sol_list_get_index(state, args, 1);
  370. obj->refcnt = sol_cast_int(state, cnt)->ival + 2; // NB: As above.
  371. sol_obj_free(cnt);
  372. sol_obj_free(obj);
  373. return sol_incref(state->None);
  374. }
  375. sol_object_t *sol_f_debug_closure(sol_state_t *state, sol_object_t *args) {
  376. sol_object_t *func = sol_list_get_index(state, args, 0);
  377. sol_object_t *res = sol_incref(func->closure);
  378. sol_obj_free(func);
  379. return res;
  380. }
  381. sol_object_t *sol_f_debug_globals(sol_state_t *state, sol_object_t *args) {
  382. return sol_list_get_index(state, state->scopes, sol_list_len(state, state->scopes)-1);
  383. }
  384. sol_object_t *sol_f_debug_locals(sol_state_t *state, sol_object_t *args) {
  385. return sol_list_get_index(state, state->scopes, 0);
  386. }
  387. sol_object_t *sol_f_debug_scopes(sol_state_t *state, sol_object_t *args) {
  388. return sol_incref(state->scopes);
  389. }
  390. sol_object_t *sol_f_iter_str(sol_state_t *state, sol_object_t *args) {
  391. sol_object_t *obj = sol_list_get_index(state, args, 0), *local = sol_list_get_index(state, args, 1);
  392. sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
  393. char temp[2] = {0, 0};
  394. if(sol_is_none(state, index)) {
  395. sol_obj_free(index);
  396. index = sol_new_int(state, 0);
  397. sol_map_set_name(state, local, "idx", index);
  398. }
  399. if(index->ival >= strlen(obj->str)) {
  400. sol_obj_free(index);
  401. sol_obj_free(obj);
  402. sol_obj_free(local);
  403. return sol_incref(state->StopIteration);
  404. }
  405. temp[0] = obj->str[index->ival];
  406. res = sol_new_string(state, temp);
  407. index->ival++;
  408. sol_obj_free(index);
  409. sol_obj_free(local);
  410. sol_obj_free(obj);
  411. return res;
  412. }
  413. sol_object_t *sol_f_iter_list(sol_state_t *state, sol_object_t *args) {
  414. sol_object_t *obj = sol_list_get_index(state, args, 0), *local = sol_list_get_index(state, args, 1);
  415. sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
  416. if(sol_is_none(state, index)) {
  417. sol_obj_free(index);
  418. index = sol_new_int(state, 0);
  419. sol_map_set_name(state, local, "idx", index);
  420. sol_obj_free(index);
  421. }
  422. if(index->ival >= sol_list_len(state, obj)) {
  423. sol_obj_free(index);
  424. sol_obj_free(obj);
  425. sol_obj_free(local);
  426. return sol_incref(state->StopIteration);
  427. }
  428. res = sol_list_get_index(state, obj, index->ival);
  429. index->ival++;
  430. sol_obj_free(local);
  431. sol_obj_free(obj);
  432. return res;
  433. }
  434. sol_object_t *sol_f_iter_map(sol_state_t *state, sol_object_t *args) {
  435. sol_object_t *obj = sol_list_get_index(state, args, 0), *local = sol_list_get_index(state, args, 1);
  436. sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
  437. if(sol_is_none(state, index)) {
  438. sol_obj_free(index);
  439. index = sol_new_int(state, 0);
  440. sol_map_set_name(state, local, "idx", index);
  441. sol_obj_free(index);
  442. }
  443. if(index->ival >= dsl_seq_len(obj->seq)) {
  444. sol_obj_free(index);
  445. sol_obj_free(obj);
  446. sol_obj_free(local);
  447. return sol_incref(state->StopIteration);
  448. }
  449. res = sol_incref(AS_OBJ(dsl_seq_get(obj->seq, index->ival))->key);
  450. index->ival++;
  451. sol_obj_free(local);
  452. sol_obj_free(obj);
  453. return res;
  454. }
  455. sol_object_t *sol_f_ast_print(sol_state_t *state, sol_object_t *args) {
  456. sol_object_t *obj = sol_list_get_index(state, args, 0);
  457. if(sol_is_aststmt(obj)) {
  458. st_print(state, obj->node);
  459. } else {
  460. ex_print(state, obj->node);
  461. }
  462. sol_obj_free(obj);
  463. return sol_incref(state->None);
  464. }
  465. sol_object_t *sol_f_singlet_tostring(sol_state_t *state, sol_object_t *args) {
  466. sol_object_t *obj = sol_list_get_index(state, args, 0), *res = sol_new_string(state, obj->str);
  467. sol_obj_free(obj);
  468. return res;
  469. }
  470. sol_object_t *sol_f_int_add(sol_state_t *state, sol_object_t *args) {
  471. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  472. sol_object_t *res = sol_new_int(state, a->ival + b->ival);
  473. sol_obj_free(a);
  474. sol_obj_free(b);
  475. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  476. return res;
  477. }
  478. sol_object_t *sol_f_int_sub(sol_state_t *state, sol_object_t *args) {
  479. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  480. sol_object_t *res = sol_new_int(state, a->ival - b->ival);
  481. sol_obj_free(a);
  482. sol_obj_free(b);
  483. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  484. return res;
  485. }
  486. sol_object_t *sol_f_int_mul(sol_state_t *state, sol_object_t *args) {
  487. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  488. sol_object_t *res = sol_new_int(state, a->ival * b->ival);
  489. sol_obj_free(a);
  490. sol_obj_free(b);
  491. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  492. return res;
  493. }
  494. sol_object_t *sol_f_int_div(sol_state_t *state, sol_object_t *args) {
  495. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  496. sol_object_t *res = sol_new_int(state, a->ival / b->ival);
  497. sol_obj_free(a);
  498. sol_obj_free(b);
  499. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  500. return res;
  501. }
  502. sol_object_t *sol_f_int_mod(sol_state_t *state, sol_object_t *args) {
  503. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  504. sol_object_t *res = sol_new_int(state, a->ival % b->ival);
  505. sol_obj_free(a);
  506. sol_obj_free(b);
  507. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  508. return res;
  509. }
  510. sol_object_t *sol_f_int_pow(sol_state_t *state, sol_object_t *args) {
  511. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  512. sol_object_t *res = sol_new_int(state, (long) pow((double) a->ival, b->ival));
  513. sol_obj_free(a);
  514. sol_obj_free(b);
  515. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  516. return res;
  517. }
  518. sol_object_t *sol_f_int_band(sol_state_t *state, sol_object_t *args) {
  519. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  520. sol_object_t *res = sol_new_int(state, a->ival & b->ival);
  521. sol_obj_free(a);
  522. sol_obj_free(b);
  523. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  524. return res;
  525. }
  526. sol_object_t *sol_f_int_bor(sol_state_t *state, sol_object_t *args) {
  527. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  528. sol_object_t *res = sol_new_int(state, a->ival | b->ival);
  529. sol_obj_free(a);
  530. sol_obj_free(b);
  531. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  532. return res;
  533. }
  534. sol_object_t *sol_f_int_bxor(sol_state_t *state, sol_object_t *args) {
  535. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  536. sol_object_t *res = sol_new_int(state, a->ival ^ b->ival);
  537. sol_obj_free(a);
  538. sol_obj_free(b);
  539. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  540. return res;
  541. }
  542. sol_object_t *sol_f_int_blsh(sol_state_t *state, sol_object_t *args) {
  543. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  544. sol_object_t *res = sol_new_int(state, a->ival << b->ival);
  545. sol_obj_free(a);
  546. sol_obj_free(b);
  547. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  548. return res;
  549. }
  550. sol_object_t *sol_f_int_brsh(sol_state_t *state, sol_object_t *args) {
  551. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  552. sol_object_t *res = sol_new_int(state, a->ival >> b->ival);
  553. sol_obj_free(a);
  554. sol_obj_free(b);
  555. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  556. return res;
  557. }
  558. sol_object_t *sol_f_int_bnot(sol_state_t *state, sol_object_t *args) {
  559. sol_object_t *a = sol_list_get_index(state, args, 0);
  560. sol_object_t *res = sol_new_int(state, ~a->ival);
  561. sol_obj_free(a);
  562. return res;
  563. }
  564. sol_object_t *sol_f_int_cmp(sol_state_t *state, sol_object_t *args) {
  565. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  566. sol_object_t *res = sol_new_int(state, a->ival==b->ival? 0 : (a->ival<b->ival? -1 : 1));
  567. sol_obj_free(a);
  568. sol_obj_free(b);
  569. return res;
  570. }
  571. sol_object_t *sol_f_int_toint(sol_state_t *state, sol_object_t *args) {
  572. return sol_list_get_index(state, args, 0);
  573. }
  574. sol_object_t *sol_f_int_tofloat(sol_state_t *state, sol_object_t *args) {
  575. sol_object_t *a = sol_list_get_index(state, args, 0);
  576. sol_object_t *res = sol_new_float(state, (double) a->ival);
  577. sol_obj_free(a);
  578. return res;
  579. }
  580. sol_object_t *sol_f_int_tostring(sol_state_t *state, sol_object_t *args) {
  581. sol_object_t *a = sol_list_get_index(state, args, 0);
  582. char *s = _itoa(a->ival);
  583. sol_object_t *res = sol_new_string(state, s);
  584. sol_obj_free(a);
  585. free(s);
  586. return res;
  587. }
  588. sol_object_t *sol_f_float_add(sol_state_t *state, sol_object_t *args) {
  589. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_float(state, sol_list_get_index(state, args, 1));
  590. sol_object_t *res = sol_new_float(state, a->fval + b->fval);
  591. sol_obj_free(a);
  592. sol_obj_free(b);
  593. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  594. return res;
  595. }
  596. sol_object_t *sol_f_float_sub(sol_state_t *state, sol_object_t *args) {
  597. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_float(state, sol_list_get_index(state, args, 1));
  598. sol_object_t *res = sol_new_float(state, a->fval - b->fval);
  599. sol_obj_free(a);
  600. sol_obj_free(b);
  601. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  602. return res;
  603. }
  604. sol_object_t *sol_f_float_mul(sol_state_t *state, sol_object_t *args) {
  605. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_float(state, sol_list_get_index(state, args, 1));
  606. sol_object_t *res = sol_new_float(state, a->fval * b->fval);
  607. sol_obj_free(a);
  608. sol_obj_free(b);
  609. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  610. return res;
  611. }
  612. sol_object_t *sol_f_float_div(sol_state_t *state, sol_object_t *args) {
  613. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_float(state, sol_list_get_index(state, args, 1));
  614. sol_object_t *res = sol_new_float(state, a->fval / b->fval);
  615. sol_obj_free(a);
  616. sol_obj_free(b);
  617. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  618. return res;
  619. }
  620. sol_object_t *sol_f_float_pow(sol_state_t *state, sol_object_t *args) {
  621. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_float(state, sol_list_get_index(state, args, 1));
  622. sol_object_t *res = sol_new_float(state, pow(a->fval, b->fval));
  623. sol_obj_free(a);
  624. sol_obj_free(b);
  625. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  626. return res;
  627. }
  628. sol_object_t *sol_f_float_cmp(sol_state_t *state, sol_object_t *args) {
  629. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_float(state, sol_list_get_index(state, args, 1));
  630. sol_object_t *res = sol_new_int(state, a->fval==b->fval? 0 : (a->fval<b->fval? -1 : 1));
  631. sol_obj_free(a);
  632. sol_obj_free(b);
  633. return res;
  634. }
  635. sol_object_t *sol_f_float_toint(sol_state_t *state, sol_object_t *args) {
  636. sol_object_t *a = sol_list_get_index(state, args, 0);
  637. sol_object_t *res = sol_new_int(state, (int) a->fval);
  638. sol_obj_free(a);
  639. return res;
  640. }
  641. sol_object_t *sol_f_float_tofloat(sol_state_t *state, sol_object_t *args) {
  642. return sol_list_get_index(state, args, 0);
  643. }
  644. sol_object_t *sol_f_float_tostring(sol_state_t *state, sol_object_t *args) {
  645. sol_object_t *a = sol_list_get_index(state, args, 0);
  646. char *s = _ftoa(a->fval);
  647. sol_object_t *res = sol_new_string(state, s);
  648. sol_obj_free(a);
  649. free(s);
  650. return res;
  651. }
  652. sol_object_t *sol_f_str_add(sol_state_t *state, sol_object_t *args) {
  653. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_string(state, sol_list_get_index(state, args, 1));
  654. sol_object_t *res = sol_string_concat(state, a, b);
  655. sol_obj_free(a);
  656. sol_obj_free(b);
  657. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  658. return res;
  659. }
  660. sol_object_t *sol_f_str_mul(sol_state_t *state, sol_object_t *args) {
  661. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
  662. int n = strlen(a->str) * b->ival + 1;
  663. char *s = malloc(n);
  664. int i;
  665. s[0]='\0';
  666. for(i = 0; i < b->ival; i++) strncat(s, a->str, n);
  667. sol_object_t *res = sol_new_string(state, s);
  668. sol_obj_free(a);
  669. sol_obj_free(b);
  670. free(s);
  671. if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
  672. return res;
  673. }
  674. sol_object_t *sol_f_str_cmp(sol_state_t *state, sol_object_t *args) {
  675. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_string(state, sol_list_get_index(state, args, 1));
  676. sol_object_t *res = sol_new_int(state, strcmp(a->str, b->str));
  677. sol_obj_free(a);
  678. sol_obj_free(b);
  679. return res;
  680. }
  681. sol_object_t *sol_f_str_len(sol_state_t *state, sol_object_t *args) {
  682. sol_object_t *a = sol_list_get_index(state, args, 0);
  683. sol_object_t *res = sol_new_int(state, strlen(a->str));
  684. sol_obj_free(a);
  685. return res;
  686. }
  687. sol_object_t *sol_f_str_index(sol_state_t *state, sol_object_t *args) {
  688. sol_object_t *str = sol_list_get_index(state, args, 0), *key = sol_list_get_index(state, args, 1), *idx, *funcs, *res;
  689. char buf[2]={0, 0};
  690. if(sol_is_string(key)) {
  691. funcs = sol_get_methods_name(state, "string");
  692. res = sol_map_get(state, funcs, key);
  693. sol_obj_free(funcs);
  694. return res;
  695. }
  696. idx = sol_cast_int(state, key);
  697. if(idx->ival>=0 && idx->ival<strlen(str->str)) {
  698. buf[0] = str->str[idx->ival];
  699. }
  700. sol_obj_free(str);
  701. sol_obj_free(key);
  702. sol_obj_free(idx);
  703. return sol_new_string(state, buf);
  704. }
  705. sol_object_t *sol_f_str_iter(sol_state_t *state, sol_object_t *args) {
  706. return sol_new_cfunc(state, sol_f_iter_str);
  707. }
  708. sol_object_t *sol_f_str_toint(sol_state_t *state, sol_object_t *args) {
  709. sol_object_t *a = sol_list_get_index(state, args, 0);
  710. sol_object_t *res = sol_new_int(state, atoi(a->str));
  711. sol_obj_free(a);
  712. return res;
  713. }
  714. sol_object_t *sol_f_str_tofloat(sol_state_t *state, sol_object_t *args) {
  715. sol_object_t *a = sol_list_get_index(state, args, 0);
  716. sol_object_t *res = sol_new_float(state, atof(a->str));
  717. sol_obj_free(a);
  718. return res;
  719. }
  720. sol_object_t *sol_f_str_tostring(sol_state_t *state, sol_object_t *args) {
  721. return sol_list_get_index(state, args, 0);
  722. }
  723. sol_object_t *sol_f_str_repr(sol_state_t *state, sol_object_t *args) {
  724. sol_object_t *obj = sol_list_get_index(state, args, 0), *cur = sol_new_string(state, "\""), *next = sol_string_concat(state, cur, obj);
  725. sol_obj_free(cur);
  726. cur = next;
  727. next = sol_string_concat_cstr(state, cur, "\"");
  728. sol_obj_free(cur);
  729. return next;
  730. }
  731. sol_object_t *sol_f_str_sub(sol_state_t *state, sol_object_t *args) {
  732. 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);
  733. sol_object_t *ilow, *ihigh;
  734. size_t len = strlen(str->str), i;
  735. char *s;
  736. if(sol_is_none(state, low)) {
  737. ilow = sol_new_int(state, 0);
  738. } else {
  739. ilow = sol_cast_int(state, low);
  740. }
  741. if(sol_is_none(state, high)) {
  742. ihigh = sol_new_int(state, len);
  743. } else {
  744. ihigh = sol_cast_int(state, high);
  745. }
  746. sol_obj_free(low);
  747. sol_obj_free(high);
  748. if(ilow->ival<0) {
  749. ilow->ival+=len;
  750. if(ilow->ival<0) ilow->ival=0;
  751. }
  752. if(ilow->ival>len) ilow->ival=len;
  753. if(ihigh->ival<0) {
  754. ihigh->ival+=len;
  755. if(ihigh->ival<0) ihigh->ival=0;
  756. }
  757. if(ihigh->ival>len) ihigh->ival=len;
  758. if(ilow->ival >= ihigh->ival) {
  759. sol_obj_free(ilow);
  760. sol_obj_free(ihigh);
  761. sol_obj_free(str);
  762. return sol_new_string(state, "");
  763. }
  764. s = malloc(ihigh->ival - ilow->ival + 1);
  765. for(i=ilow->ival; i<ihigh->ival; i++) s[i-ilow->ival] = str->str[i];
  766. s[ihigh->ival-ilow->ival]='\0';
  767. sol_obj_free(ihigh);
  768. sol_obj_free(ilow);
  769. sol_obj_free(str);
  770. return sol_new_string(state, s);
  771. }
  772. sol_object_t *sol_f_str_split(sol_state_t *state, sol_object_t *args) {
  773. 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);
  774. sol_object_t *res = sol_new_list(state), *opart;
  775. char *s = strdup(str->str);
  776. char *part = strtok(s, stok->str);
  777. sol_obj_free(tok);
  778. sol_obj_free(str);
  779. if(!part) {
  780. sol_obj_free(res);
  781. sol_obj_free(stok);
  782. return sol_incref(state->None);
  783. }
  784. opart = sol_new_string(state, part);
  785. sol_list_insert(state, res, 0, opart);
  786. sol_obj_free(opart);
  787. while(part = strtok(NULL, stok->str)) {
  788. opart = sol_new_string(state, part);
  789. sol_list_insert(state, res, sol_list_len(state, res), opart);
  790. sol_obj_free(opart);
  791. }
  792. sol_obj_free(stok);
  793. return res;
  794. }
  795. sol_object_t *sol_f_str_find(sol_state_t *state, sol_object_t *args) {
  796. 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);
  797. char *ptr = strstr(str->str, ssubstr->str);
  798. sol_object_t *res = sol_new_int(state, ptr?ptr-str->str:-1);
  799. sol_obj_free(str);
  800. sol_obj_free(substr);
  801. sol_obj_free(ssubstr);
  802. return res;
  803. }
  804. sol_object_t *sol_f_list_add(sol_state_t *state, sol_object_t *args) {
  805. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *ls;
  806. if(!sol_is_list(b)) {
  807. sol_obj_free(a);
  808. sol_obj_free(b);
  809. return sol_set_error_string(state, "Adding list to non-list");
  810. }
  811. ls = sol_list_copy(state, a);
  812. sol_list_append(state, ls, b);
  813. sol_obj_free(a);
  814. sol_obj_free(b);
  815. return ls;
  816. }
  817. sol_object_t *sol_f_list_mul(sol_state_t *state, sol_object_t *args) {
  818. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1)), *ls;
  819. int i;
  820. if(sol_has_error(state)) {
  821. sol_obj_free(a);
  822. sol_obj_free(b);
  823. return sol_incref(state->None);
  824. }
  825. ls = sol_new_list(state);
  826. for(i = 0; i < b->ival; i++) {
  827. sol_list_append(state, ls, a);
  828. if(sol_has_error(state)) {
  829. sol_obj_free(a);
  830. sol_obj_free(b);
  831. return sol_incref(state->None);
  832. }
  833. }
  834. return ls;
  835. }
  836. sol_object_t *sol_f_list_index(sol_state_t *state, sol_object_t *args) {
  837. sol_object_t *ls = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *ival;
  838. sol_object_t *res, *funcs;
  839. if(sol_is_string(b)) {
  840. funcs = sol_get_methods_name(state, "list");
  841. res = sol_map_get(state, funcs, b);
  842. sol_obj_free(funcs);
  843. } else {
  844. ival = sol_cast_int(state, b);
  845. res = sol_list_get_index(state, ls, ival->ival);
  846. sol_obj_free(ival);
  847. }
  848. sol_obj_free(ls);
  849. sol_obj_free(b);
  850. return res;
  851. }
  852. sol_object_t *sol_f_list_setindex(sol_state_t *state, sol_object_t *args) {
  853. sol_object_t *ls = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args ,1));
  854. sol_object_t *val = sol_list_get_index(state, args, 2);
  855. sol_list_set_index(state, ls, b->ival, val);
  856. sol_obj_free(ls);
  857. sol_obj_free(b);
  858. sol_obj_free(val);
  859. return sol_incref(state->None);
  860. }
  861. sol_object_t *sol_f_list_len(sol_state_t *state, sol_object_t *args) {
  862. sol_object_t *ls = sol_list_get_index(state, args, 0);
  863. sol_object_t *res = sol_new_int(state, sol_list_len(state, ls));
  864. sol_obj_free(ls);
  865. return res;
  866. }
  867. sol_object_t *sol_f_list_iter(sol_state_t *state, sol_object_t *args) {
  868. return sol_new_cfunc(state, sol_f_iter_list);
  869. }
  870. sol_object_t *sol_f_list_tostring(sol_state_t *state, sol_object_t *args) {
  871. sol_object_t *cur = sol_new_string(state, "["), *next, *str, *obj = sol_list_get_index(state, args, 0), *item;
  872. dsl_seq_iter *iter = dsl_new_seq_iter(obj->seq);
  873. char s[64];
  874. while(!dsl_seq_iter_is_invalid(iter)) {
  875. item = AS_OBJ(dsl_seq_iter_at(iter));
  876. if(test_seen(item)) {
  877. snprintf(s, 64, "... (%p)", item);
  878. next = sol_string_concat_cstr(state, cur, s);
  879. } else {
  880. str = sol_cast_repr(state, item);
  881. next = sol_string_concat(state, cur, str);
  882. sol_obj_free(str);
  883. }
  884. sol_obj_free(cur);
  885. cur = next;
  886. if(!dsl_seq_iter_at_end(iter)) {
  887. next = sol_string_concat_cstr(state, cur, ", ");
  888. sol_obj_free(cur);
  889. cur = next;
  890. }
  891. dsl_seq_iter_next(iter);
  892. }
  893. next = sol_string_concat_cstr(state, cur, "]");
  894. sol_obj_free(cur);
  895. dsl_free_seq_iter(iter);
  896. return next;
  897. }
  898. sol_object_t *sol_f_list_copy(sol_state_t *state, sol_object_t *args) {
  899. sol_object_t *list = sol_list_get_index(state, args, 0);
  900. sol_object_t *res = sol_list_copy(state, list);
  901. sol_obj_free(list);
  902. return res;
  903. }
  904. sol_object_t *sol_f_list_insert(sol_state_t *state, sol_object_t *args) {
  905. sol_object_t *list = sol_list_get_index(state, args, 0), *idx = sol_cast_int(state, sol_list_get_index(state, args, 1)), *obj = sol_list_get_index(state, args, 2);
  906. sol_list_insert(state, list, idx->ival, obj);
  907. sol_obj_free(list);
  908. return sol_incref(state->None);
  909. }
  910. sol_object_t *sol_f_list_remove(sol_state_t *state, sol_object_t *args) {
  911. sol_object_t *list = sol_list_get_index(state, args, 0), *idx = sol_cast_int(state, sol_list_get_index(state, args, 1));
  912. sol_list_remove(state, list, idx->ival);
  913. sol_obj_free(list);
  914. return sol_incref(state->None);
  915. }
  916. sol_object_t *sol_f_list_truncate(sol_state_t *state, sol_object_t *args) {
  917. sol_object_t *list = sol_list_get_index(state, args, 0), *idx = sol_list_get_index(state, args, 1);
  918. sol_object_t *res = sol_list_truncate(state, list, idx->ival);
  919. sol_obj_free(list);
  920. return res;
  921. }
  922. sol_object_t *sol_f_list_map(sol_state_t *state, sol_object_t *args) {
  923. sol_object_t *list = sol_list_get_index(state, args, 0), *func = sol_list_get_index(state, args, 1);
  924. sol_object_t *fargs = sol_new_list(state), *item;
  925. int idx=0, len = sol_list_len(state, list);
  926. sol_list_insert(state, fargs, 0, func);
  927. while(idx<len) {
  928. item = sol_list_get_index(state, list, idx);
  929. sol_list_insert(state, fargs, 1, item);
  930. sol_obj_free(item);
  931. item = func->ops->call(state, fargs);
  932. if(sol_has_error(state)) return list;
  933. sol_list_remove(state, fargs, 1);
  934. sol_list_set_index(state, list, idx, item);
  935. sol_obj_free(item);
  936. idx++;
  937. }
  938. sol_obj_free(fargs);
  939. sol_obj_free(func);
  940. return list;
  941. }
  942. sol_object_t *sol_f_list_filter(sol_state_t *state, sol_object_t *args) {
  943. sol_object_t *list = sol_list_get_index(state, args, 0), *func = sol_list_get_index(state, args, 1);
  944. sol_object_t *fargs = sol_new_list(state), *item, *ival;
  945. int idx=0, len = sol_list_len(state, list);
  946. sol_list_insert(state, fargs, 0, func);
  947. while(idx<len) {
  948. item = sol_list_get_index(state, list, idx);
  949. sol_list_insert(state, fargs, 1, item);
  950. sol_obj_free(item);
  951. item = func->ops->call(state, fargs);
  952. if(sol_has_error(state)) return list;
  953. ival = sol_cast_int(state, item);
  954. if(ival->ival) {
  955. idx++;
  956. } else {
  957. sol_list_remove(state, list, idx);
  958. len--;
  959. }
  960. sol_obj_free(item);
  961. sol_obj_free(ival);
  962. }
  963. sol_obj_free(fargs);
  964. sol_obj_free(func);
  965. return list;
  966. }
  967. sol_object_t *sol_f_map_add(sol_state_t *state, sol_object_t *args) {
  968. sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *map;
  969. if(!sol_is_map(b)) {
  970. sol_obj_free(a);
  971. sol_obj_free(b);
  972. return sol_set_error_string(state, "Adding map to non-map");
  973. }
  974. map = sol_map_copy(state, a);
  975. sol_map_merge(state, map, b);
  976. sol_obj_free(a);
  977. sol_obj_free(b);
  978. return map;
  979. }
  980. sol_object_t *sol_f_map_index(sol_state_t *state, sol_object_t *args) {
  981. sol_object_t *map = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
  982. sol_object_t *indexf = sol_map_get_name(state, map, "__index");
  983. sol_object_t *res = NULL, *newls;
  984. res = sol_map_get(state, map, b);
  985. if(sol_is_none(state, res)) {
  986. if(!sol_is_none(state, indexf)) {
  987. sol_obj_free(res);
  988. if(indexf->ops->call && (sol_is_func(indexf) || sol_is_cfunc(indexf)) && indexf->ops->call != sol_f_not_impl) {
  989. newls = sol_new_list(state);
  990. sol_list_insert(state, newls, 0, indexf);
  991. sol_list_append(state, newls, args);
  992. res = indexf->ops->call(state, newls);
  993. sol_obj_free(newls);
  994. } else if(indexf->ops->index && indexf->ops->index != sol_f_not_impl) {
  995. newls = sol_new_list(state);
  996. sol_list_insert(state, newls, 0, indexf);
  997. sol_list_insert(state, newls, 1, b);
  998. res = indexf->ops->index(state, newls);
  999. sol_obj_free(newls);
  1000. }
  1001. }
  1002. }
  1003. sol_obj_free(indexf);
  1004. sol_obj_free(map);
  1005. sol_obj_free(b);
  1006. return res;
  1007. }
  1008. sol_object_t *sol_f_map_setindex(sol_state_t *state, sol_object_t *args) {
  1009. sol_object_t *map = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
  1010. sol_object_t *val = sol_list_get_index(state, args, 2);
  1011. sol_object_t *setindexf = sol_map_get_name(state, map, "__setindex"), *newls;
  1012. if(!sol_is_none(state, setindexf)) {
  1013. if(setindexf->ops->call && (sol_is_func(setindexf) || sol_is_cfunc(setindexf)) && setindexf->ops->call != sol_f_not_impl) {
  1014. newls = sol_new_list(state);
  1015. sol_list_insert(state, newls, 0, setindexf);
  1016. sol_list_append(state, newls, args);
  1017. sol_obj_free(setindexf->ops->call(state, newls));
  1018. sol_obj_free(newls);
  1019. return sol_incref(state->None);
  1020. } else if(setindexf->ops->setindex && setindexf->ops->setindex != sol_f_not_impl) {
  1021. newls = sol_new_list(state);
  1022. sol_list_insert(state, newls, 0, setindexf);
  1023. sol_list_insert(state, newls, 1, b);
  1024. sol_list_insert(state, newls, 2, val);
  1025. sol_obj_free(setindexf->ops->index(state, newls));
  1026. sol_obj_free(newls);
  1027. return sol_incref(state->None);
  1028. }
  1029. }
  1030. sol_obj_free(setindexf);
  1031. sol_map_set(state, map, b, val);
  1032. sol_obj_free(map);
  1033. sol_obj_free(b);
  1034. sol_obj_free(val);
  1035. return sol_incref(state->None);
  1036. }
  1037. sol_object_t *sol_f_map_call(sol_state_t *state, sol_object_t *args) {
  1038. sol_object_t *map = sol_list_get_index(state, args, 0), *fargs = sol_list_sublist(state, args, 1);
  1039. sol_object_t *callf = sol_map_get_name(state, map, "__call"), *res = NULL;
  1040. if(!sol_is_none(state, callf)) {
  1041. if(callf->ops->call) {
  1042. sol_list_insert(state, fargs, 0, callf);
  1043. sol_list_insert(state, fargs, 1, map);
  1044. res = callf->ops->call(state, fargs);
  1045. }
  1046. }
  1047. sol_obj_free(map);
  1048. sol_obj_free(fargs);
  1049. sol_obj_free(callf);
  1050. if(res) return res;
  1051. return sol_set_error_string(state, "Call map without call method");
  1052. }
  1053. sol_object_t *sol_f_map_len(sol_state_t *state, sol_object_t *args) {
  1054. sol_object_t *map = sol_list_get_index(state, args, 0);
  1055. sol_object_t *res = sol_new_int(state, sol_map_len(state, map));
  1056. sol_obj_free(map);
  1057. return res;
  1058. }
  1059. sol_object_t *sol_f_map_iter(sol_state_t *state, sol_object_t *args) {
  1060. return sol_new_cfunc(state, sol_f_iter_map);
  1061. }
  1062. sol_object_t *sol_f_map_tostring(sol_state_t *state, sol_object_t *args) {
  1063. sol_object_t *map = sol_list_get_index(state, args, 0), *res;
  1064. sol_object_t *tostrf = sol_map_get_name(state, map, "__tostring"), *fargs;
  1065. if(!sol_is_none(state, tostrf) && tostrf->ops->call) {
  1066. fargs = sol_new_list(state);
  1067. sol_list_insert(state, fargs, 0, tostrf);
  1068. sol_list_insert(state, fargs, 1, map);
  1069. res = tostrf->ops->call(state, fargs);
  1070. sol_obj_free(fargs);
  1071. } else {
  1072. res = sol_cast_repr(state, map);
  1073. }
  1074. sol_obj_free(tostrf);
  1075. sol_obj_free(map);
  1076. return res;
  1077. }
  1078. sol_object_t *sol_f_map_repr(sol_state_t *state, sol_object_t *args) {
  1079. sol_object_t *cur = sol_new_string(state, "{"), *next, *str, *obj = sol_list_get_index(state, args, 0), *item, *reprf = sol_map_get_name(state, obj, "__repr"), *fargs;
  1080. dsl_seq_iter *iter;
  1081. char s[64];
  1082. if(!sol_is_none(state, reprf) && reprf->ops->call) {
  1083. sol_obj_free(cur);
  1084. fargs = sol_new_list(state);
  1085. sol_list_insert(state, fargs, 0, reprf);
  1086. sol_list_insert(state, fargs, 1, obj);
  1087. cur = reprf->ops->call(state, fargs);
  1088. sol_obj_free(fargs);
  1089. sol_obj_free(obj);
  1090. sol_obj_free(reprf);
  1091. return cur;
  1092. }
  1093. iter = dsl_new_seq_iter(obj->seq);
  1094. while(!dsl_seq_iter_is_invalid(iter)) {
  1095. item = AS_OBJ(dsl_seq_iter_at(iter));
  1096. if(test_seen(item)) {
  1097. snprintf(s, 64, "... (%p)", item);
  1098. next = sol_string_concat_cstr(state, cur, s);
  1099. } else {
  1100. str = sol_cast_repr(state, item);
  1101. next = sol_string_concat(state, cur, str);
  1102. sol_obj_free(str);
  1103. }
  1104. sol_obj_free(cur);
  1105. cur = next;
  1106. if(!dsl_seq_iter_at_end(iter)) {
  1107. next = sol_string_concat_cstr(state, cur, ", ");
  1108. sol_obj_free(cur);
  1109. cur = next;
  1110. }
  1111. dsl_seq_iter_next(iter);
  1112. }
  1113. next = sol_string_concat_cstr(state, cur, "}");
  1114. sol_obj_free(cur);
  1115. dsl_free_seq_iter(iter);
  1116. sol_obj_free(obj);
  1117. return next;
  1118. }
  1119. sol_object_t *sol_f_mcell_tostring(sol_state_t *state, sol_object_t *args) {
  1120. sol_object_t *mcell = sol_list_get_index(state, args, 0), *cur = sol_new_string(state, "["), *next, *str;
  1121. char s[64];
  1122. if(test_seen(mcell->key)) {
  1123. snprintf(s, 64, "... (%p)", mcell->key);
  1124. next = sol_string_concat_cstr(state, cur, s);
  1125. } else {
  1126. str = sol_cast_repr(state, mcell->key);
  1127. next = sol_string_concat(state, cur, str);
  1128. sol_obj_free(str);
  1129. }
  1130. sol_obj_free(cur);
  1131. cur = next;
  1132. next = sol_string_concat_cstr(state, cur, "] = ");
  1133. sol_obj_free(cur);
  1134. cur = next;
  1135. if(test_seen(mcell->val)) {
  1136. snprintf(s, 64, "... (%p)", mcell->val);
  1137. next = sol_string_concat_cstr(state, cur, s);
  1138. } else {
  1139. str = sol_cast_repr(state, mcell->val);
  1140. next = sol_string_concat(state, cur, str);
  1141. sol_obj_free(str);
  1142. }
  1143. sol_obj_free(cur);
  1144. sol_obj_free(mcell);
  1145. return next;
  1146. }
  1147. sol_object_t *sol_f_func_index(sol_state_t *state, sol_object_t *args) {
  1148. sol_object_t *func = sol_list_get_index(state, args, 0), *key = sol_list_get_index(state, args, 1), *res;
  1149. identlist_node *curi;
  1150. int i=0;
  1151. if(!sol_is_string(key)) {
  1152. res = sol_map_get(state, func->udata, key);
  1153. } else {
  1154. if(sol_string_eq(state, key, "name")) {
  1155. res = sol_new_string(state, func->fname);
  1156. } else if(sol_string_eq(state, key, "closure")) {
  1157. res = sol_incref(func->closure);
  1158. } else if(sol_string_eq(state, key, "udata")) {
  1159. res = sol_incref(func->udata);
  1160. } else if(sol_string_eq(state, key, "stmt")) {
  1161. res = sol_new_stmtnode(state, (stmt_node *) func->func);
  1162. } else if(sol_string_eq(state, key, "args")) {
  1163. res = sol_new_list(state);
  1164. curi = func->args;
  1165. while(curi) {
  1166. sol_list_insert(state, res, i++, sol_new_string(state, curi->ident));
  1167. curi = curi->next;
  1168. }
  1169. } else {
  1170. res = sol_map_get(state, func->udata, key);
  1171. }
  1172. }
  1173. sol_obj_free(func);
  1174. sol_obj_free(key);
  1175. return res;
  1176. }
  1177. sol_object_t *sol_f_func_setindex(sol_state_t *state, sol_object_t *args) {
  1178. 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), *temp;
  1179. if(sol_string_eq(state, key, "name") && sol_is_string(val)) {
  1180. free(func->fname);
  1181. func->fname = strdup(val->str);
  1182. } else if(sol_string_eq(state, key, "closure") && sol_is_map(val)) {
  1183. temp = func->closure;
  1184. func->closure = sol_incref(val);
  1185. sol_obj_free(temp);
  1186. } else if(sol_string_eq(state, key, "udata") && sol_is_map(val)) {
  1187. temp = func->udata;
  1188. func->udata = sol_incref(val);
  1189. sol_obj_free(temp);
  1190. } else if(sol_string_eq(state, key, "stmt") && sol_is_aststmt(val)) {
  1191. func->func = val->node;
  1192. } else {
  1193. sol_map_set(state, func->udata, key, val);
  1194. }
  1195. sol_obj_free(func);
  1196. sol_obj_free(key);
  1197. sol_obj_free(val);
  1198. return sol_incref(state->None);
  1199. }
  1200. sol_object_t *sol_f_func_tostring(sol_state_t *state, sol_object_t *args) {
  1201. sol_object_t *func = sol_list_get_index(state, args, 0), *ret;
  1202. char *s = malloc(256 * sizeof(char));
  1203. if(func->fname) {
  1204. snprintf(s, 256, "<Function %s>", func->fname);
  1205. } else {
  1206. snprintf(s, 256, "<Function>");
  1207. }
  1208. ret = sol_new_string(state, s);
  1209. free(s);
  1210. sol_obj_free(func);
  1211. return ret;
  1212. }
  1213. sol_object_t *sol_f_cfunc_call(sol_state_t *state, sol_object_t *args) {
  1214. sol_object_t *func = sol_list_get_index(state, args, 0), *fargs = sol_list_sublist(state, args, 1);
  1215. sol_object_t *res = func->cfunc(state, fargs);
  1216. sol_obj_free(func);
  1217. sol_obj_free(fargs);
  1218. return res;
  1219. }
  1220. sol_object_t *sol_f_cfunc_tostring(sol_state_t *state, sol_object_t *args) {
  1221. return sol_new_string(state, "<CFunction>");
  1222. }
  1223. sol_object_t *sol_f_astnode_call(sol_state_t *state, sol_object_t *args) {
  1224. sol_object_t *obj = sol_list_get_index(state, args, 0), *env=NULL, *res;
  1225. stmt_node *stmt = (stmt_node *) obj->node;
  1226. expr_node *expr = (expr_node *) obj->node;
  1227. sol_obj_free(obj);
  1228. if(sol_list_len(state, args)>1) {
  1229. env = sol_list_get_index(state, args, 1);
  1230. sol_state_push_scope(state, env);
  1231. }
  1232. if(sol_is_aststmt(obj)) {
  1233. sol_exec(state, stmt);
  1234. res = sol_incref(state->None);
  1235. } else {
  1236. res = sol_eval(state, expr);
  1237. }
  1238. if(env) {
  1239. sol_state_pop_scope(state);
  1240. sol_obj_free(env);
  1241. }
  1242. return res;
  1243. }
  1244. sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
  1245. sol_object_t *obj = sol_list_get_index(state, args, 0), *key = sol_list_get_index(state, args, 1), *str = sol_cast_string(state, key), *res=NULL, *pair;
  1246. stmt_node *stmt = (stmt_node *) obj->node;
  1247. stmtlist_node *curs;
  1248. expr_node *expr = (expr_node *) obj->node;
  1249. exprlist_node *cure;
  1250. assoclist_node *cura;
  1251. identlist_node *curi;
  1252. int i=0;
  1253. if(sol_is_aststmt(obj)) {
  1254. if(sol_string_eq(state, str, "type")) {
  1255. res = sol_new_int(state, stmt->type);
  1256. } else if(sol_string_eq(state, str, "loc")) {
  1257. res = sol_new_map(state);
  1258. sol_map_set_name(state, res, "line", sol_new_int(state, stmt->loc.line));
  1259. sol_map_set_name(state, res, "col", sol_new_int(state, stmt->loc.col));
  1260. } else {
  1261. switch(stmt->type) {
  1262. case ST_EXPR:
  1263. if(sol_string_eq(state, str, "expr")) {
  1264. res = sol_new_exprnode(state, stmt->expr);
  1265. }
  1266. break;
  1267. case ST_IFELSE:
  1268. if(sol_string_eq(state, str, "cond")) {
  1269. res = sol_new_exprnode(state, stmt->ifelse->cond);
  1270. } else if(sol_string_eq(state, str, "iftrue")) {
  1271. res = sol_new_stmtnode(state, stmt->ifelse->iftrue);
  1272. } else if(sol_string_eq(state, str, "iffalse")) {
  1273. res = sol_new_stmtnode(state, stmt->ifelse->iffalse);
  1274. }
  1275. break;
  1276. case ST_LOOP:
  1277. if(sol_string_eq(state, str, "cond")) {
  1278. res = sol_new_exprnode(state, stmt->loop->cond);
  1279. } else if(sol_string_eq(state, str, "loop")) {
  1280. res = sol_new_stmtnode(state, stmt->loop->loop);
  1281. }
  1282. break;
  1283. case ST_ITER:
  1284. if(sol_string_eq(state, str, "var")) {
  1285. res = sol_new_string(state, stmt->iter->var);
  1286. } else if(sol_string_eq(state, str, "iter")) {
  1287. res = sol_new_exprnode(state, stmt->iter->iter);
  1288. } else if(sol_string_eq(state, str, "loop")) {
  1289. res = sol_new_stmtnode(state, stmt->iter->loop);
  1290. }
  1291. break;
  1292. case ST_LIST:
  1293. if(sol_string_eq(state, str, "stmtlist")) {
  1294. res = sol_new_list(state);
  1295. curs = stmt->stmtlist;
  1296. while(curs) {
  1297. sol_list_insert(state, res, i++, sol_new_stmtnode(state, curs->stmt));
  1298. curs = curs->next;
  1299. }
  1300. }
  1301. break;
  1302. case ST_RET:
  1303. if(sol_string_eq(state, str, "ret")) {
  1304. res = sol_new_exprnode(state, stmt->ret->ret);
  1305. }
  1306. break;
  1307. }
  1308. }
  1309. } else {
  1310. if(sol_string_eq(state, str, "type")) {
  1311. res = sol_new_int(state, expr->type);
  1312. } else if(sol_string_eq(state, str, "loc")) {
  1313. res = sol_new_map(state);
  1314. sol_map_set_name(state, res, "line", sol_new_int(state, expr->loc.line));
  1315. sol_map_set_name(state, res, "col", sol_new_int(state, expr->loc.col));
  1316. } else {
  1317. switch(expr->type) {
  1318. case EX_LIT:
  1319. if(sol_string_eq(state, str, "littype")) {
  1320. res = sol_new_int(state, expr->lit->type);
  1321. } else if(sol_string_eq(state, str, "ival")) {
  1322. res = sol_new_int(state, expr->lit->ival);
  1323. } else if(sol_string_eq(state, str, "fval")) {
  1324. res = sol_new_float(state, expr->lit->fval);
  1325. } else if(sol_string_eq(state, str, "str")) {
  1326. res = sol_new_string(state, expr->lit->str);
  1327. }
  1328. break;
  1329. case EX_LISTGEN:
  1330. if(sol_string_eq(state, str, "list")) {
  1331. res = sol_new_list(state);
  1332. cure = expr->listgen->list;
  1333. while(cure) {
  1334. sol_list_insert(state, res, i++, sol_new_exprnode(state, cure->expr));
  1335. cure = cure->next;
  1336. }
  1337. }
  1338. break;
  1339. case EX_MAPGEN:
  1340. if(sol_string_eq(state, str, "map")) {
  1341. res = sol_new_list(state);
  1342. cura = expr->mapgen->map;
  1343. while(cura) {
  1344. pair = sol_new_list(state);
  1345. sol_list_insert(state, pair, 0, sol_new_exprnode(state, cura->item->key));
  1346. sol_list_insert(state, pair, 1, sol_new_exprnode(state, cura->item->value));
  1347. sol_list_insert(state, res, i++, pair);
  1348. sol_obj_free(pair);
  1349. }
  1350. }
  1351. break;
  1352. case EX_BINOP:
  1353. if(sol_string_eq(state, str, "binoptype")) {
  1354. res = sol_new_int(state, expr->binop->type);
  1355. } else if(sol_string_eq(state, str, "left")) {
  1356. res = sol_new_exprnode(state, expr->binop->left);
  1357. } else if(sol_string_eq(state, str, "right")) {
  1358. res = sol_new_exprnode(state, expr->binop->right);
  1359. }
  1360. break;
  1361. case EX_UNOP:
  1362. if(sol_string_eq(state, str, "unoptype")) {
  1363. res = sol_new_int(state, expr->unop->type);
  1364. } else if(sol_string_eq(state, str, "expr")) {
  1365. res = sol_new_exprnode(state, expr->unop->expr);
  1366. }
  1367. break;
  1368. case EX_INDEX:
  1369. if(sol_string_eq(state, str, "expr")) {
  1370. res = sol_new_exprnode(state, expr->index->expr);
  1371. } else if(sol_string_eq(state, str, "index")) {
  1372. res = sol_new_exprnode(state, expr->index->index);
  1373. }
  1374. break;
  1375. case EX_SETINDEX:
  1376. if(sol_string_eq(state, str, "expr")) {
  1377. res = sol_new_exprnode(state, expr->setindex->expr);
  1378. } else if(sol_string_eq(state, str, "index")) {
  1379. res = sol_new_exprnode(state, expr->setindex->index);
  1380. } else if(sol_string_eq(state, str, "value")) {
  1381. res = sol_new_exprnode(state, expr->setindex->value);
  1382. }
  1383. break;
  1384. case EX_ASSIGN:
  1385. if(sol_string_eq(state, str, "ident")) {
  1386. res = sol_new_string(state, expr->assign->ident);
  1387. } else if(sol_string_eq(state, str, "value")) {
  1388. res = sol_new_exprnode(state, expr->assign->value);
  1389. }
  1390. break;
  1391. case EX_REF:
  1392. if(sol_string_eq(state, str, "ident")) {
  1393. res = sol_new_string(state, expr->ref->ident);
  1394. }
  1395. break;
  1396. case EX_CALL:
  1397. if(sol_string_eq(state, str, "expr")) {
  1398. res = sol_new_exprnode(state, expr->call->expr);
  1399. } else if(sol_string_eq(state, str, "args")) {
  1400. res = sol_new_list(state);
  1401. cure = expr->call->args;
  1402. while(cure) {
  1403. sol_list_insert(state, res, i++, sol_new_exprnode(state, cure->expr));
  1404. cure = cure->next;
  1405. }
  1406. }
  1407. break;
  1408. case EX_FUNCDECL:
  1409. if(sol_string_eq(state, str, "name")) {
  1410. res = sol_new_string(state, (expr->funcdecl->name?expr->funcdecl->name:""));
  1411. } else if(sol_string_eq(state, str, "args")) {
  1412. res = sol_new_list(state);
  1413. curi = expr->funcdecl->args;
  1414. while(curi) {
  1415. sol_list_insert(state, res, i++, sol_new_string(state, curi->ident));
  1416. curi = curi->next;
  1417. }
  1418. } else if(sol_string_eq(state, str, "body")) {
  1419. res = sol_new_stmtnode(state, expr->funcdecl->body);
  1420. }
  1421. break;
  1422. }
  1423. }
  1424. }
  1425. sol_obj_free(obj);
  1426. sol_obj_free(key);
  1427. sol_obj_free(str);
  1428. if(!res) res = sol_incref(state->None);
  1429. return res;
  1430. }
  1431. sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
  1432. sol_object_t *obj = sol_list_get_index(state, args, 0), *key = sol_list_get_index(state, args, 1), *str = sol_cast_string(state, key), *val = sol_list_get_index(state, args, 2), *pair;
  1433. sol_object_t *ival, *fval, *sval;
  1434. stmt_node *stmt = (stmt_node *) obj->node;
  1435. stmtlist_node *curs, *prevs;
  1436. expr_node *expr = (expr_node *) obj->node;
  1437. exprlist_node *cure, *preve = NULL;
  1438. assoclist_node *cura, *preva = NULL;
  1439. identlist_node *curi, *previ = NULL;
  1440. int i=0, len;
  1441. if(sol_is_aststmt(obj)) {
  1442. if(sol_string_eq(state, str, "type")) {
  1443. ival = sol_cast_int(state, val);
  1444. stmt->type = ival->ival;
  1445. sol_obj_free(ival);
  1446. } else if(sol_string_eq(state, str, "loc") && sol_is_map(val)) {
  1447. pair = sol_map_get_name(state, val, "line");
  1448. ival = sol_cast_int(state, pair);
  1449. stmt->loc.line = ival->ival;
  1450. sol_obj_free(ival);
  1451. sol_obj_free(pair);
  1452. pair = sol_map_get_name(state, val, "col");
  1453. ival = sol_cast_int(state, pair);
  1454. stmt->loc.col = ival->ival;
  1455. sol_obj_free(ival);
  1456. sol_obj_free(pair);
  1457. } else {
  1458. switch(stmt->type) {
  1459. case ST_EXPR:
  1460. if(sol_string_eq(state, str, "expr") && sol_is_astexpr(val)) {
  1461. stmt->expr = val->node;
  1462. }
  1463. break;
  1464. case ST_IFELSE:
  1465. if(sol_string_eq(state, str, "cond") && sol_is_astexpr(val)) {
  1466. stmt->ifelse->cond = val->node;
  1467. } else if(sol_string_eq(state, str, "iftrue") && sol_is_aststmt(val)) {
  1468. stmt->ifelse->iftrue = val->node;
  1469. } else if(sol_string_eq(state, str, "iffalse") && sol_is_aststmt(val)) {
  1470. stmt->ifelse->iffalse = val->node;
  1471. }
  1472. break;
  1473. case ST_LOOP:
  1474. if(sol_string_eq(state, str, "cond") && sol_is_astexpr(val)) {
  1475. stmt->loop->cond = val->node;
  1476. } else if(sol_string_eq(state, str, "loop") && sol_is_aststmt(val)) {
  1477. stmt->loop->loop = val->node;
  1478. }
  1479. break;
  1480. case ST_ITER:
  1481. if(sol_string_eq(state, str, "var")) {
  1482. sval = sol_cast_string(state, val);
  1483. stmt->iter->var = strdup(sval->str);
  1484. sol_obj_free(sval);
  1485. } else if(sol_string_eq(state, str, "iter") && sol_is_astexpr(val)) {
  1486. stmt->iter->iter = val->node;
  1487. } else if(sol_string_eq(state, str, "loop") && sol_is_aststmt(val)) {
  1488. stmt->iter->loop = val->node;
  1489. }
  1490. break;
  1491. case ST_LIST:
  1492. if(sol_string_eq(state, str, "stmtlist") && sol_is_list(val)) {
  1493. len = sol_list_len(state, val);
  1494. if(len>0) {
  1495. curs = malloc(sizeof(stmtlist_node));
  1496. stmt->stmtlist = curs;
  1497. for(i=0; i<len; i++) {
  1498. if(sol_is_aststmt(sol_list_get_index(state, val, i))) {
  1499. curs->stmt = sol_list_get_index(state, val, i)->node;
  1500. prevs = curs;
  1501. curs = malloc(sizeof(stmtlist_node));
  1502. prevs->next = curs;
  1503. }
  1504. }
  1505. if(stmt->stmtlist == curs) stmt->stmtlist = NULL;
  1506. free(curs);
  1507. if(prevs) prevs->next = NULL;
  1508. } else {
  1509. stmt->stmtlist = NULL;
  1510. }
  1511. }
  1512. break;
  1513. case ST_RET:
  1514. if(sol_string_eq(state, str, "ret") && sol_is_astexpr(val)) {
  1515. stmt->ret->ret = val->node;
  1516. }
  1517. break;
  1518. }
  1519. }
  1520. } else {
  1521. if(sol_string_eq(state, str, "type")) {
  1522. ival = sol_cast_int(state, val);
  1523. expr->type = ival->ival;
  1524. sol_obj_free(ival);
  1525. } else if(sol_string_eq(state, str, "loc") && sol_is_map(val)) {
  1526. pair = sol_map_get_name(state, val, "line");
  1527. ival = sol_cast_int(state, pair);
  1528. expr->loc.line = ival->ival;
  1529. sol_obj_free(ival);
  1530. sol_obj_free(pair);
  1531. pair = sol_map_get_name(state, val, "col");
  1532. ival = sol_cast_int(state, pair);
  1533. expr->loc.col = ival->ival;
  1534. sol_obj_free(ival);
  1535. sol_obj_free(pair);
  1536. } else {
  1537. switch(expr->type) {
  1538. case EX_LIT:
  1539. if(sol_string_eq(state, str, "littype")) {
  1540. ival = sol_cast_int(state, val);
  1541. expr->lit->type = ival->ival;
  1542. sol_obj_free(ival);
  1543. } else if(sol_string_eq(state, str, "ival")) {
  1544. ival = sol_cast_int(state, val);
  1545. expr->lit->ival = ival->ival;
  1546. sol_obj_free(ival);
  1547. } else if(sol_string_eq(state, str, "fval")) {
  1548. fval = sol_cast_float(state, val);
  1549. expr->lit->fval = fval->fval;
  1550. sol_obj_free(fval);
  1551. } else if(sol_string_eq(state, str, "str")) {
  1552. sval = sol_cast_string(state, val);
  1553. expr->lit->str = strdup(sval->str);
  1554. sol_obj_free(sval);
  1555. }
  1556. break;
  1557. case EX_LISTGEN:
  1558. if(sol_string_eq(state, str, "list") && sol_is_list(val)) {
  1559. len = sol_list_len(state, val);
  1560. if(len>0) {
  1561. cure = malloc(sizeof(exprlist_node));
  1562. expr->listgen->list = cure;
  1563. for(i=0; i<len; i++) {
  1564. if(sol_is_astexpr(sol_list_get_index(state, val, i))) {
  1565. cure->expr = sol_list_get_index(state, val, i)->node;
  1566. preve = cure;
  1567. cure = malloc(sizeof(exprlist_node));
  1568. preve->next = cure;
  1569. }
  1570. }
  1571. if(expr->listgen->list == cure) expr->listgen->list = NULL;
  1572. free(cure);
  1573. if(preve) preve->next = NULL;
  1574. } else {
  1575. expr->listgen->list = NULL;
  1576. }
  1577. }
  1578. break;
  1579. case EX_MAPGEN:
  1580. if(sol_string_eq(state, str, "map") && sol_is_list(val)) {
  1581. len = sol_list_len(state, val);
  1582. if(len>0) {
  1583. cura = malloc(sizeof(assoclist_node));
  1584. expr->mapgen->map = cura;
  1585. for(i=0; i<len; i++) {
  1586. if(sol_is_list(sol_list_get_index(state, val, i))) {
  1587. pair = sol_list_get_index(state, val, i);
  1588. if(sol_list_len(state, pair) >= 2 && sol_is_astexpr(sol_list_get_index(state, pair, 0)) && sol_is_astexpr(sol_list_get_index(state, pair, 1))) {
  1589. cura->item = malloc(sizeof(associtem_node));
  1590. cura->item->key = sol_list_get_index(state, pair, 0)->node;
  1591. cura->item->value = sol_list_get_index(state, pair, 1)->node;
  1592. preva = cura;
  1593. cura = malloc(sizeof(assoclist_node));
  1594. preva->next = cura;
  1595. }
  1596. }
  1597. }
  1598. if(expr->mapgen->map == cura) expr->mapgen->map = NULL;
  1599. free(cura);
  1600. if(preva) preva->next = NULL;
  1601. } else {
  1602. expr->mapgen->map = NULL;
  1603. }
  1604. }
  1605. break;
  1606. case EX_BINOP:
  1607. if(sol_string_eq(state, str, "binoptype")) {
  1608. ival = sol_cast_int(state, val);
  1609. expr->binop->type = ival->ival;
  1610. sol_obj_free(ival);
  1611. } else if(sol_string_eq(state, str, "left") && sol_is_astexpr(val)) {
  1612. expr->binop->left = val->node;
  1613. } else if(sol_string_eq(state, str, "right") && sol_is_astexpr(val)) {
  1614. expr->binop->right = val->node;
  1615. }
  1616. break;
  1617. case EX_UNOP:
  1618. if(sol_string_eq(state, str, "unoptype")) {
  1619. ival = sol_cast_int(state, val);
  1620. expr->unop->type = ival->ival;
  1621. sol_obj_free(ival);
  1622. } else if(sol_string_eq(state, str, "expr") && sol_is_astexpr(val)) {
  1623. expr->unop->expr = val->node;
  1624. }
  1625. break;
  1626. case EX_INDEX:
  1627. if(sol_string_eq(state, str, "expr") && sol_is_astexpr(val)) {
  1628. expr->index->expr = val->node;
  1629. } else if(sol_string_eq(state, str, "index") && sol_is_astexpr(val)) {
  1630. expr->index->index = val->node;
  1631. }
  1632. break;
  1633. case EX_SETINDEX:
  1634. if(sol_string_eq(state, str, "expr") && sol_is_astexpr(val)) {
  1635. expr->setindex->expr = val->node;
  1636. } else if(sol_string_eq(state, str, "index") && sol_is_astexpr(val)) {
  1637. expr->setindex->index = val->node;
  1638. } else if(sol_string_eq(state, str, "value") && sol_is_astexpr(val)) {
  1639. expr->setindex->value = val->node;
  1640. }
  1641. break;
  1642. case EX_ASSIGN:
  1643. if(sol_string_eq(state, str, "ident")) {
  1644. sval = sol_cast_string(state, val);
  1645. expr->assign->ident = strdup(sval->str);
  1646. sol_obj_free(sval);
  1647. } else if(sol_string_eq(state, str, "value") && sol_is_astexpr(val)) {
  1648. expr->assign->value = val->node;
  1649. }
  1650. break;
  1651. case EX_REF:
  1652. if(sol_string_eq(state, str, "ident")) {
  1653. sval = sol_cast_string(state, val);
  1654. expr->ref->ident = strdup(sval->str);
  1655. sol_obj_free(sval);
  1656. }
  1657. break;
  1658. case EX_CALL:
  1659. if(sol_string_eq(state, str, "expr") && sol_is_astexpr(val)) {
  1660. expr->call->expr = val->node;
  1661. } else if(sol_string_eq(state, str, "args") && sol_is_list(val)) {
  1662. len = sol_list_len(state, val);
  1663. if(len>0) {
  1664. cure = malloc(sizeof(exprlist_node));
  1665. expr->call->args= cure;
  1666. for(i=0; i<len; i++) {
  1667. if(sol_is_astexpr(sol_list_get_index(state, val, i))) {
  1668. cure->expr = sol_list_get_index(state, val, i)->node;
  1669. preve = cure;
  1670. cure = malloc(sizeof(exprlist_node));
  1671. preve->next = cure;
  1672. }
  1673. }
  1674. if(expr->call->args == cure) expr->call->args = NULL;
  1675. free(cure);
  1676. if(preve) preve->next = NULL;
  1677. } else {
  1678. expr->call->args = NULL;
  1679. }
  1680. }
  1681. break;
  1682. case EX_FUNCDECL:
  1683. if(sol_string_eq(state, str, "name")) {
  1684. sval = sol_cast_string(state, val);
  1685. expr->funcdecl->name = strdup(sval->str);
  1686. sol_obj_free(sval);
  1687. } else if(sol_string_eq(state, str, "args") && sol_is_list(val)) {
  1688. len = sol_list_len(state, val);
  1689. if(len>0) {
  1690. curi = malloc(sizeof(identlist_node));
  1691. expr->funcdecl->args= curi;
  1692. for(i=0; i<len; i++) {
  1693. sval = sol_cast_string(state, sol_list_get_index(state, val, i));
  1694. curi->ident = strdup(sval->str);
  1695. sol_obj_free(sval);
  1696. previ = curi;
  1697. curi = malloc(sizeof(identlist_node));
  1698. previ->next = curi;
  1699. }
  1700. if(expr->funcdecl->args == curi) expr->funcdecl->args = NULL;
  1701. free(curi);
  1702. if(previ) previ->next = NULL;
  1703. } else {
  1704. expr->funcdecl->args = NULL;
  1705. }
  1706. } else if(sol_string_eq(state, str, "body") && sol_is_aststmt(val)) {
  1707. expr->funcdecl->body = val->node;
  1708. }
  1709. break;
  1710. }
  1711. }
  1712. }
  1713. sol_obj_free(obj);
  1714. sol_obj_free(key);
  1715. sol_obj_free(str);
  1716. return val;
  1717. }
  1718. static char *sol_StmtNames[]={"EXPR", "IFSELSE", "LOOP", "ITER", "LIST", "RET", "CONT", "BREAK"};
  1719. static char *sol_ExprNames[]={"LIT", "LISTGEN", "MAPGEN", "BINOP", "UNOP", "INDEX", "SETINDEX", "ASSIGN", "REF", "CALL", "FUNCDECL"};
  1720. sol_object_t *sol_f_astnode_tostring(sol_state_t *state, sol_object_t *args) {
  1721. sol_object_t *obj = sol_list_get_index(state, args, 0), *res;
  1722. char s[64];
  1723. if(sol_is_aststmt(obj)) {
  1724. snprintf(s, 64, "<Stmt[%s]>", sol_StmtNames[((stmt_node *)obj->node)->type]);
  1725. } else {
  1726. snprintf(s, 64, "<Expr[%s]>", sol_ExprNames[((expr_node *)obj->node)->type]);
  1727. }
  1728. sol_obj_free(obj);
  1729. return sol_new_string(state, s);
  1730. }
  1731. sol_object_t *sol_f_buffer_index(sol_state_t *state, sol_object_t *args) {
  1732. sol_object_t *key = sol_list_get_index(state, args, 1), *funcs = sol_get_methods_name(state, "buffer");
  1733. sol_object_t *res = sol_map_get(state, funcs, key);
  1734. sol_obj_free(key);
  1735. sol_obj_free(funcs);
  1736. return res;
  1737. }
  1738. sol_object_t *sol_f_buffer_tostring(sol_state_t *state, sol_object_t *args) {
  1739. sol_object_t *buf = sol_list_get_index(state, args, 0), *res;
  1740. char s[64];
  1741. if(buf->sz == -1) {
  1742. snprintf(s, 64, "<Buffer @%p>", buf->buffer);
  1743. } else {
  1744. snprintf(s, 64, "<Buffer @%p size %ld", buf->buffer, buf->sz);
  1745. }
  1746. res = sol_new_string(state, s);
  1747. sol_obj_free(buf);
  1748. return res;
  1749. }
  1750. sol_object_t *sol_f_buffer_new(sol_state_t *state, sol_object_t *args) {
  1751. sol_object_t *sz = sol_list_get_index(state, args, 0), *isz = sol_cast_int(state, sz);
  1752. size_t bufsz = isz->ival;
  1753. void *buf = malloc(bufsz);
  1754. sol_obj_free(sz);
  1755. sol_obj_free(isz);
  1756. if(buf) {
  1757. return sol_new_buffer(state, buf, bufsz, OWN_FREE, NULL, NULL);
  1758. }
  1759. return sol_incref(state->None);
  1760. }
  1761. sol_object_t *sol_f_buffer_get(sol_state_t *state, sol_object_t *args) {
  1762. sol_object_t *buf = sol_list_get_index(state, args, 0), *tp = sol_list_get_index(state, args, 1), *off = sol_list_get_index(state, args, 2);
  1763. sol_object_t *itp = sol_cast_int(state, tp), *ioff, *res=NULL;
  1764. sol_buftype_t buftp = itp->ival;
  1765. char *data, cbuf[2]={0, 0};
  1766. sol_obj_free(tp);
  1767. sol_obj_free(itp);
  1768. if(!sol_is_none(state, off)) {
  1769. ioff = sol_cast_int(state, off);
  1770. } else {
  1771. ioff = sol_new_int(state, 0);
  1772. }
  1773. sol_obj_free(off);
  1774. if(buf->sz != -1 && (ioff->ival >= buf->sz || ioff->ival < 0)) {
  1775. sol_obj_free(buf);
  1776. sol_obj_free(ioff);
  1777. return sol_incref(state->None);
  1778. }
  1779. data = ((char *) buf->buffer)+ioff->ival;
  1780. sol_obj_free(buf);
  1781. sol_obj_free(ioff);
  1782. switch(buftp) {
  1783. case BUF_UINT8:
  1784. res = sol_new_int(state, *((uint8_t *) data));
  1785. break;
  1786. case BUF_UINT16:
  1787. res = sol_new_int(state, *((uint16_t *) data));
  1788. break;
  1789. case BUF_UINT32:
  1790. res = sol_new_int(state, *((uint32_t *) data));
  1791. break;
  1792. case BUF_UINT64:
  1793. res = sol_new_int(state, *((uint64_t *) data));
  1794. break;
  1795. case BUF_INT8:
  1796. res = sol_new_int(state, *((int8_t *) data));
  1797. break;
  1798. case BUF_INT16:
  1799. res = sol_new_int(state, *((int16_t *) data));
  1800. break;
  1801. case BUF_INT32:
  1802. res = sol_new_int(state, *((int32_t *) data));
  1803. break;
  1804. case BUF_INT64:
  1805. res = sol_new_int(state, *((int64_t *) data));
  1806. break;
  1807. case BUF_CHAR:
  1808. cbuf[0] = *((char *) data);
  1809. res = sol_new_string(state, cbuf);
  1810. break;
  1811. case BUF_BYTE:
  1812. res = sol_new_int(state, *((unsigned char *) data));
  1813. break;
  1814. case BUF_INT:
  1815. res = sol_new_int(state, *((int *) data));
  1816. break;
  1817. case BUF_UINT:
  1818. res = sol_new_int(state, *((unsigned int *) data));
  1819. break;
  1820. case BUF_LONG:
  1821. res = sol_new_int(state, *((long *) data));
  1822. break;
  1823. case BUF_ULONG:
  1824. res = sol_new_int(state, *((unsigned long *) data));
  1825. break;
  1826. case BUF_FLOAT:
  1827. res = sol_new_float(state, *((float *) data));
  1828. break;
  1829. case BUF_DOUBLE:
  1830. res = sol_new_float(state, *((double *) data));
  1831. break;
  1832. case BUF_CSTR:
  1833. res = sol_new_string(state, (char *) data);
  1834. break;
  1835. case BUF_PTR:
  1836. res = sol_new_buffer(state, ((void *) *((unsigned long *) data)), -1, OWN_NONE, NULL, NULL);
  1837. break;
  1838. }
  1839. if(!res) res = sol_incref(state->None);
  1840. return res;
  1841. }
  1842. sol_object_t *sol_f_buffer_set(sol_state_t *state, sol_object_t *args) {
  1843. sol_object_t *buf = sol_list_get_index(state, args, 0), *tp = sol_list_get_index(state, args, 1), *val = sol_list_get_index(state, args, 2), *off = sol_list_get_index(state, args, 3);
  1844. sol_object_t *itp = sol_cast_int(state, tp), *ioff, *ival=NULL, *fval=NULL, *sval=NULL;
  1845. sol_buftype_t buftp = itp->ival;
  1846. char *data;
  1847. sol_obj_free(tp);
  1848. sol_obj_free(itp);
  1849. if(!sol_is_none(state, off)) {
  1850. ioff = sol_cast_int(state, off);
  1851. } else {
  1852. ioff = sol_new_int(state, 0);
  1853. }
  1854. sol_obj_free(off);
  1855. if(buf->sz != -1 && (ioff->ival >= buf->sz || ioff->ival < 0)) {
  1856. sol_obj_free(buf);
  1857. sol_obj_free(ioff);
  1858. return sol_incref(state->None);
  1859. }
  1860. data = ((char *) buf->buffer)+ioff->ival;
  1861. sol_obj_free(buf);
  1862. sol_obj_free(ioff);
  1863. switch(buftp) {
  1864. case BUF_UINT8:
  1865. ival = sol_cast_int(state, val);
  1866. *((uint8_t *) data) = ival->ival;
  1867. break;
  1868. case BUF_UINT16:
  1869. ival = sol_cast_int(state, val);
  1870. *((uint16_t *) data) = ival->ival;
  1871. break;
  1872. case BUF_UINT32:
  1873. ival = sol_cast_int(state, val);
  1874. *((uint32_t *) data) = ival->ival;
  1875. break;
  1876. case BUF_UINT64:
  1877. ival = sol_cast_int(state, val);
  1878. *((uint64_t *) data) = ival->ival;
  1879. break;
  1880. case BUF_INT8:
  1881. ival = sol_cast_int(state, val);
  1882. *((int8_t *) data) = ival->ival;
  1883. break;
  1884. case BUF_INT16:
  1885. ival = sol_cast_int(state, val);
  1886. *((int16_t *) data) = ival->ival;
  1887. break;
  1888. case BUF_INT32:
  1889. ival = sol_cast_int(state, val);
  1890. *((int32_t *) data) = ival->ival;
  1891. break;
  1892. case BUF_INT64:
  1893. ival = sol_cast_int(state, val);
  1894. *((int64_t *) data) = ival->ival;
  1895. break;
  1896. case BUF_CHAR:
  1897. sval = sol_cast_string(state, val);
  1898. *((char *) data) = sval->str[0];
  1899. break;
  1900. case BUF_BYTE:
  1901. ival = sol_cast_int(state, val);
  1902. *((unsigned char *) data) = ival->ival;
  1903. break;
  1904. case BUF_INT:
  1905. ival = sol_cast_int(state, val);
  1906. *((int *) data) = ival->ival;
  1907. break;
  1908. case BUF_UINT:
  1909. ival = sol_cast_int(state, val);
  1910. *((unsigned int *) data) = ival->ival;
  1911. break;
  1912. case BUF_LONG:
  1913. ival = sol_cast_int(state, val);
  1914. *((long *) data) = ival->ival;
  1915. break;
  1916. case BUF_ULONG:
  1917. ival = sol_cast_int(state, val);
  1918. *((unsigned long *) data) = ival->ival;
  1919. break;
  1920. case BUF_FLOAT:
  1921. fval = sol_cast_float(state, val);
  1922. *((float *) data) = fval->fval;
  1923. break;
  1924. case BUF_DOUBLE:
  1925. fval = sol_cast_float(state, val);
  1926. *((double *) data) = fval->fval;
  1927. break;
  1928. case BUF_CSTR:
  1929. sval = sol_cast_string(state, val);
  1930. strcpy((char *) data, sval->str);
  1931. break;
  1932. case BUF_PTR:
  1933. if(sol_is_buffer(val)) {
  1934. *((unsigned long *) data) = ((unsigned long) val->buffer);
  1935. if(val->own == OWN_CALLF) {
  1936. val->movef(val->buffer, val->sz);
  1937. }
  1938. } else {
  1939. ival = sol_cast_int(state, val);
  1940. *((unsigned long *) data) = ival->ival;
  1941. }
  1942. break;
  1943. }
  1944. if(ival) sol_obj_free(ival);
  1945. if(fval) sol_obj_free(fval);
  1946. if(sval) sol_obj_free(sval);
  1947. return sol_incref(state->None);
  1948. }
  1949. sol_object_t *sol_f_buffer_address(sol_state_t *state, sol_object_t *args) {
  1950. sol_object_t *buf = sol_list_get_index(state, args, 0);
  1951. sol_object_t *res = sol_new_int(state, (unsigned long) buf->buffer);
  1952. sol_obj_free(buf);
  1953. return res;
  1954. }
  1955. sol_object_t *sol_f_buffer_size(sol_state_t *state, sol_object_t *args) {
  1956. sol_object_t *buf = sol_list_get_index(state, args, 0);
  1957. sol_object_t *res = sol_new_int(state, (long) buf->sz);
  1958. sol_obj_free(buf);
  1959. return res;
  1960. }
  1961. sol_object_t *sol_f_buffer_fromstring(sol_state_t *state, sol_object_t *args) {
  1962. sol_object_t *val = sol_list_get_index(state, args, 0), *sval = sol_cast_string(state, val);
  1963. size_t sz = strlen(sval->str)+1;
  1964. sol_object_t *buf = sol_new_buffer(state, malloc(sz), sz, OWN_FREE, NULL, NULL);
  1965. strcpy(buf->buffer, sval->str);
  1966. sol_obj_free(val);
  1967. sol_obj_free(sval);
  1968. return buf;
  1969. }
  1970. sol_object_t *sol_f_buffer_fromobject(sol_state_t *state, sol_object_t *args) {
  1971. sol_object_t *obj = sol_list_get_index(state, args, 0);
  1972. sol_object_t *buf = sol_new_buffer(state, obj, sizeof(sol_object_t), OWN_CALLF, (sol_freefunc_t) sol_obj_free, (sol_movefunc_t) sol_obj_acquire);
  1973. //Keep ref to obj so buf remains alive
  1974. return buf;
  1975. }
  1976. sol_object_t *sol_f_buffer_fromaddress(sol_state_t *state, sol_object_t *args) {
  1977. sol_object_t *addr = sol_list_get_index(state, args, 0), *sz = sol_list_get_index(state, args, 1);
  1978. sol_object_t *iaddr = sol_cast_int(state, addr), *isz = sol_cast_int(state, sz);
  1979. sol_object_t *buf = sol_new_buffer(state, (void *) iaddr->ival, (ssize_t) isz->ival, OWN_NONE, NULL, NULL);
  1980. sol_obj_free(addr);
  1981. sol_obj_free(sz);
  1982. sol_obj_free(iaddr);
  1983. sol_obj_free(isz);
  1984. return buf;
  1985. }
  1986. sol_object_t *sol_f_dylib_index(sol_state_t *state, sol_object_t *args) {
  1987. sol_object_t *dylib = sol_list_get_index(state, args, 0), *key = sol_list_get_index(state, args, 1), *skey = sol_cast_string(state, key);
  1988. void *handle = dlsym(dylib->dlhandle, skey->str);
  1989. sol_obj_free(dylib);
  1990. sol_obj_free(key);
  1991. sol_obj_free(skey);
  1992. if(handle) {
  1993. return sol_new_dysym(state, handle, NULL, BUF_NONE);
  1994. } else {
  1995. return sol_incref(state->None);
  1996. }
  1997. }
  1998. sol_object_t *sol_f_dylib_tostring(sol_state_t *state, sol_object_t *args) {
  1999. return sol_new_string(state, "<DyLib>");
  2000. }
  2001. sol_object_t *sol_f_dysym_call(sol_state_t *state, sol_object_t *args) {
  2002. //TODO
  2003. return sol_incref(state->None);
  2004. }
  2005. sol_object_t *sol_f_dysym_index(sol_state_t *state, sol_object_t *args) {
  2006. //TODO
  2007. return sol_incref(state->None);
  2008. }
  2009. sol_object_t *sol_f_dysym_setindex(sol_state_t *state, sol_object_t *args) {
  2010. //TODO
  2011. return sol_incref(state->None);
  2012. }
  2013. sol_object_t *sol_f_dysym_tostring(sol_state_t *state, sol_object_t *args) {
  2014. return sol_new_string(state, "<DySym>");
  2015. }
  2016. sol_object_t *sol_f_stream_blsh(sol_state_t *state, sol_object_t *args) {
  2017. return sol_f_stream_write(state, args);
  2018. }
  2019. sol_object_t *sol_f_stream_brsh(sol_state_t *state, sol_object_t *args) {
  2020. return sol_f_stream_read(state, args);
  2021. }
  2022. sol_object_t *sol_f_stream_index(sol_state_t *state, sol_object_t *args) {
  2023. sol_object_t *key = sol_list_get_index(state, args, 1), *funcs = sol_get_methods_name(state, "stream");
  2024. sol_object_t *res = sol_map_get(state, funcs, key);
  2025. sol_obj_free(key);
  2026. sol_obj_free(funcs);
  2027. return res;
  2028. }
  2029. sol_object_t *sol_f_stream_tostring(sol_state_t *state, sol_object_t *args) {
  2030. return sol_new_string(state, "<Stream>");
  2031. }
  2032. sol_object_t *sol_f_stream_write(sol_state_t *state, sol_object_t *args) {
  2033. sol_object_t *stream = sol_list_get_index(state, args, 0), *obj = sol_list_get_index(state, args, 1), *str = sol_cast_string(state, obj);
  2034. size_t sz = sol_stream_printf(state, stream, "%s", str->str);
  2035. sol_obj_free(obj);
  2036. sol_obj_free(str);
  2037. sol_obj_free(stream);
  2038. return sol_new_int(state, sz);
  2039. }
  2040. sol_object_t *sol_f_stream_read(sol_state_t *state, sol_object_t *args) {
  2041. sol_object_t *stream = sol_list_get_index(state, args, 0), *amt = sol_list_get_index(state, args, 1), *iamt, *res;
  2042. char *s=NULL, *p;
  2043. size_t count=0, max=0, pos, end;
  2044. if(sol_is_string(amt)) {
  2045. if(sol_string_eq(state, amt, "ALL")) {
  2046. pos = sol_stream_ftell(state, stream);
  2047. sol_stream_fseek(state, stream, 0, SEEK_END);
  2048. end = sol_stream_ftell(state, stream);
  2049. sol_stream_fseek(state, stream, pos, SEEK_SET);
  2050. //printf("IO: Reading %ld bytes starting at %ld\n", end-pos, pos);
  2051. s = malloc((end-pos+1)*sizeof(char));
  2052. if(sol_stream_fread(state, stream, s, sizeof(char), end-pos)<(end-pos)) {
  2053. free(s);
  2054. sol_obj_free(stream);
  2055. sol_obj_free(amt);
  2056. return sol_set_error_string(state, "IO read error");
  2057. }
  2058. s[end-pos]='\0';
  2059. } else if(sol_string_eq(state, amt, "LINE")) {
  2060. s = malloc(STDIO_CHUNK_SIZE*sizeof(char));
  2061. sol_stream_fgets(state, stream, s, STDIO_CHUNK_SIZE);
  2062. }
  2063. } else {
  2064. iamt = sol_cast_int(state, amt);
  2065. s = malloc((iamt->ival + 1)*sizeof(char));
  2066. count = sol_stream_fread(state, stream, s, sizeof(char), iamt->ival);
  2067. s[count]='\0';
  2068. sol_obj_free(iamt);
  2069. }
  2070. if(s) {
  2071. //printf("IO: Read result: %s\n", s);
  2072. res = sol_new_string(state, s);
  2073. free(s);
  2074. } else {
  2075. //printf("IO: No read result!\n");
  2076. res = sol_incref(state->None);
  2077. }
  2078. sol_obj_free(amt);
  2079. sol_obj_free(stream);
  2080. return res;
  2081. }
  2082. sol_object_t *sol_f_stream_seek(sol_state_t *state, sol_object_t *args) {
  2083. sol_object_t *stream = sol_list_get_index(state, args, 0), *offset = sol_list_get_index(state, args, 1), *whence = sol_list_get_index(state, args, 2);
  2084. sol_object_t *ioffset = sol_cast_int(state, offset), *iwhence = sol_cast_int(state, whence);
  2085. sol_object_t *res = sol_new_int(state, sol_stream_fseek(state, stream, ioffset->ival, iwhence->ival));
  2086. sol_obj_free(stream);
  2087. sol_obj_free(offset);
  2088. sol_obj_free(whence);
  2089. sol_obj_free(ioffset);
  2090. sol_obj_free(iwhence);
  2091. return res;
  2092. }
  2093. sol_object_t *sol_f_stream_tell(sol_state_t *state, sol_object_t *args) {
  2094. sol_object_t *stream = sol_list_get_index(state, args, 0), *res = sol_new_int(state, sol_stream_ftell(state, stream));
  2095. sol_obj_free(stream);
  2096. return res;
  2097. }
  2098. sol_object_t *sol_f_stream_flush(sol_state_t *state, sol_object_t *args) {
  2099. sol_object_t *stream = sol_list_get_index(state, args, 0), *res = sol_new_int(state, sol_stream_fflush(state, stream));
  2100. sol_obj_free(stream);
  2101. return res;
  2102. }
  2103. sol_object_t *sol_f_stream_eof(sol_state_t *state, sol_object_t *args) {
  2104. sol_object_t *stream = sol_list_get_index(state, args, 0), *res = sol_new_int(state, sol_stream_feof(state, stream));
  2105. sol_obj_free(stream);
  2106. return res;
  2107. }
  2108. static char *sol_FileModes[]={
  2109. NULL,
  2110. "r",
  2111. "w",
  2112. "r+",
  2113. NULL,
  2114. NULL,
  2115. "a",
  2116. "a+",
  2117. NULL,
  2118. NULL,
  2119. "w",
  2120. "w+",
  2121. NULL,
  2122. NULL,
  2123. NULL,
  2124. NULL,
  2125. NULL,
  2126. "rb",
  2127. "wb",
  2128. "r+b",
  2129. NULL,
  2130. NULL,
  2131. "ab",
  2132. "a+b",
  2133. NULL,
  2134. NULL,
  2135. "wb",
  2136. "w+b",
  2137. NULL,
  2138. NULL,
  2139. NULL,
  2140. NULL
  2141. };
  2142. sol_object_t *sol_f_stream_open(sol_state_t *state, sol_object_t *args) {
  2143. sol_object_t *fn = sol_list_get_index(state, args, 0), *mode = sol_list_get_index(state, args, 1);
  2144. sol_object_t *sfn = sol_cast_string(state, fn), *imode = sol_cast_int(state, mode);
  2145. sol_modes_t m = imode->ival;
  2146. char *smode = sol_FileModes[m];
  2147. FILE *f;
  2148. sol_obj_free(mode);
  2149. sol_obj_free(imode);
  2150. if(!smode) {
  2151. sol_obj_free(fn);
  2152. sol_obj_free(sfn);
  2153. return sol_set_error_string(state, "Bad file open mode");
  2154. }
  2155. f = fopen(sfn->str, smode);
  2156. sol_obj_free(sfn);
  2157. sol_obj_free(fn);
  2158. if(!f) return sol_set_error_string(state, "File open failed");
  2159. return sol_new_stream(state, f, m);
  2160. }