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.

runtime.c 29KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <setjmp.h>
  4. #include "ast.h"
  5. expr_node *sol_comp_as_expr(stmt_node *stmt) {
  6. if(stmt->type == ST_EXPR) {
  7. return stmt->expr;
  8. }
  9. return NULL;
  10. }
  11. void sol_comp_free(stmt_node *stmt) {
  12. st_free(stmt);
  13. }
  14. expr_node *ex_copy(expr_node *);
  15. stmt_node *st_copy(stmt_node *old) {
  16. stmt_node *new;
  17. stmtlist_node *curn, *curo;
  18. if(!old) {
  19. // printf("WARNING: Copying NULL statement\n");
  20. return NULL;
  21. }
  22. new = NEW(stmt_node);
  23. new->type = old->type;
  24. switch(old->type) {
  25. case ST_EXPR:
  26. new->expr = ex_copy(old->expr);
  27. break;
  28. case ST_LIST:
  29. new->stmtlist = stl_copy(old->stmtlist);
  30. break;
  31. case ST_RET:
  32. new->ret = NEW(ret_node);
  33. new->ret->ret = ex_copy(old->ret->ret);
  34. break;
  35. case ST_CONT:
  36. new->cont = NEW(cont_node);
  37. new->cont->val = ex_copy(old->cont->val);
  38. break;
  39. case ST_BREAK:
  40. new->brk = NEW(break_node);
  41. new->brk->val = ex_copy(old->brk->val);
  42. break;
  43. default:
  44. printf("WARNING: Unknown statement type to copy: %d\n", old->type);
  45. break;
  46. }
  47. return new;
  48. }
  49. stmtlist_node *stl_copy(stmtlist_node *old) {
  50. stmtlist_node *new, *curn, *curo;
  51. if(!old) {
  52. return NULL;
  53. }
  54. new = NEW(stmtlist_node);
  55. curn = new;
  56. curo = old;
  57. while(curo) {
  58. if(curo->stmt) {
  59. curn->stmt = st_copy(curo->stmt);
  60. } else {
  61. curn->stmt = NULL;
  62. }
  63. if(curo->next) {
  64. curn->next = NEW(stmtlist_node);
  65. curn = curn->next;
  66. }
  67. curo = curo->next;
  68. }
  69. curn->next = NULL;
  70. return new;
  71. }
  72. expr_node *ex_copy(expr_node *old) {
  73. expr_node *new;
  74. exprlist_node *cureo, *curen;
  75. assoclist_node *curao, *curan;
  76. identlist_node *curio, *curin;
  77. if(!old) {
  78. // printf("WARNING: Copying NULL expression\n");
  79. return NULL;
  80. }
  81. new = NEW(expr_node);
  82. new->type = old->type;
  83. switch(old->type) {
  84. case EX_LIT:
  85. new->lit = NEW(lit_node);
  86. new->lit->type = old->lit->type;
  87. switch(old->lit->type) {
  88. case LIT_INT:
  89. new->lit->ival = old->lit->ival;
  90. break;
  91. case LIT_FLOAT:
  92. new->lit->fval = old->lit->fval;
  93. break;
  94. case LIT_STRING:
  95. new->lit->str = strdup(old->lit->str);
  96. break;
  97. case LIT_BUFFER:
  98. new->lit->buf = malloc(sizeof(unsigned long) + LENGTH_OF(old->lit->buf) * sizeof(char));
  99. LENGTH_OF(new->lit->buf) = LENGTH_OF(old->lit->buf);
  100. memcpy(BYTES_OF(new->lit->buf), BYTES_OF(old->lit->buf), LENGTH_OF(old->lit->buf) * sizeof(char));
  101. break;
  102. case LIT_NONE:
  103. break;
  104. default:
  105. printf("WARNING: Unknown literal type %d in copy\n", old->lit->type);
  106. break;
  107. }
  108. break;
  109. case EX_LISTGEN:
  110. new->listgen = NEW(listgen_node);
  111. new->listgen->list = exl_copy(old->listgen->list);
  112. break;
  113. case EX_MAPGEN:
  114. new->mapgen = NEW(mapgen_node);
  115. new->mapgen->map = asl_copy(old->mapgen->map);
  116. break;
  117. case EX_BINOP:
  118. new->binop = NEW(binop_node);
  119. new->binop->type = old->binop->type;
  120. new->binop->left = ex_copy(old->binop->left);
  121. new->binop->right = ex_copy(old->binop->right);
  122. break;
  123. case EX_UNOP:
  124. new->unop = NEW(unop_node);
  125. new->unop->type = old->unop->type;
  126. new->unop->expr = ex_copy(old->unop->expr);
  127. break;
  128. case EX_INDEX:
  129. new->index = NEW(index_node);
  130. new->index->expr = ex_copy(old->index->expr);
  131. new->index->index = ex_copy(old->index->index);
  132. break;
  133. case EX_SETINDEX:
  134. new->setindex = NEW(setindex_node);
  135. new->setindex->expr = ex_copy(old->setindex->expr);
  136. new->setindex->index = ex_copy(old->setindex->index);
  137. new->setindex->value = ex_copy(old->setindex->value);
  138. break;
  139. case EX_ASSIGN:
  140. new->assign = NEW(assign_node);
  141. new->assign->ident = strdup(old->assign->ident);
  142. new->assign->value = ex_copy(old->assign->value);
  143. break;
  144. case EX_REF:
  145. new->ref = NEW(ref_node);
  146. new->ref->ident = strdup(old->ref->ident);
  147. break;
  148. case EX_CALL:
  149. new->call = NEW(call_node);
  150. new->call->expr = ex_copy(old->call->expr);
  151. new->call->args = exl_copy(old->call->args);
  152. new->call->method = old->call->method ? strdup(old->call->method) : NULL;
  153. break;
  154. case EX_FUNCDECL:
  155. new->funcdecl = NEW(funcdecl_node);
  156. if(old->funcdecl->name) {
  157. new->funcdecl->name = strdup(old->funcdecl->name);
  158. } else {
  159. new->funcdecl->name = NULL;
  160. }
  161. new->funcdecl->params = pl_copy(old->funcdecl->params);
  162. new->funcdecl->anno = ex_copy(old->funcdecl->anno);
  163. new->funcdecl->body = st_copy(old->funcdecl->body);
  164. new->funcdecl->flags = old->funcdecl->flags;
  165. break;
  166. case EX_IFELSE:
  167. new->ifelse = NEW(ifelse_node);
  168. new->ifelse->cond = ex_copy(old->ifelse->cond);
  169. if(old->ifelse->iftrue)
  170. new->ifelse->iftrue = st_copy(old->ifelse->iftrue);
  171. else
  172. new->ifelse->iftrue = NULL;
  173. if(old->ifelse->iffalse)
  174. new->ifelse->iffalse = st_copy(old->ifelse->iffalse);
  175. else
  176. new->ifelse->iffalse = NULL;
  177. break;
  178. case EX_LOOP:
  179. new->loop = NEW(loop_node);
  180. new->loop->cond = ex_copy(old->loop->cond);
  181. new->loop->loop = st_copy(old->loop->loop);
  182. break;
  183. case EX_ITER:
  184. new->iter = NEW(iter_node);
  185. new->iter->var = strdup(old->iter->var);
  186. new->iter->iter = ex_copy(old->iter->iter);
  187. new->iter->loop = st_copy(old->iter->loop);
  188. break;
  189. default:
  190. printf("WARNING: Unknown expression type to copy: %d\n", old->type);
  191. break;
  192. }
  193. return new;
  194. }
  195. assoclist_node *asl_copy(assoclist_node *old) {
  196. assoclist_node *new, *curn, *curo;
  197. if(!old) {
  198. return NULL;
  199. }
  200. new = NEW(assoclist_node);
  201. curn = new;
  202. curo = old;
  203. while(curo) {
  204. if(curo->item && curo->item->key && curo->item->value) {
  205. curn->item = NEW(associtem_node);
  206. curn->item->key = ex_copy(curo->item->key);
  207. curn->item->value = ex_copy(curo->item->value);
  208. } else {
  209. curn->item = NULL;
  210. }
  211. if(curo->next) {
  212. curn->next = NEW(assoclist_node);
  213. curn = curn->next;
  214. }
  215. curo = curo->next;
  216. }
  217. curn->next = NULL;
  218. return new;
  219. }
  220. exprlist_node *exl_copy(exprlist_node *old) {
  221. exprlist_node *new, *curn, *curo;
  222. if(!old) {
  223. return NULL;
  224. }
  225. new = NEW(exprlist_node);
  226. curn = new;
  227. curo = old;
  228. while(curo) {
  229. if(curo->expr) {
  230. curn->expr = ex_copy(curo->expr);
  231. } else {
  232. curn->expr = NULL;
  233. }
  234. if(curo->next) {
  235. curn->next = NEW(exprlist_node);
  236. curn = curn->next;
  237. }
  238. curo = curo->next;
  239. }
  240. curn->next = NULL;
  241. return new;
  242. }
  243. identlist_node *idl_copy(identlist_node *old) {
  244. identlist_node *new, *curn, *curo;
  245. if(!old) {
  246. return NULL;
  247. }
  248. new = NEW(identlist_node);
  249. curn = new;
  250. curo = old;
  251. while(curo) {
  252. if(curo->ident) {
  253. curn->ident = strdup(curo->ident);
  254. } else {
  255. curn->ident = NULL;
  256. }
  257. if(curo->next) {
  258. curn->next = NEW(identlist_node);
  259. curn = curn->next;
  260. }
  261. curo = curo->next;
  262. }
  263. curn->next = NULL;
  264. return new;
  265. }
  266. paramlist_node *pl_copy(paramlist_node *old) {
  267. paramlist_node *new;
  268. if(!old) return NULL;
  269. new = NEW(paramlist_node);
  270. new->args = idl_copy(old->args);
  271. new->annos = exl_copy(old->annos);
  272. new->clkeys = idl_copy(old->clkeys);
  273. new->clvalues = exl_copy(old->clvalues);
  274. new->rest = old->rest ? strdup(old->rest) : NULL;
  275. return new;
  276. }
  277. void ex_free(expr_node *);
  278. void st_free(stmt_node *stmt) {
  279. stmtlist_node *curs, *prevs;
  280. if(!stmt) {
  281. return;
  282. }
  283. switch(stmt->type) {
  284. case ST_EXPR:
  285. ex_free(stmt->expr);
  286. break;
  287. case ST_LIST:
  288. stl_free(stmt->stmtlist);
  289. break;
  290. case ST_RET:
  291. ex_free(stmt->ret->ret);
  292. free(stmt->ret);
  293. break;
  294. case ST_CONT:
  295. ex_free(stmt->cont->val);
  296. break;
  297. case ST_BREAK:
  298. ex_free(stmt->brk->val);
  299. break;
  300. }
  301. free(stmt);
  302. }
  303. void stl_free(stmtlist_node *list) {
  304. stmtlist_node *cur = list, *prev;
  305. while(cur) {
  306. if(cur->stmt) {
  307. free(cur->stmt);
  308. }
  309. prev = cur;
  310. cur = cur->next;
  311. free(prev);
  312. }
  313. }
  314. void ex_free(expr_node *expr) {
  315. exprlist_node *cure, *preve;
  316. assoclist_node *cura, *preva;
  317. identlist_node *curi, *previ;
  318. if(!expr) {
  319. return;
  320. }
  321. switch(expr->type) {
  322. case EX_LIT:
  323. if(expr->lit->type == LIT_STRING) {
  324. free(expr->lit->str);
  325. }
  326. if(expr->lit->type == LIT_BUFFER) {
  327. free(expr->lit->buf);
  328. }
  329. free(expr->lit);
  330. break;
  331. case EX_LISTGEN:
  332. exl_free(expr->listgen->list);
  333. free(expr->listgen);
  334. break;
  335. case EX_MAPGEN:
  336. asl_free(expr->mapgen->map);
  337. free(expr->mapgen);
  338. break;
  339. case EX_BINOP:
  340. ex_free(expr->binop->left);
  341. ex_free(expr->binop->right);
  342. free(expr->binop);
  343. break;
  344. case EX_UNOP:
  345. ex_free(expr->unop->expr);
  346. free(expr->unop);
  347. break;
  348. case EX_INDEX:
  349. ex_free(expr->index->expr);
  350. ex_free(expr->index->index);
  351. free(expr->index);
  352. break;
  353. case EX_SETINDEX:
  354. ex_free(expr->setindex->expr);
  355. ex_free(expr->setindex->index);
  356. ex_free(expr->setindex->value);
  357. free(expr->setindex);
  358. break;
  359. case EX_ASSIGN:
  360. free(expr->assign->ident);
  361. ex_free(expr->assign->value);
  362. free(expr->assign);
  363. break;
  364. case EX_REF:
  365. free(expr->ref->ident);
  366. free(expr->ref);
  367. break;
  368. case EX_CALL:
  369. ex_free(expr->call->expr);
  370. exl_free(expr->call->args);
  371. free(expr->call->method);
  372. free(expr->call);
  373. break;
  374. case EX_FUNCDECL:
  375. free(expr->funcdecl->name);
  376. st_free(expr->funcdecl->body);
  377. pl_free(expr->funcdecl->params);
  378. ex_free(expr->funcdecl->anno);
  379. free(expr->funcdecl);
  380. break;
  381. case EX_IFELSE:
  382. ex_free(expr->ifelse->cond);
  383. st_free(expr->ifelse->iftrue);
  384. st_free(expr->ifelse->iffalse);
  385. free(expr->ifelse);
  386. break;
  387. case EX_LOOP:
  388. ex_free(expr->loop->cond);
  389. st_free(expr->loop->loop);
  390. free(expr->loop);
  391. break;
  392. case EX_ITER:
  393. free(expr->iter->var);
  394. ex_free(expr->iter->iter);
  395. st_free(expr->iter->loop);
  396. free(expr->iter);
  397. break;
  398. }
  399. free(expr);
  400. }
  401. void exl_free(exprlist_node *list) {
  402. exprlist_node *cur = list, *prev;
  403. while(cur) {
  404. if(cur->expr) {
  405. free(cur->expr);
  406. }
  407. prev = cur;
  408. cur = cur->next;
  409. free(prev);
  410. }
  411. }
  412. void asl_free(assoclist_node *list) {
  413. assoclist_node *cur = list, *prev;
  414. while(cur) {
  415. if(cur->item) {
  416. free(cur->item->key);
  417. free(cur->item->value);
  418. free(cur->item);
  419. }
  420. prev = cur;
  421. cur = cur->next;
  422. free(prev);
  423. }
  424. }
  425. void idl_free(identlist_node *list) {
  426. identlist_node *cur = list, *prev;
  427. while(cur) {
  428. if(cur->ident) {
  429. free(cur->ident);
  430. }
  431. prev = cur;
  432. cur = cur->next;
  433. free(prev);
  434. }
  435. }
  436. void pl_free(paramlist_node *list) {
  437. if(!list) return;
  438. idl_free(list->args);
  439. exl_free(list->annos);
  440. idl_free(list->clkeys);
  441. exl_free(list->clvalues);
  442. if(list->rest) free(list->rest);
  443. }
  444. #define ERR_CHECK(state) do { if(sol_has_error(state)) { sol_add_traceback(state, sol_new_exprnode(state, ex_copy(expr))); longjmp(jmp, 1); } } while(0)
  445. sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
  446. sol_object_t *res = NULL, *left = NULL, *right = NULL, *lint = NULL, *rint = NULL, *value = NULL, *list = NULL, *vint = NULL, *iter = NULL, *item = NULL;
  447. exprlist_node *cure = NULL;
  448. assoclist_node *cura = NULL;
  449. identlist_node *curi = NULL;
  450. char *buf;
  451. if(!expr) {
  452. return sol_set_error_string(state, "Evaluate NULL expression");
  453. }
  454. ERR_CHECK(state);
  455. switch(expr->type) {
  456. case EX_LIT:
  457. switch(expr->lit->type) {
  458. case LIT_INT:
  459. return sol_new_int(state, expr->lit->ival);
  460. break;
  461. case LIT_FLOAT:
  462. return sol_new_float(state, expr->lit->fval);
  463. break;
  464. case LIT_STRING:
  465. return sol_new_string(state, expr->lit->str);
  466. break;
  467. case LIT_BUFFER:
  468. buf = malloc(LENGTH_OF(expr->lit->buf));
  469. memcpy(buf, BYTES_OF(expr->lit->buf), LENGTH_OF(expr->lit->buf));
  470. return sol_new_buffer(state, buf, LENGTH_OF(expr->lit->buf), OWN_FREE, NULL, NULL);
  471. case LIT_NONE:
  472. return sol_incref(state->None);
  473. break;
  474. }
  475. break;
  476. case EX_LISTGEN:
  477. res = sol_new_list(state);
  478. cure = expr->listgen->list;
  479. while(cure) {
  480. if(cure->expr) {
  481. sol_list_insert(state, res, sol_list_len(state, res), sol_eval_inner(state, cure->expr, jmp));
  482. }
  483. ERR_CHECK(state);
  484. cure = cure->next;
  485. }
  486. return res;
  487. break;
  488. case EX_MAPGEN:
  489. res = sol_new_map(state);
  490. cura = expr->mapgen->map;
  491. while(cura) {
  492. if(cura->item) {
  493. sol_map_set(state, res, sol_eval(state, cura->item->key), sol_eval_inner(state, cura->item->value, jmp));
  494. }
  495. ERR_CHECK(state);
  496. cura = cura->next;
  497. }
  498. return res;
  499. break;
  500. case EX_BINOP:
  501. list = sol_new_list(state);
  502. ERR_CHECK(state);
  503. left = sol_eval_inner(state, expr->binop->left, jmp);
  504. ERR_CHECK(state);
  505. right = sol_eval_inner(state, expr->binop->right, jmp);
  506. ERR_CHECK(state);
  507. sol_list_insert(state, list, 0, left);
  508. sol_list_insert(state, list, 1, right);
  509. switch(expr->binop->type) {
  510. case OP_ADD:
  511. res = CALL_METHOD(state, left, add, list);
  512. break;
  513. case OP_SUB:
  514. res = CALL_METHOD(state, left, sub, list);
  515. break;
  516. case OP_MUL:
  517. res = CALL_METHOD(state, left, mul, list);
  518. break;
  519. case OP_DIV:
  520. res = CALL_METHOD(state, left, div, list);
  521. break;
  522. case OP_MOD:
  523. res = CALL_METHOD(state, left, mod, list);
  524. break;
  525. case OP_POW:
  526. res = CALL_METHOD(state, left, pow, list);
  527. break;
  528. case OP_TBANG:
  529. res = CALL_METHOD(state, left, tbang, list);
  530. break;
  531. case OP_BAND:
  532. res = CALL_METHOD(state, left, band, list);
  533. break;
  534. case OP_BOR:
  535. res = CALL_METHOD(state, left, bor, list);
  536. break;
  537. case OP_BXOR:
  538. res = CALL_METHOD(state, left, bxor, list);
  539. break;
  540. case OP_LAND:
  541. lint = sol_cast_int(state, left);
  542. ERR_CHECK(state);
  543. rint = sol_cast_int(state, right);
  544. ERR_CHECK(state);
  545. res = sol_new_int(state, BOOL_TO_INT(lint->ival && rint->ival));
  546. sol_obj_free(lint);
  547. sol_obj_free(rint);
  548. break;
  549. case OP_LOR:
  550. lint = sol_cast_int(state, left);
  551. ERR_CHECK(state);
  552. rint = sol_cast_int(state, right);
  553. ERR_CHECK(state);
  554. res = sol_new_int(state, BOOL_TO_INT(lint->ival || rint->ival));
  555. sol_obj_free(lint);
  556. sol_obj_free(rint);
  557. break;
  558. case OP_EQUAL:
  559. value = CALL_METHOD(state, left, cmp, list);
  560. lint = sol_cast_int(state, value);
  561. res = sol_new_int(state, BOOL_TO_INT(lint->ival == 0));
  562. sol_obj_free(lint);
  563. sol_obj_free(value);
  564. break;
  565. case OP_NEQUAL:
  566. value = CALL_METHOD(state, left, cmp, list);
  567. lint = sol_cast_int(state, value);
  568. res = sol_new_int(state, BOOL_TO_INT(lint->ival != 0));
  569. sol_obj_free(lint);
  570. sol_obj_free(value);
  571. break;
  572. case OP_LESS:
  573. value = CALL_METHOD(state, left, cmp, list);
  574. lint = sol_cast_int(state, value);
  575. res = sol_new_int(state, BOOL_TO_INT(lint->ival < 0));
  576. sol_obj_free(lint);
  577. sol_obj_free(value);
  578. break;
  579. case OP_GREATER:
  580. value = CALL_METHOD(state, left, cmp, list);
  581. lint = sol_cast_int(state, value);
  582. res = sol_new_int(state, BOOL_TO_INT(lint->ival > 0));
  583. sol_obj_free(lint);
  584. sol_obj_free(value);
  585. break;
  586. case OP_LESSEQ:
  587. value = CALL_METHOD(state, left, cmp, list);
  588. lint = sol_cast_int(state, value);
  589. res = sol_new_int(state, BOOL_TO_INT(lint->ival <= 0));
  590. sol_obj_free(lint);
  591. sol_obj_free(value);
  592. break;
  593. case OP_GREATEREQ:
  594. value = CALL_METHOD(state, left, cmp, list);
  595. lint = sol_cast_int(state, value);
  596. res = sol_new_int(state, BOOL_TO_INT(lint->ival >= 0));
  597. sol_obj_free(lint);
  598. sol_obj_free(value);
  599. break;
  600. case OP_LSHIFT:
  601. res = CALL_METHOD(state, left, blsh, list);
  602. break;
  603. case OP_RSHIFT:
  604. res = CALL_METHOD(state, left, brsh, list);
  605. break;
  606. }
  607. sol_obj_free(list);
  608. sol_obj_free(left);
  609. sol_obj_free(right);
  610. ERR_CHECK(state);
  611. return res;
  612. break;
  613. case EX_UNOP:
  614. left = sol_eval_inner(state, expr->unop->expr, jmp);
  615. ERR_CHECK(state);
  616. list = sol_new_list(state);
  617. ERR_CHECK(state);
  618. sol_list_insert(state, list, 0, left);
  619. switch(expr->unop->type) {
  620. case OP_NEG:
  621. right = sol_new_int(state, -1);
  622. sol_list_insert(state, list, 1, right);
  623. res = CALL_METHOD(state, left, mul, list);
  624. sol_obj_free(right);
  625. break;
  626. case OP_BNOT:
  627. res = CALL_METHOD(state, left, bnot, list);
  628. break;
  629. case OP_LNOT:
  630. lint = sol_cast_int(state, left);
  631. ERR_CHECK(state);
  632. res = sol_new_int(state, BOOL_TO_INT(!lint->ival));
  633. sol_obj_free(lint);
  634. break;
  635. case OP_LEN:
  636. res = CALL_METHOD(state, left, len, list);
  637. break;
  638. }
  639. sol_obj_free(left);
  640. sol_obj_free(list);
  641. ERR_CHECK(state);
  642. return res;
  643. break;
  644. case EX_INDEX:
  645. left = sol_eval_inner(state, expr->index->expr, jmp);
  646. ERR_CHECK(state);
  647. right = sol_eval_inner(state, expr->index->index, jmp);
  648. ERR_CHECK(state);
  649. list = sol_new_list(state);
  650. ERR_CHECK(state);
  651. sol_list_insert(state, list, 0, left);
  652. sol_list_insert(state, list, 1, right);
  653. res = CALL_METHOD(state, left, index, list);
  654. sol_obj_free(left);
  655. sol_obj_free(right);
  656. sol_obj_free(list);
  657. ERR_CHECK(state);
  658. return res;
  659. break;
  660. case EX_SETINDEX:
  661. left = sol_eval_inner(state, expr->setindex->expr, jmp);
  662. ERR_CHECK(state);
  663. right = sol_eval_inner(state, expr->setindex->index, jmp);
  664. ERR_CHECK(state);
  665. value = sol_eval_inner(state, expr->setindex->value, jmp);
  666. ERR_CHECK(state);
  667. list = sol_new_list(state);
  668. ERR_CHECK(state);
  669. sol_list_insert(state, list, 0, left);
  670. sol_list_insert(state, list, 1, right);
  671. sol_list_insert(state, list, 2, value);
  672. res = CALL_METHOD(state, left, setindex, list);
  673. sol_obj_free(left);
  674. sol_obj_free(right);
  675. sol_obj_free(res);
  676. sol_obj_free(list);
  677. ERR_CHECK(state);
  678. return value;
  679. break;
  680. case EX_ASSIGN:
  681. value = sol_eval_inner(state, expr->assign->value, jmp);
  682. sol_state_assign_l_name(state, expr->assign->ident, value);
  683. ERR_CHECK(state);
  684. return value;
  685. break;
  686. case EX_REF:
  687. return sol_state_resolve_name(state, expr->ref->ident);
  688. break;
  689. case EX_CALL:
  690. value = sol_eval_inner(state, expr->call->expr, jmp);
  691. ERR_CHECK(state);
  692. list = sol_new_list(state);
  693. ERR_CHECK(state);
  694. if(expr->call->method) {
  695. left = sol_incref(value);
  696. sol_list_insert(state, list, 0, value);
  697. right = sol_new_string(state, expr->call->method);
  698. sol_list_insert(state, list, 1, right);
  699. sol_obj_free(right);
  700. res = CALL_METHOD(state, value, index, list);
  701. sol_obj_free(value);
  702. value = sol_incref(res);
  703. sol_obj_free(res);
  704. ERR_CHECK(state);
  705. sol_obj_free(list);
  706. list = sol_new_list(state);
  707. sol_list_insert(state, list, 0, value);
  708. sol_list_insert(state, list, 1, left);
  709. sol_obj_free(left);
  710. } else {
  711. sol_list_insert(state, list, 0, value);
  712. }
  713. cure = expr->call->args;
  714. while(cure) {
  715. if(cure->expr) {
  716. if(value->ops->tflags & SOL_TF_NO_EVAL_CALL_ARGS) {
  717. sol_list_insert(state, list, sol_list_len(state, list), sol_new_exprnode(state, cure->expr));
  718. } else {
  719. sol_list_insert(state, list, sol_list_len(state, list), sol_eval_inner(state, cure->expr, jmp));
  720. }
  721. }
  722. ERR_CHECK(state);
  723. cure = cure->next;
  724. }
  725. res = CALL_METHOD(state, value, call, list);
  726. sol_obj_free(list);
  727. sol_obj_free(value);
  728. ERR_CHECK(state);
  729. return res;
  730. break;
  731. case EX_FUNCDECL:
  732. res = sol_new_func(state, expr->funcdecl->params ? expr->funcdecl->params->args : NULL, expr->funcdecl->body, expr->funcdecl->name, expr->funcdecl->params, expr->funcdecl->anno, expr->funcdecl->flags);
  733. ERR_CHECK(state);
  734. if(expr->funcdecl->name) {
  735. sol_state_assign_l_name(state, expr->funcdecl->name, res);
  736. ERR_CHECK(state);
  737. }
  738. return res;
  739. break;
  740. case EX_IFELSE:
  741. value = sol_eval_inner(state, expr->ifelse->cond, jmp);
  742. vint = sol_cast_int(state, value);
  743. if(vint->ival) {
  744. if(expr->ifelse->iftrue) {
  745. sol_exec(state, expr->ifelse->iftrue);
  746. }
  747. } else {
  748. if(expr->ifelse->iffalse) {
  749. sol_exec(state, expr->ifelse->iffalse);
  750. }
  751. }
  752. sol_obj_free(value);
  753. sol_obj_free(vint);
  754. return sol_incref(state->lastvalue);
  755. break;
  756. case EX_LOOP:
  757. left = state->loopvalue;
  758. res = sol_new_list(state);
  759. value = sol_eval_inner(state, expr->loop->cond, jmp);
  760. vint = sol_cast_int(state, value);
  761. while(vint->ival) {
  762. sol_obj_free(value);
  763. sol_obj_free(vint);
  764. state->loopvalue = res;
  765. sol_exec(state, expr->loop->loop);
  766. if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) {
  767. value = sol_incref(state->None);
  768. vint = sol_new_int(state, 0);
  769. continue;
  770. }
  771. state->sflag = SF_NORMAL;
  772. value = sol_eval_inner(state, expr->loop->cond, jmp);
  773. vint = sol_cast_int(state, value);
  774. }
  775. state->sflag = SF_NORMAL;
  776. sol_obj_free(value);
  777. sol_obj_free(vint);
  778. res = state->loopvalue;
  779. state->loopvalue = left;
  780. return sol_incref(res);
  781. break;
  782. case EX_ITER:
  783. left = state->loopvalue;
  784. res = sol_new_list(state);
  785. value = sol_eval_inner(state, expr->iter->iter, jmp);
  786. if(value->ops->iter && value->ops->iter != sol_f_not_impl) {
  787. list = sol_new_list(state);
  788. sol_list_insert(state, list, 0, value);
  789. iter = CALL_METHOD(state, value, iter, list);
  790. sol_obj_free(list);
  791. } else {
  792. iter = sol_incref(value);
  793. }
  794. if(!iter->ops->call || iter->ops->call == sol_f_not_impl) {
  795. sol_obj_free(sol_set_error_string(state, "Iterate over non-iterable"));
  796. return sol_incref(state->None);
  797. }
  798. list = sol_new_list(state);
  799. sol_list_insert(state, list, 0, iter);
  800. sol_list_insert(state, list, 1, value);
  801. sol_list_insert(state, list, 2, sol_new_map(state));
  802. item = CALL_METHOD(state, iter, call, list);
  803. while(item != state->None) {
  804. sol_state_assign_l_name(state, expr->iter->var, item);
  805. state->loopvalue = res;
  806. sol_exec(state, expr->iter->loop);
  807. sol_obj_free(item);
  808. if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) {
  809. item = sol_incref(state->None);
  810. continue;
  811. }
  812. state->sflag = SF_NORMAL;
  813. item = CALL_METHOD(state, iter, call, list);
  814. }
  815. if(state->sflag == SF_BREAKING) {
  816. res = state->loopvalue;
  817. }
  818. state->sflag = SF_NORMAL;
  819. sol_obj_free(iter);
  820. sol_obj_free(value);
  821. sol_obj_free(list);
  822. sol_obj_free(item);
  823. state->loopvalue = left;
  824. return sol_incref(res);
  825. break;
  826. }
  827. printf("WARNING: Unhandled expression (type %d) returning None\n", expr->type);
  828. return sol_incref(state->None);
  829. }
  830. sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
  831. jmp_buf jmp;
  832. if(!setjmp(jmp)) {
  833. return sol_eval_inner(state, expr, jmp);
  834. } else {
  835. return sol_incref(state->None);
  836. }
  837. }
  838. void sol_exec(sol_state_t *state, stmt_node *stmt) {
  839. sol_object_t *value = NULL, *vint = NULL, *list, *iter, *item;
  840. stmtlist_node *curs;
  841. exprlist_node *cure;
  842. if(!stmt) {
  843. sol_obj_free(sol_set_error_string(state, "Execute NULL statement"));
  844. return;
  845. }
  846. switch(stmt->type) {
  847. case ST_EXPR:
  848. vint = value;
  849. value = state->lastvalue;
  850. state->lastvalue = sol_eval(state, stmt->expr);
  851. sol_obj_free(vint);
  852. if(sol_has_error(state)) {
  853. sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
  854. }
  855. break;
  856. case ST_LIST:
  857. curs = stmt->stmtlist;
  858. while(curs && state->sflag == SF_NORMAL && !sol_has_error(state) && !state->ret) {
  859. if(curs->stmt) {
  860. sol_exec(state, curs->stmt);
  861. }
  862. curs = curs->next;
  863. }
  864. if(sol_has_error(state)) {
  865. sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
  866. }
  867. break;
  868. case ST_RET:
  869. if(stmt->ret->ret) {
  870. if(stmt->ret->ret->type == EX_CALL) {
  871. value = sol_eval(state, stmt->ret->ret->call->expr);
  872. iter = sol_new_list(state);
  873. if(stmt->ret->ret->call->method) {
  874. list = sol_new_list(state);
  875. sol_list_insert(state, list, 0, value);
  876. item = sol_new_string(state, stmt->ret->ret->call->method);
  877. sol_list_insert(state, list, 1, item);
  878. sol_obj_free(item);
  879. item = CALL_METHOD(state, value, index, list);
  880. sol_obj_free(value);
  881. sol_list_insert(state, iter, 0, value);
  882. value = item;
  883. }
  884. cure = stmt->ret->ret->call->args;
  885. while(cure) {
  886. if(cure->expr) {
  887. if(value->ops->tflags & SOL_TF_NO_EVAL_CALL_ARGS) {
  888. sol_list_insert(state, iter, sol_list_len(state, iter), sol_new_exprnode(state, cure->expr));
  889. } else {
  890. sol_list_insert(state, iter, sol_list_len(state, iter), sol_eval(state, cure->expr));
  891. }
  892. }
  893. cure = cure->next;
  894. }
  895. sol_list_insert(state, iter, 0, value);
  896. vint = sol_list_get_index(state, state->fnstack, 0);
  897. if(vint == value) {
  898. sol_obj_free(vint);
  899. sol_obj_free(value);
  900. state->topargs = iter;
  901. longjmp(state->topfunc, 1);
  902. }
  903. sol_obj_free(vint);
  904. vint = CALL_METHOD(state, value, call, iter);
  905. sol_obj_free(value);
  906. sol_obj_free(iter);
  907. state->ret = vint;
  908. } else {
  909. state->ret = sol_eval(state, stmt->ret->ret);
  910. }
  911. } else {
  912. state->ret = sol_incref(state->None);
  913. }
  914. if(sol_has_error(state)) {
  915. sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
  916. }
  917. break;
  918. case ST_CONT:
  919. if(stmt->cont->val && sol_is_list(state->loopvalue)) {
  920. value = sol_eval(state, stmt->cont->val);
  921. sol_list_insert(state, state->loopvalue, sol_list_len(state, state->loopvalue), value);
  922. sol_obj_free(value);
  923. }
  924. state->sflag = SF_CONTINUING;
  925. break;
  926. case ST_BREAK:
  927. if(stmt->brk->val) {
  928. value = sol_eval(state, stmt->brk->val);
  929. } else {
  930. value = sol_incref(state->None);
  931. }
  932. vint = state->loopvalue;
  933. state->loopvalue = sol_incref(value);
  934. sol_obj_free(vint);
  935. state->sflag = SF_BREAKING;
  936. break;
  937. default:
  938. printf("WARNING: Unhandled statement\n");
  939. break;
  940. }
  941. }
  942. sol_object_t *sol_f_func_call(sol_state_t *state, sol_object_t *args) {
  943. sol_object_t *res, *scope, *value, *key, *tmp;
  944. identlist_node *curi;
  945. dsl_seq_iter *iter;
  946. int argcnt = 0;
  947. char was_jumped = 0;
  948. if(setjmp(state->topfunc)) {
  949. //sol_obj_free(args);
  950. args = state->topargs;
  951. was_jumped = 1;
  952. }
  953. iter = dsl_new_seq_iter(args->seq);
  954. if(!args || dsl_seq_iter_is_invalid(iter) || sol_is_none(state, args)) {
  955. printf("WARNING: No parameters to function call (expecting function)\n");
  956. return sol_incref(state->None);
  957. }
  958. value = dsl_seq_iter_at(iter);
  959. if(!value || !(sol_is_func(value) || sol_is_macro(value))) {
  960. printf("WARNING: Function call without function as first parameter\n");
  961. ob_print(value);
  962. return sol_incref(state->None);
  963. }
  964. if(!value->func) {
  965. return sol_incref(state->None);
  966. }
  967. dsl_seq_iter_next(iter);
  968. scope = sol_map_copy(state, value->closure);
  969. curi = AS(value->args, identlist_node);
  970. while(curi) {
  971. if(curi->ident) {
  972. key = sol_new_string(state, curi->ident);
  973. if(dsl_seq_iter_is_invalid(iter)) {
  974. sol_map_set(state, scope, key, sol_incref(state->None));
  975. } else {
  976. sol_map_set(state, scope, key, dsl_seq_iter_at(iter));
  977. dsl_seq_iter_next(iter);
  978. }
  979. sol_obj_free(key);
  980. curi = curi->next;
  981. argcnt++;
  982. }
  983. }
  984. if(value->rest) {
  985. if(argcnt < sol_list_len(state, args) - 1) {
  986. sol_map_borrow_name(state, scope, value->rest, sol_list_sublist(state, args, argcnt + 1));
  987. } else {
  988. sol_map_borrow_name(state, scope, value->rest, sol_new_list(state));
  989. }
  990. }
  991. if(value->fname) {
  992. key = sol_new_string(state, value->fname);
  993. sol_map_set(state, scope, key, value);
  994. sol_obj_free(key);
  995. }
  996. sol_state_push_scope(state, scope);
  997. sol_list_insert(state, state->fnstack, 0, value);
  998. sol_exec(state, AS(value->func, stmt_node));
  999. key = sol_list_remove(state, state->fnstack, 0);
  1000. if(key != value) {
  1001. printf("ERROR: Function stack imbalanced\n");
  1002. }
  1003. sol_state_pop_scope(state);
  1004. sol_map_merge_existing(state, value->closure, scope);
  1005. if(state->ret) {
  1006. res = state->ret;
  1007. state->ret = NULL;
  1008. } else {
  1009. res = sol_incref(state->None);
  1010. }
  1011. sol_obj_free(scope);
  1012. return res;
  1013. }
  1014. sol_object_t *sol_new_func(sol_state_t *state, identlist_node *identlist, stmt_node *body, char *name, paramlist_node *params, expr_node *func_anno, unsigned short flags) {
  1015. identlist_node *cura;
  1016. exprlist_node *cure;
  1017. sol_object_t *obj = sol_alloc_object(state);
  1018. obj->func = st_copy(body);
  1019. obj->args = idl_copy(identlist);
  1020. obj->fname = (name ? strdup(name) : NULL);
  1021. obj->closure = sol_new_map(state);
  1022. obj->udata = sol_new_map(state);
  1023. obj->rest = NULL;
  1024. obj->annos = sol_new_map(state);
  1025. obj->type = (flags & FUNC_IS_MACRO ? SOL_MACRO : SOL_FUNCTION);
  1026. obj->ops = (flags & FUNC_IS_MACRO ? &(state->MacroOps) : &(state->FuncOps));
  1027. if(params) {
  1028. obj->rest = params->rest ? strdup(params->rest) : NULL;
  1029. cura = params->clkeys;
  1030. cure = params->clvalues;
  1031. while(cura) {
  1032. sol_map_borrow_name(state, obj->closure, cura->ident, sol_eval(state, cure->expr));
  1033. if(sol_has_error(state)) {
  1034. sol_obj_free(obj);
  1035. return sol_incref(state->None);
  1036. }
  1037. cura = cura->next;
  1038. cure = cure->next;
  1039. }
  1040. cura = params->args;
  1041. cure = params->annos;
  1042. while(cura) {
  1043. if(cure->expr) {
  1044. sol_map_borrow_name(state, obj->annos, cura->ident, sol_eval(state, cure->expr));
  1045. }
  1046. cura = cura->next;
  1047. cure = cure->next;
  1048. }
  1049. }
  1050. if(func_anno) {
  1051. sol_map_borrow(state, obj->annos, obj, sol_eval(state, func_anno));
  1052. }
  1053. return obj;
  1054. }
  1055. sol_object_t *sol_f_func_free(sol_state_t *state, sol_object_t *func) {
  1056. st_free((stmt_node *) func->func);
  1057. idl_free((identlist_node *) func->args);
  1058. if(func->fname) free(func->fname);
  1059. sol_obj_free(func->closure);
  1060. sol_obj_free(func->udata);
  1061. return func;
  1062. }
  1063. sol_object_t *sol_new_stmtnode(sol_state_t *state, stmt_node *stmt) {
  1064. sol_object_t *obj = sol_alloc_object(state);
  1065. obj->type = SOL_STMT;
  1066. obj->ops = &(state->ASTNodeOps);
  1067. obj->node = st_copy(stmt);
  1068. return obj;
  1069. }
  1070. sol_object_t *sol_new_exprnode(sol_state_t *state, expr_node *expr) {
  1071. sol_object_t *obj = sol_alloc_object(state);
  1072. obj->type = SOL_EXPR;
  1073. obj->ops = &(state->ASTNodeOps);
  1074. obj->node = ex_copy(expr);
  1075. return obj;
  1076. }