parsav  Diff

Differences From Artifact [c8d105a016]:

To Artifact [c5ea2451a4]:


1
2
3


4
5
6
7
8
9
10
..
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
..
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
...
114
115
116
117
118
119
120

121











122
123
124
125
126
127
128
...
212
213
214
215
216
217
218


219


220
221
222
223
224
225
226
-- vim: ft=terra
-- string.t: string classes
local util = dofile('common.lua')



local m = {
	sz = terralib.externfunction('strlen', rawstring -> intptr);
	cmp = terralib.externfunction('strcmp', {rawstring, rawstring} -> int);
	ncmp = terralib.externfunction('strncmp', {rawstring, rawstring, intptr} -> int);
	cpy = terralib.externfunction('stpcpy',{rawstring, rawstring} -> rawstring);
	ncpy = terralib.externfunction('stpncpy',{rawstring, rawstring, intptr} -> rawstring);
................................................................................
		terralib.types.funcpointer({&rawstring,rawstring},{int},true));
	bfmt = terralib.externfunction('sprintf',
		terralib.types.funcpointer({rawstring,rawstring},{int},true));
	span = terralib.externfunction('strspn',{rawstring, rawstring} -> rawstring);
}

do local strptr = (lib.mem.ptr(int8))

	local byteptr = (lib.mem.ptr(uint8))
	strptr.metamethods.__cast = function(from,to,e)
		if from == &int8 then
			return `strptr {ptr = e, ct = m.sz(e)}
		elseif to == &int8 then
			return e.ptr
		end
	end

	terra strptr:cmp(other: strptr)














		var sz = lib.math.biggest(self.ct, other.ct)
		for i = 0, sz do
			if self.ptr[i] == 0 and other.ptr[i] == 0 then return true end
			if self.ptr[i] ~= other.ptr[i] then return false end
		end
		return true
	end








	terra byteptr:cmp(other: byteptr)
		var sz = lib.math.biggest(self.ct, other.ct)
		for i = 0, sz do
			if self.ptr[i] == 0 and other.ptr[i] == 0 then return true end
			if self.ptr[i] ~= other.ptr[i] then return false end
		end
		return true
	end
end



















struct m.acc {
	buf: rawstring
	sz: intptr
	run: intptr
	space: intptr
}
................................................................................
	--lib.dbg('freeing string accumulator')
	if self.buf ~= nil and self.space > 0 then
		lib.mem.heapf(self.buf)
	end
end;

terra m.acc:crush()
	lib.dbg('crushing string accumulator')
	self.buf = [rawstring](lib.mem.heapr_raw(self.buf, self.sz))
	self.space = self.sz
	return self
end;

terra m.acc:finalize()
	lib.dbg('finalizing string accumulator')
	self:crush()
	var pt: lib.mem.ptr(int8)
	pt.ptr = self.buf
	pt.ct = self.sz
	self.buf = nil
	self.sz = 0
	return pt
................................................................................
	lib.mem.cpy(self.buf + self.sz, str, len)
	self.sz = self.sz + len
	self.buf[self.sz] = 0
	return self
end;

m.lit = macro(function(str)

	return `[lib.mem.ref(int8)] {ptr = [str:asvalue()], ct = [#(str:asvalue())]}











end)

m.acc.methods.lpush = macro(function(self,str)
	return `self:push([str:asvalue()], [#(str:asvalue())]) end)
m.acc.methods.ppush = terra(self: &m.acc, str: lib.mem.ptr(int8))
	self:push(str.ptr, str.ct)            return self end;
m.acc.methods.merge = terra(self: &m.acc, str: lib.mem.ptr(int8))
................................................................................
			local str,sz = v[1],v[2]
			if type(sz) == 'number' then
				memreq_const = memreq_const + sz
			elseif type(sz:asvalue()) == 'number' then
				memreq_const = memreq_const + sz:asvalue()
			else memreq_exp = `[sz] + [memreq_exp] end



			cpy = quote [kp] ; [ptr] = [&int8](lib.mem.cpy([ptr], str, sz)) end


			if ty.ptr_basetype then
				cpy = quote [cpy]; [box].obj.[k].ct = sz end
			end
			isnull = `[str] == nil
		else
			memreq_exp = `(m.sz(v) + 1) + [memreq_exp] -- make room for NUL
			isnull = `v == nil



>
>







 







>










>
>
>
>
>
>
>
>
>
>
>
>
>
>







>
>
>
>
>
>
>










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|






|







 







>
|
>
>
>
>
>
>
>
>
>
>
>







 







>
>
|
>
>







1
2
3
4
5
6
7
8
9
10
11
12
..
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
...
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
...
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
...
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
-- vim: ft=terra
-- string.t: string classes
local util = dofile('common.lua')
local pstr = lib.mem.ptr(int8)
local pref = lib.mem.ref(int8)

local m = {
	sz = terralib.externfunction('strlen', rawstring -> intptr);
	cmp = terralib.externfunction('strcmp', {rawstring, rawstring} -> int);
	ncmp = terralib.externfunction('strncmp', {rawstring, rawstring, intptr} -> int);
	cpy = terralib.externfunction('stpcpy',{rawstring, rawstring} -> rawstring);
	ncpy = terralib.externfunction('stpncpy',{rawstring, rawstring, intptr} -> rawstring);
................................................................................
		terralib.types.funcpointer({&rawstring,rawstring},{int},true));
	bfmt = terralib.externfunction('sprintf',
		terralib.types.funcpointer({rawstring,rawstring},{int},true));
	span = terralib.externfunction('strspn',{rawstring, rawstring} -> rawstring);
}

do local strptr = (lib.mem.ptr(int8))
	local strref = (lib.mem.ref(int8))
	local byteptr = (lib.mem.ptr(uint8))
	strptr.metamethods.__cast = function(from,to,e)
		if from == &int8 then
			return `strptr {ptr = e, ct = m.sz(e)}
		elseif to == &int8 then
			return e.ptr
		end
	end

	terra strptr:cmp(other: strptr)
		if self.ptr == nil and other.ptr == nil then return true end
		if self.ptr == nil or other.ptr == nil then return false end

		var sz = lib.math.biggest(self.ct, other.ct)
		for i = 0, sz do
			if self.ptr[i] == 0 and other.ptr[i] == 0 then return true end
			if self.ptr[i] ~= other.ptr[i] then return false end
		end
		return true
	end
	terra strref:cmp(other: strref)
		if self.ptr == nil and other.ptr == nil then return true end
		if self.ptr == nil or other.ptr == nil then return false end

		var sz = lib.math.biggest(self.ct, other.ct)
		for i = 0, sz do
			if self.ptr[i] == 0 and other.ptr[i] == 0 then return true end
			if self.ptr[i] ~= other.ptr[i] then return false end
		end
		return true
	end

	strptr.methods.cmpl = macro(function(self,other)
		return `self:cmp(strptr { ptr = [other:asvalue()], ct = [#(other:asvalue())] })
	end)
	strref.methods.cmpl = macro(function(self,other)
		return `self:cmp(strref { ptr = [other:asvalue()], ct = [#(other:asvalue())] })
	end)

	terra byteptr:cmp(other: byteptr)
		var sz = lib.math.biggest(self.ct, other.ct)
		for i = 0, sz do
			if self.ptr[i] == 0 and other.ptr[i] == 0 then return true end
			if self.ptr[i] ~= other.ptr[i] then return false end
		end
		return true
	end
end

terra m.normalize(s: pstr)
	var c: rawstring = s.ptr
	var n: rawstring = s.ptr
	while n < s.ptr + s.ct do
		while @n == 0 or @n == @'\r' do
			n = n + 1
			if n > s.ptr + s.ct then
				c = c + 1 goto done
			end
		end
		@c = @n
		c = c + 1
		n = n + 1
	end ::done::
	@c = 0
	return pstr { ptr = s.ptr, ct = c - s.ptr }
end

struct m.acc {
	buf: rawstring
	sz: intptr
	run: intptr
	space: intptr
}
................................................................................
	--lib.dbg('freeing string accumulator')
	if self.buf ~= nil and self.space > 0 then
		lib.mem.heapf(self.buf)
	end
end;

terra m.acc:crush()
	--lib.dbg('crushing string accumulator')
	self.buf = [rawstring](lib.mem.heapr_raw(self.buf, self.sz))
	self.space = self.sz
	return self
end;

terra m.acc:finalize()
	--lib.dbg('finalizing string accumulator')
	self:crush()
	var pt: lib.mem.ptr(int8)
	pt.ptr = self.buf
	pt.ct = self.sz
	self.buf = nil
	self.sz = 0
	return pt
................................................................................
	lib.mem.cpy(self.buf + self.sz, str, len)
	self.sz = self.sz + len
	self.buf[self.sz] = 0
	return self
end;

m.lit = macro(function(str)
	if str:asvalue() ~= nil then
		return `[lib.mem.ref(int8)] {ptr = [str:asvalue()], ct = [#(str:asvalue())]}
	else
		return `[lib.mem.ref(int8)] {ptr = nil, ct = 0}
	end
end)

m.plit = macro(function(str)
	if str:asvalue() ~= nil then
		return `[lib.mem.ptr(int8)] {ptr = [str:asvalue()], ct = [#(str:asvalue())]}
	else
		return `[lib.mem.ptr(int8)] {ptr = nil, ct = 0}
	end
end)

m.acc.methods.lpush = macro(function(self,str)
	return `self:push([str:asvalue()], [#(str:asvalue())]) end)
m.acc.methods.ppush = terra(self: &m.acc, str: lib.mem.ptr(int8))
	self:push(str.ptr, str.ct)            return self end;
m.acc.methods.merge = terra(self: &m.acc, str: lib.mem.ptr(int8))
................................................................................
			local str,sz = v[1],v[2]
			if type(sz) == 'number' then
				memreq_const = memreq_const + sz
			elseif type(sz:asvalue()) == 'number' then
				memreq_const = memreq_const + sz:asvalue()
			else memreq_exp = `[sz] + [memreq_exp] end

			cpy = quote [kp] ;
				--lib.io.fmt('encapsulating string %p → %p [%s] sz %llu\n', str, [ptr], str, sz)
				[ptr] = [&int8](lib.mem.cpy([ptr], str, sz))
				--lib.io.fmt(' :: encapsulated string %p [%s]\n', box.obj.[k],box.obj.[k])
			end
			if ty.ptr_basetype then
				cpy = quote [cpy]; [box].obj.[k].ct = sz end
			end
			isnull = `[str] == nil
		else
			memreq_exp = `(m.sz(v) + 1) + [memreq_exp] -- make room for NUL
			isnull = `v == nil