PageRenderTime 47ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/ellc.c

http://github.com/manuel/ell
C | 1830 lines | 1527 code | 201 blank | 102 comment | 239 complexity | 167fbd4c44282f590b3d01cc3980e7ce MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /***** Executable and Linkable Lisp Compiler *****/
  2. //////////////////////////////////////////////////////////////////
  3. // //
  4. // _| _| _|_| _| _| _| //
  5. // _|_|_| _|_|_| _| _| _|_|_| _|_|_|_| //
  6. // _| _| _| _| _| _|_|_|_| _| _| _| _| //
  7. // _| _| _| _| _| _| _| _| _| _| //
  8. // _| _| _|_|_| _| _| _|_|_| _| _|_| //
  9. // //
  10. // //
  11. //////////////////////////////////////////////////////////////////
  12. #include <stdio.h>
  13. #include <dlfcn.h>
  14. #include "ellc.h"
  15. struct ell_obj *
  16. ellc_eval(struct ell_obj *stx_lst);
  17. /**** AST Utilities ****/
  18. static struct ellc_id *
  19. ellc_make_id_cx(struct ell_obj *sym, enum ellc_ns ns, struct ell_cx *cx)
  20. {
  21. ell_assert_wrapper(sym, ELL_WRAPPER(sym));
  22. struct ellc_id *id = (struct ellc_id *) ell_alloc(sizeof(*id));
  23. id->sym = sym;
  24. id->ns = ns;
  25. id->cx = cx;
  26. return id;
  27. }
  28. static struct ellc_id *
  29. ellc_make_id(struct ell_obj *sym, enum ellc_ns ns)
  30. {
  31. return ellc_make_id_cx(sym, ns, NULL);
  32. }
  33. static bool
  34. ellc_id_equal(struct ellc_id *a, struct ellc_id *b)
  35. {
  36. return (a->sym == b->sym) && (a->ns == b->ns) && (ell_cx_equal(a->cx, b->cx));
  37. }
  38. static int
  39. ellc_id_cmp(struct ellc_id *a, struct ellc_id *b)
  40. {
  41. int sym_cmp = ell_sym_cmp(a->sym, b->sym);
  42. if (sym_cmp != 0) {
  43. return sym_cmp;
  44. } else {
  45. int ns_cmp = a->ns - b->ns;
  46. if (ns_cmp != 0) {
  47. return ns_cmp;
  48. } else {
  49. return ell_cx_cmp(a->cx, b->cx);
  50. }
  51. }
  52. }
  53. static struct ellc_ast_seq *
  54. ellc_make_ast_seq()
  55. {
  56. struct ellc_ast_seq *ast_seq = ell_alloc(sizeof(*ast_seq));
  57. ast_seq->exprs = ell_util_make_list();
  58. return ast_seq;
  59. }
  60. static void
  61. ellc_ast_seq_add(struct ellc_ast_seq *ast_seq, struct ellc_ast *expr)
  62. {
  63. ell_util_list_add(ast_seq->exprs, expr);
  64. }
  65. static struct ellc_ast *
  66. ellc_make_ast(enum ellc_ast_type type)
  67. {
  68. struct ellc_ast *ast = (struct ellc_ast *) ell_alloc(sizeof(*ast));
  69. ast->type = type;
  70. return ast;
  71. }
  72. static int
  73. ellc_param_boxed(struct ellc_param *p)
  74. {
  75. return (p->closed && p->mutable);
  76. }
  77. /**** Lexical Contour Utilities ****/
  78. static struct ellc_param *
  79. ellc_params_list_lookup(list_t *list, struct ellc_id *id)
  80. {
  81. for (lnode_t *n = list_first(list); n; n = list_next(list, n)) {
  82. struct ellc_param *p = (struct ellc_param *) lnode_get(n);
  83. if (ellc_id_equal(p->id, id))
  84. return p;
  85. }
  86. return NULL;
  87. }
  88. static struct ellc_param *
  89. ellc_params_lookup(struct ellc_params *params, struct ellc_id *id)
  90. {
  91. struct ellc_param *p;
  92. if ((p = ellc_params_list_lookup(params->req, id))) return p;
  93. if ((p = ellc_params_list_lookup(params->opt, id))) return p;
  94. if ((p = ellc_params_list_lookup(params->key, id))) return p;
  95. if (params->rest && ellc_id_equal(params->rest->id, id)) return params->rest;
  96. if (params->all_keys && ellc_id_equal(params->all_keys->id, id)) return params->all_keys;
  97. return NULL;
  98. }
  99. // Returns the contour containing a parameter with the given ID,
  100. // from the contour C upwards, or NULL if there is no countour
  101. // containing that parameter. If found, sets OUT to the parameter.
  102. static struct ellc_contour *
  103. ellc_contour_lookup(struct ellc_contour *c, struct ellc_id *id, struct ellc_param **out)
  104. {
  105. if (!c) return NULL;
  106. struct ellc_param *p = ellc_params_lookup(c->lam->params, id);
  107. if (p) {
  108. if (out) *out = p;
  109. return c;
  110. } else {
  111. return ellc_contour_lookup(c->up, id, out);
  112. }
  113. }
  114. /**** Normalization: Syntax Objects -> AST ****/
  115. /* Table of normalization functions. */
  116. static dict_t ellc_norm_tab; // sym -> norm_fun
  117. static struct ellc_ast *
  118. ellc_norm_stx(struct ellc_st *st, struct ell_obj *stx);
  119. typedef struct ellc_ast *
  120. (ellc_norm_fun)(struct ellc_st *st, struct ell_obj *stx_lst);
  121. /* (Simple Forms) */
  122. static struct ellc_ast *
  123. ellc_make_ref(struct ellc_st *st, struct ell_obj *stx_sym, enum ellc_ns ns)
  124. {
  125. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_REF);
  126. ast->ref.id = ellc_make_id_cx(ell_stx_sym_sym(stx_sym), ns, ell_stx_sym_cx(stx_sym));
  127. return ast;
  128. }
  129. static struct ellc_ast *
  130. ellc_norm_ref(struct ellc_st *st, struct ell_obj *stx_sym)
  131. {
  132. return ellc_make_ref(st, stx_sym, ELLC_NS_VAR);
  133. }
  134. static struct ellc_ast *
  135. ellc_norm_fref(struct ellc_st *st, struct ell_obj *stx_lst)
  136. {
  137. ell_assert_stx_lst_len(stx_lst, 2);
  138. struct ell_obj *stx_sym = ELL_SEND(stx_lst, second);
  139. return ellc_make_ref(st, stx_sym, ELLC_NS_FUN);
  140. }
  141. static struct ellc_ast *
  142. ellc_make_def(struct ellc_st *st, struct ell_obj *stx_lst, enum ellc_ns ns)
  143. {
  144. ell_assert_stx_lst_len(stx_lst, 3);
  145. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_DEF);
  146. struct ell_obj *stx_sym = ELL_SEND(stx_lst, second);
  147. ast->def.id = ellc_make_id_cx(ell_stx_sym_sym(stx_sym), ns, ell_stx_sym_cx(stx_sym));
  148. ast->def.val = ellc_norm_stx(st, ELL_SEND(stx_lst, third));
  149. ell_util_set_add(st->defined_globals, ast->def.id, (dict_comp_t) &ellc_id_cmp);
  150. return ast;
  151. }
  152. static struct ellc_ast *
  153. ellc_norm_def(struct ellc_st *st, struct ell_obj *stx_lst)
  154. {
  155. return ellc_make_def(st, stx_lst, ELLC_NS_VAR);
  156. }
  157. static struct ellc_ast *
  158. ellc_norm_fdef(struct ellc_st *st, struct ell_obj *stx_lst)
  159. {
  160. return ellc_make_def(st, stx_lst, ELLC_NS_FUN);
  161. }
  162. static struct ellc_ast *
  163. ellc_make_defp(struct ellc_st *st, struct ell_obj *stx_lst, enum ellc_ns ns)
  164. {
  165. ell_assert_stx_lst_len(stx_lst, 2);
  166. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_DEFP);
  167. struct ell_obj *stx_sym = ELL_SEND(stx_lst, second);
  168. ast->defp.id = ellc_make_id_cx(ell_stx_sym_sym(stx_sym), ns, ell_stx_sym_cx(stx_sym));
  169. return ast;
  170. }
  171. static struct ellc_ast *
  172. ellc_norm_defp(struct ellc_st *st, struct ell_obj *stx_lst)
  173. {
  174. return ellc_make_defp(st, stx_lst, ELLC_NS_VAR);
  175. }
  176. static struct ellc_ast *
  177. ellc_norm_fdefp(struct ellc_st *st, struct ell_obj *stx_lst)
  178. {
  179. return ellc_make_defp(st, stx_lst, ELLC_NS_FUN);
  180. }
  181. static struct ellc_ast *
  182. ellc_make_set(struct ellc_st *st, struct ell_obj *stx_lst, enum ellc_ns ns)
  183. {
  184. ell_assert_stx_lst_len(stx_lst, 3);
  185. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_SET);
  186. struct ell_obj *stx_sym = ELL_SEND(stx_lst, second);
  187. ast->set.id = ellc_make_id_cx(ell_stx_sym_sym(stx_sym), ns, ell_stx_sym_cx(stx_sym));
  188. ast->set.val = ellc_norm_stx(st, ELL_SEND(stx_lst, third));
  189. return ast;
  190. }
  191. static struct ellc_ast *
  192. ellc_norm_set(struct ellc_st *st, struct ell_obj *stx_lst)
  193. {
  194. return ellc_make_set(st, stx_lst, ELLC_NS_VAR);
  195. }
  196. static struct ellc_ast *
  197. ellc_norm_fset(struct ellc_st *st, struct ell_obj *stx_lst)
  198. {
  199. return ellc_make_set(st, stx_lst, ELLC_NS_FUN);
  200. }
  201. static struct ellc_ast *
  202. ellc_norm_cond(struct ellc_st *st, struct ell_obj *stx_lst)
  203. {
  204. ell_assert_stx_lst_len(stx_lst, 4);
  205. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_COND);
  206. ast->cond.test = ellc_norm_stx(st, ELL_SEND(stx_lst, second));
  207. ast->cond.consequent = ellc_norm_stx(st, ELL_SEND(stx_lst, third));
  208. ast->cond.alternative = ellc_norm_stx(st, ELL_SEND(stx_lst, fourth));
  209. return ast;
  210. }
  211. static struct ellc_ast *
  212. ellc_norm_seq(struct ellc_st *st, struct ell_obj *stx_lst)
  213. {
  214. ell_assert_stx_lst_len_min(stx_lst, 1);
  215. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_SEQ);
  216. ast->seq.exprs = ell_util_make_list();
  217. list_t *elts_stx = ell_util_sublist(ell_stx_lst_elts(stx_lst), 1);
  218. for (lnode_t *n = list_first(elts_stx); n; n = list_next(elts_stx, n)) {
  219. struct ell_obj *stx = (struct ell_obj *) lnode_get(n);
  220. ellc_ast_seq_add(&ast->seq, ellc_norm_stx(st, stx));
  221. }
  222. return ast;
  223. }
  224. /* (Application and Arguments Dissection) */
  225. static bool
  226. ellc_is_key_arg_sym(struct ell_obj *sym)
  227. {
  228. struct ell_obj *name_str = ell_sym_name(sym);
  229. size_t len = ell_str_len(name_str);
  230. return (len > 1) && (ell_str_char_at(name_str, len - 1) == ':');
  231. }
  232. static struct ell_obj *
  233. ellc_clean_key_arg_sym(struct ell_obj *sym)
  234. {
  235. ell_assert_wrapper(sym, ELL_WRAPPER(sym));
  236. struct ell_obj *name_str = ell_sym_name(sym);
  237. return ell_intern(ell_str_poplast(name_str));
  238. }
  239. static struct ellc_args *
  240. ellc_make_args()
  241. {
  242. struct ellc_args *args = (struct ellc_args *) ell_alloc(sizeof(*args));
  243. list_init(&args->pos, LISTCOUNT_T_MAX);
  244. dict_init(&args->key, DICTCOUNT_T_MAX, (dict_comp_t) &ell_sym_cmp);
  245. return args;
  246. }
  247. static struct ellc_args *
  248. ellc_dissect_args(struct ellc_st *st, list_t *args_stx)
  249. {
  250. struct ellc_args *args = ellc_make_args();
  251. for (lnode_t *n = list_first(args_stx); n; n = list_next(args_stx, n)) {
  252. struct ell_obj *arg_stx = lnode_get(n);
  253. if ((arg_stx->wrapper == ELL_WRAPPER(stx_sym)) &&
  254. ellc_is_key_arg_sym(ell_stx_sym_sym(arg_stx)))
  255. {
  256. n = list_next(args_stx, n);
  257. if (!n) {
  258. ell_fail("missing value for keyword argument\n");
  259. }
  260. struct ell_obj *key_arg_sym =
  261. ellc_clean_key_arg_sym(ell_stx_sym_sym(arg_stx));
  262. struct ellc_ast *key_arg_val_ast =
  263. ellc_norm_stx(st, (struct ell_obj *) lnode_get(n));
  264. ell_util_dict_put(&args->key, key_arg_sym, key_arg_val_ast);
  265. } else {
  266. ell_util_list_add(&args->pos, ellc_norm_stx(st, arg_stx));
  267. }
  268. }
  269. return args;
  270. }
  271. static struct ellc_ast *
  272. ellc_make_app(struct ellc_st *st, struct ellc_ast *op, list_t *arg_stx_list)
  273. {
  274. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_APP);
  275. ast->app.op = op;
  276. ast->app.args = ellc_dissect_args(st, arg_stx_list);
  277. return ast;
  278. }
  279. static struct ellc_ast *
  280. ellc_norm_app(struct ellc_st *st, struct ell_obj *stx_lst)
  281. {
  282. ell_assert_stx_lst_len_min(stx_lst, 2);
  283. return ellc_make_app(st, ellc_norm_stx(st, ELL_SEND(stx_lst, second)),
  284. ell_util_sublist(ell_stx_lst_elts(stx_lst), 2));
  285. }
  286. /* Takes a syntax list containing operator symbol and arguments and
  287. normalizes it to an application AST, with a reference to the
  288. operator function. */
  289. static struct ellc_ast *
  290. ellc_norm_ordinary_app(struct ellc_st *st, struct ell_obj *stx_lst)
  291. {
  292. ell_assert_stx_lst_len_min(stx_lst, 1);
  293. struct ell_obj *op_sym_stx = ELL_SEND(stx_lst, first);
  294. ell_assert_wrapper(op_sym_stx, ELL_WRAPPER(stx_sym));
  295. struct ellc_ast *op_ast = ellc_make_ast(ELLC_AST_REF);
  296. op_ast->ref.id = ellc_make_id_cx(ell_stx_sym_sym(op_sym_stx), ELLC_NS_FUN,
  297. ell_stx_sym_cx(op_sym_stx));
  298. return ellc_make_app(st, op_ast,
  299. ell_util_sublist(ell_stx_lst_elts(stx_lst), 1));
  300. }
  301. /* (Lambda and Parameters Dissection) */
  302. static struct ellc_param *
  303. ellc_dissect_param(struct ellc_st *st, struct ell_obj *p_stx, dict_t *deferred_inits)
  304. {
  305. struct ellc_param *p = (struct ellc_param *) ell_alloc(sizeof(*p));
  306. if (p_stx->wrapper == ELL_WRAPPER(stx_sym)) {
  307. p->id = ellc_make_id_cx(ell_stx_sym_sym(p_stx), ELLC_NS_VAR,
  308. ell_stx_sym_cx(p_stx));
  309. } else if (p_stx->wrapper == ELL_WRAPPER(stx_lst)) {
  310. ell_assert_stx_lst_len(p_stx, 2);
  311. struct ell_obj *name_stx = ELL_SEND(p_stx, first);
  312. struct ell_obj *init_stx = ELL_SEND(p_stx, second);
  313. p->id = ellc_make_id_cx(ell_stx_sym_sym(name_stx), ELLC_NS_VAR,
  314. ell_stx_sym_cx(name_stx));
  315. ell_util_dict_put(deferred_inits, p, init_stx);
  316. }
  317. return p;
  318. }
  319. static struct ellc_params *
  320. ellc_dissect_params(struct ellc_st *st, list_t *params_stx, dict_t *deferred_inits)
  321. {
  322. struct ellc_params *params =
  323. (struct ellc_params *) ell_alloc(sizeof(*params));
  324. list_t *req = ell_util_make_list();
  325. list_t *opt = ell_util_make_list();
  326. list_t *key = ell_util_make_list();
  327. list_t *rest = ell_util_make_list();
  328. list_t *all_keys = ell_util_make_list();
  329. list_t *cur = req;
  330. for (lnode_t *n = list_first(params_stx); n; n = list_next(params_stx, n)) {
  331. struct ell_obj *p_stx = lnode_get(n);
  332. if (p_stx->wrapper == ELL_WRAPPER(stx_sym)) {
  333. struct ell_obj *p_sym = ell_stx_sym_sym(p_stx);
  334. if (p_sym == ELL_SYM(param_optional)) {
  335. cur = opt;
  336. continue;
  337. } else if (p_sym == ELL_SYM(param_key)) {
  338. cur = key;
  339. continue;
  340. } else if (p_sym == ELL_SYM(param_rest)) {
  341. cur = rest;
  342. continue;
  343. } else if (p_sym == ELL_SYM(param_all_keys)) {
  344. cur = all_keys;
  345. continue;
  346. }
  347. }
  348. ell_util_list_add(cur, ellc_dissect_param(st, p_stx, deferred_inits));
  349. }
  350. if ((list_count(rest) > 1) || (list_count(all_keys) > 1)) {
  351. ell_fail("more than one rest or all-keys parameter\n");
  352. }
  353. params->req = req;
  354. params->opt = opt;
  355. params->key = key;
  356. if (list_count(rest) == 1)
  357. params->rest = lnode_get(list_first(rest));
  358. if (list_count(all_keys) == 1)
  359. params->all_keys = lnode_get(list_first(all_keys));
  360. return params;
  361. }
  362. static struct ellc_ast *
  363. ellc_norm_lam(struct ellc_st *st, struct ell_obj *stx_lst)
  364. {
  365. ell_assert_stx_lst_len(stx_lst, 3);
  366. struct ell_obj *params_stx = ELL_SEND(stx_lst, second);
  367. ell_assert_wrapper(params_stx, ELL_WRAPPER(stx_lst));
  368. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_LAM);
  369. struct ellc_contour *c = (struct ellc_contour *) ell_alloc(sizeof(*c));
  370. c->lam = &ast->lam;
  371. c->up = st->bottom_contour;
  372. st->bottom_contour = c;
  373. /* We have to defer normalization of parameter init forms until
  374. after all parameters have been seen, and have been added to the
  375. current lambda, so that local variable references work correctly. */
  376. dict_t *deferred_inits = ell_util_make_dict((dict_comp_t) &ell_ptr_cmp); // param -> init_stx
  377. ast->lam.params = ellc_dissect_params(st, ell_stx_lst_elts(params_stx), deferred_inits);
  378. for (dnode_t *dn = dict_first(deferred_inits); dn; dn = dict_next(deferred_inits, dn)) {
  379. struct ellc_param *param = (struct ellc_param *) dnode_getkey(dn);
  380. struct ell_obj *init_stx = (struct ell_obj *) dnode_get(dn);
  381. param->init = ellc_norm_stx(st, init_stx);
  382. }
  383. ast->lam.body = ellc_norm_stx(st, ELL_SEND(stx_lst, third));
  384. ast->lam.env = ell_util_make_dict((dict_comp_t) &ellc_id_cmp); // unused during norm.
  385. st->bottom_contour = c->up;
  386. return ast;
  387. }
  388. static struct ellc_ast *
  389. ellc_quote(struct ellc_st *st, struct ell_obj *stx_sym)
  390. {
  391. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_LIT_SYM);
  392. ast->lit_sym.sym = stx_sym;
  393. return ast;
  394. }
  395. static struct ellc_ast *
  396. ellc_norm_quote(struct ellc_st *st, struct ell_obj *stx_lst)
  397. {
  398. ell_assert_stx_lst_len(stx_lst, 2);
  399. return ellc_quote(st, ell_stx_sym_sym(ELL_SEND(stx_lst, second)));
  400. }
  401. static struct ellc_ast *
  402. ellc_norm_loop(struct ellc_st *st, struct ell_obj *stx_lst)
  403. {
  404. ell_assert_stx_lst_len(stx_lst, 2);
  405. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_LOOP);
  406. ast->loop.body = ellc_norm_stx(st, ELL_SEND(stx_lst, second));
  407. return ast;
  408. }
  409. /* (Quasisyntax) */
  410. static struct ellc_ast *
  411. ellc_norm_qs(struct ellc_st *st, struct ell_obj *arg_stx, unsigned depth);
  412. static struct ellc_ast *
  413. ellc_build_syntax(struct ellc_st *st, struct ell_obj *stx)
  414. {
  415. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_LIT_STX);
  416. if (!((stx->wrapper == ELL_WRAPPER(stx_sym))
  417. || (stx->wrapper == ELL_WRAPPER(stx_str)))) {
  418. ell_fail("can't build syntax AST from non-syntax object\n");
  419. }
  420. ast->lit_stx.stx = stx;
  421. return ast;
  422. }
  423. static struct ellc_ast *
  424. ellc_build_syntax_list(struct ellc_st *st, list_t *asts)
  425. {
  426. struct ellc_args *args = ellc_make_args();
  427. list_transfer(&args->pos, asts, list_first(asts));
  428. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_APP);
  429. ast->app.op = ellc_make_ref(st, ell_make_stx_sym(ELL_SYM(core_syntax_list)), ELLC_NS_FUN);
  430. ast->app.args = args;
  431. return ast;
  432. }
  433. static struct ellc_ast *
  434. ellc_build_append_syntax_lists(struct ellc_st *st, list_t *asts)
  435. {
  436. struct ellc_args *args = ellc_make_args();
  437. list_transfer(&args->pos, asts, list_first(asts));
  438. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_APP);
  439. ast->app.op = ellc_make_ref(st, ell_make_stx_sym(ELL_SYM(core_append_syntax_lists)), ELLC_NS_FUN);
  440. ast->app.args = args;
  441. return ast;
  442. }
  443. static struct ellc_ast *
  444. ellc_build_quasisyntax(struct ellc_st *st, struct ell_obj *stx, unsigned depth)
  445. {
  446. list_t *asts = ell_util_make_list();
  447. ell_util_list_add(asts, ellc_build_syntax(st, ell_make_stx_sym(ELL_SYM(core_quasisyntax))));
  448. ell_util_list_add(asts, ellc_norm_qs(st, stx, depth));
  449. return ellc_build_syntax_list(st, asts);
  450. }
  451. static struct ellc_ast *
  452. ellc_build_unsyntax(struct ellc_st *st, struct ell_obj *stx, unsigned depth)
  453. {
  454. list_t *asts = ell_util_make_list();
  455. ell_util_list_add(asts, ellc_build_syntax(st, ell_make_stx_sym(ELL_SYM(core_unsyntax))));
  456. ell_util_list_add(asts, ellc_norm_qs(st, stx, depth));
  457. return ellc_build_syntax_list(st, asts);
  458. }
  459. static struct ellc_ast *
  460. ellc_build_unsyntax_splicing(struct ellc_st *st, struct ell_obj *stx, unsigned depth)
  461. {
  462. list_t *asts = ell_util_make_list();
  463. ell_util_list_add(asts, ellc_build_syntax(st, ell_make_stx_sym(ELL_SYM(core_unsyntax_splicing))));
  464. ell_util_list_add(asts, ellc_norm_qs(st, stx, depth));
  465. return ellc_build_syntax_list(st, asts);
  466. }
  467. static bool
  468. ellc_is_unsyntax_splicing_list(struct ellc_st *st, struct ell_obj *stx)
  469. {
  470. if (stx->wrapper != ELL_WRAPPER(stx_lst)) return 0;
  471. if (ell_stx_lst_len(stx) != 2) return 0;
  472. struct ell_obj *op_stx = ELL_SEND(stx, first);
  473. return ((op_stx->wrapper == ELL_WRAPPER(stx_sym))
  474. && (ell_stx_sym_sym(op_stx) == ELL_SYM(core_unsyntax_splicing)));
  475. }
  476. static bool
  477. ellc_is_unsyntax(struct ellc_st *st, struct ell_obj *op_stx)
  478. {
  479. return ((op_stx->wrapper == ELL_WRAPPER(stx_sym))
  480. && (ell_stx_sym_sym(op_stx) == ELL_SYM(core_unsyntax)));
  481. }
  482. static bool
  483. ellc_is_quasisyntax(struct ellc_st *st, struct ell_obj *op_stx)
  484. {
  485. return ((op_stx->wrapper == ELL_WRAPPER(stx_sym))
  486. && (ell_stx_sym_sym(op_stx) == ELL_SYM(core_quasisyntax)));
  487. }
  488. /* Unfortunately, this code is very hard to understand. If you want
  489. to make sense of it, first understand Alan Bawden's implementation
  490. in appendix B of his paper "Quasiquotation in Lisp". Ha. */
  491. static struct ellc_ast *
  492. ellc_norm_qs_lst_helper(struct ellc_st *st, struct ell_obj *stx_lst, unsigned depth)
  493. {
  494. list_t *in_elts = ell_stx_lst_elts(stx_lst);
  495. list_t *lsts = ell_util_make_list();
  496. list_t *cur_elts = ell_util_make_list();
  497. for (lnode_t *n = list_first(in_elts); n; n = list_next(in_elts, n)) {
  498. struct ell_obj *sub = (struct ell_obj *) lnode_get(n);
  499. if (ellc_is_unsyntax_splicing_list(st, sub)) {
  500. if (list_count(cur_elts) > 0) {
  501. ell_util_list_add(lsts, ellc_build_syntax_list(st, cur_elts));
  502. cur_elts = ell_util_make_list();
  503. }
  504. if (depth == 0) {
  505. ell_util_list_add(lsts, ellc_norm_stx(st, ELL_SEND(sub, second)));
  506. } else {
  507. ell_util_list_add(lsts, ellc_build_unsyntax_splicing(st, ELL_SEND(sub, second), depth - 1));
  508. }
  509. } else {
  510. ell_util_list_add(cur_elts, ellc_norm_qs(st, sub, depth));
  511. }
  512. }
  513. if (list_count(cur_elts) > 0)
  514. ell_util_list_add(lsts, ellc_build_syntax_list(st, cur_elts));
  515. return ellc_build_append_syntax_lists(st, lsts);
  516. }
  517. static struct ellc_ast *
  518. ellc_norm_qs_lst(struct ellc_st *st, struct ell_obj *stx_lst, unsigned depth)
  519. {
  520. if (ell_stx_lst_len(stx_lst) == 0) {
  521. return ellc_build_syntax_list(st, ell_stx_lst_elts(stx_lst));
  522. } else {
  523. struct ell_obj *op_stx = ELL_SEND(stx_lst, first);
  524. if (ellc_is_unsyntax(st, op_stx)) {
  525. ell_assert_stx_lst_len(stx_lst, 2);
  526. struct ell_obj *arg_stx = ELL_SEND(stx_lst, second);
  527. if (depth == 0) {
  528. return ellc_norm_stx(st, arg_stx);
  529. } else {
  530. return ellc_build_unsyntax(st, arg_stx, depth - 1);
  531. }
  532. } else if (ellc_is_quasisyntax(st, op_stx)) {
  533. ell_assert_stx_lst_len(stx_lst, 2);
  534. struct ell_obj *arg_stx = ELL_SEND(stx_lst, second);
  535. return ellc_build_quasisyntax(st, arg_stx, depth + 1);
  536. } else {
  537. return ellc_norm_qs_lst_helper(st, stx_lst, depth);
  538. }
  539. }
  540. }
  541. static struct ellc_ast *
  542. ellc_norm_qs(struct ellc_st *st, struct ell_obj *arg_stx, unsigned depth)
  543. {
  544. if (depth < 0) {
  545. ell_fail("negative quasiquotation depth\n");
  546. }
  547. if ((arg_stx->wrapper == ELL_WRAPPER(stx_str)) ||
  548. (arg_stx->wrapper == ELL_WRAPPER(stx_sym))) {
  549. return ellc_build_syntax(st, arg_stx);
  550. } else if (arg_stx->wrapper == ELL_WRAPPER(stx_lst)) {
  551. return ellc_norm_qs_lst(st, arg_stx, depth);
  552. } else {
  553. ell_fail("bad quasiquoted syntax object\n");
  554. }
  555. }
  556. static struct ellc_ast *
  557. ellc_norm_quasisyntax(struct ellc_st *st, struct ell_obj *stx_lst)
  558. {
  559. ell_assert_stx_lst_len(stx_lst, 2);
  560. struct ell_obj *arg_stx = ELL_SEND(stx_lst, second);
  561. struct ellc_ast *body = ellc_norm_qs(st, arg_stx, 0);
  562. struct ellc_ast *cx_ast = ellc_make_ast(ELLC_AST_CX);
  563. cx_ast->cx.body = body;
  564. return cx_ast;
  565. }
  566. /* (Macroexpansion) */
  567. static bool
  568. ellc_is_seq(struct ell_obj *stx)
  569. {
  570. if (stx->wrapper != ELL_WRAPPER(stx_lst)) return 0;
  571. if (list_count(ell_stx_lst_elts(stx)) < 2) return 0; // todo: handle better
  572. struct ell_obj *op_stx = ELL_SEND(stx, first);
  573. return ((op_stx->wrapper == ELL_WRAPPER(stx_sym))
  574. && (ell_stx_sym_sym(op_stx) == ELL_SYM(core_seq)));
  575. }
  576. static bool
  577. ellc_is_mdef(struct ell_obj *stx)
  578. {
  579. if (stx->wrapper != ELL_WRAPPER(stx_lst)) return 0;
  580. if (list_count(ell_stx_lst_elts(stx)) != 3) return 0; // todo: handle better
  581. struct ell_obj *op_stx = ELL_SEND(stx, first);
  582. return ((op_stx->wrapper == ELL_WRAPPER(stx_sym))
  583. && (ell_stx_sym_sym(op_stx) == ELL_SYM(core_mdef)));
  584. }
  585. static struct ellc_ast *
  586. ellc_norm_mdef(struct ellc_st *st, struct ell_obj *mdef_stx)
  587. {
  588. ell_assert_stx_lst_len(mdef_stx, 3);
  589. struct ell_obj *name_stx = ELL_SEND(mdef_stx, second);
  590. ell_assert_wrapper(name_stx, ELL_WRAPPER(stx_sym));
  591. struct ell_obj *expander_stx = ELL_SEND(mdef_stx, third);
  592. ell_util_dict_put(st->defined_macros, ell_stx_sym_sym(name_stx), expander_stx);
  593. // Right now, eval requires a syntax list as input, so we need to
  594. // wrap the expander expression in one.
  595. struct ell_obj *stx_lst = ell_make_stx_lst();
  596. ELL_SEND(stx_lst, add, expander_stx);
  597. ell_util_dict_put(&ellc_mac_tab, ell_stx_sym_sym(name_stx), ellc_eval(stx_lst));
  598. return NULL; // runtime noop
  599. }
  600. /* (Inline C) */
  601. static struct ellc_ast *
  602. ellc_norm_snip(struct ellc_st *st, struct ell_obj *stx_lst)
  603. {
  604. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_SNIP);
  605. ast->snip.body = ellc_norm_seq(st, stx_lst);
  606. return ast;
  607. }
  608. static struct ellc_ast *
  609. ellc_norm_stmt(struct ellc_st *st, struct ell_obj *stx_lst)
  610. {
  611. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_STMT);
  612. ast->stmt.body = ellc_norm_seq(st, stx_lst);
  613. return ast;
  614. }
  615. /* (Putting it All Together) */
  616. // This belongs somewhere else
  617. /* (compiler-put-expander symbol function) -> unspecified */
  618. struct ell_obj *__ell_g_compilerDputDexpander_2_;
  619. struct ell_obj *
  620. ellc_compiler_put_expander_code(struct ell_obj *clo, ell_arg_ct npos,
  621. ell_arg_ct nkey, struct ell_obj **args)
  622. {
  623. ell_check_npos(npos, 2);
  624. struct ell_obj *symbol = args[0];
  625. struct ell_obj *function = args[1];
  626. ell_assert_wrapper(symbol, ELL_WRAPPER(sym));
  627. ell_assert_wrapper(function, ELL_WRAPPER(clo));
  628. ell_util_dict_put(&ellc_mac_tab, symbol, function);
  629. }
  630. __attribute__((constructor(300))) static void
  631. ellc_init()
  632. {
  633. // Constant table of normalization functions
  634. dict_init(&ellc_norm_tab, DICTCOUNT_T_MAX, (dict_comp_t) &ell_sym_cmp);
  635. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_fref), &ellc_norm_fref);
  636. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_def), &ellc_norm_def);
  637. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_fdef), &ellc_norm_fdef);
  638. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_defp), &ellc_norm_defp);
  639. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_fdefp), &ellc_norm_fdefp);
  640. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_set), &ellc_norm_set);
  641. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_fset), &ellc_norm_fset);
  642. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_cond), &ellc_norm_cond);
  643. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_seq), &ellc_norm_seq);
  644. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_app), &ellc_norm_app);
  645. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_lam), &ellc_norm_lam);
  646. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_loop), &ellc_norm_loop);
  647. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_quote), &ellc_norm_quote);
  648. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_quasisyntax), &ellc_norm_quasisyntax);
  649. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_syntax), &ellc_norm_quasisyntax);
  650. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_mdef), &ellc_norm_mdef);
  651. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_snip), &ellc_norm_snip);
  652. ell_util_dict_put(&ellc_norm_tab, ELL_SYM(core_stmt), &ellc_norm_stmt);
  653. // Compiler state
  654. dict_init(&ellc_mac_tab, DICTCOUNT_T_MAX, (dict_comp_t) &ell_sym_cmp);
  655. __ell_g_compilerDputDexpander_2_ =
  656. ell_make_clo(&ellc_compiler_put_expander_code, NULL);
  657. }
  658. static struct ellc_ast *
  659. ellc_norm_lst(struct ellc_st *st, struct ell_obj *stx_lst)
  660. {
  661. ell_assert_wrapper(stx_lst, ELL_WRAPPER(stx_lst));
  662. struct ell_obj *op_stx = ELL_SEND(stx_lst, first);
  663. ell_assert_wrapper(op_stx, ELL_WRAPPER(stx_sym));
  664. struct ell_obj *op_sym = ell_stx_sym_sym(op_stx);
  665. struct ell_cx *cx = ell_stx_sym_cx(op_stx);
  666. struct ellc_id *id = ellc_make_id_cx(op_sym, ELLC_NS_FUN, cx);
  667. if (ellc_contour_lookup(st->bottom_contour, id, NULL)) {
  668. // operator is lexically fbound
  669. return ellc_norm_ordinary_app(st, stx_lst);
  670. } else {
  671. dnode_t *exp_node = dict_lookup(&ellc_mac_tab, op_sym);
  672. if (exp_node) {
  673. // operator is a macro
  674. struct ell_obj *expander = (struct ell_obj *) dnode_get(exp_node);
  675. struct ell_obj *expansion_stx = ELL_CALL(expander, stx_lst);
  676. return ellc_norm_stx(st, expansion_stx);
  677. } else {
  678. dnode_t *norm_node = dict_lookup(&ellc_norm_tab, op_sym);
  679. if (norm_node) {
  680. // operator is a special form
  681. ellc_norm_fun *norm_fun = (ellc_norm_fun *) dnode_get(norm_node);
  682. return norm_fun(st, stx_lst);
  683. } else {
  684. // operator is assumed to be global function
  685. return ellc_norm_ordinary_app(st, stx_lst);
  686. }
  687. }
  688. }
  689. }
  690. static struct ellc_ast *
  691. ellc_norm_lit_str(struct ellc_st *st, struct ell_obj *stx)
  692. {
  693. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_LIT_STR);
  694. ast->lit_str.str = ell_stx_str_str(stx);
  695. return ast;
  696. }
  697. static struct ellc_ast *
  698. ellc_norm_lit_num(struct ellc_st *st, struct ell_obj *stx)
  699. {
  700. struct ellc_ast *ast = ellc_make_ast(ELLC_AST_LIT_NUM);
  701. ast->lit_num.num = ell_stx_num_num(stx);
  702. return ast;
  703. }
  704. /* Main normalization function. Takes syntax object as input, and
  705. returns AST. Special handling for classic Lisp evaluation rules:
  706. symbols evaluate to the variables they name; lists evaluate to
  707. function calls, special forms (taken from `ellc_norm_tab'), or
  708. macro calls (taken from `ellc_mac_tab'); literals evaluate to
  709. themselves. */
  710. static struct ellc_ast *
  711. ellc_norm_stx(struct ellc_st *st, struct ell_obj *stx)
  712. {
  713. if (stx->wrapper == ELL_WRAPPER(stx_sym)) {
  714. return ellc_norm_ref(st, stx);
  715. } else if (stx->wrapper == ELL_WRAPPER(stx_lst)) {
  716. return ellc_norm_lst(st, stx);
  717. } else if (stx->wrapper == ELL_WRAPPER(stx_str)) {
  718. return ellc_norm_lit_str(st, stx);
  719. } else if (stx->wrapper == ELL_WRAPPER(stx_num)) {
  720. return ellc_norm_lit_num(st, stx);
  721. } else {
  722. ell_fail("syntax normalization failure\n");
  723. }
  724. }
  725. static list_t *
  726. ellc_norm_macro_pass(struct ellc_st *st, list_t *stx_elts, list_t *deferred)
  727. {
  728. for (lnode_t *n = list_first(stx_elts); n; n = list_next(stx_elts, n)) {
  729. struct ell_obj *stx = (struct ell_obj *) lnode_get(n);
  730. if (ellc_is_seq(stx)) {
  731. ellc_norm_macro_pass(st, ell_util_sublist(ell_stx_lst_elts(stx), 1), deferred);
  732. } else if (ellc_is_mdef(stx)) {
  733. ellc_norm_mdef(st, stx);
  734. } else {
  735. ell_util_list_add(deferred, stx);
  736. }
  737. }
  738. }
  739. static struct ellc_ast_seq *
  740. ellc_norm(struct ellc_st *st, struct ell_obj *stx_lst)
  741. {
  742. ell_assert_wrapper(stx_lst, ELL_WRAPPER(stx_lst));
  743. list_t *deferred = ell_util_make_list();
  744. ellc_norm_macro_pass(st, ell_stx_lst_elts(stx_lst), deferred);
  745. struct ellc_ast_seq *ast_seq = ellc_make_ast_seq();
  746. for (lnode_t *n = list_first(deferred); n; n = list_next(deferred, n)) {
  747. struct ell_obj *stx = (struct ell_obj *) lnode_get(n);
  748. struct ellc_ast *res = ellc_norm_stx(st, stx);
  749. if (res) // no-ops return NULL
  750. ellc_ast_seq_add(ast_seq, res);
  751. }
  752. return ast_seq;
  753. }
  754. /**** Closure Conversion ****/
  755. static void
  756. ellc_conv_ast(struct ellc_st *st, struct ellc_ast *ast);
  757. static bool
  758. ellc_defined_at_toplevel(struct ellc_st *st, struct ellc_id *id)
  759. {
  760. return ell_util_list_contains(st->defined_globals, id, (dict_comp_t) &ellc_id_cmp);
  761. }
  762. static void
  763. ellc_env_add_ref(struct ellc_ast_lam *lam, struct ellc_id *id)
  764. {
  765. if (!dict_lookup(lam->env, id)) {
  766. struct ellc_ast *ref = ellc_make_ast(ELLC_AST_REF);
  767. ref->ref.id = id;
  768. ell_util_dict_put(lam->env, id, ref);
  769. }
  770. }
  771. static void
  772. ellc_conv_ref(struct ellc_st *st, struct ellc_ast *ast)
  773. {
  774. struct ellc_param *p = NULL;
  775. struct ellc_contour *c = ellc_contour_lookup(st->bottom_contour, ast->ref.id, &p);
  776. if (!c) {
  777. /* The identifier isn't lexically bound. Now, we still need
  778. to check whether it's defined at the top-level in the
  779. current unit, before we follow the rule that all variables
  780. are considered implicitly bound at the top-level. For such
  781. implicitly bound variables we need to ignore the hygiene
  782. context. */
  783. if (!ellc_defined_at_toplevel(st, ast->ref.id)) {
  784. ast->ref.id->cx = NULL;
  785. }
  786. struct ellc_id *tmp_id = ast->ref.id;
  787. ast->type = ELLC_AST_GLO_REF;
  788. ast->glo_ref.id = tmp_id;
  789. ell_util_set_add(st->globals, tmp_id, (dict_comp_t) &ellc_id_cmp);
  790. } else if (c == st->bottom_contour) {
  791. ast->type = ELLC_AST_ARG_REF;
  792. ast->arg_ref.param = p;
  793. } else {
  794. ast->type = ELLC_AST_ENV_REF;
  795. ast->env_ref.param = p;
  796. p->closed = 1;
  797. ellc_env_add_ref(st->bottom_contour->lam, p->id);
  798. }
  799. }
  800. static void
  801. ellc_conv_def(struct ellc_st *st, struct ellc_ast *ast)
  802. {
  803. ell_util_set_add(st->globals, ast->def.id, (dict_comp_t) &ellc_id_cmp);
  804. ellc_conv_ast(st, ast->def.val);
  805. }
  806. static void
  807. ellc_conv_defp(struct ellc_st *st, struct ellc_ast *ast)
  808. {
  809. /* See comment in ellc_conv_ref. */
  810. if (!ellc_defined_at_toplevel(st, ast->defp.id)) {
  811. ast->defp.id->cx = NULL;
  812. }
  813. ell_util_set_add(st->globals, ast->defp.id, (dict_comp_t) &ellc_id_cmp);
  814. }
  815. static void
  816. ellc_conv_set(struct ellc_st *st, struct ellc_ast *ast)
  817. {
  818. ellc_conv_ast(st, ast->set.val);
  819. struct ellc_param *p;
  820. struct ellc_contour *c = ellc_contour_lookup(st->bottom_contour, ast->set.id, &p);
  821. if (!c) {
  822. /* See comment in ellc_conv_ref. */
  823. if (!ellc_defined_at_toplevel(st, ast->ref.id)) {
  824. ast->set.id->cx = NULL;
  825. }
  826. struct ellc_id *tmp_id = ast->set.id;
  827. ast->type = ELLC_AST_GLO_SET;
  828. ast->glo_set.id = tmp_id;
  829. ell_util_set_add(st->globals, tmp_id, (dict_comp_t) &ellc_id_cmp);
  830. } else if (c == st->bottom_contour) {
  831. struct ellc_ast *tmp_val = ast->set.val;
  832. ast->type = ELLC_AST_ARG_SET;
  833. ast->arg_set.param = p;
  834. ast->arg_set.val = tmp_val;
  835. p->mutable = 1;
  836. } else {
  837. struct ellc_ast *tmp_val = ast->set.val;
  838. ast->type = ELLC_AST_ENV_SET;
  839. ast->env_set.param = p;
  840. ast->env_set.val = tmp_val;
  841. p->closed = 1;
  842. p->mutable = 1;
  843. ellc_env_add_ref(st->bottom_contour->lam, p->id);
  844. }
  845. }
  846. static void
  847. ellc_conv_cond(struct ellc_st *st, struct ellc_ast *ast)
  848. {
  849. ellc_conv_ast(st, ast->cond.test);
  850. ellc_conv_ast(st, ast->cond.consequent);
  851. ellc_conv_ast(st, ast->cond.alternative);
  852. }
  853. static void
  854. ellc_conv_seq(struct ellc_st *st, struct ellc_ast *ast)
  855. {
  856. for (lnode_t *n = list_first(ast->seq.exprs); n; n = list_next(ast->seq.exprs, n))
  857. ellc_conv_ast(st, (struct ellc_ast *) lnode_get(n));
  858. }
  859. static void
  860. ellc_conv_args(struct ellc_st *st, struct ellc_args *args)
  861. {
  862. for (lnode_t *n = list_first(&args->pos); n; n = list_next(&args->pos, n))
  863. ellc_conv_ast(st, (struct ellc_ast *) lnode_get(n));
  864. for (dnode_t *n = dict_first(&args->key); n; n = dict_next(&args->key, n))
  865. ellc_conv_ast(st, (struct ellc_ast *) dnode_get(n));
  866. }
  867. static void
  868. ellc_conv_app(struct ellc_st *st, struct ellc_ast *ast)
  869. {
  870. ellc_conv_ast(st, ast->app.op);
  871. ellc_conv_args(st, ast->app.args);
  872. }
  873. static void
  874. ellc_conv_params_list_inits(struct ellc_st *st, list_t *params)
  875. {
  876. for (lnode_t *n = list_first(params); n; n = list_next(params, n)) {
  877. struct ellc_param *p = (struct ellc_param *) lnode_get(n);
  878. if (p->init)
  879. ellc_conv_ast(st, p->init);
  880. }
  881. }
  882. static void
  883. ellc_conv_param_inits(struct ellc_st *st, struct ellc_params *params)
  884. {
  885. ellc_conv_params_list_inits(st, params->opt);
  886. ellc_conv_params_list_inits(st, params->key);
  887. }
  888. static void
  889. ellc_conv_lam(struct ellc_st *st, struct ellc_ast *ast)
  890. {
  891. struct ellc_contour *c = (struct ellc_contour *) ell_alloc(sizeof(*c));
  892. c->lam = &ast->lam;
  893. c->up = st->bottom_contour;
  894. st->bottom_contour = c;
  895. ellc_conv_param_inits(st, ast->lam.params);
  896. ellc_conv_ast(st, ast->lam.body);
  897. st->bottom_contour = c->up;
  898. for (dnode_t *n = dict_first(ast->lam.env); n; n = dict_next(ast->lam.env, n))
  899. ellc_conv_ast(st, (struct ellc_ast *) dnode_get(n));
  900. ast->lam.code_id = list_count(st->lambdas);
  901. ell_util_list_add(st->lambdas, &ast->lam);
  902. }
  903. static void
  904. ellc_conv_loop(struct ellc_st *st, struct ellc_ast *ast)
  905. {
  906. ellc_conv_ast(st, ast->loop.body);
  907. }
  908. static void
  909. ellc_conv_cx(struct ellc_st *st, struct ellc_ast *ast)
  910. {
  911. ellc_conv_ast(st, ast->cx.body);
  912. }
  913. static void
  914. ellc_conv_snip(struct ellc_st *st, struct ellc_ast *ast)
  915. {
  916. ellc_conv_ast(st, ast->snip.body);
  917. }
  918. static void
  919. ellc_conv_stmt(struct ellc_st *st, struct ellc_ast *ast)
  920. {
  921. ellc_conv_ast(st, ast->stmt.body);
  922. ell_util_list_add(st->stmts, ast);
  923. }
  924. static void
  925. ellc_conv_ast(struct ellc_st *st, struct ellc_ast *ast)
  926. {
  927. switch(ast->type) {
  928. case ELLC_AST_REF: ellc_conv_ref(st, ast); break;
  929. case ELLC_AST_DEF: ellc_conv_def(st, ast); break;
  930. case ELLC_AST_DEFP: ellc_conv_defp(st, ast); break;
  931. case ELLC_AST_SET: ellc_conv_set(st, ast); break;
  932. case ELLC_AST_COND: ellc_conv_cond(st, ast); break;
  933. case ELLC_AST_SEQ: ellc_conv_seq(st, ast); break;
  934. case ELLC_AST_APP: ellc_conv_app(st, ast); break;
  935. case ELLC_AST_LAM: ellc_conv_lam(st, ast); break;
  936. case ELLC_AST_LOOP: ellc_conv_loop(st, ast); break;
  937. case ELLC_AST_CX: ellc_conv_cx(st, ast); break;
  938. case ELLC_AST_SNIP: ellc_conv_snip(st, ast); break;
  939. case ELLC_AST_STMT: ellc_conv_stmt(st, ast); break;
  940. case ELLC_AST_LIT_SYM: break;
  941. case ELLC_AST_LIT_STR: break;
  942. case ELLC_AST_LIT_NUM: break;
  943. case ELLC_AST_LIT_STX: break;
  944. default:
  945. ell_fail("conversion error: %d\n", ast->type);
  946. }
  947. }
  948. static void
  949. ellc_conv(struct ellc_st *st, struct ellc_ast_seq *ast_seq)
  950. {
  951. if (st->bottom_contour != NULL) {
  952. ell_fail("contour tracking bug or error in compilation unit\n");
  953. }
  954. for (lnode_t *n = list_first(ast_seq->exprs); n; n = list_next(ast_seq->exprs, n))
  955. ellc_conv_ast(st, (struct ellc_ast *) lnode_get(n));
  956. }
  957. /**** Emission ****/
  958. static void
  959. ellc_emit_ast(struct ellc_st *st, struct ellc_ast *ast);
  960. static char
  961. ellc_mangle_char(char c)
  962. {
  963. // Needs to be kept in sync with sym-char in 'grammar.leg'.
  964. switch (c) {
  965. case '&': return 'A';
  966. case '_': return 'U';
  967. case '-': return 'D';
  968. case '#': return 'O';
  969. case '/': return 'F';
  970. case '<': return 'L';
  971. case '>': return 'G';
  972. case '*': return 'Z';
  973. case '+': return 'P';
  974. case '?': return 'Q';
  975. default: return c;
  976. }
  977. }
  978. static char *
  979. ellc_mangle_str(char *s)
  980. {
  981. size_t len = strlen(s);
  982. char *out = (char *) ell_alloc(len + 1);
  983. for (int i = 0; i < len; i++) {
  984. out[i] = ellc_mangle_char(s[i]);
  985. }
  986. out[len] = '\0';
  987. return out;
  988. }
  989. static char *ELLC_NO_CX = "";
  990. static char *
  991. ellc_mangle_cx(struct ell_cx *cx)
  992. {
  993. if (cx->uuid != NULL) {
  994. char *out = (char *) ell_alloc(37);
  995. uuid_unparse(cx->uuid, out);
  996. return ellc_mangle_str(out);
  997. } else {
  998. return ELLC_NO_CX;
  999. }
  1000. }
  1001. static char *
  1002. ellc_mangle_id(char *prefix, struct ellc_id *id)
  1003. {
  1004. char *std = "__ell";
  1005. char *name = ellc_mangle_str(ell_str_chars(ell_sym_name(id->sym)));
  1006. char *cx = ellc_mangle_cx(id->cx);
  1007. size_t prefix_len = strlen(prefix);
  1008. size_t std_len = strlen(std);
  1009. size_t name_len = strlen(name);
  1010. size_t cx_len = strlen(cx);
  1011. size_t len = std_len + prefix_len + name_len + cx_len
  1012. + 4 // separators
  1013. + 1 // ns (single digit, lest this become a Lisp-10)
  1014. + 1; // zero
  1015. char *out = (char *) ell_alloc(len);
  1016. snprintf(out, len, "%s_%s_%s_%u_%s", std, prefix, name, id->ns, cx);
  1017. return out;
  1018. }
  1019. static char *
  1020. ellc_mangle_glo_id(struct ellc_id *id)
  1021. {
  1022. return ellc_mangle_id("g", id);
  1023. }
  1024. static char *
  1025. ellc_mangle_param_id(struct ellc_id *id)
  1026. {
  1027. return ellc_mangle_id("p", id);
  1028. }
  1029. static char *
  1030. ellc_mangle_env_id(struct ellc_id *id)
  1031. {
  1032. return ellc_mangle_id("e", id);
  1033. }
  1034. static void
  1035. ellc_emit_glo_ref(struct ellc_st *st, struct ellc_ast *ast)
  1036. {
  1037. struct ellc_id *id = ast->glo_ref.id;
  1038. char *sid = ell_str_chars(ell_sym_name(id->sym));
  1039. char *mid = ellc_mangle_glo_id(id);
  1040. switch(id->ns) {
  1041. case ELLC_NS_VAR:
  1042. fprintf(st->f, "ELL_GEN_GLO_REF(%s, \"%s\")", mid, sid);
  1043. break;
  1044. case ELLC_NS_FUN:
  1045. fprintf(st->f, "ELL_GEN_GLO_FREF(%s, \"%s\")", mid, sid);
  1046. break;
  1047. default:
  1048. ell_fail("unknown namespace\n");
  1049. }
  1050. }
  1051. static void
  1052. ellc_emit_arg_ref_plain(struct ellc_st *st, struct ellc_ast *ast)
  1053. {
  1054. fprintf(st->f, "ELL_GEN_ARG_REF_PLAIN(%s)", ellc_mangle_param_id(ast->arg_ref.param->id));
  1055. }
  1056. static void
  1057. ellc_emit_env_ref_plain(struct ellc_st *st, struct ellc_ast *ast)
  1058. {
  1059. fprintf(st->f, "ELL_GEN_ENV_REF_PLAIN(%s)", ellc_mangle_env_id(ast->env_ref.param->id));
  1060. }
  1061. static void
  1062. ellc_emit_arg_ref(struct ellc_st *st, struct ellc_ast *ast)
  1063. {
  1064. if (ellc_param_boxed(ast->arg_ref.param)) {
  1065. fprintf(st->f, "ELL_GEN_ARG_REF_BOXED(%s)", ellc_mangle_param_id(ast->arg_ref.param->id));
  1066. } else {
  1067. ellc_emit_arg_ref_plain(st, ast);
  1068. }
  1069. }
  1070. static void
  1071. ellc_emit_env_ref(struct ellc_st *st, struct ellc_ast *ast)
  1072. {
  1073. if (ellc_param_boxed(ast->env_ref.param)) {
  1074. fprintf(st->f, "ELL_GEN_ENV_REF_BOXED(%s)", ellc_mangle_env_id(ast->env_ref.param->id));
  1075. } else {
  1076. ellc_emit_env_ref_plain(st, ast);
  1077. }
  1078. }
  1079. static void
  1080. ellc_emit_def(struct ellc_st *st, struct ellc_ast *ast)
  1081. {
  1082. fprintf(st->f, "ELL_GEN_DEF(%s, ", ellc_mangle_glo_id(ast->def.id));
  1083. ellc_emit_ast(st, ast->def.val);
  1084. fprintf(st->f, ")");
  1085. }
  1086. static void
  1087. ellc_emit_defp(struct ellc_st *st, struct ellc_ast *ast)
  1088. {
  1089. fprintf(st->f, "ELL_GEN_DEFP(%s)", ellc_mangle_glo_id(ast->defp.id));
  1090. }
  1091. static void
  1092. ellc_emit_glo_set(struct ellc_st *st, struct ellc_ast *ast)
  1093. {
  1094. char *sid = ell_str_chars(ell_sym_name(ast->glo_set.id->sym));
  1095. char *mid = ellc_mangle_glo_id(ast->glo_set.id);
  1096. fprintf(st->f, "ELL_GEN_GLO_SET(%s, \"%s\", ", mid, sid);
  1097. ellc_emit_ast(st, ast->glo_set.val);
  1098. fprintf(st->f, ")");
  1099. }
  1100. static void
  1101. ellc_emit_arg_set(struct ellc_st *st, struct ellc_ast *ast)
  1102. {
  1103. struct ellc_ast_arg_set *arg_set = &ast->arg_set;
  1104. if (ellc_param_boxed(arg_set->param)) {
  1105. fprintf(st->f, "ELL_GEN_ARG_SET_BOXED(%s, ", ellc_mangle_param_id(arg_set->param->id));
  1106. ellc_emit_ast(st, arg_set->val);
  1107. fprintf(st->f, ")");
  1108. } else {
  1109. fprintf(st->f, "ELL_GEN_ARG_SET_PLAIN(%s, ", ellc_mangle_param_id(arg_set->param->id));
  1110. ellc_emit_ast(st, arg_set->val);
  1111. fprintf(st->f, ")");
  1112. }
  1113. }
  1114. static void
  1115. ellc_emit_env_set(struct ellc_st *st, struct ellc_ast *ast)
  1116. {
  1117. struct ellc_ast_env_set *env_set = &ast->env_set;
  1118. if (ellc_param_boxed(env_set->param)) {
  1119. fprintf(st->f, "ELL_GEN_ENV_SET_BOXED(%s, ", ellc_mangle_env_id(env_set->param->id));
  1120. ellc_emit_ast(st, env_set->val);
  1121. fprintf(st->f, ")");
  1122. } else {
  1123. fprintf(st->f, "ELL_GEN_ENV_SET_PLAIN(%s, ", ellc_mangle_env_id(env_set->param->id));
  1124. ellc_emit_ast(st, env_set->val);
  1125. fprintf(st->f, ")");
  1126. }
  1127. }
  1128. static void
  1129. ellc_emit_cond(struct ellc_st *st, struct ellc_ast *ast)
  1130. {
  1131. fprintf(st->f, "ELL_GEN_COND(");
  1132. ellc_emit_ast(st, ast->cond.test);
  1133. fprintf(st->f, ", ");
  1134. ellc_emit_ast(st, ast->cond.consequent);
  1135. fprintf(st->f, ", ");
  1136. ellc_emit_ast(st, ast->cond.alternative);
  1137. fprintf(st->f, ")");
  1138. }
  1139. static void
  1140. ellc_emit_seq(struct ellc_st *st, struct ellc_ast *ast)
  1141. {
  1142. fprintf(st->f, "({ ");
  1143. for (lnode_t *n = list_first(ast->seq.exprs); n; n = list_next(ast->seq.exprs, n)) {
  1144. ellc_emit_ast(st, (struct ellc_ast *) lnode_get(n));
  1145. fprintf(st->f, "; ");
  1146. }
  1147. fprintf(st->f, " })");
  1148. }
  1149. static void
  1150. ellc_emit_app(struct ellc_st *st, struct ellc_ast *ast)
  1151. {
  1152. struct ellc_ast_app *app = &ast->app;
  1153. listcount_t npos = list_count(&app->args->pos);
  1154. dictcount_t nkey = dict_count(&app->args->key);
  1155. fprintf(st->f, "({");
  1156. if (npos || nkey) {
  1157. // evaluate arguments
  1158. unsigned ipos = 0;
  1159. for (lnode_t *n = list_first(&app->args->pos); n; n = list_next(&app->args->pos, n)) {
  1160. struct ellc_ast *arg_ast = (struct ellc_ast *) lnode_get(n);
  1161. fprintf(st->f, "struct ell_obj *__ell_pos_arg_%u = ", ipos);
  1162. ellc_emit_ast(st, arg_ast);
  1163. fprintf(st->f, "; ");
  1164. ipos++;
  1165. }
  1166. unsigned kpos = 0;
  1167. for (dnode_t *n = dict_first(&app->args->key); n; n = dict_next(&app->args->key, n)) {
  1168. struct ellc_ast *arg_ast = (struct ellc_ast *) dnode_get(n);
  1169. fprintf(st->f, "struct ell_obj *__ell_key_arg_%u = ", kpos);
  1170. ellc_emit_ast(st, arg_ast);
  1171. fprintf(st->f, "; ");
  1172. kpos++;
  1173. }
  1174. // fill arguments array
  1175. fprintf(st->f, "struct ell_obj *__ell_args[] = {");
  1176. ipos = 0;
  1177. for (lnode_t *n = list_first(&app->args->pos); n; n = list_next(&app->args->pos, n)) {
  1178. fprintf(st->f, "__ell_pos_arg_%u, ", ipos);
  1179. ipos++;
  1180. }
  1181. kpos = 0;
  1182. for (dnode_t *n = dict_first(&app->args->key); n; n = dict_next(&app->args->key, n)) {
  1183. struct ell_obj *arg_key_sym = (struct ell_obj *) dnode_getkey(n);
  1184. // enh: this can be done more efficiently (intern symbols
  1185. // used as keyword argument names at load-time)
  1186. fprintf(st->f, "ell_intern(ell_make_str(\"%s\")), ", ell_str_chars(ell_sym_name(arg_key_sym)));
  1187. fprintf(st->f, "__ell_key_arg_%u, ", kpos);
  1188. kpos++;
  1189. }
  1190. fprintf(st->f, "}; ");
  1191. }
  1192. fprintf(st->f, "ell_call(");
  1193. ellc_emit_ast(st, app->op);
  1194. fprintf(st->f, ", %lu, %lu, %s);", npos, nkey, ((npos || nkey) ? "__ell_args" : "NULL"));
  1195. fprintf(st->f, "})");
  1196. }
  1197. static void
  1198. ellc_emit_lam(struct ellc_st *st, struct ellc_ast *ast)
  1199. {
  1200. /* Inside a lambda, the enclosing hygiene context is not visible,
  1201. because it's a C local variable. Thus, setting it to off
  1202. inside the lambda's body is needed so that the code does the
  1203. right thing, namely, generate a new context when a new
  1204. quasisyntax is encountered. */
  1205. bool in_quasisyntax_tmp = st->in_quasisyntax;
  1206. st->in_quasisyntax = 0;
  1207. struct ellc_ast_lam *lam = &ast->lam;
  1208. fprintf(st->f, "({ ");
  1209. // populate env
  1210. if (dict_count(lam->env) > 0) {
  1211. fprintf(st->f, "struct __ell_env_%u *__lam_env = ell_alloc(sizeof(struct __ell_env_%u));",
  1212. lam->code_id, lam->code_id);
  1213. for (dnode_t *n = dict_first(lam->env); n; n = dict_next(lam->env, n)) {
  1214. struct ellc_id *env_id = (struct ellc_id *) dnode_getkey(n);
  1215. fprintf(st->f, "__lam_env->%s = ", ellc_mangle_env_id(env_id));
  1216. struct ellc_ast *ref_ast = (struct ellc_ast *) dnode_get(n);
  1217. /* Tricky: if a variable is boxed, the closure environment
  1218. needs to contain the box, not the box's contents. This
  1219. means we need to emit references specially here, so
  1220. that they always act as if the variable was unboxed,
  1221. even for boxed ones. */
  1222. switch(ref_ast->type) {
  1223. case ELLC_AST_ENV_REF:
  1224. ellc_emit_env_ref_plain(st, ref_ast); break;
  1225. case ELLC_AST_ARG_REF:
  1226. ellc_emit_arg_ref_plain(st, ref_ast); break;
  1227. default:
  1228. ell_fail("bad closure environment reference\n");
  1229. }
  1230. fprintf(st->f, "; ");
  1231. }
  1232. }
  1233. // create closure
  1234. if (dict_count(lam->env) > 0) {
  1235. fprintf(st->f, "ell_make_clo(&__ell_code_%u, __lam_env);",
  1236. lam->code_id);
  1237. } else {
  1238. fprintf(st->f, "ell_make_clo(&__ell_code_%u, NULL);",
  1239. lam->code_id);
  1240. }
  1241. fprintf(st->f, "})");
  1242. st->in_quasisyntax = in_quasisyntax_tmp;
  1243. }
  1244. static void
  1245. ellc_emit_loop(struct ellc_st *st, struct ellc_ast *ast)
  1246. {
  1247. fprintf(st->f, "ELL_GEN_LOOP(");
  1248. ellc_emit_ast(st, ast->loop.body);
  1249. fprintf(st->f, ")");
  1250. }
  1251. static void
  1252. ellc_emit_lit_sym(struct ellc_st *st, struct ellc_ast *ast)
  1253. {
  1254. // kludge
  1255. fprintf(st->f, "ell_intern(ell_make_str(\"%s\"))",
  1256. ell_str_chars(ell_sym_name(ast->lit_sym.sym)));
  1257. }
  1258. static void
  1259. ellc_emit_lit_str(struct ellc_st *st, struct ellc_ast *ast)
  1260. {
  1261. // kludge
  1262. fprintf(st->f, "ell_make_str(\"%s\")",
  1263. ell_str_chars(ast->lit_str.str));
  1264. }
  1265. static void
  1266. ellc_emit_lit_num(struct ellc_st *st, struct ellc_ast *ast)
  1267. {
  1268. // kludge
  1269. fprintf(st->f, "ell_make_num(\"%d\")",
  1270. ell_num_int(ast->lit_num.num));
  1271. }
  1272. static void
  1273. ellc_emit_lit_stx(struct ellc_st *st, struct ellc_ast *ast)
  1274. {
  1275. struct ell_obj *stx = ast->lit_stx.stx;
  1276. if (stx->wrapper == ELL_WRAPPER(stx_sym)) {
  1277. fprintf(st->f, "ell_make_stx_sym_cx(ell_intern(ell_make_str(\"%s\")), __ell_cur_cx)",
  1278. ell_str_chars(ell_sym_name(ell_stx_sym_sym(stx))));
  1279. } else if (stx->wrapper == ELL_WRAPPER(stx_str)) {
  1280. fprintf(st->f, "ell_make_stx_str(ell_make_str(\"%s\"))",
  1281. ell_str_chars(ell_stx_str_str(stx)));
  1282. } else {
  1283. ell_fail("literal syntax error\n");
  1284. }
  1285. }
  1286. static void
  1287. ellc_emit_cx(struct ellc_st *st, struct ellc_ast *ast)
  1288. {
  1289. if (st->in_quasisyntax) {
  1290. ellc_emit_ast(st, ast->cx.body);
  1291. } else {
  1292. /* Shadow the global current hygiene context, which is always
  1293. NULL. The trick here is that only syntax forms that are
  1294. statically enclosed in this form will pick up this new
  1295. context, that's shadowing the global context, since the new
  1296. context is a C local variable. */
  1297. st->in_quasisyntax = 1;
  1298. fprintf(st->f, "({ struct ell_cx *__ell_cur_cx = ell_make_cx(); ");
  1299. ellc_emit_ast(st, ast->cx.body);
  1300. fprintf(st->f, "; })");
  1301. st->in_quasisyntax = 0;
  1302. }
  1303. }
  1304. /* Emits a body sequence containing literal strings and other
  1305. expressions by emitting the literal strings at the top-level of the
  1306. sequence as-is to the C output. */
  1307. static void
  1308. ellc_direct_emit_c_sequence(struct ellc_st *st, struct ellc_ast *body_seq)
  1309. {
  1310. if(body_seq->type != ELLC_AST_SEQ) {
  1311. ell_fail("C output error\n");
  1312. }
  1313. list_t *exprs = body_seq->seq.exprs;
  1314. for (lnode_t *n = list_first(exprs); n; n = list_next(exprs, n)) {
  1315. struct ellc_ast *expr = (struct ellc_ast *) lnode_get(n);
  1316. if (expr->type == ELLC_AST_LIT_STR) {
  1317. fprintf(st->f, "%s", ell_str_chars(expr->lit_str.str));
  1318. } else {
  1319. ellc_emit_ast(st, expr);
  1320. }
  1321. }
  1322. }
  1323. static void
  1324. ellc_emit_snip(struct ellc_st *st, struct ellc_ast *ast)
  1325. {
  1326. struct ellc_ast *body_seq = ast->snip.body;
  1327. ellc_direct_emit_c_sequence(st, body_seq);
  1328. }
  1329. static void
  1330. ellc_emit_stmt(struct ellc_st *st, struct ellc_ast *ast)
  1331. {
  1332. /* Do nothing, statements get emitted specially before everything
  1333. else. However return something so that REPL etc is happy. */
  1334. fprintf(st->f, "ell_unspecified");
  1335. }
  1336. static void
  1337. ellc_emit_ast(struct ellc_st *st, struct ellc_ast *ast)
  1338. {
  1339. switch(ast->type) {
  1340. case ELLC_AST_GLO_REF: ellc_emit_glo_ref(st, ast); break;
  1341. case ELLC_AST_ARG_REF: ellc_emit_arg_ref(st, ast); break;
  1342. case ELLC_AST_ENV_REF: ellc_emit_env_ref(st, ast); br

Large files files are truncated, but you can click here to view the full file