C++ bindings getting underway.

This commit is contained in:
Meredith L. Patterson 2013-08-09 18:45:26 +02:00
parent a7e4def944
commit 2408106191
3 changed files with 655 additions and 0 deletions

152
src/hammer.cxx Normal file
View file

@ -0,0 +1,152 @@
#include "hammer.hxx"
namespace hammer {
typedef variant<BytesResult, UintResult, IntResult, NullResult, SequenceResult> AnyResult;
const BytesResult::result_type BytesResult::result() { return _bytes; }
const UintResult::result_type UintResult::result() { return _uint; }
const IntResult::result_type IntResult::result() { return _sint; }
const SequenceResult::result_type SequenceResult::result() { return _seq; }
template<>
BytesResult Parser<BytesResult>::parse(const string &input) {
HParseResult *res = h_parse(_parser, reinterpret_cast<const uint8_t*>(input.c_str()), input.size());
return BytesResult(vector<uint8_t>(res->ast->bytes.token, res->ast->bytes.token+res->ast->bytes.len));
}
template<>
BytesResult Parser<BytesResult>::parse(const uint8_t *input, size_t length) {
HParseResult *res = h_parse(_parser, input, length);
return BytesResult(vector<uint8_t>(res->ast->bytes.token, res->ast->bytes.token+res->ast->bytes.len));
}
template<>
UintResult Parser<UintResult>::parse(const string &input) {
HParseResult *res = h_parse(_parser, reinterpret_cast<const uint8_t*>(input.c_str()), input.size());
return UintResult(res->ast->uint);
}
template<>
UintResult Parser<UintResult>::parse(const uint8_t *input, size_t length) {
HParseResult *res = h_parse(_parser, input, length);
return UintResult(res->ast->uint);
}
template<>
IntResult Parser<IntResult>::parse(const string &input) {
HParseResult *res = h_parse(_parser, reinterpret_cast<const uint8_t*>(input.c_str()), input.size());
return IntResult(res->ast->sint);
}
template<>
IntResult Parser<IntResult>::parse(const uint8_t *input, size_t length) {
HParseResult *res = h_parse(_parser, input, length);
return IntResult(res->ast->sint);
}
template<>
NullResult Parser<NullResult>::parse(const string &input) {
HParseResult *res = h_parse(_parser, reinterpret_cast<const uint8_t*>(input.c_str()), input.size());
return NullResult();
}
template<>
NullResult Parser<NullResult>::parse(const uint8_t *input, size_t length) {
HParseResult *res = h_parse(_parser, input, length);
return NullResult();
}
vector<AnyResult> make_seq(HCountedArray *seq) {
vector<AnyResult> ret;
for (size_t i=0; i<seq->used; ++i) {
switch(seq->elements[i]->token_type) {
case TT_NONE:
ret.push_back(NullResult());
break;
case TT_BYTES:
ret.push_back(BytesResult(vector<uint8_t>(seq->elements[i]->bytes.token, seq->elements[i]->bytes.token+seq->elements[i]->bytes.len)));
break;
case TT_SINT:
ret.push_back(IntResult(seq->elements[i]->sint));
break;
case TT_UINT:
ret.push_back(UintResult(seq->elements[i]->uint));
break;
case TT_SEQUENCE:
ret.push_back(make_seq(seq->elements[i]->seq));
break;
default:
//TODO some kind of error
break;
}
}
return ret;
}
template<>
SequenceResult Parser<SequenceResult>::parse(const string &input) {
HParseResult *res = h_parse(_parser, reinterpret_cast<const uint8_t*>(input.c_str()), input.size());
return SequenceResult(make_seq(res->ast->seq));
}
template<>
SequenceResult Parser<SequenceResult>::parse(const uint8_t *input, size_t length) {
HParseResult *res = h_parse(_parser, input, length);
return SequenceResult(make_seq(res->ast->seq));
}
template<class T>
Many<T> Parser<T>::many() {
return Many<T>(this);
}
template<class T>
RepeatN<T> Parser<T>::many(size_t n) {
return RepeatN<T>(this, n);
}
template<class T>
Optional<T> Parser<T>::optional() {
return Optional<T>(this);
}
template<class T>
RepeatN<T> Parser<T>::operator[](size_t n) {
return RepeatN<T>(this, n);
}
/*
Int64 Int64::in_range(const int64_t lower, const int64_t upper) {
return IntRange(Int64(), lower, upper);
}
Int32 Int32::in_range(const int32_t lower, const int32_t upper) {
return IntRange(Int32(), lower, upper);
}
Int16 Int16::in_range(const int16_t lower, const int16_t upper) {
return IntRange(Int16(), lower, upper);
}
Int8 Int8::in_range(const int8_t lower, const int8_t upper) {
return IntRange(Int8(), lower, upper);
}
Uint64 Uint64::in_range(const uint64_t lower, const uint64_t upper) {
return IntRange(Uint64(), lower, upper);
}
Uint32 Uint32::in_range(const uint32_t lower, const uint32_t upper) {
return IntRange(Uint32(), lower, upper);
}
Uint16 Uint16::in_range(const uint16_t lower, const uint16_t upper) {
return IntRange(Uint16(), lower, upper);
}
Uint8 Uint8::in_range(const uint8_t lower, const uint8_t upper) {
return IntRange(Uint8(), lower, upper);
}
*/
}

View file

@ -27,7 +27,13 @@
#define BIT_LITTLE_ENDIAN 0x0 #define BIT_LITTLE_ENDIAN 0x0
#define BYTE_LITTLE_ENDIAN 0x0 #define BYTE_LITTLE_ENDIAN 0x0
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __cplusplus
typedef int bool; typedef int bool;
#endif
typedef struct HParseState_ HParseState; typedef struct HParseState_ HParseState;
@ -617,4 +623,8 @@ void h_benchmark_report(FILE* stream, HBenchmarkResults* results);
void h_benchmark_dump_optimized_code(FILE* stream, HBenchmarkResults* results); void h_benchmark_dump_optimized_code(FILE* stream, HBenchmarkResults* results);
// }}} // }}}
#ifdef __cplusplus
}
#endif
#endif // #ifndef HAMMER_HAMMER__H #endif // #ifndef HAMMER_HAMMER__H

493
src/hammer.hxx Normal file
View file

@ -0,0 +1,493 @@
#ifndef HAMMER_HAMMER__HXX
#define HAMMER_HAMMER__HXX
#include "hammer.h"
#include <list>
#include <string>
#include <vector>
#include <boost/variant.hpp>
using std::list; using std::string; using std::vector;
using boost::variant;
namespace hammer {
template<typename T>
class ParseResult {
public:
typedef T result_type;
protected:
ParseResult() { }
};
class BytesResult : public ParseResult<vector<uint8_t> > {
public:
typedef vector<uint8_t> result_type;
BytesResult(const vector<uint8_t> res) : _bytes(res) { }
const result_type result();
private:
BytesResult() { }
result_type _bytes;
};
class UintResult : public ParseResult<uint64_t> {
public:
typedef uint64_t result_type;
UintResult(const uint64_t res) : _uint(res) { }
const result_type result();
private:
UintResult() { }
result_type _uint;
};
class IntResult : public ParseResult<int64_t> {
public:
typedef int64_t result_type;
IntResult(const int64_t res) : _sint(res) { }
const result_type result();
private:
IntResult() { }
result_type _sint;
};
class NullResult: public ParseResult<void*> {
public:
NullResult() { }
typedef void* result_type;
const result_type result() { return NULL; }
};
class SequenceResult : public ParseResult<vector<variant<BytesResult, UintResult, IntResult, NullResult, SequenceResult> > > {
public:
typedef vector<variant<BytesResult, UintResult, IntResult, NullResult, SequenceResult> > result_type;
SequenceResult(result_type res) : _seq(res) { }
const result_type result();
private:
SequenceResult() { }
result_type _seq;
};
/* forward declarations */
template<class T> class Many;
template<class T> class Many1;
template<class T> class Optional;
template<class T> class RepeatN;
template<typename T>
class Parser {
public:
typedef T result_type;
result_type parse(const string &input);
result_type parse(const uint8_t *input, size_t length);
Many<T> many();
RepeatN<T> many(size_t n);
Optional<T> optional();
RepeatN<T> operator[](size_t n);
HParser* parser() { return _parser; }
HParser* _parser;
Parser() { }
};
class Token : public Parser<BytesResult> {
public:
Token(string &str) : _tok(str) {
_parser = h_token(reinterpret_cast<const uint8_t*>(str.c_str()), str.size());
}
Token(const uint8_t *str, size_t length) : _tok(reinterpret_cast<const char*>(str), length) {
_parser = h_token(str, length);
}
private:
string _tok;
};
class Ch : public Parser<UintResult> {
public:
Ch(const uint8_t c) : _c(c) {
_parser = h_ch(c);
}
private:
uint8_t _c;
};
class ChRange : public Parser<UintResult> {
public:
ChRange(const uint8_t lower, const uint8_t upper) : _lower(lower), _upper(upper) {
_parser = h_ch_range(lower, upper);
}
private:
uint8_t _lower, _upper;
};
class IntRange : public Parser<IntResult> {
public:
IntRange(Parser &p, const int64_t lower, const int64_t upper) : _p(p), _lower(lower), _upper(upper) {
_parser = h_int_range(p.parser(), lower, upper);
}
private:
Parser _p;
int64_t _lower, _upper;
};
class SignedBits : public Parser<IntResult> {
public:
SignedBits(size_t len) : _len(len) {
_parser = h_bits(len, true);
}
private:
size_t _len;
};
class UnsignedBits : public Parser<UintResult> {
public:
UnsignedBits(size_t len) : _len(len) {
_parser = h_bits(len, false);
}
private:
size_t _len;
};
class Int64 : public Parser<IntResult> {
public:
Int64() {
_parser = h_int64();
}
Int64 in_range(const int64_t lower, const int64_t upper);
};
class Int32 : public Parser<IntResult> {
public:
Int32() {
_parser = h_int32();
}
Int32 in_range(const int32_t lower, const int32_t upper);
};
class Int16 : public Parser<IntResult> {
public:
Int16() {
_parser = h_int16();
}
Int16 in_range(const int16_t lower, const int16_t upper);
};
class Int8 : public Parser<IntResult> {
public:
Int8() {
_parser = h_int8();
}
Int8 in_range(const int8_t lower, const int8_t upper);
};
class Uint64 : public Parser<UintResult> {
public:
Uint64() {
_parser = h_uint64();
}
Uint64 in_range(const uint64_t lower, const uint64_t upper);
};
class Uint32 : public Parser<UintResult> {
public:
Uint32() {
_parser = h_uint32();
}
Uint32 in_range(const uint32_t lower, const uint32_t upper);
};
class Uint16 : public Parser<UintResult> {
public:
Uint16() {
_parser = h_uint16();
}
Uint16 in_range(const uint16_t lower, const uint16_t upper);
};
class Uint8 : public Parser<UintResult> {
public:
Uint8() {
_parser = h_uint8();
}
Uint8 in_range(const uint8_t lower, const uint8_t upper);
};
template<class T>
class Whitespace : public Parser<T> {
public:
typedef typename T::result_type result_type;
Whitespace(Parser<T> &p) : _p(p) {
this->_parser = h_whitespace(p.parser());
}
private:
Parser<T> _p;
};
template<class T, class U>
class Left : public Parser<T> {
public:
typedef typename T::result_type result_type;
Left(Parser<T> &p, Parser<U> &q) : _p(p), _q(q) {
this->_parser = h_left(p.parser(), q.parser());
}
private:
Parser<T> _p;
Parser<U> _q;
};
template<class T, class U>
class Right : public Parser<U> {
public:
typedef typename U::result_type result_type;
Right(Parser<T> &p, Parser<U> &q) : _p(p), _q(q) {
this->_parser = h_right(p.parser(), q.parser());
}
private:
Parser<T> _p;
Parser<U> _q;
};
template <class T, class U, class V>
class Middle : public Parser<U> {
public:
typedef typename U::result_type result_type;
Middle(Parser<T> &p, Parser<U> &x, Parser<V> &q) : _p(p), _x(x), _q(q) {
this->_parser = h_middle(p.parser(), x.parser(), q.parser());
}
private:
Parser<T> _p;
Parser<U> _x;
Parser<V> _q;
};
/* what are we doing about h_action? */
class In : public Parser<UintResult> {
public:
In(string &charset) : _charset(charset) {
_parser = h_in(reinterpret_cast<const uint8_t*>(charset.c_str()), charset.size());
}
In(const uint8_t *charset, size_t length) : _charset(reinterpret_cast<const char*>(charset), length) {
_parser = h_in(charset, length);
}
private:
string _charset;
};
class NotIn : public Parser<UintResult> {
public:
NotIn(string &charset) : _charset(charset) {
_parser = h_not_in(reinterpret_cast<const uint8_t*>(charset.c_str()), charset.size());
}
NotIn(const uint8_t *charset, size_t length) : _charset(reinterpret_cast<const char*>(charset), length) {
_parser = h_not_in(charset, length);
}
private:
string _charset;
};
class End : public Parser<NullResult> {
public:
End() {
_parser = h_end_p();
}
};
class Nothing : public Parser<NullResult> {
public:
Nothing() {
_parser = h_nothing_p();
}
};
class Sequence : public Parser<SequenceResult> {
public:
Sequence(list<Parser> &ps) : _ps(ps) {
void *parsers[ps.size()];
size_t i = 0;
for (list<Parser>::iterator it=ps.begin(); it != ps.end(); ++it, ++i) {
parsers[i] = it->parser();
}
_parser = h_sequence__a(parsers);
}
// maybe also a begin and end iterator version
private:
list<Parser> _ps;
};
class Choice : public Parser<SequenceResult> {
public:
Choice(list<Parser<SequenceResult> > &ps) : _ps(ps) {
void *parsers[ps.size()];
size_t i = 0;
for (list<Parser<SequenceResult> >::iterator it=ps.begin(); it != ps.end(); ++it, ++i) {
parsers[i] = it->parser();
}
_parser = h_choice__a(parsers);
}
private:
list<Parser<SequenceResult> > _ps;
};
template<class T, class U>
class ButNot : public Parser<T> {
public:
typedef typename T::result_type result_type;
ButNot(Parser<T> &p, Parser<U> &q) : _p(p), _q(q) {
this->_parser = h_butnot(p.parser(), q.parser());
}
private:
Parser<T> _p;
Parser<U> _q;
};
template<class T, class U>
class Difference : public Parser<T> {
public:
typedef typename T::result_type result_type;
Difference(Parser<T> &p, Parser<U> &q) : _p(p), _q(q) {
this->_parser = h_difference(p.parser(), q.parser());
}
private:
Parser<T> _p;
Parser<U> _q;
};
template<class T, class U>
class Xor : public Parser<variant<T, U> > {
public:
typedef variant<T, U> result_type;
Xor(Parser<T> &p, Parser<U> &q) : _p(p), _q(q) {
this->_parser = h_xor(p.parser(), q.parser());
}
private:
Parser<T> _p;
Parser<U> _q;
};
template<class T>
class Many : public Parser<SequenceResult> {
public:
Many(Parser<T> &p) : _p(p) {
_parser = h_many(p.parser());
}
private:
Parser<T> _p;
};
template<class T>
class Many1 : public Parser<SequenceResult> {
public:
Many1(Parser<T> &p) : _p(p) {
_parser = h_many1(p.parser());
}
private:
Parser<T> _p;
};
template<class T>
class RepeatN: public Parser<SequenceResult> {
public:
RepeatN(Parser<T> &p, const size_t n) : _p(p), _n(n) {
_parser = h_repeat_n(p.parser(), n);
}
private:
Parser<T> _p;
size_t _n;
};
template<class T>
class Optional : public Parser<T> {
public:
typedef typename T::result_type result_type;
Optional(Parser<T> &p) : _p(p) {
this->_parser = h_optional(p.parser());
}
private:
Parser<T> _p;
};
template<class T>
class Ignore : public Parser<NullResult> {
public:
Ignore(Parser<T> &p) : _p(p) {
_parser = h_ignore(p.parser());
}
private:
Parser<T> _p;
};
template<class T, class U>
class SepBy : public Parser<SequenceResult> {
public:
SepBy(Parser<T> &p, Parser<U> &sep) : _p(p), _sep(sep) {
_parser = h_sepBy(p.parser(), sep.parser());
}
private:
Parser<T> _p;
Parser<U> _sep;
};
template<class T, class U>
class SepBy1 : public Parser<SequenceResult> {
public:
SepBy1(Parser<T> &p, Parser<U> &sep) : _p(p), _sep(sep) {
_parser = h_sepBy1(p.parser(), sep.parser());
}
private:
Parser<T> _p;
Parser<U> _sep;
};
class Epsilon : public Parser<NullResult> {
public:
Epsilon() {
_parser = h_epsilon_p();
}
};
template<class T>
class LengthValue : public Parser<SequenceResult> {
public:
LengthValue(Parser<UintResult> &length, Parser<T> &value) : _length(length), _value(value) {
_parser = h_length_value(length.parser(), value.parser());
}
private:
Parser<UintResult> _length;
Parser<T> _value;
};
/* FIXME attr_bool */
template<class T>
class And : public Parser<NullResult> {
public:
And(Parser<T> &p) : _p(p) {
_parser = h_and(p.parser());
}
private:
Parser<T> _p;
};
template<class T>
class Not : public Parser<NullResult> {
public:
Not(Parser &p) : _p(p) {
_parser = h_not(p.parser());
}
private:
Parser<T> _p;
};
template<class T>
class Indirect : public Parser<T> {
public:
Indirect(Parser<T> &p) : _p(p) {
this->_parser = h_indirect();
h_bind_indirect(this->_parser, p.parser());
}
private:
Parser<T> _p;
};
}
#endif