aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/check.zc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/check.zc')
-rw-r--r--src/compiler/check.zc115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/compiler/check.zc b/src/compiler/check.zc
new file mode 100644
index 0000000..a22bcdd
--- /dev/null
+++ b/src/compiler/check.zc
@@ -0,0 +1,115 @@
+// ---- check mode: the language server ----
+
+// the server runs this compiler, unchanged, over a document it holds in
+// memory. chk_unit compiles it as a whole unit, in a machine set up the way
+// start() sets one up (the genome's own names, the default operators and
+// keywords), so the document's parse words, operators and types change what
+// the rest of it means exactly as they would in a real build. the symbols
+// the document made stay in the tables afterwards for the highlighter.
+// chk_mark is the last function of the compiler proper, and LSP_SERVER (in
+// src/lsp/server.zc) the first constant of the server: the server's names are
+// hidden from the document, the runtime's and the compiler's are not.
+int chk_mark() { return 0; }
+// reset check mode for a new document.
+int chk_reset() {
+ statement_hooks = 0; included_modules = 0;
+ if_local = 0; if_edges = 0; if_value = 0;
+ rt.code_blocks = 0; code_chunk = rt.CODE_END;
+ isp = -1;
+ docs_on = 1; dn = 0; dline = 0; docpending = 0; dsect = 0; dsn = 0; dnm = 0;
+ pq_n = 0;
+ pendot = 0;
+ qdone = 0;
+ ch = 0;
+ chkind = 0;
+ line = 1;
+ tk = 0;
+ tv = 0;
+ tglue = 0;
+ tline = 1;
+ toff = 0 - 1; toklen = 0; tpend = 0 - 1; tpline = 1;
+ infn = 0;
+ fdepth = 0;
+ fslots = 0;
+ fchk = 0;
+ fret = 0;
+ live = 0;
+ bxdepth = 0;
+ epichain = 0;
+ fframe = 0;
+ xbor = 0 - 1; xaf = 0; argfact = 0; xvk = 0;
+ if (svkind) rt.fill_w(svkind, 0, symcap);
+ mdbg = 0; mdbg_flags = 0; lv = 0; lvk = 0; lvi = 0; kw_expr = 0; xcls = 0; fty = 0;
+ check_on = 1; tc_on = ifstrict; dry = 0; ntp = 0; tvauto = 0; ngbind = 0; xgive = 0; xconst = 0;
+ o3on = 0; o3nxt = 0; no3pend = 0; no3sl = 0; no3free = 0; o3nreg = 0; o3na = 0; o3fn0 = 0;
+ nfact = 0; fortest = 0; forstep = 0; argloc = 0; arrloc = 0; njps = 0; extop = 0; nnumops = 0;
+ nenh = 0; panic = 0; nerr = 0; dgprev = 0; nclo = 0; newsz = 0 - 1; nomagic = 0; callpos = 0;
+ grec = 0; gnew = 0 - 1; gt_n = 0; gi_n = 0; ginst = 0; gtab = 0;
+ return 0;
+}
+// src: the document, 4 chars to a word and a 0 at the end. buf, cap: where
+// the records go. sets: 4 * LSW words for the name sets. lim: code may grow up
+// to here. every block the caller holds is a heap object reachable from its
+// globals, so the check's garbage is collected and nothing is cut off.
+// check one document in check mode and fill the records it made.
+int chk_unit(int src, int buf, int cap, int sets, int lim) {
+ chk_reset();
+ module_name = 0; module_imports = 0;
+ chk_begin(buf, cap);
+ lsets = sets;
+ if (sets) rt.fill_w(sets, 0, 4 * LSW);
+ if (!chk_heap) { rt.heap_init(); chk_heap = 1; } else rt.gc(); // the caller's blocks are reachable from its globals, the rest goes
+ rsn = 0; evn = 0; hl_n = 0; literal_doc_n = 0; if (literal_docs) rt.fill_w(literal_docs, 0, literal_doc_cap); curinc = 0; std_done = 0; icon_done = 0; incdepth = 0; dgdrop = 0; probe_has = 0; probe_n = 0; probe_mem = 0; probe_static = 0; nameoff = 0 - 1; rsbase = src;
+ if (!rsrec) { rscap = RS_CAP; rsrec = rt.new(RS_CAP * RS_W); rstmp = rt.new(RS_CAP * RS_W); }
+ ifs = 0; ifx = 0; nifx = 0; nift = 0; nif = 0; ifcur = 0; ifkk = 0; ifgk = 0; ifcall = 0 - 1;
+ if (ifon) {
+ ifrcap = NIF; ifxcap = IFN; iftcap = IFT;
+ ifs = rt.new(symcap); ifr = chk_resize(0, 0, ifrcap); ifx = chk_resize(0, 0, ifxcap * 4); ift = chk_resize(0, 0, iftcap);
+ if_local = chk_resize(0, 0, loccap); if_edges = 0; if_value = 0;
+ rt.fill_w(ifs, 0, symcap);
+ }
+ zc_init();
+ blob_load(rt.GORG[5], 1);
+ zc_tables();
+ types_init();
+ here = 0; hdelta = 0; hlimit = lim; ptop = 0;
+ ubase = nsym; vislo = 0;
+ prescan(3, src);
+ src_push(3, src, 0, 0);
+ next();
+ unit_top();
+ rs_fix();
+ unit_end(ubase);
+ if (ifx) if_emit();
+ src_pop();
+ rs_sort();
+ chk_end();
+ return 0;
+}
+// walk a document's tokens with the lexer as the check left it. hl_begin
+// loads the first token into tk, tv, toff and toklen; next() moves on; hl_end
+// restores the previous state.
+// the syntax highlighter's view of the lexer. it re-lexes the document after
+// the check, so the tokens it sees are cut exactly where the compiler's were
+// (parse words that changed the operators included).
+int hl_begin(int src) {
+ chkabort = 0; isp = -1; pq_n = 0; pendot = 0; qdone = 0; panic = 0;
+ dry++;
+ src_push(3, src, 0, 0);
+ next();
+ return 0;
+}
+// end a highlight pass: leave the source and the dry run.
+int hl_end() {
+ src_pop();
+ dry--;
+ isp = -1;
+ pq_n = 0;
+ return 0;
+}
+// the source of the std and icon libraries, embedded when the compiler is built, so
+// `include std;` and `include icon;` need no file at run time.
+embed "src/lib/std.zc" as bstr std_embedded;
+embed "src/lib/icon.zc" as bstr icon_embedded;
+bstr std_source() { return std_embedded; }
+bstr icon_source() { return icon_embedded; }