diff --git a/src/bindings/lua/hammer.lua b/src/bindings/lua/hammer.lua index b3d975b9f9fde08f60a9438ac90f6c0eafdc40c4..2ee1656a098633801610a4ee181366d13dd69d10 100644 --- a/src/bindings/lua/hammer.lua +++ b/src/bindings/lua/hammer.lua @@ -176,20 +176,31 @@ counted_array = ffi.metatype("HCountedArray", arr_mt) local bytes_mt = { __call = function(self) local ret = "" - print(self.len) - for i = 0, tonumber(self.len)-1 + for i = 0, tonumber(ffi.cast("uintptr_t", ffi.cast("void *", self.len)))-1 do ret = ret .. string.char(self.token[i]) end return ret end } local byte_string = ffi.metatype("HBytes", bytes_mt) --- local parsed_token --- local tok_mt = { --- __call = function(self) --- end --- } --- parsed_token = ffi.metatype("HParsedToken", tok_mt) + +local token_types = ffi.new("HTokenType") + +local parsed_token +local tok_mt = { + __call = function(self) + if self.token_type == ffi.C.TT_BYTES then + return self.bytes() + elseif self.token_type == ffi.C.TT_SINT then + return tonumber(ffi.cast("intptr_t", ffi.cast("void *", self.sint))) + elseif self.token_type == ffi.C.TT_UINT then + return tonumber(ffi.cast("uintptr_t", ffi.cast("void *", self.uint))) + elseif self.token_type == ffi.C.TT_SEQUENCE then + return self.seq() + end + end +} +parsed_token = ffi.metatype("HParsedToken", tok_mt) function hammer.token(str) return h.h_token(str, #str) diff --git a/src/bindings/lua/test.lua b/src/bindings/lua/test.lua index cc0707b167672463fc6d7b90bcf429be8a09ff48..6b566ecc447bf9eae876c25bdf934d81559bea8d 100644 --- a/src/bindings/lua/test.lua +++ b/src/bindings/lua/test.lua @@ -3,6 +3,7 @@ describe("Combinator tests", function() setup(function() hammer = require("hammer") + ffi = require("ffi") end) teardown(function() @@ -25,7 +26,7 @@ describe("Combinator tests", function() local parser = hammer.ch(0xa2) it("parses a matching char", function() local ret = parser:parse(string.char(0xa2)) - assert.are.same(string.char(0xa2), ret.ast.uint) + assert.are.same(string.char(0xa2), string.char(ret.ast())) end) it("rejects a non-matching char", function() local ret = parser:parse(string.char(0xa3)) @@ -37,7 +38,7 @@ describe("Combinator tests", function() local parser = hammer.ch_range("a", "c") it("parses a char in the range", function() local ret = parser:parse("b") - assert.are.same("b", ret.ast.uint) + assert.are.same("b", string.char(ret.ast())) end) it("rejects a char outside the range", function() local ret = parser:parse("d") @@ -97,7 +98,7 @@ describe("Combinator tests", function() local parser = hammer.uint64() it("parses a valid 64-bit unsigned int", function() local ret = parser:parse(string.char(0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00)) - assert.are.same(0x200000000, ret.ast.uint) + assert.are.same(0x200000000, ret.ast()) end) it("does not parse an invalid 64-bit unsigned int", function() local ret = parser:parse(string.char(0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00)) @@ -109,7 +110,7 @@ describe("Combinator tests", function() local parser = hammer.uint32() it("parses a valid 32-bit unsigned int", function() local ret = parser:parse(string.char(0x00, 0x02, 0x00, 0x00)) - assert.are.same(0x20000, ret.ast.uint) + assert.are.same(0x20000, ret.ast()) end) it("does not parse an invalid 32-bit unsigned int", function() local ret = parser:parse(string.char(0x00, 0x02, 0x00)) @@ -121,7 +122,7 @@ describe("Combinator tests", function() local parser = hammer.uint16() it("parses a valid 16-bit unsigned int", function() local ret = parser:parse(string.char(0x02, 0x00)) - assert.are.same(0x200, ret.ast.uint) + assert.are.same(0x200, ret.ast()) end) it("does not parse an invalid 16-bit unsigned int", function() local ret = parser:parse(string.char(0x02)) @@ -133,7 +134,7 @@ describe("Combinator tests", function() local parser = hammer.uint8() it("parses a valid 8-bit unsigned int", function() local ret = parser:parse(string.char(0x78)) - assert.are.same(0x78, ret.ast.uint) + assert.are.same(0x78, ret.ast()) end) it("does not parse an invalid 8=bit unsigned int", function() local ret = parser:parse("") @@ -145,7 +146,7 @@ describe("Combinator tests", function() local parser = hammer.int_range(hammer.uint8(), 3, 10) it("parses a value in the range", function() local ret = parser:parse(string.char(0x05)) - assert.are.same(5, ret.ast.uint) + assert.are.same(5, ret.ast()) end) it("does not parse a value outside the range", function() local ret = parser:parse(string.char(0xb)) @@ -158,19 +159,19 @@ describe("Combinator tests", function() local parser2 = hammer.whitespace(hammer.end_p()) it("parses a string with no whitespace", function() local ret = parser:parse("a") - assert.are.same("a", ret.ast.uint) + assert.are.same("a", string.char(ret.ast())) end) it("parses a string with a leading space", function() local ret = parser:parse(" a") - assert.are.same("a", ret.ast.uint) + assert.are.same("a", string.char(ret.ast())) end) it("parses a string with leading spaces", function() local ret = parser:parse(" a") - assert.are.same("a", ret.ast.uint) + assert.are.same("a", string.char(ret.ast())) end) it("parses a string with a leading tab", function() local ret = parser:parse("\ta") - assert.are.same("a", ret.ast.uint) + assert.are.same("a", string.char(ret.ast())) end) it("does not parse a string with a leading underscore", function() local ret = parser:parse("_a") @@ -194,7 +195,7 @@ describe("Combinator tests", function() local parser = hammer.left(hammer.ch("a"), hammer.ch(" ")) it("parses the leftmost character", function() local ret = parser:parse("a ") - assert.are.same("a", ret.ast.uint) + assert.are.same("a", string.char(ret.ast())) end) it("does not parse a string that is too short", function() local ret = parser:parse("a") @@ -214,7 +215,7 @@ describe("Combinator tests", function() local parser = hammer.right(hammer.ch(" "), hammer.ch("a")) it("parses the rightmost character", function() local ret = parser:parse(" a") - assert.are.same("a", ret.ast.uint) + assert.are.same("a", string.char(ret.ast())) end) it("does not parse a string that starts with the wrong character", function() local ret = parser:parse("a") @@ -234,7 +235,7 @@ describe("Combinator tests", function() local parser = hammer.middle(hammer.ch(" "), hammer.ch("a"), hammer.ch(" ")) it("parses the middle character", function() local ret = parser:parse(" a ") - assert.are.same("a", ret.ast.uint) + assert.are.same("a", string.char(ret.ast())) end) it("does not parse a string that is too short", function() local ret = parser:parse("a") @@ -262,21 +263,21 @@ describe("Combinator tests", function() describe("Semantic action tests", function() local function upcase(result, user_data) - local chars = result.ast.seq() + local chars = result.ast() local ret = "" for i, v in ipairs(chars) - do ret = ret .. string.char(tonumber(v.uint)):upper() + do ret = ret .. string.char(v()):upper() end - return ret + return ffi.new("HParsedToken", {hammer.TT_BYTES, ret}) end local parser = hammer.action(hammer.sequence(hammer.choice(hammer.ch("a"), hammer.ch("A")), hammer.choice(hammer.ch("b"), hammer.ch("B"))), upcase, nil) it("converts a lowercase 'ab' to uppercase", function() local ret = parser:parse("ab") - assert.are.same({"A", "B"}, ret.ast.seq()) + assert.are.same("AB", ret.ast()) end) it("accepts an uppercase 'AB' unchanged", function() local ret = parser:parse("AB") - assert.are.same({"A", "B"}, ret.ast.seq()) + assert.are.same("AB", ret.ast()) end) it("rejects strings that don't match the underlying parser", function() local ret = parser:parse("XX") @@ -288,7 +289,7 @@ describe("Combinator tests", function() local parser = hammer.in_({"a", "b", "c"}) it("parses a character that is in the included set", function() local ret = parser:parse("b") - assert.are.same("b", ret.ast.uint) + assert.are.same("b", string.char(ret.ast())) end) it("does not parse a character that is not in the included set", function() local ret = parser:parse("d") @@ -300,7 +301,7 @@ describe("Combinator tests", function() local parser = hammer.not_in({"a", "b", "c"}) it("parses a character that is not in the excluded set", function() local ret = parser:parse("d") - assert.are.same("d", ret.ast.uint) + assert.are.same("d", string.char(ret.ast())) end) it("does not parse a character that is in the excluded set", function() local ret = parser:parse("a") @@ -309,10 +310,10 @@ describe("Combinator tests", function() end) describe("End-of-input tests", function() - local parser = hammer.seq()uence(hammer.ch("a"), hammer.end_p()) + local parser = hammer.sequence(hammer.ch("a"), hammer.end_p()) it("parses a string that ends where it is expected to", function() local ret = parser:parse("a") - assert.are.same({"a"}, ret.ast.seq()) + assert.are.same({"a"}, ret.ast()) end) it("does not parse a string that is too long", function() local ret = parser:parse("aa") @@ -333,7 +334,7 @@ describe("Combinator tests", function() local parser2 = hammer.sequence(hammer.ch("a"), hammer.whitespace(hammer.ch("b"))) it("parses a string matching the sequence", function() local ret = parser:parse("ab") - assert.are.same({"a", "b"}, ret.ast.seq()) + assert.are.same({"a", "b"}, ret.ast()) end) it("does not parse a string that is too short", function() local ret = parser:parse("a") @@ -345,14 +346,14 @@ describe("Combinator tests", function() end) it("parses a whitespace-optional string with no whitespace", function() local ret = parser2:parse("ab") - assert.are.same({"a", "b"}, ret.ast.seq()) + assert.are.same({"a", "b"}, ret.ast()) end) -- it("parses a whitespace-optional string containing whitespace", function() -- local ret = parser:parse("a b") - -- assert.are.same({"a", "b"}, ret.ast.seq()) -- this is the line that segfaults + -- assert.are.same({"a", "b"}, ret.ast()) -- this is the line that segfaults -- print("in sequence") -- ret = parser:parse("a b") - -- assert.are.same({"a", "b"}, ret.ast.seq()) + -- assert.are.same({"a", "b"}, ret.ast()) -- end) end) @@ -360,9 +361,9 @@ describe("Combinator tests", function() local parser = hammer.choice(hammer.ch("a"), hammer.ch("b")) it("parses a character in the choice set", function() local ret = parser:parse("a") - assert.are.same("a", ret.ast.uint) + assert.are.same("a", string.char(ret.ast())) ret = parser:parse("b") - assert.are.same("b", ret.ast.uint) + assert.are.same("b", string.char(ret.ast())) end) it("does not parse a character not in the choice set", function() local ret = parser:parse("c") @@ -375,9 +376,9 @@ describe("Combinator tests", function() local parser2 = hammer.butnot(hammer.ch_range("0", "9"), hammer.ch("6")) it("succeeds when 'a' matches but 'ab' doesn't", function() local ret = parser:parse("a") - assert.are.same("a", ret.ast.uint) + assert.are.same("a", string.char(ret.ast())) ret = parser:parse("aa") - assert.are.same("a", ret.ast.uint) + assert.are.same("a", string.char(ret.ast())) end) it("fails when p2's result is longer than p1's", function() local ret = parser:parse("ab") @@ -393,7 +394,7 @@ describe("Combinator tests", function() local parser = hammer.difference(hammer.token("ab"), hammer.ch("a")) it("succeeds when 'ab' matches and its result is longer than the result for 'a'", function() local ret = parser:parse("ab") - assert.are.same("ab", ret.ast.bytes()) + assert.are.same("ab", ret.ast()) end) it("fails if 'ab' doesn't match", function() local ret = parser:parse("a") @@ -405,11 +406,11 @@ describe("Combinator tests", function() local parser = hammer.xor(hammer.ch_range("0", "6"), hammer.ch_range("5", "9")) it("parses a value only in the first range", function() local ret = parser:parse("0") - assert.are.same("0", ret.ast.uint) + assert.are.same("0", string.char(ret.ast())) end) it("parses a value only in the second range", function() local ret = parser:parse("9") - assert.are.same("9", ret.ast.uint) + assert.are.same("9", string.char(ret.ast())) end) it("does not parse a value inside both ranges", function() local ret = parser:parse("5") @@ -425,17 +426,17 @@ describe("Combinator tests", function() local parser = hammer.many(hammer.choice(hammer.ch("a"), hammer.ch("b"))) it("parses an empty string", function() local ret = parser:parse("") - assert.are.same({}, ret.ast.seq()) + assert.are.same({}, ret.ast()) end) it("parses a single repetition of the pattern", function() local ret = parser:parse("a") - assert.are.same({"a"}, ret.ast.seq()) + assert.are.same({"a"}, ret.ast()) ret = parser:parse("b") - assert.are.same({"b"}, ret.ast.seq()) + assert.are.same({"b"}, ret.ast()) end) it("parses multiple repetitions of the pattern", function() local ret = parser:parse("aabbaba") - assert.are.same({"a", "a", "b", "b", "a", "b", "a"}, ret.ast.seq()) + assert.are.same({"a", "a", "b", "b", "a", "b", "a"}, ret.ast()) end) end) @@ -447,13 +448,13 @@ describe("Combinator tests", function() end) it("parses a single repetition of the pattern", function() local ret = parser:parse("a") - assert.are.same({"a"}, ret.ast.seq()) + assert.are.same({"a"}, ret.ast()) ret = parser:parse("b") - assert.are.same({"b"}, ret.ast.seq()) + assert.are.same({"b"}, ret.ast()) end) it("parses multiple repetitions of the pattern", function() local ret = parser:parse("aabbaba") - assert.are.same({"a", "a", "b", "b", "a", "b", "a"}, ret.ast.seq()) + assert.are.same({"a", "a", "b", "b", "a", "b", "a"}, ret.ast()) end) it("does not parse a string that does not start with one of the patterns to repeat", function() local ret = parser:parse("daabbabadef") @@ -469,7 +470,7 @@ describe("Combinator tests", function() end) it("parses a string containing the correct number of repetitions", function() local ret = parser:parse("abdef") - assert.are.same({"a", "b"}, ret.ast.seq()) + assert.are.same({"a", "b"}, ret.ast()) end) it("does not parse a string that does not start with a character in the repetition set", function() local ret = parser:parse("dabdef") @@ -481,13 +482,13 @@ describe("Combinator tests", function() local parser = hammer.sequence(hammer.ch("a"), hammer.optional(hammer.choice(hammer.ch("b"), hammer.ch("c"))), hammer.ch("d")) it("parses a string containing either optional character", function() local ret = parser:parse("abd") - assert.are.same({"a", "b", "d"}, ret.ast.seq()) + assert.are.same({"a", "b", "d"}, ret.ast()) ret = parser:parse("acd") - assert.are.same({"a", "c", "d"}, ret.ast.seq()) + assert.are.same({"a", "c", "d"}, ret.ast()) end) it("parses a string missing one of the optional characters", function() local ret = parser:parse("ad") - assert.are.same({"a", {}, "d"}, ret.ast.seq()) + assert.are.same({"a", {}, "d"}, ret.ast()) end) it("does not parse a string containing a character not among the optional ones", function() local ret = parser:parse("aed") @@ -499,7 +500,7 @@ describe("Combinator tests", function() local parser = hammer.sequence(hammer.ch("a"), hammer.ignore(hammer.ch("b")), hammer.ch("c")) it("parses a string containing the pattern to ignore, and leaves that pattern out of the result", function() local ret = parser:parse("abc") - assert.are.same({"a", "c"}, ret.ast.seq()) + assert.are.same({"a", "c"}, ret.ast()) end) it("does not parse a string not containing the pattern to ignore", function() local ret = parser:parse("ac") @@ -511,23 +512,23 @@ describe("Combinator tests", function() local parser = hammer.sepBy(hammer.choice(hammer.ch("1"), hammer.ch("2"), hammer.ch("3")), hammer.ch(",")) it("parses an ordered list", function() local ret = parser:parse("1,2,3") - assert.are.same({"1", "2", "3"}, ret.ast.seq()) + assert.are.same({"1", "2", "3"}, ret.ast()) end) it("parses an unordered list", function() local ret = parser:parse("1,3,2") - assert.are.same({"1", "3", "2"}, ret.ast.seq()) + assert.are.same({"1", "3", "2"}, ret.ast()) end) it("parses a list not containing all options", function() local ret = parser:parse("1,3") - assert.are.same({"1", "3"}, ret.ast.seq()) + assert.are.same({"1", "3"}, ret.ast()) end) it("parses a unary list", function() local ret = parser:parse("3") - assert.are.same({"3"}, ret.ast.seq()) + assert.are.same({"3"}, ret.ast()) end) it("parses an empty list", function() local ret = parser:parse("") - assert.are.same({}, ret.ast.seq()) + assert.are.same({}, ret.ast()) end) end) @@ -535,20 +536,20 @@ describe("Combinator tests", function() local parser = hammer.sepBy1(hammer.choice(hammer.ch("1"), hammer.ch("2"), hammer.ch("3")), hammer.ch(",")) it("parses an ordered list", function() local ret = parser:parse("1,2,3") - assert.are.same({"1", "2", "3"}, ret.ast.seq()) + assert.are.same({"1", "2", "3"}, ret.ast()) end) it("parses an unordered list", function() local ret = parser:parse("1,3,2") - assert.are.same({"1", "3", "2"}, ret.ast.seq()) + assert.are.same({"1", "3", "2"}, ret.ast()) end) it("parses a list not containing all options", function() local ret = parser:parse("1,3") - assert.are.same({"1", "3"}, ret.ast.seq()) + assert.are.same({"1", "3"}, ret.ast()) end) -- it("parses a unary list", function() -- local ret = parser:parse("3") -- print("in sepBy1") - -- assert.are.same({"3"}, ret.ast.seq()) -- this line also segfaults + -- assert.are.same({"3"}, ret.ast()) -- this line also segfaults -- end) it("does not parse an empty list", function() local ret = parser:parse("") @@ -562,15 +563,15 @@ describe("Combinator tests", function() local parser3 = hammer.sequence(hammer.ch("a"), hammer.epsilon_p()) it("parses an empty string between two characters", function() local ret = parser:parse("ab") - assert.are.same({"a", "b"}, ret.ast.seq()) + assert.are.same({"a", "b"}, ret.ast()) end) it("parses an empty string before a character", function() local ret = parser2:parse("a") - assert.are.same({"a"}, ret.ast.seq()) + assert.are.same({"a"}, ret.ast()) end) - it("parses a ", function() + it("parses an empty string after a character", function() local ret = parser3:parse("a") - assert.are.same({"a"}, ret.ast.seq()) + assert.are.same({"a"}, ret.ast()) end) end) @@ -581,9 +582,9 @@ describe("Combinator tests", function() local parser = hammer.attr_bool(hammer.many1(hammer.choice(hammer.ch("a"), hammer.ch("b"))), equals) it("parses successfully when both characters are the same (i.e., the validation function succeeds)", function() local ret = parser:parse("aa") - assert.are.same({"a", "a"}, ret.ast.seq()) + assert.are.same({"a", "a"}, ret.ast()) ret = parser:parse("bb") - assert.are.same({"b", "b"}, ret.ast.seq()) + assert.are.same({"b", "b"}, ret.ast()) end) it("does not parse successfully when the characters are different (i.e., the validation function fails)", function() local ret = parser:parse("ab") @@ -597,7 +598,7 @@ describe("Combinator tests", function() local parser3 = hammer.sequence(hammer.ch("1"), hammer.and_(hammer.ch("2"))) it("parses successfully when the lookahead matches the next character to parse", function() local ret = parser:parse("0") - assert.are.same({"0"}, ret.ast.seq()) + assert.are.same({"0"}, ret.ast()) end) it("does not parse successfully when the lookahead does not match the next character to parse", function() local ret = parser2:parse("0") @@ -605,7 +606,7 @@ describe("Combinator tests", function() end) it("parses successfully when the lookahead is there", function() local ret = parser3:parse("12") - assert.are.same({"1"}, ret.ast.seq()) + assert.are.same({"1"}, ret.ast()) end) end) @@ -614,7 +615,7 @@ describe("Combinator tests", function() local parser2 = hammer.sequence(hammer.ch("a"), hammer.choice(hammer.sequence(hammer.ch("+"), hammer.not_(hammer.ch("+"))), hammer.token("++")), hammer.ch("b")) it("parses a single plus correctly in the 'choice' example", function() local ret = parser:parse("a+b") - assert.are.same({"a", "+", "b"}, ret.ast.seq()) + assert.are.same({"a", "+", "b"}, ret.ast()) end) it("does not parse a double plus correctly in the 'choice' example", function() local ret = parser:parse("a++b") @@ -622,11 +623,11 @@ describe("Combinator tests", function() end) it("parses a single plus correctly in the 'not' example", function() local ret = parser2:parse("a+b") - assert.are.same({"a", {"+"}, "b"}, ret.ast.seq()) + assert.are.same({"a", {"+"}, "b"}, ret.ast()) end) it("parses a double plus correctly in the 'not' example", function() local ret = parser2:parse("a++b") - assert.are.same({"a", "++", "b"}, ret.ast.seq()) + assert.are.same({"a", "++", "b"}, ret.ast()) end) end) @@ -636,16 +637,15 @@ describe("Combinator tests", function() -- it("parses the base case", function() -- print("in leftrec") -- local ret = parser:parse("a") -- this line segfaults - -- assert.are.same({"a"}, ret.ast.seq()) + -- assert.are.same({"a"}, ret.ast()) -- end) it("parses one level of recursion", function() - print("in leftrec") local ret = parser:parse("aa") - assert.are.same({"a", "a"}, ret.ast.seq()) + assert.are.same({"a", "a"}, ret.ast()) end) it("parses two levels of recursion", function() local ret = parser:parse("aaa") - assert.are.same({{"a", "a"}, "a"}, ret.ast.seq()) + assert.are.same({{"a", "a"}, "a"}, ret.ast()) end) end) @@ -654,15 +654,15 @@ describe("Combinator tests", function() hammer.bind_indirect(parser, hammer.choice(hammer.sequence(hammer.ch("a"), parser), hammer.epsilon_p())) it("parses the base case", function() local ret = parser:parse("a") - assert.are.same({"a"}, ret.ast.seq()) + assert.are.same({"a"}, ret.ast()) end) it("parses one level of recursion", function() local ret = parser:parse("aa") - assert.are.same({"a", {"a"}}, ret.ast.seq()) + assert.are.same({"a", {"a"}}, ret.ast()) end) it("parses two levels of recursion", function() local ret = parser:parse("aaa") - assert.are.same({"a", {"a", {"a"}}}, ret.ast.seq()) + assert.are.same({"a", {"a", {"a"}}}, ret.ast()) end) end) @@ -684,25 +684,25 @@ describe("Combinator tests", function() local parser8 = hammer.with_endianness(lb, u5) it("parses big-endian cases", function() local ret = parser1:parse("abcd") - assert.are.same(0x61626364, ret.ast.uint) + assert.are.same(0x61626364, ret.ast()) ret = parser2:parse("abcd") - assert.are.same(0xc, ret.ast.uint) + assert.are.same(0xc, ret.ast()) end) it("parses little-endian cases", function() local ret = parser3:parse("abcd") - assert.are.same(0x61626364, ret.ast.uint) + assert.are.same(0x61626364, ret.ast()) ret = parser4:parse("abcd") - assert.are.same(0xc, ret.ast.uint) + assert.are.same(0xc, ret.ast()) end) it("parses mixed-endian cases", function() local ret = parser5:parse("abcd") - assert.are.same(0x61626364, ret.ast.uint) + assert.are.same(0x61626364, ret.ast()) ret = parser6:parse("abcd") - assert.are.same(0x1, ret.ast.uint) + assert.are.same(0x1, ret.ast()) ret = parser7:parse("abcd") - assert.are.same(0x64636261, ret.ast.uint) + assert.are.same(0x64636261, ret.ast()) ret = parser8:parse("abcd") - assert.are.same(0xc, ret.ast.uint) + assert.are.same(0xc, ret.ast()) end) end) @@ -710,8 +710,8 @@ describe("Combinator tests", function() local parser = hammer.sequence(hammer.put_value(hammer.uint8(), "size"), hammer.token("foo"), hammer.length_value(hammer.get_value("size"), hammer.uint8())) it("parses a string that has enough bytes for the specified length", function() local ret = parser:parse(string.char(0x06) .. "fooabcdef") - assert.are.same("foo", ret.ast.seq[2]) - assert.are.same({0x61, 0x62, 0x63, 0x64, 0x65, 0x66}, ret.ast.seq[3]) + assert.are.same("foo", ret.ast()[2]) + assert.are.same({0x61, 0x62, 0x63, 0x64, 0x65, 0x66}, ret.ast()[3]) end) it("does not parse a string that does not have enough bytes for the specified length", function() local ret = parser:parse(string.char(0x06) .. "fooabcde") @@ -723,17 +723,17 @@ describe("Combinator tests", function() local parser = hammer.permutation(hammer.ch("a"), hammer.ch("b"), hammer.ch("c")) it("parses a permutation of 'abc'", function() local ret = parser:parse("abc") - assert.are.same({"a", "b", "c"}, ret.ast.seq()) + assert.are.same({"a", "b", "c"}, ret.ast()) ret = parser:parse("acb") - assert.are.same({"a", "c", "b"}, ret.ast.seq()) + assert.are.same({"a", "c", "b"}, ret.ast()) ret = parser:parse("bac") - assert.are.same({"b", "a", "c"}, ret.ast.seq()) + assert.are.same({"b", "a", "c"}, ret.ast()) ret = parser:parse("bca") - assert.are.same({"b", "c", "a"}, ret.ast.seq()) + assert.are.same({"b", "c", "a"}, ret.ast()) ret = parser:parse("cab") - assert.are.same({"c", "a", "b"}, ret.ast.seq()) + assert.are.same({"c", "a", "b"}, ret.ast()) ret = parser:parse("cba") - assert.are.same({"c", "b", "a"}, ret.ast.seq()) + assert.are.same({"c", "b", "a"}, ret.ast()) end) it("does not parse a string that is not a permutation of 'abc'", function() local ret = parser:parse("a") @@ -746,21 +746,21 @@ describe("Combinator tests", function() parser = hammer.permutation(hammer.ch("a"), hammer.ch("b"), hammer.optional(hammer.ch("c"))) it("parses a string that is a permutation of 'ab[c]'", function() local ret = parser:parse("abc") - assert.are.same({"a", "b", "c"}, ret.ast.seq()) + assert.are.same({"a", "b", "c"}, ret.ast()) ret = parser:parse("acb") - assert.are.same({"a", "c", "b"}, ret.ast.seq()) + assert.are.same({"a", "c", "b"}, ret.ast()) ret = parser:parse("bac") - assert.are.same({"b", "a", "c"}, ret.ast.seq()) + assert.are.same({"b", "a", "c"}, ret.ast()) ret = parser:parse("bca") - assert.are.same({"b", "c", "a"}, ret.ast.seq()) + assert.are.same({"b", "c", "a"}, ret.ast()) ret = parser:parse("cab") - assert.are.same({"c", "a", "b"}, ret.ast.seq()) + assert.are.same({"c", "a", "b"}, ret.ast()) ret = parser:parse("cba") - assert.are.same({"c", "b", "a"}, ret.ast.seq()) + assert.are.same({"c", "b", "a"}, ret.ast()) ret = parser:parse("ab") - assert.are.same({"a", "b"}, ret.ast.seq()) + assert.are.same({"a", "b"}, ret.ast()) ret = parser:parse("ba") - assert.are.same({"b", "a"}, ret.ast.seq()) + assert.are.same({"b", "a"}, ret.ast()) end) it("does not parse a string that is not a permutation of 'ab[c]'", function() local ret = parser:parse("a") @@ -783,21 +783,21 @@ describe("Combinator tests", function() parser = hammer.permutation(hammer.optional(hammer.ch("c")), hammer.ch("a"), hammer.ch("b")) it("parses a string that is a permutation of '[c]ab'", function() local ret = parser:parse("abc") - assert.are.same({"a", "b", "c"}, ret.ast.seq()) + assert.are.same({"a", "b", "c"}, ret.ast()) ret = parser:parse("acb") - assert.are.same({"a", "c", "b"}, ret.ast.seq()) + assert.are.same({"a", "c", "b"}, ret.ast()) ret = parser:parse("bac") - assert.are.same({"b", "a", "c"}, ret.ast.seq()) + assert.are.same({"b", "a", "c"}, ret.ast()) ret = parser:parse("bca") - assert.are.same({"b", "c", "a"}, ret.ast.seq()) + assert.are.same({"b", "c", "a"}, ret.ast()) ret = parser:parse("cab") - assert.are.same({"c", "a", "b"}, ret.ast.seq()) + assert.are.same({"c", "a", "b"}, ret.ast()) ret = parser:parse("cba") - assert.are.same({"c", "b", "a"}, ret.ast.seq()) + assert.are.same({"c", "b", "a"}, ret.ast()) ret = parser:parse("ab") - assert.are.same({"a", "b"}, ret.ast.seq()) + assert.are.same({"a", "b"}, ret.ast()) ret = parser:parse("ba") - assert.are.same({"b", "a"}, ret.ast.seq()) + assert.are.same({"b", "a"}, ret.ast()) end) it("does not parse a string that is not a permutation of '[c]ab'", function() local ret = parser:parse("a")