diff --git a/splubp.p8 b/splubp.p8 index 8a32f60..26bd681 100644 --- a/splubp.p8 +++ b/splubp.p8 @@ -4,7 +4,8 @@ __lua__ -- splubp data transport -- by kistaro windrider --- main +-- shrinko-8 hints +DEBUG = true --[[const]] -- >8 -- utilities @@ -44,54 +45,107 @@ function mknew(tt) return tt end -function set(t) - local ret = {} - for v in all(t) do - ret[v]=true +function trim(s) + local f, e = 1, #s + while (f <= e and s[f]==" ") f += 1 + while (e >= f and s[e]==" ") e -= 1 + if (f 0) add(row, cell) + end + if (#row > 0) add(ret, row) end return ret end -whitespace = set(split" ,\t,\n") - -function trim(s) - local f, e = 1, #s - while (f <= e and whitespace[s[f]]) f += 1 - while (e >= f and whitespace[s[e]]) e -= 1 - if (f 0) return sub(ret, 1, -2) return "" end +-- >8 +-- common + +--[[preserve-keys]] splubp = mknew{ + ptr = 0x8000, + init = function(self) + -- fill from ffile or saved file + self.fmts = {} + if (not self.ffile) self.ffile, self.ptr = self:e() + for f in all(split(self.ffile, "===", false)) do + local tok = shatter(f) + assert(#tok > 1, "not enough rows in "..tostr(tok)) -- debug + assert(#tok[1] == 1 and tok[1][1][1] == ".", "bad extension row: "..tostr(tok[1])) -- debug + self.fmts[sub(deli(tok, 1)[1], 1)] = tok + end + end, +} + +function splubp:e() + local ret = chr(peek(self.ptr + 2, %self.ptr)) + return ret, self.ptr + 2 + #ret +end + -- >8 -- writer -splubp_writer = mknew{ - init = function(self) - -- fill from single file - self.fmts = self.fmts or {} - if self.ffile then - for f in all(split(self.ffile, "===", false)) do - local ext, fmt = split(f, "---") - self.fmts[trim(ext)] = trim(fmt) - end +function splubp:emit_fmts() + self.ptr = self:emit_e(self.ffile) +end + +function splubp:emit_item(obj, filename) + debug_last_emit = obj -- global debug + filename = filename or obj._file + obj._addr = self.ptr + self.ptr = self:write_s(filename) + for row in all(self.fmts[split(filename, ".")[2]]) do + local alt = self.wdirectives[row[1]] + if alt then + self.ptr = alt(self, obj, row) + else + self.ptr = self:write_fmt(obj[row[1]], row, 2) end end -} +end +-- TODO: splubp.wdirectives -- a +-- table mapping non-key +-- special values to +-- functions to write them +-- TODO: write_fmt: recursive +-- writing thing + +function splubp:write_s(s) + poke(self.ptr, #s, ord(s, 1, #s)) + return self.ptr + 1 + #s +) +end + +function splubp:write_e(s) + poke2(self.ptr, #s) + poke(self.ptr+2, ord(s, 1, #s)) + return self.ptr + 2 + #s +end -->8 -- loader --- essay: `e` directive --- reads int16 char count, --- then parses that many bytes --- into a string (via chr). --- returns string, new read offset. -function splubp_read_essay(addr) - local cs, n = {}, %addr - for a2 = addr+2, addr+n+1 do - add(cs, @a2) - end - return chr(unpack(cs)), addr+2+n +function splubp:s() + local ret = chr(peek(self.ptr + 1, @self.ptr)) + return ret, self.ptr + 1 + #ret end -