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

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