parsav  Diff

Differences From Artifact [d98a573fe7]:

To Artifact [89921fa130]:


   109    109   struct m.acc {
   110    110   	buf: rawstring
   111    111   	sz: intptr
   112    112   	run: intptr
   113    113   	space: intptr
          114  +	pool: &lib.mem.pool
   114    115   }
   115    116   
   116    117   terra m.cdowncase(c: int8)
   117    118   	if c >= @'A' and c <= @'Z' then
   118    119   		return c + (@'a' - @'A')
................................................................................
   129    130   	if a > b then return a else return b end
   130    131   end
   131    132   
   132    133   terra m.acc:init(run: intptr)
   133    134   	--lib.dbg('initializing string accumulator')
          135  +	self.pool = nil
   134    136   	if run == 0 then
   135    137   		lib.warn('attempted to allocate zero-length string accumulator')
   136    138   		self.buf = nil
   137    139   	else
   138    140   		self.buf = [rawstring](lib.mem.heapa_raw(run))
................................................................................
   143    145   	self.run = lib.trn(self.buf == nil, 0, run)
   144    146   	self.space = self.run
   145    147   	self.sz = 0
   146    148   	return self
   147    149   end;
          150  +
          151  +terra m.acc:pool(pool: &lib.mem.pool, run: intptr)
          152  +	self.buf = [&int8](pool:alloc_bytes(run))
          153  +	self.pool = pool
          154  +	self.run = run
          155  +	self.space = self.run
          156  +	self.sz = 0
          157  +	return self
          158  +end
   148    159   
   149    160   terra m.acc:free()
   150    161   	--lib.dbg('freeing string accumulator')
          162  +	if self.pool ~= nil then
          163  +		lib.dbg('attempted to free pooled string accumulator; use frame-reset instead')
          164  +		return
          165  +	end
   151    166   	if self.buf ~= nil and self.space > 0 then
   152    167   		lib.mem.heapf(self.buf)
   153    168   	end
   154    169   end;
   155    170   
   156    171   terra m.acc:crush()
   157    172   	--lib.dbg('crushing string accumulator')
          173  +	if self.pool ~= nil then return self end -- no point unless at end of buffer
   158    174   	self.buf = [rawstring](lib.mem.heapr_raw(self.buf, self.sz))
   159    175   	self.space = self.sz
   160    176   	return self
   161    177   end;
   162    178   
................................................................................
   171    187   	return pt
   172    188   end;
   173    189   
   174    190   terra m.acc:cue(sz: intptr)
   175    191   	if sz <= self.run then return end
          192  +	var curspace = self.space
   176    193   	self.run = sz
   177    194   	if self.space - self.sz < self.run then
   178    195   		self.space = self.sz + self.run
   179         -		self.buf = [rawstring](lib.mem.heapr_raw(self.buf, self.space))
          196  +		if self.pool ~= nil then
          197  +			self.buf = [&int8](self.pool:realloc_bytes(self.buf, curspace, self.space))
          198  +		else
          199  +			self.buf = [rawstring](lib.mem.heapr_raw(self.buf, self.space))
          200  +		end
   180    201   	end
   181    202   end
   182    203   
   183    204   terra m.acc:reset() -- semantic convenience function
   184    205   	self.sz = 0
................................................................................
   191    212   	-- lib.dbg('pushing "',{str,llen},'" onto accumulator')
   192    213   	if self.buf == nil then self:init(self.run) end
   193    214   	if self.buf == nil then lib.warn('attempted to push string onto unallocated accumulator') return self end
   194    215   	if len == 0 then len = m.sz(str) end
   195    216   	if len >= self.space - self.sz then
   196         -		self.space = self.space + biggest(self.run,len + 1)
   197         -		self.buf = [rawstring](lib.mem.heapr_raw(self.buf, self.space))
          217  +		self:cue(self.space + biggest(self.run,len + 1))
          218  +		--self.space = self.space + biggest(self.run,len + 1)
          219  +		--self.buf = [rawstring](lib.mem.heapr_raw(self.buf, self.space))
   198    220   	end
   199    221   	lib.mem.cpy(self.buf + self.sz, str, len)
   200    222   	self.sz = self.sz + len
   201    223   	self.buf[self.sz] = 0
   202    224   	return self
................................................................................
   244    266   	self:push(str.ptr, str.ct)            return self end;
   245    267   m.acc.methods.rpush = terra(self: &m.acc, str: lib.mem.ref(int8))
   246    268   	self:push(str.ptr, str.ct)            return self end;
   247    269   m.acc.methods.merge = terra(self: &m.acc, str: lib.mem.ptr(int8))
   248    270   	self:push(str.ptr, str.ct) str:free() return self end;
   249         -m.acc.methods.compose = macro(function(self, ...)
          271  +local composefn = function(call, ...)
   250    272   	local minlen = 0
   251    273   	local pstrs = {}
   252    274   	for i,v in ipairs{...} do
   253    275   		if type(v) == 'table' then
   254    276   			local gl = 16 -- guess wildly
................................................................................
   265    287   		elseif type(v) == 'string' then 
   266    288   			pstrs[#pstrs+1] = {str = v, len = #v}
   267    289   			minlen = minlen + #v + 1
   268    290   		else error('invalid type in compose expression') end
   269    291   	end
   270         -	local call = `self:init(minlen)
          292  +	call = call(minlen) --`self:init(minlen)
   271    293   	for i,v in ipairs(pstrs) do
   272    294   		call = `[call]:push([v.str],[v.len])
   273    295   	end
   274    296   	return call
          297  +end
          298  +m.acc.methods.compose = macro(function(self, ...)
          299  +	return composefn(function(minlen) return `self:init(minlen) end, ...)
          300  +end)
          301  +m.acc.methods.pcompose = macro(function(self, pool, ...)
          302  +	return composefn(function(minlen) return `self:pool(pool,minlen) end, ...)
   275    303   end)
          304  +
   276    305   m.acc.metamethods.__lshift = terralib.overloadedfunction('(<<)', {
   277    306   	terra(self: &m.acc, str: rawstring)         return self: push(str,0) end;
   278    307   	terra(self: &m.acc, str: lib.mem.ptr(int8)) return self:ppush(str  ) end;
   279    308   })
   280    309