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.

709 lines
17 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. void ex_free(expr_node *);
  15. void st_free(stmt_node *stmt) {
  16. stmtlist_node *curs, *prevs;
  17. if(!stmt) {
  18. return;
  19. }
  20. switch(stmt->type) {
  21. case ST_EXPR:
  22. ex_free(stmt->expr);
  23. break;
  24. case ST_IFELSE:
  25. ex_free(stmt->ifelse->cond);
  26. st_free(stmt->ifelse->iftrue);
  27. st_free(stmt->ifelse->iffalse);
  28. free(stmt->ifelse);
  29. break;
  30. case ST_LOOP:
  31. ex_free(stmt->loop->cond);
  32. st_free(stmt->loop->loop);
  33. free(stmt->loop);
  34. break;
  35. case ST_ITER:
  36. free(stmt->iter->var);
  37. ex_free(stmt->iter->iter);
  38. st_free(stmt->iter->loop);
  39. free(stmt->iter);
  40. break;
  41. case ST_LIST:
  42. curs = stmt->stmtlist;
  43. while(curs) {
  44. if(curs->stmt) {
  45. st_free(curs->stmt);
  46. }
  47. prevs = curs;
  48. curs = curs->next;
  49. free(prevs);
  50. }
  51. break;
  52. case ST_RET:
  53. ex_free(stmt->ret->ret);
  54. free(stmt->ret);
  55. break;
  56. case ST_CONT:
  57. case ST_BREAK:
  58. break; // Make the compiler happy :D
  59. }
  60. free(stmt);
  61. }
  62. void ex_free(expr_node *expr) {
  63. exprlist_node *cure, *preve;
  64. assoclist_node *cura, *preva;
  65. identlist_node *curi, *previ;
  66. if(!expr) {
  67. return;
  68. }
  69. switch(expr->type) {
  70. case EX_LIT:
  71. if(expr->lit->type == LIT_STRING) {
  72. free(expr->lit->str);
  73. }
  74. free(expr->lit);
  75. break;
  76. case EX_LISTGEN:
  77. cure = expr->listgen->list;
  78. while(cure) {
  79. if(cure->expr) {
  80. ex_free(cure->expr);
  81. }
  82. preve = cure;
  83. cure = cure->next;
  84. free(preve);
  85. }
  86. free(expr->listgen);
  87. break;
  88. case EX_MAPGEN:
  89. cura = expr->mapgen->map;
  90. while(cura) {
  91. if(cura->item) {
  92. ex_free(cura->item->key);
  93. ex_free(cura->item->value);
  94. free(cura->item);
  95. }
  96. preva = cura;
  97. cura = cura->next;
  98. free(preva);
  99. }
  100. free(expr->mapgen);
  101. break;
  102. case EX_BINOP:
  103. ex_free(expr->binop->left);
  104. ex_free(expr->binop->right);
  105. free(expr->binop);
  106. break;
  107. case EX_UNOP:
  108. ex_free(expr->unop->expr);
  109. free(expr->unop);
  110. break;
  111. case EX_INDEX:
  112. ex_free(expr->index->expr);
  113. ex_free(expr->index->index);
  114. free(expr->index);
  115. break;
  116. case EX_SETINDEX:
  117. ex_free(expr->setindex->expr);
  118. ex_free(expr->setindex->index);
  119. ex_free(expr->setindex->value);
  120. free(expr->setindex);
  121. break;
  122. case EX_ASSIGN:
  123. free(expr->assign->ident);
  124. ex_free(expr->assign->value);
  125. free(expr->assign);
  126. break;
  127. case EX_REF:
  128. free(expr->ref->ident);
  129. free(expr->ref);
  130. break;
  131. case EX_CALL:
  132. ex_free(expr->call->expr);
  133. cure = expr->call->args;
  134. while(cure) {
  135. if(cure->expr) {
  136. ex_free(cure->expr);
  137. }
  138. preve = cure;
  139. cure = cure->next;
  140. free(preve);
  141. }
  142. free(expr->call);
  143. break;
  144. case EX_FUNCDECL:
  145. free(expr->funcdecl->name);
  146. st_free(expr->funcdecl->body);
  147. curi = expr->funcdecl->args;
  148. while(curi) {
  149. if(curi->ident) {
  150. free(curi->ident);
  151. }
  152. previ = curi;
  153. curi = curi->next;
  154. free(previ);
  155. }
  156. free(expr->funcdecl);
  157. break;
  158. }
  159. free(expr);
  160. }
  161. #define ERR_CHECK(state) do { if(sol_has_error(state)) longjmp(jmp, 1); } while(0)
  162. sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
  163. sol_object_t *res, *left, *right, *lint, *rint, *value, *list;
  164. exprlist_node *cure;
  165. assoclist_node *cura;
  166. if(!expr) {
  167. return sol_set_error_string(state, "Evaluate NULL expression");
  168. }
  169. ERR_CHECK(state);
  170. switch(expr->type) {
  171. case EX_LIT:
  172. switch(expr->lit->type) {
  173. case LIT_INT:
  174. return sol_new_int(state, expr->lit->ival);
  175. break;
  176. case LIT_FLOAT:
  177. return sol_new_float(state, expr->lit->fval);
  178. break;
  179. case LIT_STRING:
  180. return sol_new_string(state, expr->lit->str);
  181. break;
  182. case LIT_NONE:
  183. return sol_incref(state->None);
  184. break;
  185. }
  186. break;
  187. case EX_LISTGEN:
  188. res = sol_new_list(state);
  189. cure = expr->listgen->list;
  190. while(cure) {
  191. if(cure->expr) {
  192. sol_list_insert(state, res, sol_list_len(state, res), sol_eval_inner(state, cure->expr, jmp));
  193. }
  194. ERR_CHECK(state);
  195. cure = cure->next;
  196. }
  197. return res;
  198. break;
  199. case EX_MAPGEN:
  200. res = sol_new_map(state);
  201. cura = expr->mapgen->map;
  202. while(cura) {
  203. if(cura->item) {
  204. sol_map_set(state, res, sol_eval(state, cura->item->key), sol_eval_inner(state, cura->item->value, jmp));
  205. }
  206. ERR_CHECK(state);
  207. cura = cura->next;
  208. }
  209. return res;
  210. break;
  211. case EX_BINOP:
  212. list = sol_new_list(state);
  213. ERR_CHECK(state);
  214. left = sol_eval_inner(state, expr->binop->left, jmp);
  215. ERR_CHECK(state);
  216. right = sol_eval_inner(state, expr->binop->right, jmp);
  217. ERR_CHECK(state);
  218. sol_list_insert(state, list, 0, left);
  219. sol_list_insert(state, list, 1, right);
  220. switch(expr->binop->type) {
  221. case OP_ADD:
  222. res = CALL_METHOD(state, left, add, list);
  223. break;
  224. case OP_SUB:
  225. res = CALL_METHOD(state, left, sub, list);
  226. break;
  227. case OP_MUL:
  228. res = CALL_METHOD(state, left, mul, list);
  229. break;
  230. case OP_DIV:
  231. res = CALL_METHOD(state, left, div, list);
  232. break;
  233. case OP_MOD:
  234. res = CALL_METHOD(state, left, mod, list);
  235. break;
  236. case OP_POW:
  237. res = CALL_METHOD(state, left, pow, list);
  238. break;
  239. case OP_BAND:
  240. res = CALL_METHOD(state, left, band, list);
  241. break;
  242. case OP_BOR:
  243. res = CALL_METHOD(state, left, bor, list);
  244. break;
  245. case OP_BXOR:
  246. res = CALL_METHOD(state, left, bxor, list);
  247. break;
  248. case OP_LAND:
  249. lint = sol_cast_int(state, left);
  250. ERR_CHECK(state);
  251. rint = sol_cast_int(state, right);
  252. ERR_CHECK(state);
  253. res = sol_new_int(state, BOOL_TO_INT(lint && rint));
  254. sol_obj_free(lint);
  255. sol_obj_free(rint);
  256. break;
  257. case OP_LOR:
  258. lint = sol_cast_int(state, left);
  259. ERR_CHECK(state);
  260. rint = sol_cast_int(state, right);
  261. ERR_CHECK(state);
  262. res = sol_new_int(state, BOOL_TO_INT(lint || rint));
  263. sol_obj_free(lint);
  264. sol_obj_free(rint);
  265. break;
  266. case OP_EQUAL:
  267. value = CALL_METHOD(state, left, cmp, list);
  268. lint = sol_cast_int(state, value);
  269. res = sol_new_int(state, BOOL_TO_INT(lint->ival == 0));
  270. sol_obj_free(lint);
  271. sol_obj_free(value);
  272. break;
  273. case OP_NEQUAL:
  274. value = CALL_METHOD(state, left, cmp, list);
  275. lint = sol_cast_int(state, value);
  276. res = sol_new_int(state, BOOL_TO_INT(lint->ival != 0));
  277. sol_obj_free(lint);
  278. sol_obj_free(value);
  279. break;
  280. case OP_LESS:
  281. value = CALL_METHOD(state, left, cmp, list);
  282. lint = sol_cast_int(state, value);
  283. res = sol_new_int(state, BOOL_TO_INT(lint->ival < 0));
  284. sol_obj_free(lint);
  285. sol_obj_free(value);
  286. break;
  287. case OP_GREATER:
  288. value = CALL_METHOD(state, left, cmp, list);
  289. lint = sol_cast_int(state, value);
  290. res = sol_new_int(state, BOOL_TO_INT(lint->ival > 0));
  291. sol_obj_free(lint);
  292. sol_obj_free(value);
  293. break;
  294. case OP_LESSEQ:
  295. value = CALL_METHOD(state, left, cmp, list);
  296. lint = sol_cast_int(state, value);
  297. res = sol_new_int(state, BOOL_TO_INT(lint->ival <= 0));
  298. sol_obj_free(lint);
  299. sol_obj_free(value);
  300. break;
  301. case OP_GREATEREQ:
  302. value = CALL_METHOD(state, left, cmp, list);
  303. lint = sol_cast_int(state, value);
  304. res = sol_new_int(state, BOOL_TO_INT(lint->ival >= 0));
  305. sol_obj_free(lint);
  306. sol_obj_free(value);
  307. break;
  308. case OP_LSHIFT:
  309. res = CALL_METHOD(state, left, blsh, list);
  310. break;
  311. case OP_RSHIFT:
  312. res = CALL_METHOD(state, left, brsh, list);
  313. break;
  314. }
  315. sol_obj_free(list);
  316. sol_obj_free(left);
  317. sol_obj_free(right);
  318. ERR_CHECK(state);
  319. return res;
  320. break;
  321. case EX_UNOP:
  322. left = sol_eval_inner(state, expr->unop->expr, jmp);
  323. ERR_CHECK(state);
  324. list = sol_new_list(state);
  325. ERR_CHECK(state);
  326. sol_list_insert(state, list, 0, left);
  327. switch(expr->unop->type) {
  328. case OP_NEG:
  329. right = sol_new_int(state, -1);
  330. sol_list_insert(state, list, 1, right);
  331. res = CALL_METHOD(state, left, mul, list);
  332. sol_obj_free(right);
  333. break;
  334. case OP_BNOT:
  335. res = CALL_METHOD(state, left, bnot, list);
  336. break;
  337. case OP_LNOT:
  338. lint = sol_cast_int(state, left);
  339. ERR_CHECK(state);
  340. res = sol_new_int(state, BOOL_TO_INT(!lint->ival));
  341. sol_obj_free(lint);
  342. break;
  343. case OP_LEN:
  344. res = CALL_METHOD(state, left, len, list);
  345. break;
  346. }
  347. sol_obj_free(left);
  348. sol_obj_free(list);
  349. ERR_CHECK(state);
  350. return res;
  351. break;
  352. case EX_INDEX:
  353. left = sol_eval_inner(state, expr->index->expr, jmp);
  354. ERR_CHECK(state);
  355. right = sol_eval_inner(state, expr->index->index, jmp);
  356. ERR_CHECK(state);
  357. list = sol_new_list(state);
  358. ERR_CHECK(state);
  359. sol_list_insert(state, list, 0, left);
  360. sol_list_insert(state, list, 1, right);
  361. res = CALL_METHOD(state, left, index, list);
  362. sol_obj_free(left);
  363. sol_obj_free(right);
  364. sol_obj_free(list);
  365. ERR_CHECK(state);
  366. return res;
  367. break;
  368. case EX_SETINDEX:
  369. left = sol_eval_inner(state, expr->setindex->expr, jmp);
  370. ERR_CHECK(state);
  371. right = sol_eval_inner(state, expr->setindex->index, jmp);
  372. ERR_CHECK(state);
  373. value = sol_eval_inner(state, expr->setindex->value, jmp);
  374. ERR_CHECK(state);
  375. list = sol_new_list(state);
  376. ERR_CHECK(state);
  377. sol_list_insert(state, list, 0, left);
  378. sol_list_insert(state, list, 1, right);
  379. sol_list_insert(state, list, 2, value);
  380. res = CALL_METHOD(state, left, setindex, list);
  381. sol_obj_free(left);
  382. sol_obj_free(right);
  383. sol_obj_free(value);
  384. sol_obj_free(list);
  385. ERR_CHECK(state);
  386. return res;
  387. break;
  388. case EX_ASSIGN:
  389. value = sol_eval_inner(state, expr->assign->value, jmp);
  390. sol_state_assign_l_name(state, expr->assign->ident, value);
  391. ERR_CHECK(state);
  392. return value;
  393. break;
  394. case EX_REF:
  395. return sol_state_resolve_name(state, expr->ref->ident);
  396. break;
  397. case EX_CALL:
  398. value = sol_eval_inner(state, expr->call->expr, jmp);
  399. ERR_CHECK(state);
  400. list = sol_new_list(state);
  401. ERR_CHECK(state);
  402. sol_list_insert(state, list, 0, value);
  403. cure = expr->call->args;
  404. while(cure) {
  405. if(cure->expr) {
  406. sol_list_insert(state, list, sol_list_len(state, list), sol_eval_inner(state, cure->expr, jmp));
  407. }
  408. ERR_CHECK(state);
  409. cure = cure->next;
  410. }
  411. res = CALL_METHOD(state, value, call, list);
  412. sol_obj_free(value);
  413. sol_obj_free(list);
  414. ERR_CHECK(state);
  415. return res;
  416. break;
  417. case EX_FUNCDECL:
  418. res = sol_new_func(state, expr->funcdecl->args, expr->funcdecl->body, expr->funcdecl->name);
  419. ERR_CHECK(state);
  420. if(expr->funcdecl->name) {
  421. sol_state_assign_l_name(state, expr->funcdecl->name, res);
  422. ERR_CHECK(state);
  423. }
  424. return res;
  425. break;
  426. }
  427. printf("WARNING: Unhandled expression returning None");
  428. return sol_incref(state->None);
  429. }
  430. sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
  431. jmp_buf jmp;
  432. if(!setjmp(jmp)) {
  433. return sol_eval_inner(state, expr, jmp);
  434. } else {
  435. return sol_incref(state->None);
  436. }
  437. }
  438. void sol_exec(sol_state_t *state, stmt_node *stmt) {
  439. sol_object_t *value, *vint, *list, *iter, *item;
  440. stmtlist_node *curs;
  441. if(!stmt) {
  442. sol_obj_free(sol_set_error_string(state, "Execute NULL statement"));
  443. return;
  444. }
  445. switch(stmt->type) {
  446. case ST_EXPR:
  447. sol_obj_free(sol_eval(state, stmt->expr));
  448. if(sol_has_error(state)) {
  449. sol_add_traceback(state, sol_new_stmtnode(state, stmt));
  450. }
  451. break;
  452. case ST_IFELSE:
  453. value = sol_eval(state, stmt->ifelse->cond);
  454. vint = sol_cast_int(state, value);
  455. if(vint->ival) {
  456. if(stmt->ifelse->iftrue) {
  457. sol_exec(state, stmt->ifelse->iftrue);
  458. }
  459. } else {
  460. if(stmt->ifelse->iffalse) {
  461. sol_exec(state, stmt->ifelse->iffalse);
  462. }
  463. }
  464. sol_obj_free(value);
  465. sol_obj_free(vint);
  466. if(sol_has_error(state)) {
  467. sol_add_traceback(state, sol_new_stmtnode(state, stmt));
  468. }
  469. break;
  470. case ST_LOOP:
  471. value = sol_eval(state, stmt->loop->cond);
  472. vint = sol_cast_int(state, value);
  473. while(vint->ival) {
  474. sol_obj_free(value);
  475. sol_obj_free(vint);
  476. sol_exec(state, stmt->loop->loop);
  477. if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) {
  478. value = sol_incref(state->None);
  479. vint = sol_new_int(state, 0);
  480. continue;
  481. }
  482. state->sflag = SF_NORMAL;
  483. value = sol_eval(state, stmt->loop->cond);
  484. vint = sol_cast_int(state, value);
  485. }
  486. state->sflag = SF_NORMAL;
  487. if(sol_has_error(state)) {
  488. sol_add_traceback(state, sol_new_stmtnode(state, stmt));
  489. }
  490. sol_obj_free(value);
  491. sol_obj_free(vint);
  492. break;
  493. case ST_ITER:
  494. value = sol_eval(state, stmt->iter->iter);
  495. if(value->ops->iter && value->ops->iter != sol_f_not_impl) {
  496. list = sol_new_list(state);
  497. sol_list_insert(state, list, 0, value);
  498. iter = CALL_METHOD(state, value, iter, list);
  499. sol_obj_free(list);
  500. } else {
  501. iter = value;
  502. }
  503. if(!iter->ops->call || iter->ops->call == sol_f_not_impl) {
  504. sol_obj_free(sol_set_error_string(state, "Iterate over non-iterable"));
  505. return;
  506. }
  507. list = sol_new_list(state);
  508. sol_list_insert(state, list, 0, iter);
  509. sol_list_insert(state, list, 1, value);
  510. sol_list_insert(state, list, 2, sol_new_map(state));
  511. item = CALL_METHOD(state, iter, call, list);
  512. while(item != state->StopIteration) {
  513. sol_state_assign_l_name(state, stmt->iter->var, item);
  514. sol_exec(state, stmt->iter->loop);
  515. sol_obj_free(item);
  516. if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) {
  517. item = sol_incref(state->StopIteration);
  518. }
  519. state->sflag = SF_NORMAL;
  520. item = CALL_METHOD(state, iter, call, list);
  521. }
  522. state->sflag = SF_NORMAL;
  523. if(sol_has_error(state)) {
  524. sol_add_traceback(state, sol_new_stmtnode(state, stmt));
  525. }
  526. sol_obj_free(iter);
  527. sol_obj_free(value);
  528. sol_obj_free(list);
  529. sol_obj_free(item);
  530. break;
  531. case ST_LIST:
  532. curs = stmt->stmtlist;
  533. while(curs && state->sflag == SF_NORMAL && !sol_has_error(state) && !state->ret) {
  534. if(curs->stmt) {
  535. sol_exec(state, curs->stmt);
  536. }
  537. curs = curs->next;
  538. }
  539. if(sol_has_error(state)) {
  540. sol_add_traceback(state, sol_new_stmtnode(state, stmt));
  541. }
  542. break;
  543. case ST_RET:
  544. if(stmt->ret->ret) {
  545. state->ret = sol_eval(state, stmt->ret->ret);
  546. } else {
  547. state->ret = sol_incref(state->None);
  548. }
  549. if(sol_has_error(state)) {
  550. sol_add_traceback(state, sol_new_stmtnode(state, stmt));
  551. }
  552. break;
  553. case ST_CONT:
  554. state->sflag = SF_CONTINUING;
  555. break;
  556. case ST_BREAK:
  557. state->sflag = SF_BREAKING;
  558. break;
  559. default:
  560. printf("WARNING: Unhandled statement\n");
  561. break;
  562. }
  563. }
  564. sol_object_t *sol_f_func_call(sol_state_t *state, sol_object_t *args) {
  565. sol_object_t *res, *scope, *value, *key;
  566. identlist_node *curi;
  567. dsl_seq_iter *iter;
  568. iter = dsl_new_seq_iter(args->seq);
  569. if(!args || dsl_seq_iter_is_invalid(iter) || sol_is_none(state, args)) {
  570. printf("WARNING: No parameters to function call (expecting function)\n");
  571. return sol_incref(state->None);
  572. }
  573. value = dsl_seq_iter_at(iter);
  574. if(!value || !sol_is_func(value)) {
  575. printf("WARNING: Function call without function as first parameter\n");
  576. return sol_incref(state->None);
  577. }
  578. if(!value->func) {
  579. return sol_incref(state->None);
  580. }
  581. dsl_seq_iter_next(iter);
  582. scope = sol_map_copy(state, value->closure);
  583. curi = AS(value->args, identlist_node);
  584. while(curi) {
  585. if(curi->ident) {
  586. key = sol_new_string(state, curi->ident);
  587. if(dsl_seq_iter_is_invalid(iter)) {
  588. sol_map_set(state, scope, key, sol_incref(state->None));
  589. } else {
  590. sol_map_set(state, scope, key, dsl_seq_iter_at(iter));
  591. dsl_seq_iter_next(iter);
  592. }
  593. sol_obj_free(key);
  594. curi = curi->next;
  595. }
  596. }
  597. if(value->fname) {
  598. key = sol_new_string(state, value->fname);
  599. sol_map_set(state, scope, key, value);
  600. sol_obj_free(key);
  601. }
  602. sol_state_push_scope(state, scope);
  603. sol_exec(state, AS(value->func, stmt_node));
  604. sol_state_pop_scope(state);
  605. sol_map_merge_existing(state, value->closure, scope);
  606. if(state->ret) {
  607. res = state->ret;
  608. state->ret = NULL;
  609. } else {
  610. res = sol_incref(state->None);
  611. }
  612. sol_obj_free(scope);
  613. return res;
  614. }
  615. sol_object_t *sol_new_func(sol_state_t *state, identlist_node *identlist, stmt_node *body, char *name) {
  616. sol_object_t *obj = sol_alloc_object(state);
  617. obj->func = body;
  618. obj->args = identlist;
  619. obj->fname = (name ? strdup(name) : NULL);
  620. obj->closure = sol_new_map(state);
  621. obj->udata = sol_new_map(state);
  622. obj->type = SOL_FUNCTION;
  623. obj->ops = &(state->FuncOps);
  624. return obj;
  625. }
  626. sol_object_t *sol_new_stmtnode(sol_state_t *state, stmt_node *stmt) {
  627. sol_object_t *obj = sol_alloc_object(state);
  628. obj->type = SOL_STMT;
  629. obj->ops = &(state->ASTNodeOps);
  630. obj->node = stmt;
  631. return obj;
  632. }
  633. sol_object_t *sol_new_exprnode(sol_state_t *state, expr_node *expr) {
  634. sol_object_t *obj = sol_alloc_object(state);
  635. obj->type = SOL_EXPR;
  636. obj->ops = &(state->ASTNodeOps);
  637. obj->node = expr;
  638. return obj;
  639. }