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.

1017 lines
23 KiB

  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_BAND:
  491. res = CALL_METHOD(state, left, band, list);
  492. break;
  493. case OP_BOR:
  494. res = CALL_METHOD(state, left, bor, list);
  495. break;
  496. case OP_BXOR:
  497. res = CALL_METHOD(state, left, bxor, list);
  498. break;
  499. case OP_LAND:
  500. lint = sol_cast_int(state, left);
  501. ERR_CHECK(state);
  502. rint = sol_cast_int(state, right);
  503. ERR_CHECK(state);
  504. res = sol_new_int(state, BOOL_TO_INT(lint && rint));
  505. sol_obj_free(lint);
  506. sol_obj_free(rint);
  507. break;
  508. case OP_LOR:
  509. lint = sol_cast_int(state, left);
  510. ERR_CHECK(state);
  511. rint = sol_cast_int(state, right);
  512. ERR_CHECK(state);
  513. res = sol_new_int(state, BOOL_TO_INT(lint || rint));
  514. sol_obj_free(lint);
  515. sol_obj_free(rint);
  516. break;
  517. case OP_EQUAL:
  518. value = CALL_METHOD(state, left, cmp, list);
  519. lint = sol_cast_int(state, value);
  520. res = sol_new_int(state, BOOL_TO_INT(lint->ival == 0));
  521. sol_obj_free(lint);
  522. sol_obj_free(value);
  523. break;
  524. case OP_NEQUAL:
  525. value = CALL_METHOD(state, left, cmp, list);
  526. lint = sol_cast_int(state, value);
  527. res = sol_new_int(state, BOOL_TO_INT(lint->ival != 0));
  528. sol_obj_free(lint);
  529. sol_obj_free(value);
  530. break;
  531. case OP_LESS:
  532. value = CALL_METHOD(state, left, cmp, list);
  533. lint = sol_cast_int(state, value);
  534. res = sol_new_int(state, BOOL_TO_INT(lint->ival < 0));
  535. sol_obj_free(lint);
  536. sol_obj_free(value);
  537. break;
  538. case OP_GREATER:
  539. value = CALL_METHOD(state, left, cmp, list);
  540. lint = sol_cast_int(state, value);
  541. res = sol_new_int(state, BOOL_TO_INT(lint->ival > 0));
  542. sol_obj_free(lint);
  543. sol_obj_free(value);
  544. break;
  545. case OP_LESSEQ:
  546. value = CALL_METHOD(state, left, cmp, list);
  547. lint = sol_cast_int(state, value);
  548. res = sol_new_int(state, BOOL_TO_INT(lint->ival <= 0));
  549. sol_obj_free(lint);
  550. sol_obj_free(value);
  551. break;
  552. case OP_GREATEREQ:
  553. value = CALL_METHOD(state, left, cmp, list);
  554. lint = sol_cast_int(state, value);
  555. res = sol_new_int(state, BOOL_TO_INT(lint->ival >= 0));
  556. sol_obj_free(lint);
  557. sol_obj_free(value);
  558. break;
  559. case OP_LSHIFT:
  560. res = CALL_METHOD(state, left, blsh, list);
  561. break;
  562. case OP_RSHIFT:
  563. res = CALL_METHOD(state, left, brsh, list);
  564. break;
  565. }
  566. sol_obj_free(list);
  567. sol_obj_free(left);
  568. sol_obj_free(right);
  569. ERR_CHECK(state);
  570. return res;
  571. break;
  572. case EX_UNOP:
  573. left = sol_eval_inner(state, expr->unop->expr, jmp);
  574. ERR_CHECK(state);
  575. list = sol_new_list(state);
  576. ERR_CHECK(state);
  577. sol_list_insert(state, list, 0, left);
  578. switch(expr->unop->type) {
  579. case OP_NEG:
  580. right = sol_new_int(state, -1);
  581. sol_list_insert(state, list, 1, right);
  582. res = CALL_METHOD(state, left, mul, list);
  583. sol_obj_free(right);
  584. break;
  585. case OP_BNOT:
  586. res = CALL_METHOD(state, left, bnot, list);
  587. break;
  588. case OP_LNOT:
  589. lint = sol_cast_int(state, left);
  590. ERR_CHECK(state);
  591. res = sol_new_int(state, BOOL_TO_INT(!lint->ival));
  592. sol_obj_free(lint);
  593. break;
  594. case OP_LEN:
  595. res = CALL_METHOD(state, left, len, list);
  596. break;
  597. }
  598. sol_obj_free(left);
  599. sol_obj_free(list);
  600. ERR_CHECK(state);
  601. return res;
  602. break;
  603. case EX_INDEX:
  604. left = sol_eval_inner(state, expr->index->expr, jmp);
  605. ERR_CHECK(state);
  606. right = sol_eval_inner(state, expr->index->index, jmp);
  607. ERR_CHECK(state);
  608. list = sol_new_list(state);
  609. ERR_CHECK(state);
  610. sol_list_insert(state, list, 0, left);
  611. sol_list_insert(state, list, 1, right);
  612. res = CALL_METHOD(state, left, index, list);
  613. sol_obj_free(left);
  614. sol_obj_free(right);
  615. sol_obj_free(list);
  616. ERR_CHECK(state);
  617. return res;
  618. break;
  619. case EX_SETINDEX:
  620. left = sol_eval_inner(state, expr->setindex->expr, jmp);
  621. ERR_CHECK(state);
  622. right = sol_eval_inner(state, expr->setindex->index, jmp);
  623. ERR_CHECK(state);
  624. value = sol_eval_inner(state, expr->setindex->value, jmp);
  625. ERR_CHECK(state);
  626. list = sol_new_list(state);
  627. ERR_CHECK(state);
  628. sol_list_insert(state, list, 0, left);
  629. sol_list_insert(state, list, 1, right);
  630. sol_list_insert(state, list, 2, value);
  631. res = CALL_METHOD(state, left, setindex, list);
  632. sol_obj_free(left);
  633. sol_obj_free(right);
  634. sol_obj_free(value);
  635. sol_obj_free(list);
  636. ERR_CHECK(state);
  637. return res;
  638. break;
  639. case EX_ASSIGN:
  640. value = sol_eval_inner(state, expr->assign->value, jmp);
  641. sol_state_assign_l_name(state, expr->assign->ident, value);
  642. ERR_CHECK(state);
  643. return value;
  644. break;
  645. case EX_REF:
  646. return sol_state_resolve_name(state, expr->ref->ident);
  647. break;
  648. case EX_CALL:
  649. value = sol_eval_inner(state, expr->call->expr, jmp);
  650. ERR_CHECK(state);
  651. list = sol_new_list(state);
  652. ERR_CHECK(state);
  653. sol_list_insert(state, list, 0, value);
  654. cure = expr->call->args;
  655. while(cure) {
  656. if(cure->expr) {
  657. sol_list_insert(state, list, sol_list_len(state, list), sol_eval_inner(state, cure->expr, jmp));
  658. }
  659. ERR_CHECK(state);
  660. cure = cure->next;
  661. }
  662. res = CALL_METHOD(state, value, call, list);
  663. sol_obj_free(value);
  664. sol_obj_free(list);
  665. ERR_CHECK(state);
  666. return res;
  667. break;
  668. case EX_FUNCDECL:
  669. res = sol_new_func(state, expr->funcdecl->args, expr->funcdecl->body, expr->funcdecl->name);
  670. ERR_CHECK(state);
  671. if(expr->funcdecl->name) {
  672. sol_state_assign_l_name(state, expr->funcdecl->name, res);
  673. ERR_CHECK(state);
  674. }
  675. return res;
  676. break;
  677. case EX_IFELSE:
  678. value = sol_eval(state, expr->ifelse->cond);
  679. vint = sol_cast_int(state, value);
  680. if(vint->ival) {
  681. if(expr->ifelse->iftrue) {
  682. sol_exec(state, expr->ifelse->iftrue);
  683. }
  684. } else {
  685. if(expr->ifelse->iffalse) {
  686. sol_exec(state, expr->ifelse->iffalse);
  687. }
  688. }
  689. sol_obj_free(value);
  690. sol_obj_free(vint);
  691. return sol_incref(state->lastvalue);
  692. break;
  693. case EX_LOOP:
  694. sol_obj_free(state->loopvalue);
  695. state->loopvalue = sol_new_list(state);
  696. value = sol_eval(state, expr->loop->cond);
  697. vint = sol_cast_int(state, value);
  698. while(vint->ival) {
  699. sol_obj_free(value);
  700. sol_obj_free(vint);
  701. sol_exec(state, expr->loop->loop);
  702. if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) {
  703. value = sol_incref(state->None);
  704. vint = sol_new_int(state, 0);
  705. continue;
  706. }
  707. state->sflag = SF_NORMAL;
  708. value = sol_eval(state, expr->loop->cond);
  709. vint = sol_cast_int(state, value);
  710. }
  711. state->sflag = SF_NORMAL;
  712. sol_obj_free(value);
  713. sol_obj_free(vint);
  714. return sol_incref(state->loopvalue);
  715. break;
  716. case EX_ITER:
  717. sol_obj_free(state->loopvalue);
  718. state->loopvalue = sol_new_list(state);
  719. value = sol_eval(state, expr->iter->iter);
  720. if(value->ops->iter && value->ops->iter != sol_f_not_impl) {
  721. list = sol_new_list(state);
  722. sol_list_insert(state, list, 0, value);
  723. iter = CALL_METHOD(state, value, iter, list);
  724. sol_obj_free(list);
  725. } else {
  726. iter = value;
  727. }
  728. if(!iter->ops->call || iter->ops->call == sol_f_not_impl) {
  729. sol_obj_free(sol_set_error_string(state, "Iterate over non-iterable"));
  730. return sol_incref(state->None);
  731. }
  732. list = sol_new_list(state);
  733. sol_list_insert(state, list, 0, iter);
  734. sol_list_insert(state, list, 1, value);
  735. sol_list_insert(state, list, 2, sol_new_map(state));
  736. item = CALL_METHOD(state, iter, call, list);
  737. while(item != state->StopIteration) {
  738. sol_state_assign_l_name(state, expr->iter->var, item);
  739. sol_exec(state, expr->iter->loop);
  740. sol_obj_free(item);
  741. if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) {
  742. item = sol_incref(state->StopIteration);
  743. }
  744. state->sflag = SF_NORMAL;
  745. item = CALL_METHOD(state, iter, call, list);
  746. }
  747. state->sflag = SF_NORMAL;
  748. sol_obj_free(iter);
  749. sol_obj_free(value);
  750. sol_obj_free(list);
  751. sol_obj_free(item);
  752. return sol_incref(state->loopvalue);
  753. break;
  754. }
  755. printf("WARNING: Unhandled expression (type %d) returning None\n", expr->type);
  756. return sol_incref(state->None);
  757. }
  758. sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
  759. jmp_buf jmp;
  760. if(!setjmp(jmp)) {
  761. return sol_eval_inner(state, expr, jmp);
  762. } else {
  763. return sol_incref(state->None);
  764. }
  765. }
  766. void sol_exec(sol_state_t *state, stmt_node *stmt) {
  767. sol_object_t *value, *vint, *list, *iter, *item;
  768. stmtlist_node *curs;
  769. if(!stmt) {
  770. sol_obj_free(sol_set_error_string(state, "Execute NULL statement"));
  771. return;
  772. }
  773. switch(stmt->type) {
  774. case ST_EXPR:
  775. value = state->lastvalue;
  776. state->lastvalue = sol_eval(state, stmt->expr);
  777. sol_obj_free(value);
  778. if(sol_has_error(state)) {
  779. sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
  780. }
  781. break;
  782. case ST_LIST:
  783. curs = stmt->stmtlist;
  784. while(curs && state->sflag == SF_NORMAL && !sol_has_error(state) && !state->ret) {
  785. if(curs->stmt) {
  786. sol_exec(state, curs->stmt);
  787. }
  788. curs = curs->next;
  789. }
  790. if(sol_has_error(state)) {
  791. sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
  792. }
  793. break;
  794. case ST_RET:
  795. if(stmt->ret->ret) {
  796. state->ret = sol_eval(state, stmt->ret->ret);
  797. } else {
  798. state->ret = sol_incref(state->None);
  799. }
  800. if(sol_has_error(state)) {
  801. sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
  802. }
  803. break;
  804. case ST_CONT:
  805. if(stmt->cont->val && sol_is_list(state->loopvalue)) {
  806. value = sol_eval(state, stmt->cont->val);
  807. sol_list_insert(state, state->loopvalue, sol_list_len(state, state->loopvalue), value);
  808. sol_obj_free(value);
  809. }
  810. state->sflag = SF_CONTINUING;
  811. break;
  812. case ST_BREAK:
  813. if(stmt->brk->val) {
  814. value = sol_eval(state, stmt->brk->val);
  815. } else {
  816. value = sol_incref(state->None);
  817. }
  818. vint = state->loopvalue;
  819. state->loopvalue = sol_incref(value);
  820. sol_obj_free(vint);
  821. state->sflag = SF_BREAKING;
  822. break;
  823. default:
  824. printf("WARNING: Unhandled statement\n");
  825. break;
  826. }
  827. }
  828. sol_object_t *sol_f_func_call(sol_state_t *state, sol_object_t *args) {
  829. sol_object_t *res, *scope, *value, *key;
  830. identlist_node *curi;
  831. dsl_seq_iter *iter;
  832. iter = dsl_new_seq_iter(args->seq);
  833. if(!args || dsl_seq_iter_is_invalid(iter) || sol_is_none(state, args)) {
  834. printf("WARNING: No parameters to function call (expecting function)\n");
  835. return sol_incref(state->None);
  836. }
  837. value = dsl_seq_iter_at(iter);
  838. if(!value || !sol_is_func(value)) {
  839. printf("WARNING: Function call without function as first parameter\n");
  840. return sol_incref(state->None);
  841. }
  842. if(!value->func) {
  843. return sol_incref(state->None);
  844. }
  845. dsl_seq_iter_next(iter);
  846. scope = sol_map_copy(state, value->closure);
  847. curi = AS(value->args, identlist_node);
  848. while(curi) {
  849. if(curi->ident) {
  850. key = sol_new_string(state, curi->ident);
  851. if(dsl_seq_iter_is_invalid(iter)) {
  852. sol_map_set(state, scope, key, sol_incref(state->None));
  853. } else {
  854. sol_map_set(state, scope, key, dsl_seq_iter_at(iter));
  855. dsl_seq_iter_next(iter);
  856. }
  857. sol_obj_free(key);
  858. curi = curi->next;
  859. }
  860. }
  861. if(value->fname) {
  862. key = sol_new_string(state, value->fname);
  863. sol_map_set(state, scope, key, value);
  864. sol_obj_free(key);
  865. }
  866. sol_state_push_scope(state, scope);
  867. sol_exec(state, AS(value->func, stmt_node));
  868. sol_state_pop_scope(state);
  869. sol_map_merge_existing(state, value->closure, scope);
  870. if(state->ret) {
  871. res = state->ret;
  872. state->ret = NULL;
  873. } else {
  874. res = sol_incref(state->None);
  875. }
  876. sol_obj_free(scope);
  877. return res;
  878. }
  879. sol_object_t *sol_new_func(sol_state_t *state, identlist_node *identlist, stmt_node *body, char *name) {
  880. sol_object_t *obj = sol_alloc_object(state);
  881. obj->func = st_copy(body);
  882. obj->args = idl_copy(identlist);
  883. obj->fname = (name ? strdup(name) : NULL);
  884. obj->closure = sol_new_map(state);
  885. obj->udata = sol_new_map(state);
  886. obj->type = SOL_FUNCTION;
  887. obj->ops = &(state->FuncOps);
  888. return obj;
  889. }
  890. sol_object_t *sol_f_func_free(sol_state_t *state, sol_object_t *func) {
  891. st_free((stmt_node *) func->func);
  892. idl_free((identlist_node *) func->args);
  893. if(func->fname) free(func->fname);
  894. sol_obj_free(func->closure);
  895. sol_obj_free(func->udata);
  896. return func;
  897. }
  898. sol_object_t *sol_new_stmtnode(sol_state_t *state, stmt_node *stmt) {
  899. sol_object_t *obj = sol_alloc_object(state);
  900. obj->type = SOL_STMT;
  901. obj->ops = &(state->ASTNodeOps);
  902. obj->node = st_copy(stmt);
  903. return obj;
  904. }
  905. sol_object_t *sol_new_exprnode(sol_state_t *state, expr_node *expr) {
  906. sol_object_t *obj = sol_alloc_object(state);
  907. obj->type = SOL_EXPR;
  908. obj->ops = &(state->ASTNodeOps);
  909. obj->node = ex_copy(expr);
  910. return obj;
  911. }