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.

642 lines
14 KiB

  1. #include <string.h>
  2. #include <stdlib.h>
  3. #include "ast.h"
  4. extern int yydebug;
  5. char *sol_BytecodeNames[] = {
  6. "BC_NULL",
  7. "BC_ST_EXPR",
  8. "BC_ST_LIST",
  9. "BC_ST_RET",
  10. "BC_ST_CONT",
  11. "BC_ST_BREAK",
  12. "BC_EX_LIT",
  13. "BC_EX_LISTGEN",
  14. "BC_EX_MAPGEN",
  15. "BC_EX_BINOP",
  16. "BC_EX_UNOP",
  17. "BC_EX_INDEX",
  18. "BC_EX_SETINDEX",
  19. "BC_EX_ASSIGN",
  20. "BC_EX_REF",
  21. "BC_EX_CALL",
  22. "BC_EX_FUNCDECL",
  23. "BC_EX_IFELSE",
  24. "BC_EX_LOOP",
  25. "BC_EX_ITER",
  26. "BC_LIT_INT",
  27. "BC_LIT_FLOAT",
  28. "BC_LIT_STRING",
  29. "BC_LIT_NONE",
  30. "BC_INT",
  31. "BC_FLOAT",
  32. "BC_STRING",
  33. "BC_LIST_ST",
  34. "BC_LIST_EX",
  35. "BC_LIST_AS",
  36. "BC_LIST_ID",
  37. "BC_LIST_PM",
  38. "BC_ENDLIST",
  39. };
  40. void sol_ser_stmt(FILE *io, stmt_node *st) {
  41. if(!st) {
  42. fputc(BC_NULL, io);
  43. return;
  44. }
  45. switch(st->type) {
  46. case ST_EXPR:
  47. fputc(BC_ST_EXPR, io);
  48. sol_ser_expr(io, st->expr);
  49. break;
  50. case ST_LIST:
  51. fputc(BC_ST_LIST, io);
  52. sol_ser_stl(io, st->stmtlist);
  53. break;
  54. case ST_RET:
  55. fputc(BC_ST_RET, io);
  56. sol_ser_expr(io, st->ret->ret);
  57. break;
  58. case ST_CONT:
  59. fputc(BC_ST_CONT, io);
  60. sol_ser_expr(io, st->cont->val);
  61. break;
  62. case ST_BREAK:
  63. fputc(BC_ST_BREAK, io);
  64. sol_ser_expr(io, st->brk->val);
  65. break;
  66. default:
  67. printf("WARNING: Unknown statement type to serialize: %d\n", st->type);
  68. break;
  69. }
  70. }
  71. void sol_ser_stl(FILE *io, stmtlist_node *stl) {
  72. fputc(BC_LIST_ST, io);
  73. while(stl) {
  74. sol_ser_stmt(io, stl->stmt);
  75. stl = stl->next;
  76. }
  77. fputc(BC_ENDLIST, io);
  78. }
  79. void sol_ser_expr(FILE *io, expr_node *ex) {
  80. if(!ex) {
  81. fputc(BC_NULL, io);
  82. return;
  83. }
  84. switch(ex->type) {
  85. case EX_LIT:
  86. fputc(BC_EX_LIT, io);
  87. sol_ser_lit(io, ex->lit);
  88. break;
  89. case EX_LISTGEN:
  90. fputc(BC_EX_LISTGEN, io);
  91. sol_ser_exl(io, ex->listgen->list);
  92. break;
  93. case EX_MAPGEN:
  94. fputc(BC_EX_MAPGEN, io);
  95. sol_ser_asl(io, ex->mapgen->map);
  96. break;
  97. case EX_BINOP:
  98. fputc(BC_EX_BINOP, io);
  99. fputc(ex->binop->type - OP_ADD, io);
  100. sol_ser_expr(io, ex->binop->left);
  101. sol_ser_expr(io, ex->binop->right);
  102. break;
  103. case EX_UNOP:
  104. fputc(BC_EX_UNOP, io);
  105. fputc(ex->unop->type - OP_NEG, io);
  106. sol_ser_expr(io, ex->unop->expr);
  107. break;
  108. case EX_INDEX:
  109. fputc(BC_EX_INDEX, io);
  110. sol_ser_expr(io, ex->index->expr);
  111. sol_ser_expr(io, ex->index->index);
  112. break;
  113. case EX_SETINDEX:
  114. fputc(BC_EX_SETINDEX, io);
  115. sol_ser_expr(io, ex->setindex->expr);
  116. sol_ser_expr(io, ex->setindex->index);
  117. sol_ser_expr(io, ex->setindex->value);
  118. break;
  119. case EX_ASSIGN:
  120. fputc(BC_EX_ASSIGN, io);
  121. sol_ser_str(io, ex->assign->ident);
  122. sol_ser_expr(io, ex->assign->value);
  123. break;
  124. case EX_REF:
  125. fputc(BC_EX_REF, io);
  126. sol_ser_str(io, ex->ref->ident);
  127. break;
  128. case EX_CALL:
  129. fputc(BC_EX_CALL, io);
  130. sol_ser_expr(io, ex->call->expr);
  131. sol_ser_exl(io, ex->call->args);
  132. sol_ser_str(io, ex->call->method);
  133. break;
  134. case EX_FUNCDECL:
  135. fputc(BC_EX_FUNCDECL, io);
  136. sol_ser_str(io, ex->funcdecl->name);
  137. sol_ser_pl(io, ex->funcdecl->params);
  138. sol_ser_expr(io, ex->funcdecl->anno);
  139. sol_ser_stmt(io, ex->funcdecl->body);
  140. break;
  141. case EX_IFELSE:
  142. fputc(BC_EX_IFELSE, io);
  143. sol_ser_expr(io, ex->ifelse->cond);
  144. sol_ser_stmt(io, ex->ifelse->iftrue);
  145. sol_ser_stmt(io, ex->ifelse->iffalse);
  146. break;
  147. case EX_LOOP:
  148. fputc(BC_EX_LOOP, io);
  149. sol_ser_expr(io, ex->loop->cond);
  150. sol_ser_stmt(io, ex->loop->loop);
  151. break;
  152. case EX_ITER:
  153. fputc(BC_EX_ITER, io);
  154. sol_ser_str(io, ex->iter->var);
  155. sol_ser_expr(io, ex->iter->iter);
  156. sol_ser_stmt(io, ex->iter->loop);
  157. break;
  158. default:
  159. printf("WARNING: Unknown expression type to serialize: %d\n", ex->type);
  160. break;
  161. }
  162. }
  163. void sol_ser_exl(FILE *io, exprlist_node *exn) {
  164. fputc(BC_LIST_EX, io);
  165. while(exn) {
  166. sol_ser_expr(io, exn->expr);
  167. exn = exn->next;
  168. }
  169. fputc(BC_ENDLIST, io);
  170. }
  171. void sol_ser_asl(FILE *io, assoclist_node *asl) {
  172. fputc(BC_LIST_AS, io);
  173. while(asl) {
  174. if(asl->item) {
  175. sol_ser_expr(io, asl->item->key);
  176. sol_ser_expr(io, asl->item->value);
  177. }
  178. asl = asl->next;
  179. }
  180. fputc(BC_ENDLIST, io);
  181. }
  182. void sol_ser_idl(FILE *io, identlist_node *idl) {
  183. fputc(BC_LIST_ID, io);
  184. while(idl) {
  185. sol_ser_str(io, idl->ident);
  186. idl = idl->next;
  187. }
  188. fputc(BC_ENDLIST, io);
  189. }
  190. void sol_ser_pl(FILE *io, paramlist_node *pl) {
  191. if(!pl) {
  192. fputc(BC_NULL, io);
  193. return;
  194. }
  195. fputc(BC_LIST_PM, io);
  196. sol_ser_idl(io, pl->args);
  197. sol_ser_exl(io, pl->annos);
  198. sol_ser_idl(io, pl->clkeys);
  199. sol_ser_exl(io, pl->clvalues);
  200. sol_ser_str(io, pl->rest);
  201. fputc(BC_ENDLIST, io);
  202. }
  203. void sol_ser_lit(FILE *io, lit_node *lit) {
  204. if(!lit) {
  205. fputc(BC_NULL, io);
  206. return;
  207. }
  208. switch(lit->type) {
  209. case LIT_INT:
  210. fputc(BC_LIT_INT, io);
  211. sol_ser_int(io, lit->ival);
  212. break;
  213. case LIT_FLOAT:
  214. fputc(BC_LIT_FLOAT, io);
  215. sol_ser_float(io, lit->fval);
  216. break;
  217. case LIT_STRING:
  218. fputc(BC_LIT_STRING, io);
  219. sol_ser_str(io, lit->str);
  220. break;
  221. case LIT_NONE:
  222. fputc(BC_LIT_NONE, io);
  223. break;
  224. default:
  225. printf("WARNING: Unknown literal type to serialize: %d\n", lit->type);
  226. break;
  227. }
  228. }
  229. void sol_ser_str(FILE *io, const char *s) {
  230. size_t len;
  231. if(!s) {
  232. fputc(BC_NULL, io);
  233. return;
  234. }
  235. fputc(BC_STRING, io);
  236. len = strlen(s);
  237. fwrite(&len, sizeof(size_t), 1, io);
  238. fwrite(s, sizeof(char), len, io);
  239. }
  240. void sol_ser_int(FILE *io, long i) {
  241. fputc(BC_INT, io);
  242. fwrite(&i, sizeof(long), 1, io);
  243. }
  244. void sol_ser_float(FILE *io, double f) {
  245. fputc(BC_FLOAT, io);
  246. fwrite(&f, sizeof(double), 1, io);
  247. }
  248. void *sol_deser_checked(FILE *io, bytecode b) {
  249. int c = fgetc(io);
  250. if(c != b && c != BC_NULL) {
  251. printf("WARNING: Deserialization failed; expected %d, got %d\n", b, c);
  252. }
  253. ungetc(c, io);
  254. return sol_deser(io);
  255. }
  256. void *sol_deser_stmt(FILE *io) {
  257. int c = fgetc(io);
  258. switch(c) {
  259. default:
  260. printf("WARNING: Deserialization failed; expected stmt type, got %d\n", c);
  261. break;
  262. case BC_NULL:
  263. case BC_ST_EXPR:
  264. case BC_ST_LIST:
  265. case BC_ST_RET:
  266. case BC_ST_CONT:
  267. case BC_ST_BREAK:
  268. ;
  269. }
  270. ungetc(c, io);
  271. return sol_deser(io);
  272. }
  273. void *sol_deser_expr(FILE *io) {
  274. int c = fgetc(io);
  275. switch(c) {
  276. default:
  277. printf("WARNING: Deserialization failed; expected expr type, got %d\n", c);
  278. break;
  279. case BC_NULL:
  280. case BC_EX_LIT:
  281. case BC_EX_LISTGEN:
  282. case BC_EX_MAPGEN:
  283. case BC_EX_BINOP:
  284. case BC_EX_UNOP:
  285. case BC_EX_INDEX:
  286. case BC_EX_SETINDEX:
  287. case BC_EX_ASSIGN:
  288. case BC_EX_REF:
  289. case BC_EX_CALL:
  290. case BC_EX_FUNCDECL:
  291. case BC_EX_IFELSE:
  292. case BC_EX_LOOP:
  293. case BC_EX_ITER:
  294. ;
  295. }
  296. ungetc(c, io);
  297. return sol_deser(io);
  298. }
  299. void *sol_deser_lit(FILE *io) {
  300. int c = fgetc(io);
  301. switch(c) {
  302. default:
  303. printf("WARNING: Deserialization failed; expected lit type, got %d\n", c);
  304. break;
  305. case BC_NULL:
  306. case BC_LIT_INT:
  307. case BC_LIT_FLOAT:
  308. case BC_LIT_STRING:
  309. case BC_LIT_NONE:
  310. ;
  311. }
  312. ungetc(c, io);
  313. return sol_deser(io);
  314. }
  315. void *sol_deser(FILE *io) {
  316. bytecode b = fgetc(io);
  317. void *obj = NULL, *node = NULL;
  318. if(yydebug) {
  319. fprintf(stderr, "Encountered BC %s", sol_BytecodeNames[b]);
  320. }
  321. switch(b) {
  322. case BC_NULL:
  323. return NULL;
  324. break;
  325. case BC_ST_EXPR:
  326. obj = NEW(stmt_node);
  327. AS_ST(obj)->type = ST_EXPR;
  328. AS_ST(obj)->expr = sol_deser_expr(io);
  329. return obj;
  330. break;
  331. case BC_ST_LIST:
  332. obj = NEW(stmt_node);
  333. AS_ST(obj)->type = ST_LIST;
  334. AS_ST(obj)->stmtlist = sol_deser_checked(io, BC_LIST_ST);
  335. return obj;
  336. case BC_ST_RET:
  337. obj = NEW(stmt_node);
  338. AS_ST(obj)->type = ST_RET;
  339. AS_ST(obj)->ret = NEW(ret_node);
  340. AS_ST(obj)->ret->ret = sol_deser_expr(io);
  341. return obj;
  342. case BC_ST_CONT:
  343. obj = NEW(stmt_node);
  344. AS_ST(obj)->type = ST_CONT;
  345. AS_ST(obj)->cont = NEW(cont_node);
  346. AS_ST(obj)->cont->val = sol_deser_expr(io);
  347. return obj;
  348. case BC_ST_BREAK:
  349. obj = NEW(stmt_node);
  350. AS_ST(obj)->type = ST_BREAK;
  351. AS_ST(obj)->brk = NEW(break_node);
  352. AS_ST(obj)->brk->val = sol_deser_expr(io);
  353. return obj;
  354. case BC_EX_LIT:
  355. obj = NEW(expr_node);
  356. AS_EX(obj)->type = EX_LIT;
  357. AS_EX(obj)->lit = sol_deser_lit(io);
  358. return obj;
  359. case BC_EX_LISTGEN:
  360. obj = NEW(expr_node);
  361. AS_EX(obj)->type = EX_LISTGEN;
  362. AS_EX(obj)->listgen = NEW(listgen_node);
  363. AS_EX(obj)->listgen->list = sol_deser_checked(io, BC_LIST_EX);
  364. return obj;
  365. case BC_EX_MAPGEN:
  366. obj = NEW(expr_node);
  367. AS_EX(obj)->type = EX_MAPGEN;
  368. AS_EX(obj)->mapgen = NEW(mapgen_node);
  369. AS_EX(obj)->mapgen->map = sol_deser_checked(io, BC_LIST_AS);
  370. return obj;
  371. case BC_EX_BINOP:
  372. obj = NEW(expr_node);
  373. AS_EX(obj)->type = EX_BINOP;
  374. AS_EX(obj)->binop = NEW(binop_node);
  375. AS_EX(obj)->binop->type = OP_ADD + fgetc(io);
  376. AS_EX(obj)->binop->left = sol_deser_expr(io);
  377. AS_EX(obj)->binop->right = sol_deser_expr(io);
  378. return obj;
  379. case BC_EX_UNOP:
  380. obj = NEW(expr_node);
  381. AS_EX(obj)->type = EX_UNOP;
  382. AS_EX(obj)->unop = NEW(unop_node);
  383. AS_EX(obj)->unop->type = OP_NEG + fgetc(io);
  384. AS_EX(obj)->unop->expr = sol_deser_expr(io);
  385. return obj;
  386. case BC_EX_INDEX:
  387. obj = NEW(expr_node);
  388. AS_EX(obj)->type = EX_INDEX;
  389. AS_EX(obj)->index = NEW(index_node);
  390. AS_EX(obj)->index->expr = sol_deser_expr(io);
  391. AS_EX(obj)->index->index = sol_deser_expr(io);
  392. return obj;
  393. case BC_EX_SETINDEX:
  394. obj = NEW(expr_node);
  395. AS_EX(obj)->type = EX_SETINDEX;
  396. AS_EX(obj)->setindex = NEW(setindex_node);
  397. AS_EX(obj)->setindex->expr = sol_deser_expr(io);
  398. AS_EX(obj)->setindex->index = sol_deser_expr(io);
  399. AS_EX(obj)->setindex->value = sol_deser_expr(io);
  400. return obj;
  401. case BC_EX_ASSIGN:
  402. obj = NEW(expr_node);
  403. AS_EX(obj)->type = EX_ASSIGN;
  404. AS_EX(obj)->assign = NEW(assign_node);
  405. AS_EX(obj)->assign->ident = sol_deser_checked(io, BC_STRING);
  406. AS_EX(obj)->assign->value = sol_deser_expr(io);
  407. return obj;
  408. case BC_EX_REF:
  409. obj = NEW(expr_node);
  410. AS_EX(obj)->type = EX_REF;
  411. AS_EX(obj)->ref = NEW(ref_node);
  412. AS_EX(obj)->ref->ident = sol_deser_checked(io, BC_STRING);
  413. return obj;
  414. case BC_EX_CALL:
  415. obj = NEW(expr_node);
  416. AS_EX(obj)->type = EX_CALL;
  417. AS_EX(obj)->call = NEW(call_node);
  418. AS_EX(obj)->call->expr = sol_deser_expr(io);
  419. AS_EX(obj)->call->args = sol_deser_checked(io, BC_LIST_EX);
  420. AS_EX(obj)->call->method = sol_deser_checked(io, BC_STRING);
  421. return obj;
  422. case BC_EX_FUNCDECL:
  423. obj = NEW(expr_node);
  424. AS_EX(obj)->type = EX_FUNCDECL;
  425. AS_EX(obj)->funcdecl = NEW(funcdecl_node);
  426. AS_EX(obj)->funcdecl->name = sol_deser_checked(io, BC_STRING);
  427. AS_EX(obj)->funcdecl->params = sol_deser_checked(io, BC_LIST_PM);
  428. AS_EX(obj)->funcdecl->anno = sol_deser_expr(io);
  429. AS_EX(obj)->funcdecl->body = sol_deser_stmt(io);
  430. return obj;
  431. case BC_EX_IFELSE:
  432. obj = NEW(expr_node);
  433. AS_EX(obj)->type = EX_IFELSE;
  434. AS_EX(obj)->ifelse = NEW(ifelse_node);
  435. AS_EX(obj)->ifelse->cond = sol_deser_expr(io);
  436. AS_EX(obj)->ifelse->iftrue = sol_deser_stmt(io);
  437. AS_EX(obj)->ifelse->iffalse = sol_deser_stmt(io);
  438. return obj;
  439. case BC_EX_LOOP:
  440. obj = NEW(expr_node);
  441. AS_EX(obj)->type = EX_LOOP;
  442. AS_EX(obj)->loop = NEW(loop_node);
  443. AS_EX(obj)->loop->cond = sol_deser_expr(io);
  444. AS_EX(obj)->loop->loop = sol_deser_stmt(io);
  445. return obj;
  446. case BC_EX_ITER:
  447. obj = NEW(expr_node);
  448. AS_EX(obj)->type = EX_ITER;
  449. AS_EX(obj)->iter = NEW(iter_node);
  450. AS_EX(obj)->iter->var = sol_deser_checked(io, BC_STRING);
  451. AS_EX(obj)->iter->iter = sol_deser_expr(io);
  452. AS_EX(obj)->iter->loop = sol_deser_stmt(io);
  453. return obj;
  454. case BC_LIT_INT:
  455. obj = NEW(lit_node);
  456. AS(obj, lit_node)->type = LIT_INT;
  457. node = sol_deser_checked(io, BC_INT);
  458. AS(obj, lit_node)->ival = *AS(node, long);
  459. free(node);
  460. return obj;
  461. case BC_LIT_FLOAT:
  462. obj = NEW(lit_node);
  463. AS(obj, lit_node)->type = LIT_FLOAT;
  464. node = sol_deser_checked(io, BC_FLOAT);
  465. AS(obj, lit_node)->fval = *AS(node, double);
  466. free(node);
  467. return obj;
  468. case BC_LIT_STRING:
  469. obj = NEW(lit_node);
  470. AS(obj, lit_node)->type = LIT_STRING;
  471. AS(obj, lit_node)->str = sol_deser_checked(io, BC_STRING);
  472. return obj;
  473. case BC_LIT_NONE:
  474. obj = NEW(lit_node);
  475. AS(obj, lit_node)->type = LIT_NONE;
  476. return obj;
  477. case BC_INT:
  478. obj = NEW(long);
  479. fread(obj, sizeof(long), 1, io);
  480. return obj;
  481. case BC_FLOAT:
  482. obj = NEW(double);
  483. fread(obj, sizeof(double), 1, io);
  484. return obj;
  485. case BC_STRING:
  486. node = NEW(size_t);
  487. fread(node, sizeof(size_t), 1, io);
  488. obj = malloc(*AS(node, size_t) + 1);
  489. fread(obj, sizeof(char), *AS(node, size_t), io);
  490. AS(obj, char)[*AS(node, size_t)] = 0;
  491. free(node);
  492. return obj;
  493. case BC_LIST_ST:
  494. while((b = fgetc(io)) != BC_ENDLIST) {
  495. ungetc(b, io);
  496. if(!node) {
  497. node = NEW(stmtlist_node);
  498. obj = node;
  499. } else {
  500. AS(node, stmtlist_node)->next = NEW(stmtlist_node);
  501. node = AS(node, stmtlist_node)->next;
  502. }
  503. AS(node, stmtlist_node)->stmt = sol_deser_stmt(io);
  504. }
  505. return obj;
  506. case BC_LIST_EX:
  507. while((b = fgetc(io)) != BC_ENDLIST) {
  508. ungetc(b, io);
  509. if(!node) {
  510. node = NEW(exprlist_node);
  511. obj = node;
  512. } else {
  513. AS(node, exprlist_node)->next = NEW(exprlist_node);
  514. node = AS(node, exprlist_node)->next;
  515. }
  516. AS(node, exprlist_node)->expr = sol_deser_expr(io);
  517. }
  518. return obj;
  519. case BC_LIST_AS:
  520. while((b = fgetc(io)) != BC_ENDLIST) {
  521. ungetc(b, io);
  522. if(!node) {
  523. node = NEW(assoclist_node);
  524. obj = node;
  525. } else {
  526. AS(node, assoclist_node)->next = NEW(assoclist_node);
  527. node = AS(node, assoclist_node)->next;
  528. }
  529. AS(node, assoclist_node)->item = NEW(associtem_node);
  530. AS(node, assoclist_node)->item->key = sol_deser_expr(io);
  531. AS(node, assoclist_node)->item->value = sol_deser_expr(io);
  532. }
  533. return obj;
  534. case BC_LIST_ID:
  535. while((b = fgetc(io)) != BC_ENDLIST) {
  536. ungetc(b, io);
  537. if(!node) {
  538. node = NEW(identlist_node);
  539. obj = node;
  540. } else {
  541. AS(node, identlist_node)->next = NEW(identlist_node);
  542. node = AS(node, identlist_node)->next;
  543. }
  544. AS(node, identlist_node)->ident = sol_deser_checked(io, BC_STRING);
  545. }
  546. return obj;
  547. case BC_LIST_PM:
  548. obj = NEW(paramlist_node);
  549. AS(obj, paramlist_node)->args = sol_deser_checked(io, BC_LIST_ID);
  550. AS(obj, paramlist_node)->annos = sol_deser_checked(io, BC_LIST_EX);
  551. AS(obj, paramlist_node)->clkeys = sol_deser_checked(io, BC_LIST_ID);
  552. AS(obj, paramlist_node)->clvalues = sol_deser_checked(io, BC_LIST_EX);
  553. AS(obj, paramlist_node)->rest = sol_deser_checked(io, BC_STRING);
  554. if(fgetc(io) != BC_ENDLIST) {
  555. printf("WARNING: Missed ENDLIST for paramlist_node\n");
  556. }
  557. return obj;
  558. default:
  559. printf("WARNING: Illegal bytecode %d\n", b);
  560. break;
  561. }
  562. return NULL;
  563. }