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.

state.c 36KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <termios.h>
  6. #include <sys/ioctl.h>
  7. #include "ast.h"
  8. #define TMP_PATH_SZ 256
  9. char *sol_AbsInitPaths[SOL_PATH_ARRAY_SIZE] = {
  10. "/etc/sol/init.sol",
  11. "/opt/sol/init.sol",
  12. };
  13. char *sol_HomeInitPaths[SOL_PATH_ARRAY_SIZE] = {
  14. "/.config/sol/init.sol",
  15. };
  16. char sol_TempPath[TMP_PATH_SZ];
  17. #define LENGTH(array) (sizeof(array) / sizeof(array[0]))
  18. int sol_state_init(sol_state_t *state) {
  19. sol_object_t *globals, *mod, *meths;
  20. sol_object_t *btype, *bsize, *bobj;
  21. unsigned long i;
  22. FILE *fp;
  23. stmt_node *stmt;
  24. char *suffix;
  25. sol_mm_initialize(state);
  26. state->None = NULL;
  27. state->OutOfMemory = NULL;
  28. state->scopes = NULL;
  29. state->error = NULL;
  30. state->traceback = NULL;
  31. state->ret = NULL;
  32. state->sflag = SF_NORMAL;
  33. state->lastvalue = NULL;
  34. state->loopvalue = NULL;
  35. #ifdef DEBUG_GC
  36. // This is necessary for DEBUG_GC's early allocation; it gets overwritten,
  37. // unfortunately, during sol_ops_init below, so it's duplicated.
  38. state->SingletOps.tname = "singlet";
  39. #endif
  40. // If any of the following fail, some very weird things are happening.
  41. if(!(state->None = sol_new_singlet(state, "None"))) {
  42. goto cleanup;
  43. }
  44. if(!(state->OutOfMemory = sol_new_singlet(state, "OutOfMemory"))) {
  45. goto cleanup;
  46. }
  47. // We can now use the normal error reporting mechanism, now
  48. // that errors are distinguishable. Set that up now.
  49. //Initialize all of the builtin operations
  50. //(these ones are technically already pointed to by None/OOM)
  51. sol_ops_init(&(state->NullOps));
  52. state->SingletOps = state->NullOps;
  53. state->IntOps = state->NullOps;
  54. state->FloatOps = state->NullOps;
  55. state->StringOps = state->NullOps;
  56. state->ListOps = state->NullOps;
  57. state->MapOps = state->NullOps;
  58. state->MCellOps = state->NullOps;
  59. state->FuncOps = state->NullOps;
  60. state->MacroOps = state->NullOps;
  61. state->CFuncOps = state->NullOps;
  62. state->ASTNodeOps = state->NullOps;
  63. state->BufferOps = state->NullOps;
  64. state->DyLibOps = state->NullOps;
  65. state->DySymOps = state->NullOps;
  66. state->StreamOps = state->NullOps;
  67. state->SingletOps.tname = "singlet";
  68. state->SingletOps.tostring = sol_f_singlet_tostring;
  69. state->SingletOps.tobuffer = sol_f_singlet_tobuffer;
  70. state->SingletOps.free = sol_f_singlet_free;
  71. state->IntOps.tname = "int";
  72. state->IntOps.add = sol_f_int_add;
  73. state->IntOps.sub = sol_f_int_sub;
  74. state->IntOps.mul = sol_f_int_mul;
  75. state->IntOps.div = sol_f_int_div;
  76. state->IntOps.mod = sol_f_int_mod;
  77. state->IntOps.pow = sol_f_int_pow;
  78. state->IntOps.band = sol_f_int_band;
  79. state->IntOps.bor = sol_f_int_bor;
  80. state->IntOps.bxor = sol_f_int_bxor;
  81. state->IntOps.blsh = sol_f_int_blsh;
  82. state->IntOps.brsh = sol_f_int_brsh;
  83. state->IntOps.bnot = sol_f_int_bnot;
  84. state->IntOps.cmp = sol_f_int_cmp;
  85. state->IntOps.toint = sol_f_int_toint;
  86. state->IntOps.tofloat = sol_f_int_tofloat;
  87. state->IntOps.tostring = sol_f_int_tostring;
  88. state->FloatOps.tname = "float";
  89. state->FloatOps.add = sol_f_float_add;
  90. state->FloatOps.sub = sol_f_float_sub;
  91. state->FloatOps.mul = sol_f_float_mul;
  92. state->FloatOps.div = sol_f_float_div;
  93. state->FloatOps.cmp = sol_f_float_cmp;
  94. state->FloatOps.toint = sol_f_float_toint;
  95. state->FloatOps.tofloat = sol_f_float_tofloat;
  96. state->FloatOps.tostring = sol_f_float_tostring;
  97. state->StringOps.tname = "string";
  98. state->StringOps.add = sol_f_str_add;
  99. state->StringOps.mul = sol_f_str_mul;
  100. state->StringOps.cmp = sol_f_str_cmp;
  101. state->StringOps.index = sol_f_str_index;
  102. state->StringOps.len = sol_f_str_len;
  103. state->StringOps.iter = sol_f_str_iter;
  104. state->StringOps.toint = sol_f_str_toint;
  105. state->StringOps.tofloat = sol_f_str_tofloat;
  106. state->StringOps.tostring = sol_f_str_tostring;
  107. state->StringOps.tobuffer = sol_f_str_tobuffer;
  108. state->StringOps.repr = sol_f_str_repr;
  109. state->StringOps.free = sol_f_str_free;
  110. state->ListOps.tname = "list";
  111. state->ListOps.add = sol_f_list_add;
  112. state->ListOps.mul = sol_f_list_mul;
  113. state->ListOps.cmp = sol_f_list_cmp;
  114. state->ListOps.call = sol_f_not_impl;
  115. state->ListOps.index = sol_f_list_index;
  116. state->ListOps.setindex = sol_f_list_setindex;
  117. state->ListOps.len = sol_f_list_len;
  118. state->ListOps.iter = sol_f_list_iter;
  119. state->ListOps.tostring = sol_f_list_tostring;
  120. state->ListOps.free = sol_f_list_free;
  121. state->MapOps.tname = "map";
  122. state->MapOps.add = sol_f_map_add;
  123. state->MapOps.call = sol_f_map_call;
  124. state->MapOps.index = sol_f_map_index;
  125. state->MapOps.setindex = sol_f_map_setindex;
  126. state->MapOps.len = sol_f_map_len;
  127. state->MapOps.iter = sol_f_map_iter;
  128. state->MapOps.tostring = sol_f_map_tostring;
  129. state->MapOps.repr = sol_f_map_repr;
  130. state->MapOps.free = sol_f_map_free;
  131. state->MCellOps.tname = "mcell";
  132. state->MCellOps.tostring = sol_f_mcell_tostring;
  133. state->MCellOps.free = sol_f_mcell_free;
  134. state->FuncOps.tname = "function";
  135. state->FuncOps.call = sol_f_func_call;
  136. state->FuncOps.index = sol_f_func_index;
  137. state->FuncOps.setindex = sol_f_func_setindex;
  138. state->FuncOps.tostring = sol_f_func_tostring;
  139. state->FuncOps.free = sol_f_func_free;
  140. state->MacroOps = state->FuncOps; // XXX Hack
  141. state->MacroOps.tname = "macro";
  142. state->MacroOps.tflags = SOL_TF_NO_EVAL_CALL_ARGS;
  143. state->CFuncOps.tname = "cfunction";
  144. state->CFuncOps.call = sol_f_cfunc_call;
  145. state->CFuncOps.tostring = sol_f_cfunc_tostring;
  146. state->CFuncOps.free = sol_f_cfunc_free;
  147. state->CMacroOps = state->CFuncOps;
  148. state->CMacroOps.tname = "cmacro";
  149. state->CMacroOps.tflags = SOL_TF_NO_EVAL_CALL_ARGS;
  150. state->ASTNodeOps.tname = "astnode";
  151. state->ASTNodeOps.call = sol_f_astnode_call;
  152. state->ASTNodeOps.index = sol_f_astnode_index;
  153. state->ASTNodeOps.setindex = sol_f_astnode_setindex;
  154. state->ASTNodeOps.tostring = sol_f_astnode_tostring;
  155. state->ASTNodeOps.free = sol_f_astnode_free;
  156. state->BufferOps.tname = "buffer";
  157. state->BufferOps.add = sol_f_buffer_add;
  158. state->BufferOps.mul = sol_f_buffer_mul;
  159. state->BufferOps.cmp = sol_f_buffer_cmp;
  160. state->BufferOps.len = sol_f_buffer_len;
  161. state->BufferOps.iter = sol_f_buffer_iter;
  162. state->BufferOps.index = sol_f_buffer_index;
  163. state->BufferOps.tostring = sol_f_buffer_tostring;
  164. state->BufferOps.repr = sol_f_buffer_repr;
  165. state->BufferOps.toint = sol_f_buffer_toint;
  166. state->BufferOps.tofloat = sol_f_buffer_tofloat;
  167. state->BufferOps.tobuffer = sol_f_buffer_tobuffer;
  168. state->BufferOps.free = sol_f_buffer_free;
  169. state->DyLibOps.tname = "dylib";
  170. state->DyLibOps.index = sol_f_dylib_index;
  171. state->DyLibOps.free = sol_f_dylib_free;
  172. state->DyLibOps.tostring = sol_f_dylib_tostring;
  173. state->DySymOps.tname = "dysym";
  174. state->DySymOps.call = sol_f_dysym_call;
  175. state->DySymOps.index = sol_f_dysym_index;
  176. state->DySymOps.setindex = sol_f_dysym_setindex;
  177. state->DySymOps.tostring = sol_f_dysym_tostring;
  178. state->StreamOps.tname = "stream";
  179. state->StreamOps.blsh = sol_f_stream_blsh;
  180. state->StreamOps.brsh = sol_f_stream_brsh;
  181. state->StreamOps.index = sol_f_stream_index;
  182. state->StreamOps.free = sol_f_stream_free;
  183. state->StreamOps.tostring = sol_f_stream_tostring;
  184. #ifdef DEBUG_GC
  185. state->obfuncs.copy = (dsl_copier) _sol_gc_dsl_copier;
  186. state->obfuncs.destr = (dsl_destructor) _sol_gc_dsl_destructor;
  187. #else
  188. state->obfuncs.copy = (dsl_copier) sol_obj_acquire;
  189. state->obfuncs.destr = (dsl_destructor) sol_obj_free;
  190. #endif
  191. #ifdef SOL_ICACHE
  192. state->icache_bypass = 1;
  193. for(i = 0; i <= (SOL_ICACHE_MAX - SOL_ICACHE_MIN); i++) {
  194. state->icache[i] = sol_new_int(state, ((long) i) + SOL_ICACHE_MIN);
  195. }
  196. state->icache_bypass = 0;
  197. #endif
  198. state->calling_type = "(none)";
  199. state->calling_meth = "(none)";
  200. state->lastvalue = sol_incref(state->None);
  201. state->loopvalue = sol_incref(state->None);
  202. state->error = state->None;
  203. state->scopes = sol_new_list(state);
  204. if(sol_has_error(state)) {
  205. goto cleanup;
  206. }
  207. globals = sol_new_map(state);
  208. state->modules = sol_new_map(state);
  209. state->methods = sol_new_map(state);
  210. if(sol_has_error(state)) {
  211. goto cleanup;
  212. }
  213. sol_list_insert(state, state->scopes, 0, globals);
  214. sol_obj_free(globals);
  215. if(sol_has_error(state)) {
  216. goto cleanup;
  217. }
  218. state->_stdin = sol_new_stream(state, stdin, MODE_READ);
  219. state->_stdout = sol_new_stream(state, stdout, MODE_WRITE);
  220. state->_stderr = sol_new_stream(state, stderr, MODE_WRITE);
  221. // NB: None is actually a keyword in the language--it doesn't need to be a
  222. // global (see parser.y)
  223. // OutOfMemory (and other important singlets) are set, not borrowed,
  224. // because the state still holds a reference to them
  225. sol_map_set_name(state, globals, "OutOfMemory", state->OutOfMemory);
  226. sol_map_borrow_name(state, globals, "toint", sol_new_cfunc(state, sol_f_toint, "toint"));
  227. sol_map_borrow_name(state, globals, "tofloat", sol_new_cfunc(state, sol_f_tofloat, "tofloat"));
  228. sol_map_borrow_name(state, globals, "tostring", sol_new_cfunc(state, sol_f_tostring, "tostring"));
  229. sol_map_borrow_name(state, globals, "tobuffer", sol_new_cfunc(state, sol_f_tobuffer, "tobuffer"));
  230. sol_map_borrow_name(state, globals, "try", sol_new_cfunc(state, sol_f_try, "try"));
  231. sol_map_borrow_name(state, globals, "apply", sol_new_cfunc(state, sol_f_apply, "apply"));
  232. sol_map_borrow_name(state, globals, "error", sol_new_cfunc(state, sol_f_error, "error"));
  233. sol_map_borrow_name(state, globals, "type", sol_new_cfunc(state, sol_f_type, "type"));
  234. sol_map_borrow_name(state, globals, "prepr", sol_new_cfunc(state, sol_f_prepr, "prepr"));
  235. sol_map_borrow_name(state, globals, "print", sol_new_cfunc(state, sol_f_print, "print"));
  236. sol_map_borrow_name(state, globals, "rawget", sol_new_cfunc(state, sol_f_rawget, "rawget"));
  237. sol_map_borrow_name(state, globals, "rawset", sol_new_cfunc(state, sol_f_rawset, "rawset"));
  238. sol_map_borrow_name(state, globals, "range", sol_new_cfunc(state, sol_f_range, "range"));
  239. //sol_map_borrow_name(state, globals, "exec", sol_new_cfunc(state, sol_f_exec, "exec"));
  240. //sol_map_borrow_name(state, globals, "eval", sol_new_cfunc(state, sol_f_eval, "eval"));
  241. sol_map_borrow_name(state, globals, "execfile", sol_new_cfunc(state, sol_f_execfile, "execfile"));
  242. sol_map_borrow_name(state, globals, "parse", sol_new_cfunc(state, sol_f_parse, "parse"));
  243. sol_map_borrow_name(state, globals, "ord", sol_new_cfunc(state, sol_f_ord, "ord"));
  244. sol_map_borrow_name(state, globals, "chr", sol_new_cfunc(state, sol_f_chr, "chr"));
  245. mod = sol_new_map(state);
  246. sol_map_borrow_name(state, mod, "getref", sol_new_cfunc(state, sol_f_debug_getref, "debug.getref"));
  247. sol_map_borrow_name(state, mod, "setref", sol_new_cfunc(state, sol_f_debug_setref, "debug.setref"));
  248. sol_map_borrow_name(state, mod, "closure", sol_new_cfunc(state, sol_f_debug_closure, "debug.closure"));
  249. sol_map_borrow_name(state, mod, "globals", sol_new_cfunc(state, sol_f_debug_globals, "debug.globals"));
  250. sol_map_borrow_name(state, mod, "locals", sol_new_cfunc(state, sol_f_debug_locals, "debug.locals"));
  251. sol_map_borrow_name(state, mod, "scopes", sol_new_cfunc(state, sol_f_debug_scopes, "debug.scopes"));
  252. sol_map_borrow_name(state, mod, "fnstack", sol_new_cfunc(state, sol_f_debug_fnstack, "debug.fnstack"));
  253. sol_map_borrow_name(state, mod, "version", sol_new_buffer(state, SOL_VERSION, strlen(SOL_VERSION), OWN_NONE, NULL, NULL));
  254. sol_map_borrow_name(state, mod, "hexversion", sol_new_int(state, SOL_HEXVER));
  255. #ifdef SOL_ICACHE
  256. sol_map_borrow_name(state, mod, "icache_min", sol_new_int(state, SOL_ICACHE_MIN));
  257. sol_map_borrow_name(state, mod, "icache_max", sol_new_int(state, SOL_ICACHE_MAX));
  258. #endif
  259. sol_map_borrow_name(state, mod, "modules", state->modules);
  260. sol_map_borrow_name(state, mod, "methods", state->methods);
  261. sol_map_borrow_name(state, mod, "getops", sol_new_cfunc(state, sol_f_debug_getops, "debug.getops"));
  262. sol_register_module_name(state, "debug", mod);
  263. sol_obj_free(mod);
  264. mod = sol_new_map(state);
  265. sol_map_borrow_name(state, mod, "str", sol_new_cfunc(state, sol_f_iter_str, "iter.str"));
  266. sol_map_borrow_name(state, mod, "buffer", sol_new_cfunc(state, sol_f_iter_buffer, "iter.buffer"));
  267. sol_map_borrow_name(state, mod, "list", sol_new_cfunc(state, sol_f_iter_list, "iter.list"));
  268. sol_map_borrow_name(state, mod, "map", sol_new_cfunc(state, sol_f_iter_map, "iter.map"));
  269. sol_register_module_name(state, "iter", mod);
  270. sol_obj_free(mod);
  271. #ifndef NO_READLINE
  272. mod = sol_new_map(state);
  273. sol_map_borrow_name(state, mod, "readline", sol_new_cfunc(state, sol_f_readline_readline, "readline.readline"));
  274. sol_map_borrow_name(state, mod, "add_history", sol_new_cfunc(state, sol_f_readline_add_history, "readline.add_history"));
  275. sol_register_module_name(state, "readline", mod);
  276. sol_obj_free(mod);
  277. #endif
  278. mod = sol_new_map(state);
  279. sol_map_borrow_name(state, mod, "ST_EXPR", sol_new_int(state, ST_EXPR));
  280. sol_map_borrow_name(state, mod, "ST_LIST", sol_new_int(state, ST_LIST));
  281. sol_map_borrow_name(state, mod, "ST_RET", sol_new_int(state, ST_RET));
  282. sol_map_borrow_name(state, mod, "ST_CONT", sol_new_int(state, ST_CONT));
  283. sol_map_borrow_name(state, mod, "ST_BREAK", sol_new_int(state, ST_BREAK));
  284. sol_map_borrow_name(state, mod, "EX_LIT", sol_new_int(state, EX_LIT));
  285. sol_map_borrow_name(state, mod, "EX_LISTGEN", sol_new_int(state, EX_LISTGEN));
  286. sol_map_borrow_name(state, mod, "EX_MAPGEN", sol_new_int(state, EX_MAPGEN));
  287. sol_map_borrow_name(state, mod, "EX_BINOP", sol_new_int(state, EX_BINOP));
  288. sol_map_borrow_name(state, mod, "EX_UNOP", sol_new_int(state, EX_UNOP));
  289. sol_map_borrow_name(state, mod, "EX_INDEX", sol_new_int(state, EX_INDEX));
  290. sol_map_borrow_name(state, mod, "EX_SETINDEX", sol_new_int(state, EX_SETINDEX));
  291. sol_map_borrow_name(state, mod, "EX_ASSIGN", sol_new_int(state, EX_ASSIGN));
  292. sol_map_borrow_name(state, mod, "EX_REF", sol_new_int(state, EX_REF));
  293. sol_map_borrow_name(state, mod, "EX_CALL", sol_new_int(state, EX_CALL));
  294. sol_map_borrow_name(state, mod, "EX_FUNCDECL", sol_new_int(state, EX_FUNCDECL));
  295. sol_map_borrow_name(state, mod, "EX_IFELSE", sol_new_int(state, EX_IFELSE));
  296. sol_map_borrow_name(state, mod, "EX_LOOP", sol_new_int(state, EX_LOOP));
  297. sol_map_borrow_name(state, mod, "EX_ITER", sol_new_int(state, EX_ITER));
  298. sol_map_borrow_name(state, mod, "OP_ADD", sol_new_int(state, OP_ADD));
  299. sol_map_borrow_name(state, mod, "OP_SUB", sol_new_int(state, OP_SUB));
  300. sol_map_borrow_name(state, mod, "OP_MUL", sol_new_int(state, OP_MUL));
  301. sol_map_borrow_name(state, mod, "OP_DIV", sol_new_int(state, OP_DIV));
  302. sol_map_borrow_name(state, mod, "OP_MOD", sol_new_int(state, OP_MOD));
  303. sol_map_borrow_name(state, mod, "OP_POW", sol_new_int(state, OP_POW));
  304. sol_map_borrow_name(state, mod, "OP_BAND", sol_new_int(state, OP_BAND));
  305. sol_map_borrow_name(state, mod, "OP_BOR", sol_new_int(state, OP_BOR));
  306. sol_map_borrow_name(state, mod, "OP_BXOR", sol_new_int(state, OP_BXOR));
  307. sol_map_borrow_name(state, mod, "OP_LAND", sol_new_int(state, OP_LAND));
  308. sol_map_borrow_name(state, mod, "OP_LOR", sol_new_int(state, OP_LOR));
  309. sol_map_borrow_name(state, mod, "OP_EQUAL", sol_new_int(state, OP_EQUAL));
  310. sol_map_borrow_name(state, mod, "OP_NEQUAL", sol_new_int(state, OP_NEQUAL));
  311. sol_map_borrow_name(state, mod, "OP_LESS", sol_new_int(state, OP_LESS));
  312. sol_map_borrow_name(state, mod, "OP_GREATER", sol_new_int(state, OP_GREATER));
  313. sol_map_borrow_name(state, mod, "OP_LESSEQ", sol_new_int(state, OP_LESSEQ));
  314. sol_map_borrow_name(state, mod, "OP_GREATEREQ", sol_new_int(state, OP_GREATEREQ));
  315. sol_map_borrow_name(state, mod, "OP_LSHIFT", sol_new_int(state, OP_LSHIFT));
  316. sol_map_borrow_name(state, mod, "OP_RSHIFT", sol_new_int(state, OP_RSHIFT));
  317. sol_map_borrow_name(state, mod, "OP_NEG", sol_new_int(state, OP_NEG));
  318. sol_map_borrow_name(state, mod, "OP_BNOT", sol_new_int(state, OP_BNOT));
  319. sol_map_borrow_name(state, mod, "OP_LNOT", sol_new_int(state, OP_LNOT));
  320. sol_map_borrow_name(state, mod, "OP_LEN", sol_new_int(state, OP_LEN));
  321. sol_map_borrow_name(state, mod, "LIT_INT", sol_new_int(state, LIT_INT));
  322. sol_map_borrow_name(state, mod, "LIT_FLOAT", sol_new_int(state, LIT_FLOAT));
  323. sol_map_borrow_name(state, mod, "LIT_STRING", sol_new_int(state, LIT_STRING));
  324. sol_map_borrow_name(state, mod, "LIT_NONE", sol_new_int(state, LIT_NONE));
  325. sol_map_borrow_name(state, mod, "KIND_STMT", sol_new_int(state, -1));
  326. sol_map_borrow_name(state, mod, "KIND_EXPR", sol_new_int(state, -2));
  327. sol_map_invert(state, mod);
  328. sol_map_borrow_name(state, mod, "print", sol_new_cfunc(state, sol_f_ast_print, "ast.print"));
  329. sol_register_module_name(state, "ast", mod);
  330. btype = sol_new_map(state);
  331. sol_map_borrow_name(state, btype, "none", sol_new_int(state, BUF_NONE));
  332. sol_map_borrow_name(state, btype, "uint8", sol_new_int(state, BUF_UINT8));
  333. sol_map_borrow_name(state, btype, "uint16", sol_new_int(state, BUF_UINT16));
  334. sol_map_borrow_name(state, btype, "uint32", sol_new_int(state, BUF_UINT32));
  335. sol_map_borrow_name(state, btype, "uint64", sol_new_int(state, BUF_UINT64));
  336. sol_map_borrow_name(state, btype, "int8", sol_new_int(state, BUF_INT8));
  337. sol_map_borrow_name(state, btype, "int16", sol_new_int(state, BUF_INT16));
  338. sol_map_borrow_name(state, btype, "int32", sol_new_int(state, BUF_INT32));
  339. sol_map_borrow_name(state, btype, "int64", sol_new_int(state, BUF_INT64));
  340. sol_map_borrow_name(state, btype, "char", sol_new_int(state, BUF_CHAR));
  341. sol_map_borrow_name(state, btype, "byte", sol_new_int(state, BUF_BYTE));
  342. sol_map_borrow_name(state, btype, "int", sol_new_int(state, BUF_INT));
  343. sol_map_borrow_name(state, btype, "uint", sol_new_int(state, BUF_UINT));
  344. sol_map_borrow_name(state, btype, "long", sol_new_int(state, BUF_LONG));
  345. sol_map_borrow_name(state, btype, "ulong", sol_new_int(state, BUF_ULONG));
  346. sol_map_borrow_name(state, btype, "float", sol_new_int(state, BUF_FLOAT));
  347. sol_map_borrow_name(state, btype, "double", sol_new_int(state, BUF_DOUBLE));
  348. sol_map_borrow_name(state, btype, "cstr", sol_new_int(state, BUF_CSTR));
  349. sol_map_borrow_name(state, btype, "ptr", sol_new_int(state, BUF_PTR));
  350. sol_map_invert(state, btype);
  351. bsize = sol_new_map(state);
  352. sol_map_borrow_name(state, bsize, "uint8", sol_new_int(state, sizeof(uint8_t)));
  353. sol_map_borrow_name(state, bsize, "uint16", sol_new_int(state, sizeof(uint16_t)));
  354. sol_map_borrow_name(state, bsize, "uint32", sol_new_int(state, sizeof(uint32_t)));
  355. sol_map_borrow_name(state, bsize, "uint64", sol_new_int(state, sizeof(uint64_t)));
  356. sol_map_borrow_name(state, bsize, "int8", sol_new_int(state, sizeof(int8_t)));
  357. sol_map_borrow_name(state, bsize, "int16", sol_new_int(state, sizeof(int16_t)));
  358. sol_map_borrow_name(state, bsize, "int32", sol_new_int(state, sizeof(int32_t)));
  359. sol_map_borrow_name(state, bsize, "int64", sol_new_int(state, sizeof(int64_t)));
  360. sol_map_borrow_name(state, bsize, "char", sol_new_int(state, sizeof(char)));
  361. sol_map_borrow_name(state, bsize, "byte", sol_new_int(state, sizeof(unsigned char)));
  362. sol_map_borrow_name(state, bsize, "int", sol_new_int(state, sizeof(int)));
  363. sol_map_borrow_name(state, bsize, "uint", sol_new_int(state, sizeof(unsigned int)));
  364. sol_map_borrow_name(state, bsize, "long", sol_new_int(state, sizeof(long)));
  365. sol_map_borrow_name(state, bsize, "ulong", sol_new_int(state, sizeof(unsigned long)));
  366. sol_map_borrow_name(state, bsize, "float", sol_new_int(state, sizeof(float)));
  367. sol_map_borrow_name(state, bsize, "double", sol_new_int(state, sizeof(double)));
  368. sol_map_borrow_name(state, bsize, "cstr", sol_new_int(state, sizeof(char *)));
  369. sol_map_borrow_name(state, bsize, "ptr", sol_new_int(state, sizeof(void *)));
  370. bobj = sol_new_map(state);
  371. sol_map_borrow_name(state, bobj, "SOL_SINGLET", sol_new_int(state, SOL_SINGLET));
  372. sol_map_borrow_name(state, bobj, "SOL_INTEGER", sol_new_int(state, SOL_INTEGER));
  373. sol_map_borrow_name(state, bobj, "SOL_FLOAT", sol_new_int(state, SOL_FLOAT));
  374. sol_map_borrow_name(state, bobj, "SOL_STRING", sol_new_int(state, SOL_STRING));
  375. sol_map_borrow_name(state, bobj, "SOL_LIST", sol_new_int(state, SOL_LIST));
  376. sol_map_borrow_name(state, bobj, "SOL_MAP", sol_new_int(state, SOL_MAP));
  377. sol_map_borrow_name(state, bobj, "SOL_MCELL", sol_new_int(state, SOL_MCELL));
  378. sol_map_borrow_name(state, bobj, "SOL_FUNCTION", sol_new_int(state, SOL_FUNCTION));
  379. sol_map_borrow_name(state, bobj, "SOL_CFUNCTION", sol_new_int(state, SOL_CFUNCTION));
  380. sol_map_borrow_name(state, bobj, "SOL_STMT", sol_new_int(state, SOL_STMT));
  381. sol_map_borrow_name(state, bobj, "SOL_EXPR", sol_new_int(state, SOL_EXPR));
  382. sol_map_borrow_name(state, bobj, "SOL_BUFFER", sol_new_int(state, SOL_BUFFER));
  383. sol_map_borrow_name(state, bobj, "SOL_DYLIB", sol_new_int(state, SOL_DYLIB));
  384. sol_map_borrow_name(state, bobj, "SOL_DYSYM", sol_new_int(state, SOL_DYSYM));
  385. sol_map_borrow_name(state, bobj, "SOL_STREAM", sol_new_int(state, SOL_STREAM));
  386. sol_map_borrow_name(state, bobj, "SOL_CDATA", sol_new_int(state, SOL_CDATA));
  387. sol_map_invert(state, bobj);
  388. mod = sol_new_map(state);
  389. sol_map_borrow_name(state, mod, "new", sol_new_cfunc(state, sol_f_buffer_new, "buffer.new"));
  390. sol_map_borrow_name(state, mod, "fromstring", sol_new_cfunc(state, sol_f_buffer_fromstring, "buffer.fromstring"));
  391. sol_map_borrow_name(state, mod, "fromobject", sol_new_cfunc(state, sol_f_buffer_fromobject, "buffer.fromobject"));
  392. sol_map_borrow_name(state, mod, "fromaddress", sol_new_cfunc(state, sol_f_buffer_fromaddress, "buffer.fromaddress"));
  393. sol_map_set_name(state, mod, "type", btype);
  394. sol_map_set_name(state, mod, "sizeof", bsize);
  395. sol_map_set_name(state, mod, "objtype", bobj);
  396. sol_register_module_name(state, "buffer", mod);
  397. sol_obj_free(mod);
  398. sol_obj_free(bobj);
  399. sol_obj_free(bsize);
  400. sol_obj_free(btype);
  401. mod = sol_new_map(state);
  402. sol_map_borrow_name(state, mod, "MODE_READ", sol_new_int(state, MODE_READ));
  403. sol_map_borrow_name(state, mod, "MODE_WRITE", sol_new_int(state, MODE_WRITE));
  404. sol_map_borrow_name(state, mod, "MODE_APPEND", sol_new_int(state, MODE_APPEND));
  405. sol_map_borrow_name(state, mod, "MODE_TRUNCATE", sol_new_int(state, MODE_TRUNCATE));
  406. sol_map_borrow_name(state, mod, "MODE_BINARY", sol_new_int(state, MODE_BINARY));
  407. sol_map_borrow_name(state, mod, "SEEK_SET", sol_new_int(state, SEEK_SET));
  408. sol_map_borrow_name(state, mod, "SEEK_CUR", sol_new_int(state, SEEK_CUR));
  409. sol_map_borrow_name(state, mod, "SEEK_END", sol_new_int(state, SEEK_END));
  410. sol_map_borrow_name(state, mod, "ALL", sol_new_buffer(state, "ALL", 3, OWN_NONE, NULL, NULL));
  411. sol_map_borrow_name(state, mod, "LINE", sol_new_buffer(state, "LINE", 4, OWN_NONE, NULL, NULL));
  412. sol_map_borrow_name(state, mod, "TIOCGWINSZ", sol_new_int(state, TIOCGWINSZ));
  413. sol_map_borrow_name(state, mod, "TIOCSWINSZ", sol_new_int(state, TIOCSWINSZ));
  414. sol_map_borrow_name(state, mod, "open", sol_new_cfunc(state, sol_f_stream_open, "io.open"));
  415. sol_map_borrow_name(state, mod, "__setindex", sol_new_cfunc(state, sol_f_io_setindex, "io.__setindex"));
  416. sol_map_borrow_name(state, mod, "__index", sol_new_cfunc(state, sol_f_io_index, "io.__index"));
  417. sol_register_module_name(state, "io", mod);
  418. sol_obj_free(mod);
  419. meths = sol_new_map(state);
  420. sol_map_borrow_name(state, meths, "get", sol_new_cfunc(state, sol_f_buffer_get, "buffer.get"));
  421. sol_map_borrow_name(state, meths, "set", sol_new_cfunc(state, sol_f_buffer_set, "buffer.set"));
  422. sol_map_borrow_name(state, meths, "address", sol_new_cfunc(state, sol_f_buffer_address, "buffer.address"));
  423. sol_map_borrow_name(state, meths, "size", sol_new_cfunc(state, sol_f_buffer_size, "buffer.size"));
  424. sol_map_borrow_name(state, meths, "sub", sol_new_cfunc(state, sol_f_buffer_sub, "buffer.sub"));
  425. sol_map_borrow_name(state, meths, "split", sol_new_cfunc(state, sol_f_buffer_split, "buffer.split"));
  426. sol_map_borrow_name(state, meths, "find", sol_new_cfunc(state, sol_f_buffer_find, "buffer.find"));
  427. sol_register_methods_name(state, "buffer", meths);
  428. sol_obj_free(meths);
  429. meths = sol_new_map(state);
  430. sol_map_borrow_name(state, meths, "copy", sol_new_cfunc(state, sol_f_list_copy, "list.copy"));
  431. sol_map_borrow_name(state, meths, "insert", sol_new_cfunc(state, sol_f_list_insert, "list.insert"));
  432. sol_map_borrow_name(state, meths, "remove", sol_new_cfunc(state, sol_f_list_remove, "list.remove"));
  433. sol_map_borrow_name(state, meths, "truncate", sol_new_cfunc(state, sol_f_list_truncate, "list.truncate"));
  434. sol_map_borrow_name(state, meths, "map", sol_new_cfunc(state, sol_f_list_map, "list.map"));
  435. sol_map_borrow_name(state, meths, "filter", sol_new_cfunc(state, sol_f_list_filter, "list.filter"));
  436. sol_map_borrow_name(state, meths, "reduce", sol_new_cfunc(state, sol_f_list_reduce, "list.reduce"));
  437. sol_register_methods_name(state, "list", meths);
  438. sol_obj_free(meths);
  439. meths = sol_new_map(state);
  440. sol_map_borrow_name(state, meths, "read", sol_new_cfunc(state, sol_f_stream_read_buffer, "stream.read_buffer"));
  441. sol_map_borrow_name(state, meths, "read_buffer", sol_new_cfunc(state, sol_f_stream_read_buffer, "stream.read_buffer"));
  442. sol_map_borrow_name(state, meths, "write", sol_new_cfunc(state, sol_f_stream_write, "stream.write"));
  443. sol_map_borrow_name(state, meths, "seek", sol_new_cfunc(state, sol_f_stream_seek, "stream.seek"));
  444. sol_map_borrow_name(state, meths, "tell", sol_new_cfunc(state, sol_f_stream_tell, "stream.tell"));
  445. sol_map_borrow_name(state, meths, "flush", sol_new_cfunc(state, sol_f_stream_flush, "stream.flush"));
  446. sol_map_borrow_name(state, meths, "eof", sol_new_cfunc(state, sol_f_stream_eof, "stream.eof"));
  447. sol_map_borrow_name(state, meths, "ioctl", sol_new_cfunc(state, sol_f_stream_ioctl, "stream.ioctl"));
  448. sol_register_methods_name(state, "stream", meths);
  449. sol_obj_free(meths);
  450. meths = sol_new_map(state);
  451. sol_map_borrow_name(state, meths, "sub", sol_new_cfunc(state, sol_f_str_sub, "str.sub"));
  452. sol_map_borrow_name(state, meths, "split", sol_new_cfunc(state, sol_f_str_split, "str.split"));
  453. sol_map_borrow_name(state, meths, "find", sol_new_cfunc(state, sol_f_str_find, "str.find"));
  454. sol_register_methods_name(state, "string", meths);
  455. sol_obj_free(meths);
  456. state->fnstack = sol_new_list(state);
  457. if(sol_has_error(state)) {
  458. goto cleanup;
  459. }
  460. // Perform initialization based on the user profile, if so requested.
  461. if(!(state->features & SOL_FT_NO_USR_INIT)) {
  462. for(i = 0; i < LENGTH(sol_AbsInitPaths); i++) {
  463. if(!sol_AbsInitPaths[i]) continue;
  464. fp = fopen(sol_AbsInitPaths[i], "r");
  465. if(state->features & SOL_FT_DEBUG) {
  466. printf("state init: loading abs %s: ", sol_AbsInitPaths[i]);
  467. }
  468. if(fp) {
  469. if(state->features & SOL_FT_DEBUG) {
  470. printf("found");
  471. }
  472. stmt = sol_compile_file(fp);
  473. sol_exec(state, stmt);
  474. st_free(stmt);
  475. fclose(fp);
  476. } else {
  477. if(state->features & SOL_FT_DEBUG) {
  478. printf("not found");
  479. }
  480. }
  481. if(state->features & SOL_FT_DEBUG) {
  482. printf("\n");
  483. }
  484. }
  485. suffix = getenv("HOME");
  486. if(state->features & SOL_FT_DEBUG) {
  487. printf("state init: loading relative to %s\n", suffix);
  488. }
  489. if(suffix) {
  490. strncpy(sol_TempPath, suffix, TMP_PATH_SZ);
  491. suffix = sol_TempPath + strlen(sol_TempPath);
  492. for(i = 0; i < LENGTH(sol_HomeInitPaths); i++) {
  493. if(!sol_HomeInitPaths[i]) continue;
  494. strncpy(suffix, sol_HomeInitPaths[i], TMP_PATH_SZ - (suffix - sol_TempPath));
  495. if(state->features & SOL_FT_DEBUG) {
  496. printf("state init: loading rel %s: ", sol_TempPath);
  497. }
  498. fp = fopen(sol_TempPath, "r");
  499. if(fp) {
  500. if(state->features & SOL_FT_DEBUG) {
  501. printf("found");
  502. }
  503. stmt = sol_compile_file(fp);
  504. sol_exec(state, stmt);
  505. st_free(stmt);
  506. fclose(fp);
  507. } else {
  508. if(state->features & SOL_FT_DEBUG) {
  509. printf("not found");
  510. }
  511. }
  512. if(state->features & SOL_FT_DEBUG) {
  513. printf("\n");
  514. }
  515. }
  516. }
  517. if(sol_has_error(state)) {
  518. goto cleanup;
  519. }
  520. }
  521. // We're all set!
  522. return 1;
  523. cleanup:
  524. sol_obj_free(state->None);
  525. sol_obj_free(state->OutOfMemory);
  526. return 0;
  527. }
  528. void sol_state_cleanup(sol_state_t *state) {
  529. long i;
  530. sol_obj_free(state->scopes);
  531. sol_obj_free(state->error);
  532. sol_obj_free(state->None);
  533. sol_obj_free(state->OutOfMemory);
  534. sol_obj_free(state->_stdin);
  535. sol_obj_free(state->_stdout);
  536. sol_obj_free(state->_stderr);
  537. if(state->ret) {
  538. sol_obj_free(state->ret);
  539. }
  540. #ifdef SOL_ICACHE
  541. for(i = 0; i <= (SOL_ICACHE_MAX - SOL_ICACHE_MIN); i++) {
  542. sol_obj_free(state->icache[i]);
  543. }
  544. #endif
  545. sol_obj_free(state->modules);
  546. sol_obj_free(state->methods);
  547. sol_mm_finalize(state);
  548. }
  549. sol_object_t *sol_state_resolve(sol_state_t *state, sol_object_t *key) {
  550. sol_object_t *temp, *args;
  551. dsl_seq_iter *iter = dsl_new_seq_iter(state->scopes->seq);
  552. args = sol_new_list(state);
  553. sol_list_insert(state, args, 0, state->None);
  554. sol_list_insert(state, args, 1, key);
  555. while(!dsl_seq_iter_is_invalid(iter)) {
  556. sol_list_set_index(state, args, 0, dsl_seq_iter_at(iter));
  557. temp = CALL_METHOD(state, ((sol_object_t *) dsl_seq_iter_at(iter)), index, args);
  558. if(!sol_is_none(state, temp)) {
  559. dsl_free_seq_iter(iter);
  560. sol_obj_free(args);
  561. return temp;
  562. }
  563. sol_obj_free(temp);
  564. dsl_seq_iter_next(iter);
  565. }
  566. dsl_free_seq_iter(iter);
  567. sol_obj_free(args);
  568. temp = sol_get_module(state, key);
  569. if(!sol_is_none(state, temp)) {
  570. return temp;
  571. }
  572. sol_obj_free(temp);
  573. return sol_incref(state->None);
  574. }
  575. sol_object_t *sol_state_resolve_name(sol_state_t *state, const char *name) {
  576. sol_object_t *key = sol_new_buffer(state, (char *) name, strlen(name), OWN_NONE, NULL, NULL), *temp;
  577. if(sol_has_error(state)) {
  578. return sol_incref(state->None);
  579. }
  580. temp = sol_state_resolve(state, key);
  581. sol_obj_free(key);
  582. return temp;
  583. }
  584. void sol_state_assign(sol_state_t *state, sol_object_t *key, sol_object_t *val) {
  585. sol_object_t *cur = state->scopes, *next, *active = NULL, *args;
  586. if(!cur) {
  587. sol_set_error_string(state, "Global state does not exist");
  588. return;
  589. }
  590. active = sol_list_get_index(state, state->scopes, sol_list_len(state, state->scopes) - 1);
  591. if(!active || sol_is_none(state, cur)) {
  592. sol_set_error_string(state, "No scopes exist");
  593. return;
  594. }
  595. args = sol_new_list(state);
  596. sol_list_insert(state, args, 0, active);
  597. sol_list_insert(state, args, 1, key);
  598. sol_list_insert(state, args, 2, val);
  599. sol_obj_free(CALL_METHOD(state, active, setindex, args));
  600. sol_obj_free(args);
  601. }
  602. void sol_state_assign_name(sol_state_t *state, const char *name, sol_object_t *val) {
  603. sol_object_t *key = sol_new_buffer(state, (char *) name, strlen(name), OWN_NONE, NULL, NULL);
  604. if(sol_has_error(state)) {
  605. return;
  606. }
  607. sol_state_assign(state, key, val);
  608. sol_obj_free(key);
  609. }
  610. void sol_state_assign_l(sol_state_t *state, sol_object_t *key, sol_object_t *val) {
  611. sol_object_t *cur = state->scopes, *args;
  612. cur = sol_list_get_index(state, state->scopes, 0);
  613. if(!cur || sol_is_none(state, cur)) {
  614. sol_set_error_string(state, "Local state does not exist");
  615. return;
  616. }
  617. args = sol_new_list(state);
  618. sol_list_insert(state, args, 0, cur);
  619. sol_list_insert(state, args, 1, key);
  620. sol_list_insert(state, args, 2, val);
  621. sol_obj_free(CALL_METHOD(state, cur, setindex, args));
  622. sol_obj_free(args);
  623. }
  624. void sol_state_assign_l_name(sol_state_t *state, const char *name, sol_object_t *val) {
  625. sol_object_t *key = sol_new_buffer(state, (char *) name, strlen(name), OWN_NONE, NULL, NULL);
  626. if(sol_has_error(state)) {
  627. return;
  628. }
  629. sol_state_assign_l(state, key, val);
  630. sol_obj_free(key);
  631. }
  632. void sol_state_push_scope(sol_state_t *state, sol_object_t *scope) {
  633. sol_list_push(state, state->scopes, scope);
  634. }
  635. sol_object_t *sol_state_pop_scope(sol_state_t *state) {
  636. return sol_list_pop(state, state->scopes);
  637. }
  638. sol_object_t *sol_get_error(sol_state_t *state) {
  639. return sol_incref(state->error);
  640. }
  641. sol_object_t *sol_set_error(sol_state_t *state, sol_object_t *err) {
  642. state->error = sol_incref(err);
  643. sol_init_traceback(state);
  644. return sol_incref(state->None);
  645. }
  646. sol_object_t *sol_set_error_string(sol_state_t *state, const char *serr) {
  647. sol_object_t *err = sol_new_buffer(state, strdup(serr), strlen(serr), OWN_FREE, NULL, NULL), *res;
  648. if(sol_has_error(state)) {
  649. sol_obj_free(err);
  650. return sol_incref(state->None);
  651. }
  652. res = sol_set_error(state, err);
  653. sol_obj_free(err);
  654. return res;
  655. }
  656. void sol_clear_error(sol_state_t *state) {
  657. // This silliness ensures we don't accidentally free None.
  658. sol_object_t *olderr = state->error;
  659. state->error = sol_incref(state->None);
  660. sol_obj_free(olderr);
  661. }
  662. void sol_init_traceback(sol_state_t *state) {
  663. if(state->traceback) {
  664. sol_obj_free(state->traceback);
  665. }
  666. state->traceback = sol_new_list(state);
  667. }
  668. void sol_add_traceback(sol_state_t *state, sol_object_t *node) {
  669. sol_object_t *pair = sol_new_list(state), *scope = sol_list_get_index(state, state->scopes, 0);
  670. sol_list_insert(state, pair, 0, node);
  671. sol_list_insert(state, pair, 1, scope);
  672. sol_obj_free(scope);
  673. if(sol_list_len(state, state->fnstack) > 0) {
  674. scope = sol_list_get_index(state, state->fnstack, 0);
  675. sol_list_insert(state, pair, 2, scope);
  676. sol_obj_free(scope);
  677. } else {
  678. sol_list_insert(state, pair, 2, state->None);
  679. }
  680. sol_list_insert(state, state->traceback, 0, pair);
  681. sol_obj_free(pair);
  682. }
  683. sol_object_t *sol_traceback(sol_state_t *state) {
  684. if(state->traceback) {
  685. return sol_incref(state->traceback);
  686. }
  687. return sol_incref(state->None);
  688. }
  689. void sol_register_module(sol_state_t *state, sol_object_t *key, sol_object_t *val) {
  690. sol_map_set(state, state->modules, key, val);
  691. }
  692. void sol_register_module_name(sol_state_t *state, char *name, sol_object_t *val) {
  693. sol_map_set_name(state, state->modules, name, val);
  694. }
  695. sol_object_t *sol_get_module(sol_state_t *state, sol_object_t *key) {
  696. return sol_map_get(state, state->modules, key);
  697. }
  698. sol_object_t *sol_get_module_name(sol_state_t *state, char *name) {
  699. return sol_map_get_name(state, state->modules, name);
  700. }
  701. void sol_register_methods(sol_state_t *state, sol_object_t *key, sol_object_t *val) {
  702. sol_map_set(state, state->methods, key, val);
  703. }
  704. void sol_register_methods_name(sol_state_t *state, char *name, sol_object_t *val) {
  705. sol_map_set_name(state, state->methods, name, val);
  706. }
  707. sol_object_t *sol_get_methods(sol_state_t *state, sol_object_t *key) {
  708. return sol_map_get(state, state->methods, key);
  709. }
  710. sol_object_t *sol_get_methods_name(sol_state_t *state, char *name) {
  711. return sol_map_get_name(state, state->methods, name);
  712. }
  713. sol_object_t *sol_f_io_index(sol_state_t *state, sol_object_t *args) {
  714. sol_object_t *self = sol_list_get_index(state, args, 0), *name = sol_list_get_index(state, args, 1), *namestr = sol_cast_string(state, name), *res;
  715. if(sol_string_eq(state, namestr, "stdin")) {
  716. sol_obj_free(name);
  717. sol_obj_free(namestr);
  718. return sol_incref(state->_stdin);
  719. }
  720. if(sol_string_eq(state, namestr, "stdout")) {
  721. sol_obj_free(name);
  722. sol_obj_free(namestr);
  723. return sol_incref(state->_stdout);
  724. }
  725. if(sol_string_eq(state, namestr, "stderr")) {
  726. sol_obj_free(name);
  727. sol_obj_free(namestr);
  728. return sol_incref(state->_stderr);
  729. }
  730. sol_obj_free(namestr);
  731. res = sol_map_get(state, self, name);
  732. sol_obj_free(self);
  733. sol_obj_free(name);
  734. return res;
  735. }
  736. sol_object_t *sol_f_io_setindex(sol_state_t *state, sol_object_t *args) {
  737. sol_object_t *name = sol_list_get_index(state, args, 1), *value = sol_list_get_index(state, args, 2);
  738. sol_object_t *namestr = sol_cast_string(state, name), *io;
  739. if(sol_string_eq(state, namestr, "stdin")) {
  740. sol_obj_free(state->_stdin);
  741. state->_stdin = sol_incref(value);
  742. goto done;
  743. }
  744. if(sol_string_eq(state, namestr, "stdout")) {
  745. sol_obj_free(state->_stdout);
  746. state->_stdout = sol_incref(value);
  747. goto done;
  748. }
  749. if(sol_string_eq(state, namestr, "stderr")) {
  750. sol_obj_free(state->_stderr);
  751. state->_stderr = sol_incref(value);
  752. goto done;
  753. }
  754. io = sol_list_get_index(state, args, 0);
  755. sol_map_set(state, io, name, value);
  756. sol_obj_free(io);
  757. done:
  758. sol_obj_free(namestr);
  759. sol_obj_free(value);
  760. sol_obj_free(name);
  761. return sol_incref(state->None);
  762. }
  763. sol_object_t *sol_get_stdin(sol_state_t *state) {
  764. return sol_incref(state->_stdin);
  765. }
  766. sol_object_t *sol_get_stdout(sol_state_t *state) {
  767. return sol_incref(state->_stdout);
  768. }
  769. sol_object_t *sol_get_stderr(sol_state_t *state) {
  770. return sol_incref(state->_stderr);
  771. }
  772. void sol_ops_init(sol_ops_t *ops) {
  773. ops->tname = "unknown";
  774. ops->tflags = 0;
  775. ops->add = sol_f_not_impl;
  776. ops->sub = sol_f_not_impl;
  777. ops->mul = sol_f_not_impl;
  778. ops->div = sol_f_not_impl;
  779. ops->mod = sol_f_not_impl;
  780. ops->pow = sol_f_not_impl;
  781. ops->tbang = sol_f_tbang;
  782. ops->band = sol_f_not_impl;
  783. ops->bor = sol_f_not_impl;
  784. ops->bxor = sol_f_not_impl;
  785. ops->blsh = sol_f_not_impl;
  786. ops->brsh = sol_f_not_impl;
  787. ops->bnot = sol_f_not_impl;
  788. ops->cmp = sol_f_default_cmp;
  789. ops->call = sol_f_not_impl;
  790. ops->index = sol_f_not_impl;
  791. ops->setindex = sol_f_not_impl;
  792. ops->len = sol_f_not_impl;
  793. ops->iter = sol_f_not_impl;
  794. ops->toint = sol_f_not_impl;
  795. ops->tofloat = sol_f_not_impl;
  796. ops->tostring = sol_f_default_tostring;
  797. ops->tobuffer = sol_f_default_tobuffer;
  798. ops->repr = sol_f_default_repr;
  799. ops->init = sol_f_no_op;
  800. ops->free = sol_f_no_op;
  801. }