diff --git a/splubp.p8 b/splubp.p8 index 26bd681..ace9cd5 100644 --- a/splubp.p8 +++ b/splubp.p8 @@ -89,36 +89,65 @@ end 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 + if DEBUG then + assert(#tok > 1, "not enough rows in "..tostr(tok)) + assert(#tok[1] == 1, "bad extension row: "..tostr(tok[1])) + end + self.fmts[deli(tok, 1)[1]] = tok end end, } +function splubp:ppi(n) + self.ptr += n + return self.ptr - n +end + +function splubp:op() + self.cri += 1 + return self.row[self.cri] +end + +function splubp:c(n) + n = n or 1 + return peek(self:ppi(n), n) +end + +function splubp:i() + return %self:ppi(2) +end + +function splubp:n() + return $self:ppi(4) +end + function splubp:e() - local ret = chr(peek(self.ptr + 2, %self.ptr)) - return ret, self.ptr + 2 + #ret + return chr(self:c(self:i())) end -- >8 -- writer function splubp:emit_fmts() - self.ptr = self:emit_e(self.ffile) + self:write_e(self.ffile) +end + +-- execute next op (write data) +function splubp:wnx(...) + return self["write_"..self:op()](self, ...) 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) + 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) + alt(self, obj, row) else - self.ptr = self:write_fmt(obj[row[1]], row, 2) + self:write_fmt(obj[row[1]], row, 2) end end end @@ -130,22 +159,61 @@ end -- TODO: write_fmt: recursive -- writing thing +-- Write each argument as one +-- byte at self.ptr, then +-- increment self.ptr by the +-- number of bytes written. +function splubp:write_c(...) + poke(self:ppi(#{...}), ...) +end + +-- Like etch but it takes only +-- a single 2-byte int. +function splubp:write_i(i) + poke2(self:ppi(2), i) +end + +-- Like etch but it takes only +-- a single 4-byte number. +function splubp:write_n(n) + poke4(self:ppi(4), n) +end + function splubp:write_s(s) - poke(self.ptr, #s, ord(s, 1, #s)) - return self.ptr + 1 + #s -) + self:write_c(#s, ord(s, 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 + self:write_i(#s) + self:write_c(ord(s,1,#s)) +end + +splubp.write_b = splubp.write_c + +function splubp:write_shr(n) + n <<= self:op() + self:wnx(n) end -->8 -- loader -function splubp:s() - local ret = chr(peek(self.ptr + 1, @self.ptr)) - return ret, self.ptr + 1 + #ret +-- execute next op (read) +function splubp:rnx() + return self[self:op()](self) +end + +function splubp:s() + return chr(self:c(self:c())) +end + +function splubp:b() + local ret = self:c() + if (ret < 128) return ret + return ret-256 +end + +function splubp:shr() + local amt = self:op() + return self:rnx() >>> amt end