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.

624 lines
19 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) 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. break;
  397. case ST_IFELSE:
  398. value = sol_eval(state, stmt->ifelse->cond);
  399. vint = sol_cast_int(state, value);
  400. if(vint->ival) {
  401. if(stmt->ifelse->iftrue) sol_exec(state, stmt->ifelse->iftrue);
  402. } else {
  403. if(stmt->ifelse->iffalse) sol_exec(state, stmt->ifelse->iffalse);
  404. }
  405. sol_obj_free(value);
  406. sol_obj_free(vint);
  407. break;
  408. case ST_LOOP:
  409. value = sol_eval(state, stmt->loop->cond);
  410. vint = sol_cast_int(state, value);
  411. while(vint->ival) {
  412. sol_obj_free(value);
  413. sol_obj_free(vint);
  414. sol_exec(state, stmt->loop->loop);
  415. if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) break;
  416. value = sol_eval(state, stmt->loop->cond);
  417. vint = sol_cast_int(state, value);
  418. }
  419. state->sflag = SF_NORMAL;
  420. sol_obj_free(value);
  421. sol_obj_free(vint);
  422. break;
  423. case ST_ITER:
  424. value = sol_eval(state, stmt->iter->iter);
  425. if(value->ops->iter && value->ops->iter != sol_f_not_impl) {
  426. list = sol_new_list(state);
  427. sol_list_insert(state, list, 0, value);
  428. iter = value->ops->iter(state, list);
  429. sol_obj_free(list);
  430. } else {
  431. iter = value;
  432. }
  433. if(!iter->ops->call || iter->ops->call==sol_f_not_impl) {
  434. sol_obj_free(sol_set_error_string(state, "Iterate over non-iterable"));
  435. return;
  436. }
  437. list = sol_new_list(state);
  438. sol_list_insert(state, list, 0, iter);
  439. sol_list_insert(state, list, 1, value);
  440. sol_list_insert(state, list, 2, sol_new_map(state));
  441. item = iter->ops->call(state, list);
  442. while(item != state->StopIteration) {
  443. sol_state_assign_l_name(state, stmt->iter->var, item);
  444. sol_exec(state, stmt->iter->loop);
  445. sol_obj_free(item);
  446. if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) break;
  447. item = iter->ops->call(state, list);
  448. }
  449. state->sflag = SF_NORMAL;
  450. sol_obj_free(list);
  451. sol_obj_free(iter);
  452. sol_obj_free(value);
  453. break;
  454. case ST_LIST:
  455. curs = stmt->stmtlist;
  456. while(curs && state->sflag == SF_NORMAL && !sol_has_error(state) && !state->ret) {
  457. if(curs->stmt) sol_exec(state, curs->stmt);
  458. curs = curs->next;
  459. }
  460. break;
  461. case ST_RET:
  462. if(stmt->ret->ret) {
  463. state->ret = sol_eval(state, stmt->ret->ret);
  464. } else {
  465. state->ret = sol_incref(state->None);
  466. }
  467. break;
  468. case ST_CONT:
  469. state->sflag = SF_CONTINUING;
  470. break;
  471. case ST_BREAK:
  472. state->sflag = SF_BREAKING;
  473. break;
  474. default:
  475. printf("WARNING: Unhandled statement\n");
  476. break;
  477. }
  478. }
  479. sol_object_t *sol_f_func_call(sol_state_t *state, sol_object_t *args) {
  480. sol_object_t *res, *scope, *value, *key;
  481. identlist_node *curi;
  482. dsl_seq_iter *iter;
  483. iter = dsl_new_seq_iter(args->seq);
  484. if(!args || dsl_seq_iter_is_invalid(iter) || sol_is_none(state, args)) {
  485. printf("WARNING: No parameters to function call (expecting function)\n");
  486. return sol_incref(state->None);
  487. }
  488. value = dsl_seq_iter_at(iter);
  489. if(!value || !sol_is_func(value)) {
  490. printf("WARNING: Function call without function as first parameter\n");
  491. return sol_incref(state->None);
  492. }
  493. if(!value->func) return sol_incref(state->None);
  494. dsl_seq_iter_next(iter);
  495. scope = sol_map_copy(state, value->closure);
  496. curi = AS(value->args, identlist_node);
  497. while(curi) {
  498. if(curi->ident) {
  499. key = sol_new_string(state, curi->ident);
  500. if(dsl_seq_iter_is_invalid(iter)) {
  501. sol_map_set(state, scope, key, sol_incref(state->None));
  502. } else {
  503. sol_map_set(state, scope, key, dsl_seq_iter_at(iter));
  504. dsl_seq_iter_next(iter);
  505. }
  506. sol_obj_free(key);
  507. curi = curi->next;
  508. }
  509. }
  510. if(value->fname) {
  511. key = sol_new_string(state, value->fname);
  512. sol_map_set(state, scope, key, value);
  513. sol_obj_free(key);
  514. }
  515. sol_state_push_scope(state, scope);
  516. sol_exec(state, AS(value->func, stmt_node));
  517. sol_state_pop_scope(state);
  518. sol_map_merge_existing(state, value->closure, scope);
  519. if(state->ret) {
  520. res = state->ret;
  521. state->ret = NULL;
  522. } else {
  523. res = sol_incref(state->None);
  524. }
  525. sol_obj_free(scope);
  526. return res;
  527. }
  528. sol_object_t *sol_new_func(sol_state_t *state, identlist_node *identlist, stmt_node *body, char *name) {
  529. sol_object_t *obj = sol_alloc_object(state);
  530. if(sol_has_error(state)) return sol_incref(state->None);
  531. obj->func = body;
  532. obj->args = identlist;
  533. obj->fname = (name?strdup(name):NULL);
  534. obj->closure = sol_new_map(state);
  535. obj->udata = sol_new_map(state);
  536. obj->type = SOL_FUNCTION;
  537. obj->ops = &(state->FuncOps);
  538. return obj;
  539. }
  540. sol_object_t *sol_new_stmtnode(sol_state_t *state, stmt_node *stmt) {
  541. sol_object_t *obj = sol_alloc_object(state);
  542. if(sol_has_error(state)) return sol_incref(state->None);
  543. obj->type = SOL_STMT;
  544. obj->ops = &(state->ASTNodeOps);
  545. obj->node = stmt;
  546. return obj;
  547. }
  548. sol_object_t *sol_new_exprnode(sol_state_t *state, expr_node *expr) {
  549. sol_object_t *obj = sol_alloc_object(state);
  550. if(sol_has_error(state)) return sol_incref(state->None);
  551. obj->type = SOL_EXPR;
  552. obj->ops = &(state->ASTNodeOps);
  553. obj->node = expr;
  554. return obj;
  555. }