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

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