--- Lisp-family imports (Scheme, Racket) --- S-expression grammars model (import (lib ...)) / (require mod) / (load "f") as a `list` whose first named child is a `symbol` naming the form. Walk top-level lists; for import/require/load/use, take the remaining children as module references (a symbol, a string, or a nested list whose meaningful module symbol we take as-is).
| 1634 | // module references (a symbol, a string, or a nested list whose meaningful |
| 1635 | // module symbol we take as-is). |
| 1636 | static void lisp_push_module(CBMExtractCtx *ctx, TSNode mod_node) { |
| 1637 | CBMArena *a = ctx->arena; |
| 1638 | const char *mk = ts_node_type(mod_node); |
| 1639 | char *mod = NULL; |
| 1640 | if (strcmp(mk, "symbol") == 0 || strcmp(mk, "string") == 0 || strcmp(mk, "sym_lit") == 0 || |
| 1641 | strcmp(mk, "str_lit") == 0 || strcmp(mk, "kwd_lit") == 0) { |
| 1642 | mod = strip_quotes(a, cbm_node_text(a, mod_node, ctx->source)); |
| 1643 | /* Clojure/Fennel keyword module refs carry a leading ':' (e.g. `:util`, |
| 1644 | * `(require :util)`); strip it so the name matches the sibling file. */ |
| 1645 | if (mod && mod[0] == ':') { |
| 1646 | mod = cbm_arena_strdup(a, mod + 1); |
| 1647 | } |
| 1648 | } else if (strcmp(mk, "list") == 0 || strcmp(mk, "list_lit") == 0 || |
| 1649 | strcmp(mk, "vec_lit") == 0) { |
| 1650 | /* (only-in racket/math pi) → take first symbol after a leading keyword, |
| 1651 | * else join inner symbols with '/'. Simplest robust choice: the whole |
| 1652 | * list text minus the parens. */ |
| 1653 | mod = cbm_node_text(a, mod_node, ctx->source); |
| 1654 | if (mod) { |
| 1655 | size_t len = strlen(mod); |
| 1656 | if (len >= 2 && mod[0] == '(' && mod[len - 1] == ')') { |
| 1657 | mod = cbm_arena_strndup(a, mod + 1, len - 2); |
| 1658 | } |
| 1659 | } |
| 1660 | } |
| 1661 | if (mod && mod[0]) { |
| 1662 | CBMImport imp = {.local_name = path_last(a, mod), .module_path = mod}; |
| 1663 | cbm_imports_push(&ctx->result->imports, a, imp); |
| 1664 | } |
| 1665 | } |
| 1666 | |
| 1667 | /* Strip a leading ':' from a lisp keyword/symbol token (Clojure/Fennel/CL |
| 1668 | * package keywords carry it: `:util` → `util`). Returns an arena copy. */ |
no test coverage detected