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 26KB

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