// ---- 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; defer_drop(0); dfr_base = 0; dfr_on = 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; }