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.

545 lines
17 KiB

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