diff options
Diffstat (limited to 'parsers')
-rw-r--r-- | parsers/rle.lua | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/parsers/rle.lua b/parsers/rle.lua new file mode 100644 index 0000000..cd10493 --- /dev/null +++ b/parsers/rle.lua @@ -0,0 +1,95 @@ +-- http://psoup.math.wisc.edu/mcell/ca_files_formats.html#RLE +local C, Cs, Ct, P, R, S, match = lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S, lpeg.match + +local rows = {} +local coords = {} + +local n_row = 1 +rows[n_row] = "" + +local eol = P"\n" +local hashmark = P"#" +local space = S" \t" +local whitespace = S(" \n\t")^0 +local num = R"09" +local comma = P"," +local exclam = P"!" +local equals = P"=" +local dollar = P"$" +local state = S"bo" +--local sign = S("+-")^0 -- support negative grid values? not yet + +local comment = hashmark * (1-eol)^0 * eol + +local getx = space^0 * P"x" * space^0 * equals * space^0 * C(num^1) / function (x) + coords.x = tonumber(x) +end +local gety = space^0 * P"y" * space^0 * equals * space^0 * C(num^1) / function (y) + coords.y = tonumber(y) +end +geometry = getx * comma * gety * (1-eol)^0 * eol + +local function n_of_t (n, c) + local tmp = "" + if c == "o" then -- live + c = "1" + else -- dead + c = "0" + end + + for i=1, n, 1 do + tmp = tmp .. c + end + return tmp +end + +local cell = C(num^0) * C(state) / function (n, c) + if n == "" then + n = 1 + end + + if n_of_t (tonumber(n), c) == nil then + print("OVER HERE", n_row,n, c) + end + rows[n_row] = rows[n_row] .. n_of_t (tonumber(n), c) +end + +local line = whitespace * (cell * whitespace)^0 * C(num^0) / function (empty) + + if rows[n_row]:len() < coords.x then -- fill grid with dead cells + rows[n_row] = rows[n_row] .. n_of_t( coords.x - rows[n_row]:len(), "0" ) + end + + if empty ~= "" then + for n=1, tonumber(empty)-1, 1 do + n_row = n_row + 1 + rows[n_row] = n_of_t( coords.x, "0" ) + end + end + + n_row = n_row + 1 + + if n_row <= coords.y then + rows[n_row] = "" + end +end + +local p_rle = comment^0 * geometry * line * (dollar * line)^0 * whitespace * exclam + +local function parser(fname) + local file = assert(io.open(fname, "r"), "Not a file: " .. fname) + local data = file:read("*all") + file:close() + + if p_rle:match(data) then + if context then + context.writestatus("simpleslides", "Sucessfully loaded frame from "..fname..".") + end + return rows + else + return false + end +end + +return parser + |