diff options
| author | 2026-10-14 10:06:27 +0000 | |
|---|---|---|
| committer | 2026-10-14 10:06:27 +0000 | |
| commit | c2270cc944424579e4577e67ed17a66512d856b4 (patch) | |
| tree | 04fc1ede53e0cbf2c2562f724fd539836c450306 /src/lsp/server.zc | |
| parent | todo: tick the spec; list the bugs its appendix b found (diff) | |
| parent | split compiler.zc into files by phase (diff) | |
Merge the compiler split into phase files
also: ca_owners in the language server keeps the owner order in a fixed
array instead of a heap list the analyzer rejected.
Diffstat (limited to 'src/lsp/server.zc')
| -rw-r--r-- | src/lsp/server.zc | 78 |
1 files changed, 60 insertions, 18 deletions
diff --git a/src/lsp/server.zc b/src/lsp/server.zc index 3262e39..afa8de4 100644 --- a/src/lsp/server.zc +++ b/src/lsp/server.zc @@ -3,10 +3,10 @@ include rt, run; // ============================================================================ // server.zc: the language server. it is appended to the genome after the -// compiler (cat src/runtime/rt.zc src/compiler/compiler.zc src/lsp/server.zc | zc0), so it does not +// compiler (the files of src/compiler/parts in order, then this one, read as one stream), so it does not // analyze zc with a second implementation of the grammar: it runs the // compiler itself over the document, in check mode (see chk_unit in -// compiler.zc), and reports what the compiler said. a parse word, an +// src/compiler/check.zc), and reports what the compiler said. a parse word, an // operator or a type the document defines changes how the rest of the // document is read, for the checker and for the highlighter, because both are // the compiler. it speaks json-rpc on stdin and stdout, and when stdin is not @@ -14,7 +14,7 @@ include rt, run; // ============================================================================ // the first constant the server declares: the blob cut for a document starts -// here (blob_load, compiler.zc), so this name must stay the first one of the server. +// here (blob_load, src/compiler/image.zc), so this name must stay the first one of the server. const int LSP_SERVER = 1; // the compiler's own functions, declared here so this file checks on its own @@ -2121,15 +2121,51 @@ int do_nav(int i, int refs) { // 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 +// of its own at tinyvm:/NAME.zc, which the editor shows read only and can ask for with zc/source. +// the compiler is several files (src/compiler/parts lists them in order); an embed takes a literal +// path, so they are named here, in the same order, and joined into the one document tinyvm:/compiler.zc +// when it is loaded. tests/drivers/nav_test.js checks that this list is the parts file. const int BS_COUNT = 6; +const int CC_PARTS = 12; embed "src/runtime/rt.zc" as bstr rt_embedded; -embed "src/compiler/compiler.zc" as bstr compiler_embedded; +embed "src/compiler/base.zc" as bstr cc_base; +embed "src/compiler/lex.zc" as bstr cc_lex; +embed "src/compiler/ops.zc" as bstr cc_ops; +embed "src/compiler/analyzer.zc" as bstr cc_analyzer; +embed "src/compiler/types.zc" as bstr cc_types; +embed "src/compiler/builtins.zc" as bstr cc_builtins; +embed "src/compiler/expr.zc" as bstr cc_expr; +embed "src/compiler/stmt.zc" as bstr cc_stmt; +embed "src/compiler/decl.zc" as bstr cc_decl; +embed "src/compiler/image.zc" as bstr cc_image; +embed "src/compiler/setup.zc" as bstr cc_setup; +embed "src/compiler/check.zc" as bstr cc_check; embed "src/lsp/server.zc" as bstr server_embedded; embed "src/core/core.zc" as bstr core_embedded; -bstr bs_text(int k) { +// part i of the compiler, in the order of src/compiler/parts +bstr cc_part(int i) { + if (i == 0) return cc_base; + if (i == 1) return cc_lex; + if (i == 2) return cc_ops; + if (i == 3) return cc_analyzer; + if (i == 4) return cc_types; + if (i == 5) return cc_builtins; + if (i == 6) return cc_expr; + if (i == 7) return cc_stmt; + if (i == 8) return cc_decl; + if (i == 9) return cc_image; + if (i == 10) return cc_setup; + return cc_check; +} +// source k is this many pieces of text: the compiler's parts, or one file +int bs_pieces(int k) { + if (k == 1) return CC_PARTS; + return 1; +} +// piece i of source k +bstr bs_text(int k, int i) { if (k == 0) return rt_embedded; - if (k == 1) return compiler_embedded; + if (k == 1) return cc_part(i); if (k == 2) return server_embedded; if (k == 3) return run.std_source(); if (k == 4) return run.icon_source(); @@ -2145,15 +2181,20 @@ 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; bstr p; word text; + int i, n = 0, j = 0, q = 0, at, len; bstr p; word text; if (!bs_idx) bs_idx = lsp_grow(0, 0, BS_COUNT); if (bs_idx[k]) return bs_idx[k] - 1; - p = bs_text(k); j = rt.len_s(p); + while (q < bs_pieces(k)) { j = j + rt.len_s(bs_text(k, q)); q++; } 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++; + q = 0; + while (q < bs_pieces(k)) { + p = bs_text(k, q); len = rt.len_s(p); at = 0; + while (at < len) { + if ((n & 3) == 0) text[n >> 2] = 0; + text[n >> 2] = text[n >> 2] | (rt.at_s(p, at) << ((n & 3) * 8)); + n++; at++; + } + q++; } i = docnew(bs_uri(k), rt.len_w(bs_uri(k))); doff[i] = text; dsize[i] = n; dver[i] = 1; dgen[i]++; @@ -3199,11 +3240,12 @@ int ca_add(char* owner, char* path, int from) { return 0; } // the fixes for every module that exports name, best first +word[32] ca_order; int ca_owners(char* name, int from) { - word p = run.export_owners(name), q = 0, next; - // ca_add prepends, so the list goes in backwards and comes out best first - while (p) { next = rt.new(2); next[0] = q; next[1] = p; q = next; p = p[0]; } - while (q) { p = q[1]; ca_add(p[1], p[2], from); next = q[0]; rt.free(q); q = next; } + word p = run.export_owners(name); int n = 0; + // ca_add prepends, so the owners go in backwards and come out best first + while (p && n < 32) { ca_order[n] = p; n++; p = p[0]; } + while (n > 0) { n--; p = ca_order[n]; ca_add(p[1], p[2], from); } return 0; } int ca_import_point(int i) { @@ -3658,7 +3700,7 @@ int cli(int first) { // zclsp --annotate < file.zc prints the file with the types the compiler can // see written in: locals from their initializers, parameters from what every // call passes them or from being used as an address, returns from what the -// function returns (the type facts of compiler.zc). the typechecker is on for +// function returns (the type facts of the compiler). the typechecker is on for // it, and every edit has to leave the file with no error it didn't have, so // what comes out compiles wherever the input did. when a batch of edits // fails, the batch is cut in halves until the bad edits are found and left |
