C++ bindings now work!
This commit is contained in:
parent
a942880d50
commit
7e5e0f00b6
7 changed files with 195 additions and 86 deletions
|
|
@ -19,6 +19,10 @@
|
|||
#define HAMMER_ALLOCATOR__H__
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// TODO(thequux): Turn this into an "HAllocatorVtable", and add a wrapper that also takes an environment pointer.
|
||||
typedef struct HAllocator_ {
|
||||
void* (*alloc)(struct HAllocator_* allocator, size_t size);
|
||||
|
|
@ -44,5 +48,8 @@ typedef struct {
|
|||
|
||||
void h_allocator_stats(HArena *arena, HArenaStats *stats);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // #ifndef LIB_ALLOCATOR__H__
|
||||
|
|
|
|||
2
src/bindings/cpp/.gitignore
vendored
Normal file
2
src/bindings/cpp/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
hammer_test
|
||||
test_detail.xml
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
Import("env libhammer_shared")
|
||||
|
||||
cppenv = env.Clone()
|
||||
cppenv.Append(CPPPATH=[".", "vendor/gtest-1.7.0/fused-src"])
|
||||
cppenv.Append(CPPPATH=[".", "vendor/gtest-1.7.0/fused-src", "../.."])
|
||||
cppenv.MergeFlags("-Wno-missing-field-initializers -DGTEST_HAS_PTHREAD=0")
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include <hammer/hammer.hpp>
|
||||
#include <hammer/internal.h>
|
||||
#include <hammer/hammer_test.hpp>
|
||||
|
||||
#define a_new_(arena, typ, count) ((typ*)h_arena_malloc((arena), sizeof(typ)*(count)))
|
||||
|
||||
namespace {
|
||||
using namespace ::hammer;
|
||||
TEST(ParserTypes, Token) {
|
||||
|
|
@ -24,23 +27,23 @@ namespace {
|
|||
|
||||
TEST(ParserTypes, Int64) {
|
||||
Parser p = Int64();
|
||||
EXPECT_TRUE(ParsesTo(p, "\xff\xff\xff\xfe\x00\x00\x00\x00", "s-0x200000000"));
|
||||
EXPECT_TRUE(ParseFails(p, "\xff\xff\xff\xfe\x00\x00\x00"));
|
||||
EXPECT_TRUE(ParsesTo(p, std::string("\xff\xff\xff\xfe\x00\x00\x00\x00", 8), "s-0x200000000"));
|
||||
EXPECT_TRUE(ParseFails(p, std::string("\xff\xff\xff\xfe\x00\x00\x00", 7)));
|
||||
}
|
||||
|
||||
TEST(ParserTypes, Int32) {
|
||||
Parser p = Int32();
|
||||
EXPECT_TRUE(ParsesTo(p, "\xff\xfe\x00\x00", "s-0x20000"));
|
||||
EXPECT_TRUE(ParseFails(p, "\xff\xfe\x00"));
|
||||
EXPECT_TRUE(ParsesTo(p, "\x00\x02\x00\x00","s0x20000"));
|
||||
EXPECT_TRUE(ParseFails(p, "\x00\x02\x00"));
|
||||
EXPECT_TRUE(ParsesTo(p, std::string("\xff\xfe\x00\x00", 4), "s-0x20000"));
|
||||
EXPECT_TRUE(ParseFails(p, std::string("\xff\xfe\x00", 3)));
|
||||
EXPECT_TRUE(ParsesTo(p, std::string("\x00\x02\x00\x00",4) ,"s0x20000"));
|
||||
EXPECT_TRUE(ParseFails(p, std::string("\x00\x02\x00", 3)));
|
||||
}
|
||||
|
||||
TEST(ParserTypes, Int16) {
|
||||
Parser p = Int16();
|
||||
EXPECT_TRUE(ParsesTo(p, "\xfe\x00", "s-0x200"));
|
||||
EXPECT_TRUE(ParsesTo(p, std::string("\xfe\x00", 2), "s-0x200"));
|
||||
EXPECT_TRUE(ParseFails(p, "\xfe"));
|
||||
EXPECT_TRUE(ParsesTo(p, "\x02\x00", "s0x200"));
|
||||
EXPECT_TRUE(ParsesTo(p, std::string("\x02\x00", 2), "s0x200"));
|
||||
EXPECT_TRUE(ParseFails(p, "\x01"));
|
||||
}
|
||||
|
||||
|
|
@ -52,19 +55,19 @@ namespace {
|
|||
|
||||
TEST(ParserTypes, Uint64) {
|
||||
Parser p = Uint64();
|
||||
EXPECT_TRUE(ParsesTo(p, "\x00\x00\x00\x02\x00\x00\x00\x00", "u0x200000000"));
|
||||
EXPECT_TRUE(ParseFails(p, "\x00\x00\x00\x02\x00\x00\x00"));
|
||||
EXPECT_TRUE(ParsesTo(p, std::string("\x00\x00\x00\x02\x00\x00\x00\x00", 8), "u0x200000000"));
|
||||
EXPECT_TRUE(ParseFails(p, std::string("\x00\x00\x00\x02\x00\x00\x00", 7)));
|
||||
}
|
||||
|
||||
TEST(ParserTypes, Uint32) {
|
||||
Parser p = Uint32();
|
||||
EXPECT_TRUE(ParsesTo(p, "\x00\x02\x00\x00", "u0x20000"));
|
||||
EXPECT_TRUE(ParseFails(p, "\x00\x02\x00"));
|
||||
EXPECT_TRUE(ParsesTo(p, std::string("\x00\x02\x00\x00", 4), "u0x20000"));
|
||||
EXPECT_TRUE(ParseFails(p, std::string("\x00\x02\x00", 3)));
|
||||
}
|
||||
|
||||
TEST(ParserTypes, Uint16) {
|
||||
Parser p = Uint16();
|
||||
EXPECT_TRUE(ParsesTo(p, "\x02\x00", "u0x200"));
|
||||
EXPECT_TRUE(ParsesTo(p, std::string("\x02\x00", 2), "u0x200"));
|
||||
EXPECT_TRUE(ParseFails(p, "\x02"));
|
||||
}
|
||||
|
||||
|
|
@ -82,7 +85,7 @@ namespace {
|
|||
|
||||
TEST(ParserTypes, Whitespace) {
|
||||
Parser p = Whitespace(Ch('a'));
|
||||
Parser q = Whitespace(EndP());
|
||||
Parser q = Whitespace(End());
|
||||
EXPECT_TRUE(ParsesTo(p, "a", "u0x61"));
|
||||
EXPECT_TRUE(ParsesTo(p, " a", "u0x61"));
|
||||
EXPECT_TRUE(ParsesTo(p, " a", "u0x61"));
|
||||
|
|
@ -121,13 +124,45 @@ namespace {
|
|||
EXPECT_TRUE(ParseFails(p, " ab"));
|
||||
}
|
||||
|
||||
// TODO action function
|
||||
#include <ctype.h>
|
||||
|
||||
HParsedToken* upcase(const HParseResult *p, void* user_data) {
|
||||
switch(p->ast->token_type) {
|
||||
case TT_SEQUENCE:
|
||||
{
|
||||
HParsedToken *ret = a_new_(p->arena, HParsedToken, 1);
|
||||
HCountedArray *seq = h_carray_new_sized(p->arena, p->ast->seq->used);
|
||||
ret->token_type = TT_SEQUENCE;
|
||||
for (size_t i=0; i<p->ast->seq->used; ++i) {
|
||||
if (TT_UINT == ((HParsedToken*)p->ast->seq->elements[i])->token_type) {
|
||||
HParsedToken *tmp = a_new_(p->arena, HParsedToken, 1);
|
||||
tmp->token_type = TT_UINT;
|
||||
tmp->uint = toupper(((HParsedToken*)p->ast->seq->elements[i])->uint);
|
||||
h_carray_append(seq, tmp);
|
||||
} else {
|
||||
h_carray_append(seq, p->ast->seq->elements[i]);
|
||||
}
|
||||
}
|
||||
ret->seq = seq;
|
||||
return ret;
|
||||
}
|
||||
case TT_UINT:
|
||||
{
|
||||
HParsedToken *ret = a_new_(p->arena, HParsedToken, 1);
|
||||
ret->token_type = TT_UINT;
|
||||
ret->uint = toupper(p->ast->uint);
|
||||
return ret;
|
||||
}
|
||||
default:
|
||||
return (HParsedToken*)p->ast;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ParserTypes, Action) {
|
||||
Parser p = Action(Sequence(Choice(Ch('a'), Ch('A'), NULL),
|
||||
Choice(Ch('b'), Ch('B'), NULL),
|
||||
NULL),
|
||||
toupper); // this won't compile
|
||||
upcase);
|
||||
EXPECT_TRUE(ParsesTo(p, "ab", "(u0x41 u0x42)"));
|
||||
EXPECT_TRUE(ParsesTo(p, "AB", "(u0x41 u0x42)"));
|
||||
EXPECT_TRUE(ParseFails(p, "XX"));
|
||||
|
|
@ -145,14 +180,14 @@ namespace {
|
|||
EXPECT_TRUE(ParseFails(p, "a"));
|
||||
}
|
||||
|
||||
TEST(ParserTypes, EndP) {
|
||||
Parser p = Sequence(Ch('a'), EndP(), NULL);
|
||||
TEST(ParserTypes, End) {
|
||||
Parser p = Sequence(Ch('a'), End(), NULL);
|
||||
EXPECT_TRUE(ParsesTo(p, "a", "(u0x61)"));
|
||||
EXPECT_TRUE(ParseFails(p, "aa"));
|
||||
}
|
||||
|
||||
TEST(ParserTypes, NothingP) {
|
||||
Parser p = NothingP();
|
||||
TEST(ParserTypes, Nothing) {
|
||||
Parser p = Nothing();
|
||||
EXPECT_TRUE(ParseFails(p, "a"));
|
||||
}
|
||||
|
||||
|
|
@ -207,7 +242,7 @@ namespace {
|
|||
|
||||
TEST(ParserTypes, Many1) {
|
||||
Parser p = Many1(Choice(Ch('a'), Ch('b'), NULL));
|
||||
EXPECT_TRUE(ParseFails(p, "", "()"));
|
||||
EXPECT_TRUE(ParseFails(p, ""));
|
||||
EXPECT_TRUE(ParsesTo(p, "a", "(u0x61)"));
|
||||
EXPECT_TRUE(ParsesTo(p, "b", "(u0x62)"));
|
||||
EXPECT_TRUE(ParsesTo(p, "aabbaba", "(u0x61 u0x61 u0x62 u0x62 u0x61 u0x62 u0x61)"));
|
||||
|
|
@ -232,7 +267,7 @@ namespace {
|
|||
}
|
||||
|
||||
TEST(ParserTypes, Ignore) {
|
||||
Parser p = Sequence(Ch('a'), Ignore(Ch('b'), Ch('c'), NULL));
|
||||
Parser p = Sequence(Ch('a'), Ignore(Ch('b')), Ch('c'), NULL);
|
||||
EXPECT_TRUE(ParsesTo(p, "abc", "(u0x61 u0x63)"));
|
||||
EXPECT_TRUE(ParseFails(p, "ac"));
|
||||
}
|
||||
|
|
@ -256,15 +291,23 @@ namespace {
|
|||
}
|
||||
|
||||
TEST(ParserTypes, EpsilonP) {
|
||||
Parser p = Sequence(Ch('a'), EpsilonP(), Ch('b'), NULL);
|
||||
Parser q = Sequence(EpsilonP(), Ch('a'), NULL);
|
||||
Parser r = Sequence(Ch('a'), EpsilonP(), NULL);
|
||||
Parser p = Sequence(Ch('a'), Epsilon(), Ch('b'), NULL);
|
||||
Parser q = Sequence(Epsilon(), Ch('a'), NULL);
|
||||
Parser r = Sequence(Ch('a'), Epsilon(), NULL);
|
||||
EXPECT_TRUE(ParsesTo(p, "ab", "(u0x61 u0x62)"));
|
||||
EXPECT_TRUE(ParsesTo(q, "a", "(u0x61)"));
|
||||
EXPECT_TRUE(ParsesTo(r, "a", "(u0x61)"));
|
||||
}
|
||||
|
||||
bool validate_test_ab() { return false; }
|
||||
bool validate_test_ab(HParseResult *p, void* user_data) {
|
||||
if (TT_SEQUENCE != p->ast->token_type)
|
||||
return false;
|
||||
if (TT_UINT != p->ast->seq->elements[0]->token_type)
|
||||
return false;
|
||||
if (TT_UINT != p->ast->seq->elements[1]->token_type)
|
||||
return false;
|
||||
return (p->ast->seq->elements[0]->uint == p->ast->seq->elements[1]->uint);
|
||||
}
|
||||
|
||||
TEST(ParserTypes, AttrBool) {
|
||||
Parser p = AttrBool(Many1(Choice(Ch('a'), Ch('b'), NULL)),
|
||||
|
|
@ -293,21 +336,21 @@ namespace {
|
|||
Ch('b'), NULL);
|
||||
EXPECT_TRUE(ParsesTo(p, "a+b", "(u0x61 u0x2b u0x62)"));
|
||||
EXPECT_TRUE(ParseFails(p, "a++b"));
|
||||
EXPECT_TRUE(ParsesTo(p, "a+b", "(u0x61 (u0x2b) u0x62)"));
|
||||
EXPECT_TRUE(ParsesTo(p, "a++b", "(u0x61 <2b.2b> u0x62)"));
|
||||
EXPECT_TRUE(ParsesTo(q, "a+b", "(u0x61 (u0x2b) u0x62)"));
|
||||
EXPECT_TRUE(ParsesTo(q, "a++b", "(u0x61 <2b.2b> u0x62)"));
|
||||
}
|
||||
|
||||
/*
|
||||
TEST(ParserTypes, Leftrec) {
|
||||
IndirectParser p = Indirect();
|
||||
p.bind(Choice(Sequence(p, Ch('a'), NULL), EpsilonP(), NULL));
|
||||
Indirect p = Indirect();
|
||||
p.bind(Choice(Sequence(p, Ch('a'), NULL), Epsilon(), NULL));
|
||||
EXPECT_TRUE(ParsesTo(p, "a", "(u0x61)"));
|
||||
EXPECT_TRUE(ParsesTo(p, "aa", "((u0x61) u0x61)"));
|
||||
EXPECT_TRUE(ParsesTo(p, "aaa", "(((u0x61) u0x61) u0x61)"));
|
||||
}
|
||||
|
||||
*/
|
||||
TEST(ParserTypes, Rightrec) {
|
||||
IndirectParser p = Indirect();
|
||||
p.bind(Choice(Sequence(Ch('a'), p, NULL), EpsilonP(), NULL));
|
||||
Indirect p = Indirect();
|
||||
p.bind(Choice(Sequence(Ch('a'), p, NULL), Epsilon(), NULL));
|
||||
EXPECT_TRUE(ParsesTo(p, "a", "(u0x61)"));
|
||||
EXPECT_TRUE(ParsesTo(p, "aa", "(u0x61 (u0x61))"));
|
||||
EXPECT_TRUE(ParsesTo(p, "aaa", "(u0x61 (u0x61 (u0x61)))"));
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
#include <hammer/hammer.h>
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
#include <cstdarg>
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused"
|
||||
|
||||
namespace hammer {
|
||||
class ParseResult;
|
||||
|
|
@ -12,9 +15,9 @@ namespace hammer {
|
|||
const HParser *parser;
|
||||
|
||||
Parser(const HParser* inner) : parser(inner) {}
|
||||
Parser(const Parser &other) : parser(other.parser) {}
|
||||
|
||||
ParseResult parse(std::string string);
|
||||
//static Parser nil = Parser(NULL);
|
||||
ParseResult parse(const std::string &string);
|
||||
};
|
||||
|
||||
class ParsedToken {
|
||||
|
|
@ -39,7 +42,7 @@ namespace hammer {
|
|||
void* getUser() const {return token->user;}
|
||||
uint64_t getUint() const {return token->uint;}
|
||||
int64_t getSint() const {return token->sint;}
|
||||
// TODO: Sequence GetSeq() const {return Sequence(token->seq);}
|
||||
// TODO: Sequence getSeq() const {return Sequence(token->seq);}
|
||||
std::string getBytes() const {return std::string((char*)token->bytes.token, token->bytes.len); }
|
||||
|
||||
|
||||
|
|
@ -78,7 +81,7 @@ namespace hammer {
|
|||
}
|
||||
};
|
||||
|
||||
inline ParseResult Parser::parse(std::string string) {
|
||||
inline ParseResult Parser::parse(const std::string &string) {
|
||||
return ParseResult(h_parse(parser, (uint8_t*)string.data(), string.length()));
|
||||
}
|
||||
|
||||
|
|
@ -96,66 +99,109 @@ namespace hammer {
|
|||
return Parser(h_ch_range(lower,upper));
|
||||
}
|
||||
|
||||
static inline Parser int64() { return Parser(h_int64()); }
|
||||
static inline Parser int32() { return Parser(h_int32()); }
|
||||
static inline Parser int16() { return Parser(h_int16()); }
|
||||
static inline Parser int8 () { return Parser(h_int8 ()); }
|
||||
static inline Parser Int64() { return Parser(h_int64()); }
|
||||
static inline Parser Int32() { return Parser(h_int32()); }
|
||||
static inline Parser Int16() { return Parser(h_int16()); }
|
||||
static inline Parser Int8 () { return Parser(h_int8 ()); }
|
||||
|
||||
static inline Parser uint64() { return Parser(h_uint64()); }
|
||||
static inline Parser uint32() { return Parser(h_uint32()); }
|
||||
static inline Parser uint16() { return Parser(h_uint16()); }
|
||||
static inline Parser uint8 () { return Parser(h_uint8 ()); }
|
||||
static inline Parser Uint64() { return Parser(h_uint64()); }
|
||||
static inline Parser Uint32() { return Parser(h_uint32()); }
|
||||
static inline Parser Uint16() { return Parser(h_uint16()); }
|
||||
static inline Parser Uint8 () { return Parser(h_uint8 ()); }
|
||||
|
||||
static inline Parser int_range(Parser p, int64_t lower, int64_t upper) {
|
||||
static inline Parser IntRange(Parser p, int64_t lower, int64_t upper) {
|
||||
return Parser(h_int_range(p.parser, lower, upper));
|
||||
}
|
||||
|
||||
static inline Parser bits(size_t len, bool sign) { return Parser(h_bits(len, sign)); }
|
||||
static inline Parser whitespace(Parser p) { return Parser(h_whitespace(p.parser)); }
|
||||
static inline Parser left(Parser p, Parser q) { return Parser(h_left(p.parser, q.parser)); }
|
||||
static inline Parser right(Parser p, Parser q) { return Parser(h_right(p.parser, q.parser)); }
|
||||
static inline Parser middle(Parser p, Parser q, Parser r) {
|
||||
static inline Parser Bits(size_t len, bool sign) { return Parser(h_bits(len, sign)); }
|
||||
static inline Parser Whitespace(Parser p) { return Parser(h_whitespace(p.parser)); }
|
||||
static inline Parser Left(Parser p, Parser q) { return Parser(h_left(p.parser, q.parser)); }
|
||||
static inline Parser Right(Parser p, Parser q) { return Parser(h_right(p.parser, q.parser)); }
|
||||
static inline Parser Middle(Parser p, Parser q, Parser r) {
|
||||
return Parser(h_middle(p.parser, q.parser, r.parser));
|
||||
}
|
||||
|
||||
// TODO: Define Action
|
||||
//Parser action(Parser p, Action a);
|
||||
// User is responsible for ensuring that function remains allocated.
|
||||
Parser Action(Parser p, HAction action, void* user_data) {
|
||||
return Parser(h_action(p.parser, action, user_data));
|
||||
}
|
||||
|
||||
static inline Parser in(std::string charset);
|
||||
static inline Parser in(const uint8_t *charset, size_t length);
|
||||
static inline Parser in(std::set<uint8_t> charset);
|
||||
Parser Action(Parser p, HAction action) {
|
||||
return Parser(h_action(p.parser, action, NULL));
|
||||
}
|
||||
|
||||
static inline Parser not_in(std::string charset);
|
||||
static inline Parser not_in(const uint8_t *charset, size_t length);
|
||||
static inline Parser not_in(std::set<uint8_t> charset);
|
||||
Parser AttrBool(Parser p, HPredicate pred, void* user_data) {
|
||||
return Parser(h_attr_bool(p.parser, pred, user_data));
|
||||
}
|
||||
|
||||
static inline Parser end() { return Parser(h_end_p()); }
|
||||
static inline Parser nothing() { return Parser(h_nothing_p()); }
|
||||
Parser AttrBool(Parser p, HPredicate pred) {
|
||||
return Parser(h_attr_bool(p.parser, pred, NULL));
|
||||
}
|
||||
|
||||
static inline Parser In(const std::string &charset) {
|
||||
return Parser(h_in((const uint8_t*)charset.data(), charset.length()));
|
||||
}
|
||||
static inline Parser In(const uint8_t *charset, size_t length) {
|
||||
return Parser(h_in(charset, length));
|
||||
}
|
||||
/* TODO
|
||||
static inline Parser In(std::set<uint8_t> charset) {
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
static inline Parser NotIn(const std::string &charset) {
|
||||
return Parser(h_not_in((const uint8_t*)charset.data(), charset.length()));
|
||||
}
|
||||
static inline Parser NotIn(const uint8_t *charset, size_t length) {
|
||||
return Parser(h_not_in(charset, length));
|
||||
}
|
||||
/* TODO
|
||||
static inline Parser NotIn(std::set<uint8_t> charset) { }
|
||||
*/
|
||||
static inline Parser End() { return Parser(h_end_p()); }
|
||||
static inline Parser Nothing() { return Parser(h_nothing_p()); }
|
||||
|
||||
// TODO: figure out varargs
|
||||
//Parser sequence();
|
||||
//
|
||||
//Parser choice();
|
||||
static inline Parser Sequence(Parser p, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, p);
|
||||
// old-skool reinterpret_cast<HParser*>(p)
|
||||
HParser* ret = h_sequence__v(*(HParser**)(void*)&p,
|
||||
ap);
|
||||
va_end(ap);
|
||||
return Parser(ret);
|
||||
}
|
||||
|
||||
static inline Parser butnot(Parser p1, Parser p2) { return Parser(h_butnot(p1.parser, p2.parser)); }
|
||||
static inline Parser difference(Parser p1, Parser p2) { return Parser(h_difference(p1.parser, p2.parser)); }
|
||||
static inline Parser xor_(Parser p1, Parser p2) { return Parser(h_xor(p1.parser, p2.parser)); }
|
||||
static inline Parser many(Parser p) { return Parser(h_many(p.parser)); }
|
||||
static inline Parser many1(Parser p) { return Parser(h_many1(p.parser)); }
|
||||
static inline Parser repeat_n(Parser p, size_t n) { return Parser(h_repeat_n(p.parser, n)); }
|
||||
static inline Parser optional(Parser p) { return Parser(h_optional(p.parser)); }
|
||||
static inline Parser ignore(Parser p) { return Parser(h_ignore(p.parser)); }
|
||||
static inline Parser sepBy(Parser p, Parser sep) { return Parser(h_sepBy(p.parser, sep.parser)); }
|
||||
static inline Parser sepBy1(Parser p, Parser sep) { return Parser(h_sepBy1(p.parser, sep.parser)); }
|
||||
static inline Parser epsilon() { return Parser(h_epsilon_p()); }
|
||||
static inline Parser length_value(Parser length, Parser value) { return Parser(h_length_value(length.parser, value.parser)); }
|
||||
static inline Parser Choice(Parser p, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, p);
|
||||
// old-skool reinterpret_cast<HParser*>(p)
|
||||
HParser* ret = h_choice__v(*(HParser**)(void*)&p,
|
||||
ap);
|
||||
va_end(ap);
|
||||
return Parser(ret);
|
||||
}
|
||||
|
||||
static inline Parser ButNot(Parser p1, Parser p2) { return Parser(h_butnot(p1.parser, p2.parser)); }
|
||||
static inline Parser Difference(Parser p1, Parser p2) { return Parser(h_difference(p1.parser, p2.parser)); }
|
||||
static inline Parser Xor(Parser p1, Parser p2) { return Parser(h_xor(p1.parser, p2.parser)); }
|
||||
static inline Parser Many(Parser p) { return Parser(h_many(p.parser)); }
|
||||
static inline Parser Many1(Parser p) { return Parser(h_many1(p.parser)); }
|
||||
static inline Parser RepeatN(Parser p, size_t n) { return Parser(h_repeat_n(p.parser, n)); }
|
||||
static inline Parser Optional(Parser p) { return Parser(h_optional(p.parser)); }
|
||||
static inline Parser Ignore(Parser p) { return Parser(h_ignore(p.parser)); }
|
||||
static inline Parser SepBy(Parser p, Parser sep) { return Parser(h_sepBy(p.parser, sep.parser)); }
|
||||
static inline Parser SepBy1(Parser p, Parser sep) { return Parser(h_sepBy1(p.parser, sep.parser)); }
|
||||
static inline Parser Epsilon() { return Parser(h_epsilon_p()); }
|
||||
static inline Parser LengthValue(Parser length, Parser value) { return Parser(h_length_value(length.parser, value.parser)); }
|
||||
|
||||
// Was attr_bool in the old C bindings.
|
||||
// TODO: Figure out closure
|
||||
//Parser validate(Parser p, Predicate pred);
|
||||
|
||||
static inline Parser and_(Parser p) { return Parser(h_and(p.parser)); }
|
||||
static inline Parser not_(Parser p) { return Parser(h_not(p.parser)); }
|
||||
static inline Parser And(Parser p) { return Parser(h_and(p.parser)); }
|
||||
static inline Parser Not(Parser p) { return Parser(h_not(p.parser)); }
|
||||
|
||||
class Indirect : public Parser {
|
||||
public:
|
||||
|
|
@ -169,4 +215,6 @@ namespace hammer {
|
|||
// return Parser(foo);
|
||||
//}
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -7,9 +7,8 @@
|
|||
|
||||
#define HAMMER_DECL_UNUSED __attribute__((unused))
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused"
|
||||
|
||||
static ::testing::AssertionResult ParseFails (hammer::Parser parser,
|
||||
const std::string &input) HAMMER_DECL_UNUSED;
|
||||
static ::testing::AssertionResult ParseFails (hammer::Parser parser,
|
||||
const std::string &input) {
|
||||
hammer::ParseResult result = parser.parse(input);
|
||||
|
|
@ -20,6 +19,8 @@ static ::testing::AssertionResult ParseFails (hammer::Parser parser,
|
|||
}
|
||||
}
|
||||
|
||||
static ::testing::AssertionResult ParsesOK(hammer::Parser parser,
|
||||
const std::string &input) HAMMER_DECL_UNUSED;
|
||||
static ::testing::AssertionResult ParsesOK(hammer::Parser parser,
|
||||
const std::string &input) {
|
||||
hammer::ParseResult result = parser.parse(input);
|
||||
|
|
@ -30,6 +31,9 @@ static ::testing::AssertionResult ParsesOK(hammer::Parser parser,
|
|||
}
|
||||
}
|
||||
|
||||
static ::testing::AssertionResult ParsesTo(hammer::Parser parser,
|
||||
const std::string &input,
|
||||
const std::string &expected_result) HAMMER_DECL_UNUSED;
|
||||
static ::testing::AssertionResult ParsesTo(hammer::Parser parser,
|
||||
const std::string &input,
|
||||
const std::string &expected_result) {
|
||||
|
|
@ -47,6 +51,4 @@ static ::testing::AssertionResult ParsesTo(hammer::Parser parser,
|
|||
}
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#endif // defined(HAMMER_HAMMER_TEST__HPP)
|
||||
|
|
|
|||
|
|
@ -47,8 +47,13 @@
|
|||
#define h_new(type, count) ((type*)(mm__->alloc(mm__, sizeof(type)*(count))))
|
||||
#define h_free(addr) (mm__->free(mm__, (addr)))
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define false 0
|
||||
#define true 1
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// This is going to be generally useful.
|
||||
static inline void h_generic_free(HAllocator *allocator, void* ptr) {
|
||||
|
|
@ -388,5 +393,7 @@ bool h_not_regular(HRVMProg*, void*);
|
|||
#include <stdlib.h>
|
||||
#define h_arena_malloc(a, s) malloc(s)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
#endif // #ifndef HAMMER_INTERNAL__H
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue