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

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