aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/check.zc
blob: a22bcddd9e81ddba53bd40999d1337efcc027365 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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; }