diff options
| author | 2026-10-14 07:28:39 +0000 | |
|---|---|---|
| committer | 2026-10-14 07:28:39 +0000 | |
| commit | 7451eb090d890fb5ea5e4d40627a1b4df15a49de (patch) | |
| tree | 357bdf4b528e860bffa688865306f656b788d2c2 /src/lsp | |
| parent | analyzer: close the ownership gaps that stopped the compiler compiling itself (diff) | |
build: embed images with #embed, keep everything generated in build/
the cores take their genome in with c23 #embed through src/core/genome.h,
so images are plain little-endian word files (genome.bin) instead of
generated c headers. zc0 writes that format, mkgenome checks an image
against its map and shows a compiler's diagnostics when it gets them,
and the javascript vm and the editor's vm host read the same files.
src/tools/findcc.sh picks a compiler with #embed (clang 19 or gcc 15).
zc gets an embed declaration, embed "file" as [type] name, for globals
and locals: a byte string by default, char*, numbers read little-endian,
and arrays of numbers. the compiler and language server carry their
library and source texts through it, so embed.sh and the text it
spliced into compiler.zc are gone.
make writes executables to build/bin, the default map to build/core/map,
the web page to build/web and the extension staging to build/vsix, and
the genome now rebuilds when its sources change. the test suite lays
out its own map and bootstrap and reads nothing from build/.
also: rt.put_s of a byte string in zc0 images, retained function
sources no longer count as live objects, a missing include no longer
cascades into undefined-name errors, consecutive comment lines join
into one hover paragraph, and stale test fixtures follow the include
format.
Diffstat (limited to 'src/lsp')
| -rw-r--r-- | src/lsp/server.zc | 61 |
1 files changed, 36 insertions, 25 deletions
diff --git a/src/lsp/server.zc b/src/lsp/server.zc index a07e4d4..48fdf90 100644 --- a/src/lsp/server.zc +++ b/src/lsp/server.zc @@ -1057,8 +1057,15 @@ int doc_gap(int base, int from, int to) { return 1; } // remove comment delimiters and optional line-leading stars; retain markdown. +// the line comment emitted last: consecutive // lines are one paragraph, joined by a soft break +int hct_doc = 0 - 1, hct_end, hct_hn; +int hover_comment_adjacent(int base, int from, int to) { + int lines = 0, c; + while (from < to) { c = dc(base, from); if (c == 10) lines++; else if (c != 32 && c != 9 && c != 13) return 0; from++; } + return lines <= 1; +} int hover_comment_text(int i, int index) { - int base = doff[i], o = hc_start[index] + 2, end = hc_end[index], bol = 1, c, before = hn; + int base = doff[i], o = hc_start[index] + 2, end = hc_end[index], bol = 1, c, before = hn, joined; if (hc_kind[index] == 3) { if (end >= o + 2 && dc(base, end - 2) == '*' && dc(base, end - 1) == '/') end = end - 2; if (o < end && dc(base, o) == '*') o++; @@ -1066,7 +1073,8 @@ int hover_comment_text(int i, int index) { while (o < end && (dc(base, o) == 32 || dc(base, o) == 9 || dc(base, o) == 10 || dc(base, o) == 13)) o++; while (end > o && (dc(base, end - 1) == 32 || dc(base, end - 1) == 9 || dc(base, end - 1) == 10 || dc(base, end - 1) == 13)) end--; if (o == end) return 0; - hov_text("\n\n"); + joined = hc_kind[index] != 3 && hct_doc == i && hct_hn == hn && hn > 0 && hover_comment_adjacent(base, hct_end, hc_start[index]); + if (joined) hov_put(10); else hov_text("\n\n"); while (o < end) { if (bol && hc_kind[index] == 3) { while (o < end && (dc(base, o) == 32 || dc(base, o) == 9)) o++; @@ -1078,6 +1086,7 @@ int hover_comment_text(int i, int index) { if (c != 13) hov_put(c); if (c == 10) bol = 1; } + if (hc_kind[index] != 3) { hct_doc = i; hct_end = hc_end[index]; hct_hn = hn; } else hct_doc = 0 - 1; return hn - before; } // a trailing declaration comment belongs to its last name, not the next line. @@ -2085,18 +2094,21 @@ int do_nav(int i, int refs) { } //: ---- the sources of this image ---- -//: the image carries the text of rt.zc, compiler.zc, server.zc, std.zc, icon.zc and core.zc (the -//: pieces src/tools/embed.sh made), so the definition of a built-in has somewhere to go. each source is a document +//: the image carries the text of rt.zc, compiler.zc, server.zc, std.zc, icon.zc and core.zc, embedded +//: when the image is built, so the definition of a built-in has somewhere to go. each source is a document //: of its own at tinyvm:/NAME.zc, which the editor shows read only and can ask for with zc/source const int BS_COUNT = 6; -bstr rt_part(int i); bstr compiler_part(int i); bstr server_part(int i); bstr core_part(int i); -bstr bs_part(int k, int i) { - if (k == 0) return rt_part(i); - if (k == 1) return compiler_part(i); - if (k == 2) return server_part(i); - if (k == 3) return run.std_part(i); - if (k == 4) return run.icon_part(i); - return core_part(i); +embed "src/runtime/rt.zc" as bstr rt_embedded; +embed "src/compiler/compiler.zc" as bstr compiler_embedded; +embed "src/lsp/server.zc" as bstr server_embedded; +embed "src/core/core.zc" as bstr core_embedded; +bstr bs_text(int k) { + if (k == 0) return rt_embedded; + if (k == 1) return compiler_embedded; + if (k == 2) return server_embedded; + if (k == 3) return run.std_source(); + if (k == 4) return run.icon_source(); + return core_embedded; } char* bs_uri(int k) { if (k == 0) return "tinyvm:/rt.zc"; @@ -2108,21 +2120,15 @@ char* bs_uri(int k) { } // the document of built-in source k, loaded the first time it is asked for int bs_load(int k) { - int i, n = 0, j = 0, b; bstr p; word text; + int i, n = 0, j = 0; bstr p; word text; if (!bs_idx) bs_idx = lsp_grow(0, 0, BS_COUNT); if (bs_idx[k]) return bs_idx[k] - 1; - while (1) { p = bs_part(k, j); if (!p) break; n = n + rt.len_s(p); j++; } - text = lsp_grow(0, 0, (n >> 2) + 3); - n = 0; j = 0; - while (1) { - p = bs_part(k, j); if (!p) break; - b = 0; - while (b < rt.len_s(p)) { - if ((n & 3) == 0) text[n >> 2] = 0; - text[n >> 2] = text[n >> 2] | (rt.at_s(p, b) << ((n & 3) * 8)); - n++; b++; - } - j++; + p = bs_text(k); j = rt.len_s(p); + text = lsp_grow(0, 0, (j >> 2) + 3); + while (n < j) { + if ((n & 3) == 0) text[n >> 2] = 0; + text[n >> 2] = text[n >> 2] | (rt.at_s(p, n) << ((n & 3) * 8)); + n++; } i = docnew(bs_uri(k), rt.len_w(bs_uri(k))); doff[i] = text; dsize[i] = n; dver[i] = 1; dgen[i]++; @@ -2334,8 +2340,13 @@ int fm_symbol(int base, int o, int size) { return n; } // split document i into tokens, each with the spaces before it on its line (-1 for the first of a line) +// the document the token arrays describe: hover lookups lex the same documents again and +// again, so a lex of an unchanged document is reused +int fm_doc = 0 - 1, fm_gen, fm_size; word fm_base; int fm_lex(int i) { int base = doff[i], size = dsize[i], o = 0, ln = 0, gap = 0 - 1, c, s, q, e, el, n; + if (fm_doc == i && fm_gen == dgen[i] && fm_base == base && fm_size == size && fm_s) return 0; + fm_doc = i; fm_gen = dgen[i]; fm_base = base; fm_size = size; fm_nt = 0; if (!fm_s) { fm_tcap = 256; |
