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.

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