binpac: Add pre-commit hooks and run clang-format on everything

This commit is contained in:
Tim Wojtulewicz 2022-07-07 11:49:24 -07:00
parent 090ac0a6e0
commit 090325df40
91 changed files with 3086 additions and 3665 deletions

View file

@ -1,27 +1,28 @@
#ifndef binpac_an_h #ifndef binpac_an_h
#define binpac_an_h #define binpac_an_h
namespace binpac { namespace binpac
{
// TODO: Add the Done() function // TODO: Add the Done() function
// The interface for a connection analyzer // The interface for a connection analyzer
class ConnectionAnalyzer { class ConnectionAnalyzer
{
public: public:
virtual ~ConnectionAnalyzer() {} virtual ~ConnectionAnalyzer() { }
virtual void NewData(bool is_orig, virtual void NewData(bool is_orig, const unsigned char* begin_of_data,
const unsigned char* begin_of_data,
const unsigned char* end_of_data) = 0; const unsigned char* end_of_data) = 0;
}; };
// The interface for a flow analyzer // The interface for a flow analyzer
class FlowAnalyzer { class FlowAnalyzer
{
public: public:
virtual ~FlowAnalyzer() {} virtual ~FlowAnalyzer() { }
virtual void NewData(const unsigned char* begin_of_data, virtual void NewData(const unsigned char* begin_of_data, const unsigned char* end_of_data) = 0;
const unsigned char* end_of_data) = 0; };
};
} // namespace binpac } // namespace binpac
#endif // binpac_an_h #endif // binpac_an_h

View file

@ -1,5 +1,5 @@
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> // for memcpy #include <string.h> // for memcpy
#define binpac_regex_h #define binpac_regex_h
@ -7,14 +7,16 @@
#include "binpac.h" #include "binpac.h"
#include "binpac_buffer.h" #include "binpac_buffer.h"
namespace binpac { namespace binpac
{
extern double network_time(); extern double network_time();
namespace { namespace
const unsigned char CR = '\r'; {
const unsigned char LF = '\n'; const unsigned char CR = '\r';
} const unsigned char LF = '\n';
}
binpac::FlowBuffer::Policy binpac::FlowBuffer::policy = { binpac::FlowBuffer::Policy binpac::FlowBuffer::policy = {
// max_capacity // max_capacity
@ -67,9 +69,7 @@ void FlowBuffer::NewMessage()
switch ( mode_ ) switch ( mode_ )
{ {
case LINE_MODE: case LINE_MODE:
bytes_to_advance = (frame_length_ + bytes_to_advance = (frame_length_ + (linebreak_style_ == STRICT_CRLF ? 2 : 1));
(linebreak_style_ == STRICT_CRLF ?
2 : 1));
break; break;
case FRAME_MODE: case FRAME_MODE:
bytes_to_advance = frame_length_; bytes_to_advance = frame_length_;
@ -118,14 +118,13 @@ void FlowBuffer::ExpandBuffer(int length)
if ( length > policy.max_capacity ) if ( length > policy.max_capacity )
{ {
std::string reason = strfmt("expand past max capacity %d/%d", std::string reason = strfmt("expand past max capacity %d/%d", length, policy.max_capacity);
length, policy.max_capacity);
throw ExceptionFlowBufferAlloc(reason.c_str()); throw ExceptionFlowBufferAlloc(reason.c_str());
} }
// Allocate a new buffer and copy the existing contents // Allocate a new buffer and copy the existing contents
buffer_length_ = length; buffer_length_ = length;
unsigned char* new_buf = (unsigned char *) realloc(buffer_, buffer_length_); unsigned char* new_buf = (unsigned char*)realloc(buffer_, buffer_length_);
if ( ! new_buf ) if ( ! new_buf )
throw ExceptionFlowBufferAlloc("expand realloc OOM"); throw ExceptionFlowBufferAlloc("expand realloc OOM");
@ -139,7 +138,7 @@ void FlowBuffer::ContractBuffer()
return; return;
buffer_length_ = policy.min_capacity; buffer_length_ = policy.min_capacity;
unsigned char* new_buf = (unsigned char *) realloc(buffer_, buffer_length_); unsigned char* new_buf = (unsigned char*)realloc(buffer_, buffer_length_);
if ( ! new_buf ) if ( ! new_buf )
throw ExceptionFlowBufferAlloc("contract realloc OOM"); throw ExceptionFlowBufferAlloc("contract realloc OOM");
@ -233,8 +232,7 @@ void FlowBuffer::NewData(const_byteptr begin, const_byteptr end)
ClearPreviousData(); ClearPreviousData();
BINPAC_ASSERT((buffer_n_ == 0 && message_complete_) || BINPAC_ASSERT((buffer_n_ == 0 && message_complete_) || orig_data_begin_ == orig_data_end_);
orig_data_begin_ == orig_data_end_);
orig_data_begin_ = begin; orig_data_begin_ = begin;
orig_data_end_ = end; orig_data_end_ = end;
@ -273,8 +271,7 @@ void FlowBuffer::ClearPreviousData()
{ {
if ( frame_length_ > 0 ) if ( frame_length_ > 0 )
{ {
frame_length_ -= frame_length_ -= (orig_data_end_ - orig_data_begin_);
(orig_data_end_ - orig_data_begin_);
} }
orig_data_begin_ = orig_data_end_; orig_data_begin_ = orig_data_end_;
} }
@ -335,8 +332,7 @@ void FlowBuffer::MarkOrCopyLine_CR_OR_LF()
if ( ! (orig_data_begin_ && orig_data_end_) ) if ( ! (orig_data_begin_ && orig_data_end_) )
return; return;
if ( state_ == CR_OR_LF_1 && if ( state_ == CR_OR_LF_1 && orig_data_begin_ < orig_data_end_ && *orig_data_begin_ == LF )
orig_data_begin_ < orig_data_end_ && *orig_data_begin_ == LF )
{ {
state_ = CR_OR_LF_0; state_ = CR_OR_LF_0;
++orig_data_begin_; ++orig_data_begin_;
@ -378,9 +374,8 @@ found_end_of_line:
message_complete_ = true; message_complete_ = true;
#if DEBUG_FLOW_BUFFER #if DEBUG_FLOW_BUFFER
fprintf(stderr, "%.6f Line complete: [%s]\n", fprintf(stderr, "%.6f Line complete: [%s]\n", network_time(),
network_time(), string((const char*)begin(), (const char*)end()).c_str());
string((const char *) begin(), (const char *) end()).c_str());
#endif #endif
} }
@ -442,9 +437,8 @@ found_end_of_line:
message_complete_ = true; message_complete_ = true;
#if DEBUG_FLOW_BUFFER #if DEBUG_FLOW_BUFFER
fprintf(stderr, "%.6f Line complete: [%s]\n", fprintf(stderr, "%.6f Line complete: [%s]\n", network_time(),
network_time(), string((const char*)begin(), (const char*)end()).c_str());
string((const char *) begin(), (const char *) end()).c_str());
#endif #endif
} }
@ -477,13 +471,11 @@ found_end_of_line:
message_complete_ = true; message_complete_ = true;
#if DEBUG_FLOW_BUFFER #if DEBUG_FLOW_BUFFER
fprintf(stderr, "%.6f Line complete: [%s]\n", fprintf(stderr, "%.6f Line complete: [%s]\n", network_time(),
network_time(), string((const char*)begin(), (const char*)end()).c_str());
string((const char *) begin(), (const char *) end()).c_str());
#endif #endif
} }
// Invariants: // Invariants:
// //
// When buffer_n_ == 0: // When buffer_n_ == 0:
@ -494,8 +486,7 @@ found_end_of_line:
void FlowBuffer::MarkOrCopyFrame() void FlowBuffer::MarkOrCopyFrame()
{ {
if ( mode_ == FRAME_MODE && state_ == CR_OR_LF_1 && if ( mode_ == FRAME_MODE && state_ == CR_OR_LF_1 && orig_data_begin_ < orig_data_end_ )
orig_data_begin_ < orig_data_end_ )
{ {
// Skip the lingering LF // Skip the lingering LF
if ( *orig_data_begin_ == LF ) if ( *orig_data_begin_ == LF )
@ -508,8 +499,7 @@ void FlowBuffer::MarkOrCopyFrame()
if ( buffer_n_ == 0 ) if ( buffer_n_ == 0 )
{ {
// If there is enough data // If there is enough data
if ( frame_length_ >= 0 && if ( frame_length_ >= 0 && orig_data_end_ - orig_data_begin_ >= frame_length_ )
orig_data_end_ - orig_data_begin_ >= frame_length_ )
{ {
// Do nothing except setting the message complete flag // Do nothing except setting the message complete flag
message_complete_ = true; message_complete_ = true;
@ -518,15 +508,14 @@ void FlowBuffer::MarkOrCopyFrame()
{ {
if ( ! chunked_ ) if ( ! chunked_ )
{ {
AppendToBuffer(orig_data_begin_, AppendToBuffer(orig_data_begin_, orig_data_end_ - orig_data_begin_);
orig_data_end_ - orig_data_begin_);
} }
message_complete_ = false; message_complete_ = false;
} }
} }
else else
{ {
BINPAC_ASSERT(!chunked_); BINPAC_ASSERT(! chunked_);
int bytes_to_copy = orig_data_end_ - orig_data_begin_; int bytes_to_copy = orig_data_end_ - orig_data_begin_;
message_complete_ = false; message_complete_ = false;
if ( frame_length_ >= 0 && buffer_n_ + bytes_to_copy >= frame_length_ ) if ( frame_length_ >= 0 && buffer_n_ + bytes_to_copy >= frame_length_ )
@ -540,10 +529,8 @@ void FlowBuffer::MarkOrCopyFrame()
#if DEBUG_FLOW_BUFFER #if DEBUG_FLOW_BUFFER
if ( message_complete_ ) if ( message_complete_ )
{ {
fprintf(stderr, "%.6f frame complete: [%s]\n", fprintf(stderr, "%.6f frame complete: [%s]\n", network_time(),
network_time(), string((const char*)begin(), (const char*)end()).c_str());
string((const char *) begin(),
(const char *) end()).c_str());
} }
#endif #endif
} }
@ -562,4 +549,4 @@ void FlowBuffer::AppendToBuffer(const_byteptr data, int len)
BINPAC_ASSERT(orig_data_begin_ <= orig_data_end_); BINPAC_ASSERT(orig_data_begin_ <= orig_data_end_);
} }
} // namespace binpac } // namespace binpac

View file

@ -2,19 +2,24 @@
#define binpac_buffer_h #define binpac_buffer_h
#include <sys/types.h> #include <sys/types.h>
#include "binpac.h" #include "binpac.h"
namespace binpac { namespace binpac
{
class FlowBuffer { class FlowBuffer
{
public: public:
struct Policy { struct Policy
{
int max_capacity; int max_capacity;
int min_capacity; int min_capacity;
int contract_threshold; int contract_threshold;
}; };
enum LineBreakStyle { enum LineBreakStyle
{
CR_OR_LF, // CR or LF or CRLF CR_OR_LF, // CR or LF or CRLF
STRICT_CRLF, // CR followed by LF STRICT_CRLF, // CR followed by LF
CR_LF_NUL, // CR or LF or CR-LF or CR-NUL CR_LF_NUL, // CR or LF or CR-LF or CR-NUL
@ -39,13 +44,12 @@ public:
void DiscardData(); void DiscardData();
// Whether there is enough data for the frame // Whether there is enough data for the frame
bool ready() const{ return message_complete_ || mode_ == UNKNOWN_MODE; } bool ready() const { return message_complete_ || mode_ == UNKNOWN_MODE; }
inline const_byteptr begin() const inline const_byteptr begin() const
{ {
BINPAC_ASSERT(ready()); BINPAC_ASSERT(ready());
return ( buffer_n_ == 0 ) ? return (buffer_n_ == 0) ? orig_data_begin_ : buffer_;
orig_data_begin_ : buffer_;
} }
inline const_byteptr end() const inline const_byteptr end() const
@ -67,8 +71,7 @@ public:
if ( buffer_n_ > 0 ) if ( buffer_n_ > 0 )
return buffer_n_; return buffer_n_;
if ( frame_length_ < 0 || if ( frame_length_ < 0 || orig_data_begin_ + frame_length_ > orig_data_end_ )
orig_data_begin_ + frame_length_ > orig_data_end_ )
return orig_data_end_ - orig_data_begin_; return orig_data_end_ - orig_data_begin_;
else else
return frame_length_; return frame_length_;
@ -88,8 +91,7 @@ public:
int data_seq() const int data_seq() const
{ {
int data_seq_at_orig_data_begin = int data_seq_at_orig_data_begin = data_seq_at_orig_data_end_ -
data_seq_at_orig_data_end_ -
(orig_data_end_ - orig_data_begin_); (orig_data_end_ - orig_data_begin_);
if ( buffer_n_ > 0 ) if ( buffer_n_ > 0 )
return data_seq_at_orig_data_begin; return data_seq_at_orig_data_begin;
@ -101,8 +103,7 @@ public:
bool have_pending_request() const { return have_pending_request_; } bool have_pending_request() const { return have_pending_request_; }
static void init(Policy p) static void init(Policy p) { policy = p; }
{ policy = p; }
protected: protected:
// Reset the buffer for a new message // Reset the buffer for a new message
@ -152,13 +153,15 @@ protected:
LineBreakStyle linebreak_style_default; LineBreakStyle linebreak_style_default;
unsigned char linebreaker_; unsigned char linebreaker_;
enum { enum
{
UNKNOWN_MODE, UNKNOWN_MODE,
LINE_MODE, LINE_MODE,
FRAME_MODE, FRAME_MODE,
} mode_; } mode_;
enum { enum
{
CR_OR_LF_0, CR_OR_LF_0,
CR_OR_LF_1, CR_OR_LF_1,
STRICT_CRLF_0, STRICT_CRLF_0,
@ -171,10 +174,10 @@ protected:
bool have_pending_request_; bool have_pending_request_;
static Policy policy; static Policy policy;
}; };
typedef FlowBuffer *flow_buffer_t; typedef FlowBuffer* flow_buffer_t;
} // namespace binpac } // namespace binpac
#endif // binpac_buffer_h #endif // binpac_buffer_h

View file

@ -1,24 +1,25 @@
#define binpac_regex_h #define binpac_regex_h
#include <stdlib.h>
#include "binpac_bytestring.h" #include "binpac_bytestring.h"
#include <stdlib.h>
namespace binpac namespace binpac
{
std::string std_string(bytestring const *s)
{ {
return std::string((const char *) s->begin(), (const char *) s->end());
std::string std_string(bytestring const* s)
{
return std::string((const char*)s->begin(), (const char*)s->end());
} }
int bytestring_to_int(bytestring const *s) int bytestring_to_int(bytestring const* s)
{ {
return atoi((const char *) s->begin()); return atoi((const char*)s->begin());
} }
double bytestring_to_double(bytestring const *s) double bytestring_to_double(bytestring const* s)
{ {
return atof((const char *) s->begin()); return atof((const char*)s->begin());
} }
} // namespace binpac } // namespace binpac

View file

@ -3,155 +3,118 @@
#include <string.h> #include <string.h>
#include <string> #include <string>
#include "binpac.h" #include "binpac.h"
namespace binpac namespace binpac
{ {
template<class T> class datastring; template <class T> class datastring;
template <class T> template <class T> class const_datastring
class const_datastring {
{
public: public:
const_datastring() const_datastring() : begin_(0), end_(0) { }
: begin_(0), end_(0)
{
}
const_datastring(T const *data, int length) const_datastring(T const* data, int length) : begin_(data), end_(data + length) { }
: begin_(data), end_(data + length)
{
}
const_datastring(const T *begin, const T *end) const_datastring(const T* begin, const T* end) : begin_(begin), end_(end) { }
: begin_(begin), end_(end)
{
}
const_datastring(datastring<T> const &s) const_datastring(datastring<T> const& s) : begin_(s.begin()), end_(s.end()) { }
: begin_(s.begin()), end_(s.end())
{
}
void init(const T *data, int length) void init(const T* data, int length)
{ {
begin_ = data; begin_ = data;
end_ = data + length; end_ = data + length;
} }
T const *begin() const { return begin_; } T const* begin() const { return begin_; }
T const *end() const { return end_; } T const* end() const { return end_; }
int length() const { return end_ - begin_; } int length() const { return end_ - begin_; }
T const &operator[](int index) const T const& operator[](int index) const { return begin()[index]; }
{
return begin()[index];
}
bool operator==(const_datastring<T> const &s) bool operator==(const_datastring<T> const& s)
{ {
if ( length() != s.length() ) if ( length() != s.length() )
return false; return false;
return memcmp((const void *) begin(), (const void *) s.begin(), return memcmp((const void*)begin(), (const void*)s.begin(), sizeof(T) * length()) == 0;
sizeof(T) * length()) == 0;
} }
void set_begin(T const *begin) { begin_ = begin; } void set_begin(T const* begin) { begin_ = begin; }
void set_end(T const *end) { end_ = end; } void set_end(T const* end) { end_ = end; }
private: private:
T const *begin_; T const* begin_;
T const *end_; T const* end_;
}; };
typedef const_datastring<uint8> const_bytestring; typedef const_datastring<uint8> const_bytestring;
template<class T> template <class T> class datastring
class datastring {
{
public: public:
datastring() datastring() { clear(); }
{
clear();
}
datastring(T *data, int len) datastring(T* data, int len) { set(data, len); }
{
set(data, len);
}
datastring(T const *begin, T const *end) datastring(T const* begin, T const* end) { set_const(begin, end - begin); }
{
set_const(begin, end - begin);
}
datastring(datastring<T> const &x) datastring(datastring<T> const& x) : data_(x.data()), length_(x.length()) { }
: data_(x.data()), length_(x.length())
{
}
explicit datastring(const_datastring<T> const &x) explicit datastring(const_datastring<T> const& x) { set_const(x.begin(), x.length()); }
{
set_const(x.begin(), x.length());
}
datastring const &operator=(datastring<T> const &x) datastring const& operator=(datastring<T> const& x)
{ {
BINPAC_ASSERT(!data_); BINPAC_ASSERT(! data_);
set(x.data(), x.length()); set(x.data(), x.length());
return *this; return *this;
} }
void init(T const *begin, int length) void init(T const* begin, int length)
{ {
BINPAC_ASSERT(!data_); BINPAC_ASSERT(! data_);
set_const(begin, length); set_const(begin, length);
} }
void clear() void clear()
{ {
data_ = 0; length_ = 0; data_ = 0;
length_ = 0;
} }
void free() void free()
{ {
if ( data_ ) if ( data_ )
delete [] data_; delete[] data_;
clear(); clear();
} }
void clone() void clone() { set_const(begin(), length()); }
{
set_const(begin(), length());
}
datastring const &operator=(const_datastring<T> const &x) datastring const& operator=(const_datastring<T> const& x)
{ {
BINPAC_ASSERT(!data_); BINPAC_ASSERT(! data_);
set_const(x.begin(), x.length()); set_const(x.begin(), x.length());
return *this; return *this;
} }
T const &operator[](int index) const T const& operator[](int index) const { return begin()[index]; }
{
return begin()[index];
}
T *data() const { return data_; } T* data() const { return data_; }
int length() const { return length_; } int length() const { return length_; }
T const *begin() const { return data_; } T const* begin() const { return data_; }
T const *end() const { return data_ + length_; } T const* end() const { return data_ + length_; }
private: private:
void set(T *data, int len) void set(T* data, int len)
{ {
data_ = data; data_ = data;
length_ = len; length_ = len;
} }
void set_const(T const *data, int len) void set_const(T const* data, int len)
{ {
length_ = len; length_ = len;
data_ = new T[len + 1]; data_ = new T[len + 1];
@ -159,41 +122,39 @@ private:
data_[len] = 0; data_[len] = 0;
} }
T * data_; T* data_;
int length_; int length_;
}; };
typedef datastring<uint8> bytestring; typedef datastring<uint8> bytestring;
inline const char *c_str(bytestring const &s) inline const char* c_str(bytestring const& s)
{ {
return (const char *) s.begin(); return (const char*)s.begin();
} }
inline std::string std_str(const_bytestring const &s) inline std::string std_str(const_bytestring const& s)
{ {
return std::string((const char *) s.begin(), (const char *) s.end()); return std::string((const char*)s.begin(), (const char*)s.end());
} }
inline bool operator==(bytestring const &s1, const char *s2) inline bool operator==(bytestring const& s1, const char* s2)
{ {
return strcmp(c_str(s1), s2) == 0; return strcmp(c_str(s1), s2) == 0;
} }
inline void get_pointers(const_bytestring const &s, inline void get_pointers(const_bytestring const& s, uint8 const** pbegin, uint8 const** pend)
uint8 const **pbegin, uint8 const **pend)
{ {
*pbegin = s.begin(); *pbegin = s.begin();
*pend = s.end(); *pend = s.end();
} }
inline void get_pointers(bytestring const *s, inline void get_pointers(bytestring const* s, uint8 const** pbegin, uint8 const** pend)
uint8 const **pbegin, uint8 const **pend)
{ {
*pbegin = s->begin(); *pbegin = s->begin();
*pend = s->end(); *pend = s->end();
} }
} // namespace binpac } // namespace binpac
#endif // binpac_bytestring_h #endif // binpac_bytestring_h

View file

@ -1,16 +1,16 @@
#ifndef binpac_exception_h #ifndef binpac_exception_h
#define binpac_exception_h #define binpac_exception_h
#include <stdint.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdint.h>
namespace binpac { namespace binpac
{
class Exception class Exception
{ {
public: public:
Exception(const char* m = 0) Exception(const char* m = 0) : msg_("binpac exception: ")
: msg_("binpac exception: ")
{ {
if ( m ) if ( m )
append(m); append(m);
@ -23,111 +23,98 @@ public:
protected: protected:
string msg_; string msg_;
}; };
class ExceptionEnforceViolation : public Exception class ExceptionEnforceViolation : public Exception
{ {
public: public:
ExceptionEnforceViolation(const char* where) ExceptionEnforceViolation(const char* where)
{ {
append(binpac_fmt("&enforce violation : %s", where)); append(binpac_fmt("&enforce violation : %s", where));
} }
}; };
class ExceptionOutOfBound : public Exception class ExceptionOutOfBound : public Exception
{ {
public: public:
ExceptionOutOfBound(const char* where, int len_needed, int len_given) ExceptionOutOfBound(const char* where, int len_needed, int len_given)
{ {
append(binpac_fmt("out_of_bound: %s: %d > %d", append(binpac_fmt("out_of_bound: %s: %d > %d", where, len_needed, len_given));
where, len_needed, len_given));
} }
}; };
class ExceptionInvalidCase : public Exception class ExceptionInvalidCase : public Exception
{
public:
ExceptionInvalidCase(const char* location,
int64_t index,
const char *expected)
: location_(location),
index_(index),
expected_(expected)
{ {
append(binpac_fmt("invalid case: %s: %" PRIi64 " (%s)", public:
location, index, expected)); ExceptionInvalidCase(const char* location, int64_t index, const char* expected)
: location_(location), index_(index), expected_(expected)
{
append(binpac_fmt("invalid case: %s: %" PRIi64 " (%s)", location, index, expected));
} }
protected: protected:
const char* location_; const char* location_;
int64_t index_; int64_t index_;
string expected_; string expected_;
}; };
class ExceptionInvalidCaseIndex : public Exception class ExceptionInvalidCaseIndex : public Exception
{
public:
ExceptionInvalidCaseIndex(const char* location,
int64_t index)
: location_(location),
index_(index)
{ {
append(binpac_fmt("invalid index for case: %s: %" PRIi64, public:
location, index)); ExceptionInvalidCaseIndex(const char* location, int64_t index)
: location_(location), index_(index)
{
append(binpac_fmt("invalid index for case: %s: %" PRIi64, location, index));
} }
protected: protected:
const char* location_; const char* location_;
int64_t index_; int64_t index_;
}; };
class ExceptionInvalidOffset : public Exception class ExceptionInvalidOffset : public Exception
{
public:
ExceptionInvalidOffset(const char* location,
int min_offset, int offset)
: location_(location),
min_offset_(min_offset), offset_(offset)
{ {
append(binpac_fmt("invalid offset: %s: min_offset = %d, offset = %d", public:
location, min_offset, offset)); ExceptionInvalidOffset(const char* location, int min_offset, int offset)
: location_(location), min_offset_(min_offset), offset_(offset)
{
append(binpac_fmt("invalid offset: %s: min_offset = %d, offset = %d", location, min_offset,
offset));
} }
protected: protected:
const char* location_; const char* location_;
int min_offset_, offset_; int min_offset_, offset_;
}; };
class ExceptionStringMismatch : public Exception class ExceptionStringMismatch : public Exception
{ {
public: public:
ExceptionStringMismatch(const char* location, ExceptionStringMismatch(const char* location, const char* expected, const char* actual_data)
const char *expected, const char *actual_data)
{ {
append(binpac_fmt("string mismatch at %s: \nexpected pattern: \"%s\"\nactual data: \"%s\"", append(binpac_fmt("string mismatch at %s: \nexpected pattern: \"%s\"\nactual data: \"%s\"",
location, expected, actual_data)); location, expected, actual_data));
} }
}; };
class ExceptionInvalidStringLength : public Exception class ExceptionInvalidStringLength : public Exception
{ {
public: public:
ExceptionInvalidStringLength(const char* location, int len) ExceptionInvalidStringLength(const char* location, int len)
{ {
append(binpac_fmt("invalid length string: %s: %d", append(binpac_fmt("invalid length string: %s: %d", location, len));
location, len));
} }
}; };
class ExceptionFlowBufferAlloc : public Exception class ExceptionFlowBufferAlloc : public Exception
{ {
public: public:
ExceptionFlowBufferAlloc(const char* reason) ExceptionFlowBufferAlloc(const char* reason)
{ {
append(binpac_fmt("flowbuffer allocation failed: %s", reason)); append(binpac_fmt("flowbuffer allocation failed: %s", reason));
} }
}; };
} }
#endif // binpac_exception_h #endif // binpac_exception_h

View file

@ -3,8 +3,9 @@
class RE_Matcher; class RE_Matcher;
namespace binpac { namespace binpac
{
std::vector<RE_Matcher*>* uncompiled_re_matchers = 0; std::vector<RE_Matcher*>* uncompiled_re_matchers = 0;
} }

View file

@ -1,13 +1,17 @@
#ifndef binpac_regex_h #ifndef binpac_regex_h
#define binpac_regex_h #define binpac_regex_h
#include "binpac.h"
#include "zeek/RE.h" #include "zeek/RE.h"
namespace zeek { class RE_Matcher; } #include "binpac.h"
namespace zeek
{
class RE_Matcher;
}
namespace binpac namespace binpac
{ {
// Must be called before any binpac functionality is used. // Must be called before any binpac functionality is used.
// //
@ -19,10 +23,10 @@ inline void init(FlowBuffer::Policy* fbp = 0);
// Internal vector recording not yet compiled matchers. // Internal vector recording not yet compiled matchers.
extern std::vector<zeek::RE_Matcher*>* uncompiled_re_matchers; extern std::vector<zeek::RE_Matcher*>* uncompiled_re_matchers;
class RegExMatcher { class RegExMatcher
{
public: public:
RegExMatcher(const char *pattern) RegExMatcher(const char* pattern) : pattern_(pattern)
: pattern_(pattern)
{ {
if ( ! uncompiled_re_matchers ) if ( ! uncompiled_re_matchers )
uncompiled_re_matchers = new std::vector<zeek::RE_Matcher*>; uncompiled_re_matchers = new std::vector<zeek::RE_Matcher*>;
@ -31,16 +35,10 @@ public:
uncompiled_re_matchers->push_back(re_matcher_); uncompiled_re_matchers->push_back(re_matcher_);
} }
~RegExMatcher() ~RegExMatcher() { delete re_matcher_; }
{
delete re_matcher_;
}
// Returns the length of longest match, or -1 on mismatch. // Returns the length of longest match, or -1 on mismatch.
int MatchPrefix(const_byteptr data, int len) int MatchPrefix(const_byteptr data, int len) { return re_matcher_->MatchPrefix(data, len); }
{
return re_matcher_->MatchPrefix(data, len);
}
private: private:
friend void ::binpac::init(FlowBuffer::Policy*); friend void ::binpac::init(FlowBuffer::Policy*);
@ -49,8 +47,8 @@ private:
static void init(); static void init();
string pattern_; string pattern_;
zeek::RE_Matcher *re_matcher_; zeek::RE_Matcher* re_matcher_;
}; };
inline void RegExMatcher::init() inline void RegExMatcher::init()
{ {
@ -77,6 +75,6 @@ inline void init(FlowBuffer::Policy* fbp)
FlowBuffer::init(*fbp); FlowBuffer::init(*fbp);
} }
} // namespace binpac } // namespace binpac
#endif // binpac_regex_h #endif // binpac_regex_h

View file

@ -1,3 +1,5 @@
#include "pac_action.h"
#include "pac_embedded.h" #include "pac_embedded.h"
#include "pac_exception.h" #include "pac_exception.h"
#include "pac_id.h" #include "pac_id.h"
@ -6,17 +8,8 @@
#include "pac_typedecl.h" #include "pac_typedecl.h"
#include "pac_utils.h" #include "pac_utils.h"
#include "pac_action.h" AnalyzerAction::AnalyzerAction(ID* action_id, When when, ActionParam* param, EmbeddedCode* code)
: AnalyzerElement(ACTION), action_id_(action_id), when_(when), param_(param), code_(code),
AnalyzerAction::AnalyzerAction(ID *action_id,
When when,
ActionParam *param,
EmbeddedCode *code)
: AnalyzerElement(ACTION),
action_id_(action_id),
when_(when),
param_(param),
code_(code),
analyzer_(0) analyzer_(0)
{ {
} }
@ -33,31 +26,25 @@ string AnalyzerAction::action_function() const
return strfmt("Action_%s", action_id_->Name()); return strfmt("Action_%s", action_id_->Name());
} }
void AnalyzerAction::InstallHook(AnalyzerDecl *analyzer) void AnalyzerAction::InstallHook(AnalyzerDecl* analyzer)
{ {
ASSERT(0); ASSERT(0);
analyzer_ = analyzer; analyzer_ = analyzer;
// param_->MainDataType()->InstallAction(this); // param_->MainDataType()->InstallAction(this);
} }
void AnalyzerAction::GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl) void AnalyzerAction::GenCode(Output* out_h, Output* out_cc, AnalyzerDecl* decl)
{ {
Env action_func_env(decl->env(), this); Env action_func_env(decl->env(), this);
action_func_env.AddID(param_->id(), action_func_env.AddID(param_->id(), TEMP_VAR, param_->DataType());
TEMP_VAR,
param_->DataType());
action_func_env.SetEvaluated(param_->id()); action_func_env.SetEvaluated(param_->id());
string action_func_proto = string action_func_proto = strfmt("%s(%s)", action_function().c_str(),
strfmt("%s(%s)",
action_function().c_str(),
ParamDecls(&action_func_env).c_str()); ParamDecls(&action_func_env).c_str());
out_h->println("void %s;", action_func_proto.c_str()); out_h->println("void %s;", action_func_proto.c_str());
out_cc->println("void %s::%s", out_cc->println("void %s::%s", decl->class_name().c_str(), action_func_proto.c_str());
decl->class_name().c_str(),
action_func_proto.c_str());
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
@ -69,28 +56,27 @@ void AnalyzerAction::GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl)
out_cc->println(""); out_cc->println("");
} }
string AnalyzerAction::ParamDecls(Env *env) const string AnalyzerAction::ParamDecls(Env* env) const
{ {
return param_->DeclStr(env); return param_->DeclStr(env);
} }
Type *ActionParam::MainDataType() const Type* ActionParam::MainDataType() const
{ {
// Note: this is not equal to DataType() // Note: this is not equal to DataType()
Type *main_type = TypeDecl::LookUpType(type()->type_id()); Type* main_type = TypeDecl::LookUpType(type()->type_id());
if ( ! main_type ) if ( ! main_type )
{ {
throw Exception(type()->type_id(), throw Exception(type()->type_id(), "type not defined");
"type not defined");
} }
return main_type; return main_type;
} }
Type *ActionParam::DataType() const Type* ActionParam::DataType() const
{ {
Type *main_type = MainDataType(); Type* main_type = MainDataType();
if ( ! type()->field_id() ) if ( ! type()->field_id() )
{ {
@ -98,22 +84,18 @@ Type *ActionParam::DataType() const
} }
else else
{ {
Type *member_type = Type* member_type = main_type->MemberDataType(type()->field_id());
main_type->MemberDataType(type()->field_id());
if ( ! member_type ) if ( ! member_type )
{ {
throw Exception(type()->field_id(), throw Exception(type()->field_id(),
strfmt("cannot find member type for `%s.%s'", strfmt("cannot find member type for `%s.%s'", type()->type_id()->Name(),
type()->type_id()->Name(),
type()->field_id()->Name())); type()->field_id()->Name()));
} }
return member_type; return member_type;
} }
} }
string ActionParam::DeclStr(Env *env) const string ActionParam::DeclStr(Env* env) const
{ {
return strfmt("%s %s", return strfmt("%s %s", DataType()->DataTypeStr().c_str(), env->LValue(id()));
DataType()->DataTypeStr().c_str(),
env->LValue(id()));
} }

View file

@ -3,72 +3,74 @@
// Classes representing analyzer actions. // Classes representing analyzer actions.
#include "pac_common.h"
#include "pac_analyzer.h" #include "pac_analyzer.h"
#include "pac_common.h"
class AnalyzerAction : public AnalyzerElement class AnalyzerAction : public AnalyzerElement
{ {
public: public:
enum When { BEFORE, AFTER }; enum When
{
BEFORE,
AFTER
};
AnalyzerAction(ID *action_id, AnalyzerAction(ID* action_id, When when, ActionParam* param, EmbeddedCode* code);
When when,
ActionParam *param,
EmbeddedCode *code);
~AnalyzerAction(); ~AnalyzerAction();
When when() const { return when_; } When when() const { return when_; }
ActionParam *param() const { return param_; } ActionParam* param() const { return param_; }
AnalyzerDecl *analyzer() const { return analyzer_; } AnalyzerDecl* analyzer() const { return analyzer_; }
string action_function() const; string action_function() const;
// Generate function prototype and code for the action // Generate function prototype and code for the action
void GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl); void GenCode(Output* out_h, Output* out_cc, AnalyzerDecl* decl);
// Install the hook at the corresponding data type parsing // Install the hook at the corresponding data type parsing
// function to invoke the action. // function to invoke the action.
void InstallHook(AnalyzerDecl *analyzer); void InstallHook(AnalyzerDecl* analyzer);
private: private:
string ParamDecls(Env *env) const; string ParamDecls(Env* env) const;
ID *action_id_; ID* action_id_;
When when_; When when_;
ActionParam *param_; ActionParam* param_;
EmbeddedCode *code_; EmbeddedCode* code_;
AnalyzerDecl *analyzer_; AnalyzerDecl* analyzer_;
}; };
class ActionParam class ActionParam
{ {
public: public:
ActionParam(const ID *id, ActionParamType *type) ActionParam(const ID* id, ActionParamType* type) : id_(id), type_(type) { }
: id_(id), type_(type) {}
const ID *id() const { return id_; } const ID* id() const { return id_; }
ActionParamType *type() const { return type_; } ActionParamType* type() const { return type_; }
Type *MainDataType() const; Type* MainDataType() const;
Type *DataType() const; Type* DataType() const;
string DeclStr(Env *env) const; string DeclStr(Env* env) const;
private: private:
const ID *id_; const ID* id_;
ActionParamType *type_; ActionParamType* type_;
}; };
class ActionParamType class ActionParamType
{ {
public: public:
ActionParamType(const ID *type_id, const ID *field_id = 0) ActionParamType(const ID* type_id, const ID* field_id = 0)
: type_id_(type_id), field_id_(field_id) {} : type_id_(type_id), field_id_(field_id)
{
}
const ID *type_id() const { return type_id_; } const ID* type_id() const { return type_id_; }
const ID *field_id() const { return field_id_; } const ID* field_id() const { return field_id_; }
protected: protected:
const ID *type_id_, *field_id_; const ID *type_id_, *field_id_;
}; };
#endif // pac_action_h #endif // pac_action_h

View file

@ -1,3 +1,5 @@
#include "pac_analyzer.h"
#include "pac_action.h" #include "pac_action.h"
#include "pac_context.h" #include "pac_context.h"
#include "pac_embedded.h" #include "pac_embedded.h"
@ -12,11 +14,7 @@
#include "pac_type.h" #include "pac_type.h"
#include "pac_varfield.h" #include "pac_varfield.h"
#include "pac_analyzer.h" AnalyzerDecl::AnalyzerDecl(ID* id, DeclType decl_type, ParamList* params)
AnalyzerDecl::AnalyzerDecl(ID *id,
DeclType decl_type,
ParamList *params)
: TypeDecl(id, params, new DummyType()) : TypeDecl(id, params, new DummyType())
{ {
decl_type_ = decl_type; decl_type_ = decl_type;
@ -47,37 +45,32 @@ AnalyzerDecl::~AnalyzerDecl()
delete_list(AnalyzerHelperList, eof_helpers_); delete_list(AnalyzerHelperList, eof_helpers_);
} }
void AnalyzerDecl::AddElements(AnalyzerElementList *elemlist) void AnalyzerDecl::AddElements(AnalyzerElementList* elemlist)
{ {
ASSERT(! env_); ASSERT(! env_);
foreach(i, AnalyzerElementList, elemlist) foreach (i, AnalyzerElementList, elemlist)
{ {
AnalyzerElement *elem = *i; AnalyzerElement* elem = *i;
switch ( elem->type() ) switch ( elem->type() )
{ {
case AnalyzerElement::STATE: case AnalyzerElement::STATE:
{ {
ASSERT(0); ASSERT(0);
AnalyzerState *state_elem = AnalyzerState* state_elem = (AnalyzerState*)elem;
(AnalyzerState *) elem; statevars_->insert(statevars_->end(), state_elem->statevars()->begin(),
statevars_->insert(
statevars_->end(),
state_elem->statevars()->begin(),
state_elem->statevars()->end()); state_elem->statevars()->end());
} }
break; break;
case AnalyzerElement::ACTION: case AnalyzerElement::ACTION:
{ {
ASSERT(0); ASSERT(0);
AnalyzerAction *action_elem = AnalyzerAction* action_elem = (AnalyzerAction*)elem;
(AnalyzerAction *) elem;
actions_->push_back(action_elem); actions_->push_back(action_elem);
} }
break; break;
case AnalyzerElement::HELPER: case AnalyzerElement::HELPER:
{ {
AnalyzerHelper *helper_elem = AnalyzerHelper* helper_elem = (AnalyzerHelper*)elem;
(AnalyzerHelper *) elem;
switch ( helper_elem->helper_type() ) switch ( helper_elem->helper_type() )
{ {
@ -97,24 +90,21 @@ void AnalyzerDecl::AddElements(AnalyzerElementList *elemlist)
break; break;
case AnalyzerElement::FUNCTION: case AnalyzerElement::FUNCTION:
{ {
AnalyzerFunction *func_elem = AnalyzerFunction* func_elem = (AnalyzerFunction*)elem;
(AnalyzerFunction *) elem; Function* func = func_elem->function();
Function *func = func_elem->function();
func->set_analyzer_decl(this); func->set_analyzer_decl(this);
functions_->push_back(func); functions_->push_back(func);
} }
break; break;
case AnalyzerElement::FLOW: case AnalyzerElement::FLOW:
{ {
AnalyzerFlow *flow_elem = AnalyzerFlow* flow_elem = (AnalyzerFlow*)elem;
(AnalyzerFlow *) elem;
ProcessFlowElement(flow_elem); ProcessFlowElement(flow_elem);
} }
break; break;
case AnalyzerElement::DATAUNIT: case AnalyzerElement::DATAUNIT:
{ {
AnalyzerDataUnit *dataunit_elem = AnalyzerDataUnit* dataunit_elem = (AnalyzerDataUnit*)elem;
(AnalyzerDataUnit *) elem;
ProcessDataUnitElement(dataunit_elem); ProcessDataUnitElement(dataunit_elem);
} }
break; break;
@ -134,19 +124,19 @@ void AnalyzerDecl::Prepare()
ASSERT(statevars_->empty()); ASSERT(statevars_->empty());
ASSERT(actions_->empty()); ASSERT(actions_->empty());
foreach(i, FunctionList, functions_) foreach (i, FunctionList, functions_)
{ {
Function *function = *i; Function* function = *i;
function->Prepare(env_); function->Prepare(env_);
} }
foreach(i, StateVarList, statevars_) foreach (i, StateVarList, statevars_)
{ {
StateVar *statevar = *i; StateVar* statevar = *i;
env_->AddID(statevar->id(), STATE_VAR, statevar->type()); env_->AddID(statevar->id(), STATE_VAR, statevar->type());
} }
foreach(i, AnalyzerActionList, actions_) foreach (i, AnalyzerActionList, actions_)
{ {
AnalyzerAction *action = *i; AnalyzerAction* action = *i;
action->InstallHook(this); action->InstallHook(this);
} }
} }
@ -154,30 +144,30 @@ void AnalyzerDecl::Prepare()
void AnalyzerDecl::GenForwardDeclaration(Output* out_h) void AnalyzerDecl::GenForwardDeclaration(Output* out_h)
{ {
out_h->println("class %s;", class_name().c_str()); out_h->println("class %s;", class_name().c_str());
foreach(i, FunctionList, functions_) foreach (i, FunctionList, functions_)
{ {
Function *function = *i; Function* function = *i;
function->GenForwardDeclaration(out_h); function->GenForwardDeclaration(out_h);
} }
} }
void AnalyzerDecl::GenActions(Output *out_h, Output *out_cc) void AnalyzerDecl::GenActions(Output* out_h, Output* out_cc)
{ {
foreach(i, AnalyzerActionList, actions_) foreach (i, AnalyzerActionList, actions_)
{ {
(*i)->GenCode(out_h, out_cc, this); (*i)->GenCode(out_h, out_cc, this);
} }
} }
void AnalyzerDecl::GenHelpers(Output *out_h, Output *out_cc) void AnalyzerDecl::GenHelpers(Output* out_h, Output* out_cc)
{ {
foreach(i, AnalyzerHelperList, helpers_) foreach (i, AnalyzerHelperList, helpers_)
{ {
(*i)->GenCode(out_h, out_cc, this); (*i)->GenCode(out_h, out_cc, this);
} }
} }
void AnalyzerDecl::GenPubDecls(Output *out_h, Output *out_cc) void AnalyzerDecl::GenPubDecls(Output* out_h, Output* out_cc)
{ {
TypeDecl::GenPubDecls(out_h, out_cc); TypeDecl::GenPubDecls(out_h, out_cc);
@ -196,7 +186,7 @@ void AnalyzerDecl::GenPubDecls(Output *out_h, Output *out_cc)
// TODO: export public state variables // TODO: export public state variables
} }
void AnalyzerDecl::GenPrivDecls(Output *out_h, Output *out_cc) void AnalyzerDecl::GenPrivDecls(Output* out_h, Output* out_cc)
{ {
TypeDecl::GenPrivDecls(out_h, out_cc); TypeDecl::GenPrivDecls(out_h, out_cc);
@ -210,65 +200,65 @@ void AnalyzerDecl::GenPrivDecls(Output *out_h, Output *out_cc)
// TODO: declare state variables // TODO: declare state variables
} }
void AnalyzerDecl::GenInitCode(Output *out_cc) void AnalyzerDecl::GenInitCode(Output* out_cc)
{ {
TypeDecl::GenInitCode(out_cc); TypeDecl::GenInitCode(out_cc);
foreach(i, AnalyzerHelperList, constructor_helpers_) foreach (i, AnalyzerHelperList, constructor_helpers_)
{ {
(*i)->GenCode(0, out_cc, this); (*i)->GenCode(0, out_cc, this);
} }
} }
void AnalyzerDecl::GenCleanUpCode(Output *out_cc) void AnalyzerDecl::GenCleanUpCode(Output* out_cc)
{ {
TypeDecl::GenCleanUpCode(out_cc); TypeDecl::GenCleanUpCode(out_cc);
foreach(i, AnalyzerHelperList, destructor_helpers_) foreach (i, AnalyzerHelperList, destructor_helpers_)
{ {
(*i)->GenCode(0, out_cc, this); (*i)->GenCode(0, out_cc, this);
} }
} }
void AnalyzerDecl::GenStateVarDecls(Output *out_h) void AnalyzerDecl::GenStateVarDecls(Output* out_h)
{ {
foreach(i, StateVarList, statevars_) foreach (i, StateVarList, statevars_)
{ {
StateVar *var = *i; StateVar* var = *i;
var->GenDecl(out_h, env_); var->GenDecl(out_h, env_);
} }
} }
void AnalyzerDecl::GenStateVarSetFunctions(Output *out_h) void AnalyzerDecl::GenStateVarSetFunctions(Output* out_h)
{ {
foreach(i, StateVarList, statevars_) foreach (i, StateVarList, statevars_)
{ {
StateVar *var = *i; StateVar* var = *i;
var->GenSetFunction(out_h, env_); var->GenSetFunction(out_h, env_);
} }
} }
void AnalyzerDecl::GenStateVarInitCode(Output *out_cc) void AnalyzerDecl::GenStateVarInitCode(Output* out_cc)
{ {
foreach(i, StateVarList, statevars_) foreach (i, StateVarList, statevars_)
{ {
StateVar *var = *i; StateVar* var = *i;
var->GenInitCode(out_cc, env_); var->GenInitCode(out_cc, env_);
} }
} }
void AnalyzerDecl::GenStateVarCleanUpCode(Output *out_cc) void AnalyzerDecl::GenStateVarCleanUpCode(Output* out_cc)
{ {
foreach(i, StateVarList, statevars_) foreach (i, StateVarList, statevars_)
{ {
StateVar *var = *i; StateVar* var = *i;
var->GenCleanUpCode(out_cc, env_); var->GenCleanUpCode(out_cc, env_);
} }
} }
void AnalyzerDecl::GenFunctions(Output *out_h, Output *out_cc) void AnalyzerDecl::GenFunctions(Output* out_h, Output* out_cc)
{ {
foreach(i, FunctionList, functions_) foreach (i, FunctionList, functions_)
{ {
Function *function = *i; Function* function = *i;
function->GenCode(out_h, out_cc); function->GenCode(out_h, out_cc);
} }
} }
@ -285,9 +275,9 @@ AnalyzerHelper::~AnalyzerHelper()
delete code_; delete code_;
} }
void AnalyzerHelper::GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl) void AnalyzerHelper::GenCode(Output* out_h, Output* out_cc, AnalyzerDecl* decl)
{ {
Output *out = 0; Output* out = 0;
switch ( helper_type_ ) switch ( helper_type_ )
{ {
case MEMBER_DECLS: case MEMBER_DECLS:
@ -303,22 +293,18 @@ void AnalyzerHelper::GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl)
code()->GenCode(out, decl->env()); code()->GenCode(out, decl->env());
} }
FlowField::FlowField(ID *flow_id, ParameterizedType *flow_type) FlowField::FlowField(ID* flow_id, ParameterizedType* flow_type)
: Field(FLOW_FIELD, : Field(FLOW_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, flow_id, flow_type)
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
flow_id, flow_type)
{ {
} }
void FlowField::GenInitCode(Output *out_cc, Env *env) void FlowField::GenInitCode(Output* out_cc, Env* env)
{ {
type_->GenPreParsing(out_cc, env); type_->GenPreParsing(out_cc, env);
} }
AnalyzerFlow::AnalyzerFlow(Direction dir, ID *type_id, ExprList *params) AnalyzerFlow::AnalyzerFlow(Direction dir, ID* type_id, ExprList* params)
: AnalyzerElement(FLOW), : AnalyzerElement(FLOW), dir_(dir), type_id_(type_id)
dir_(dir),
type_id_(type_id)
{ {
if ( ! params ) if ( ! params )
params = new ExprList(); params = new ExprList();
@ -326,9 +312,9 @@ AnalyzerFlow::AnalyzerFlow(Direction dir, ID *type_id, ExprList *params)
// Add "this" to the list of params // Add "this" to the list of params
params->insert(params->begin(), new Expr(this_id->clone())); params->insert(params->begin(), new Expr(this_id->clone()));
ID *flow_id = ((dir == UP) ? upflow_id : downflow_id)->clone(); ID* flow_id = ((dir == UP) ? upflow_id : downflow_id)->clone();
ParameterizedType *flow_type = new ParameterizedType(type_id_, params); ParameterizedType* flow_type = new ParameterizedType(type_id_, params);
flow_field_ = new FlowField(flow_id, flow_type); flow_field_ = new FlowField(flow_id, flow_type);
@ -340,18 +326,17 @@ AnalyzerFlow::~AnalyzerFlow()
delete flow_field_; delete flow_field_;
} }
FlowDecl *AnalyzerFlow::flow_decl() FlowDecl* AnalyzerFlow::flow_decl()
{ {
DEBUG_MSG("Getting flow_decl for %s\n", type_id_->Name()); DEBUG_MSG("Getting flow_decl for %s\n", type_id_->Name());
if ( ! flow_decl_ ) if ( ! flow_decl_ )
{ {
Decl *decl = Decl::LookUpDecl(type_id_); Decl* decl = Decl::LookUpDecl(type_id_);
if ( decl && decl->decl_type() == Decl::FLOW ) if ( decl && decl->decl_type() == Decl::FLOW )
flow_decl_ = static_cast<FlowDecl *>(decl); flow_decl_ = static_cast<FlowDecl*>(decl);
if ( ! flow_decl_ ) if ( ! flow_decl_ )
{ {
throw Exception(this, throw Exception(this, "cannot find the flow declaration");
"cannot find the flow declaration");
} }
} }
return flow_decl_; return flow_decl_;

View file

@ -14,155 +14,165 @@ class AnalyzerDataUnit;
class AnalyzerFunction; class AnalyzerFunction;
class ConnDecl; class ConnDecl;
class FlowDecl; class FlowDecl;
typedef vector<AnalyzerHelper *> AnalyzerHelperList; typedef vector<AnalyzerHelper*> AnalyzerHelperList;
typedef vector<Function *> FunctionList; typedef vector<Function*> FunctionList;
class AnalyzerDecl : public TypeDecl class AnalyzerDecl : public TypeDecl
{ {
public: public:
AnalyzerDecl(ID *id, DeclType decl_type, ParamList *params); AnalyzerDecl(ID* id, DeclType decl_type, ParamList* params);
~AnalyzerDecl(); ~AnalyzerDecl();
void AddElements(AnalyzerElementList *elemlist); void AddElements(AnalyzerElementList* elemlist);
void Prepare(); void Prepare();
void GenForwardDeclaration(Output *out_h); void GenForwardDeclaration(Output* out_h);
// void GenCode(Output *out_h, Output *out_cc); // void GenCode(Output *out_h, Output *out_cc);
void GenInitCode(Output *out_cc); void GenInitCode(Output* out_cc);
void GenCleanUpCode(Output *out_cc); void GenCleanUpCode(Output* out_cc);
string class_name() const; string class_name() const;
// string cookie_name() const; // string cookie_name() const;
protected: protected:
virtual void ProcessFlowElement(AnalyzerFlow *flow_elem) = 0; virtual void ProcessFlowElement(AnalyzerFlow* flow_elem) = 0;
virtual void ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem) = 0; virtual void ProcessDataUnitElement(AnalyzerDataUnit* dataunit_elem) = 0;
// Generate public/private declarations for member functions and // Generate public/private declarations for member functions and
// variables // variables
void GenPubDecls(Output *out_h, Output *out_cc); void GenPubDecls(Output* out_h, Output* out_cc);
void GenPrivDecls(Output *out_h, Output *out_cc); void GenPrivDecls(Output* out_h, Output* out_cc);
// Generate the NewData() function // Generate the NewData() function
virtual void GenProcessFunc(Output *out_h, Output *out_cc) = 0; virtual void GenProcessFunc(Output* out_h, Output* out_cc) = 0;
// Generate the NewGap() function // Generate the NewGap() function
virtual void GenGapFunc(Output *out_h, Output *out_cc) = 0; virtual void GenGapFunc(Output* out_h, Output* out_cc) = 0;
// Generate the FlowEOF() function // Generate the FlowEOF() function
virtual void GenEOFFunc(Output *out_h, Output *out_cc) = 0; virtual void GenEOFFunc(Output* out_h, Output* out_cc) = 0;
// Generate the functions // Generate the functions
void GenFunctions(Output *out_h, Output *out_cc); void GenFunctions(Output* out_h, Output* out_cc);
// Generate the action functions // Generate the action functions
void GenActions(Output *out_h, Output *out_cc); void GenActions(Output* out_h, Output* out_cc);
// Generate the helper code segments // Generate the helper code segments
void GenHelpers(Output *out_h, Output *out_cc); void GenHelpers(Output* out_h, Output* out_cc);
// Generate declarations for state variables and their set functions // Generate declarations for state variables and their set functions
void GenStateVarDecls(Output *out_h); void GenStateVarDecls(Output* out_h);
void GenStateVarSetFunctions(Output *out_h); void GenStateVarSetFunctions(Output* out_h);
// Generate code for initializing and cleaning up (including // Generate code for initializing and cleaning up (including
// memory de-allocating) state variables // memory de-allocating) state variables
void GenStateVarInitCode(Output *out_cc); void GenStateVarInitCode(Output* out_cc);
void GenStateVarCleanUpCode(Output *out_cc); void GenStateVarCleanUpCode(Output* out_cc);
StateVarList *statevars_; StateVarList* statevars_;
AnalyzerActionList *actions_; AnalyzerActionList* actions_;
AnalyzerHelperList *helpers_; AnalyzerHelperList* helpers_;
FunctionList *functions_; FunctionList* functions_;
AnalyzerHelperList *constructor_helpers_; AnalyzerHelperList* constructor_helpers_;
AnalyzerHelperList *destructor_helpers_; AnalyzerHelperList* destructor_helpers_;
AnalyzerHelperList *eof_helpers_; AnalyzerHelperList* eof_helpers_;
}; };
class AnalyzerElement : public Object class AnalyzerElement : public Object
{ {
public: public:
enum ElementType { STATE, ACTION, FUNCTION, HELPER, FLOW, DATAUNIT }; enum ElementType
AnalyzerElement(ElementType type) {
: type_(type) {} STATE,
virtual ~AnalyzerElement() {} ACTION,
FUNCTION,
HELPER,
FLOW,
DATAUNIT
};
AnalyzerElement(ElementType type) : type_(type) { }
virtual ~AnalyzerElement() { }
ElementType type() const { return type_; } ElementType type() const { return type_; }
private: private:
ElementType type_; ElementType type_;
}; };
// A collection of variables representing analyzer states. // A collection of variables representing analyzer states.
class AnalyzerState : public AnalyzerElement class AnalyzerState : public AnalyzerElement
{ {
public: public:
AnalyzerState(StateVarList *statevars) AnalyzerState(StateVarList* statevars) : AnalyzerElement(STATE), statevars_(statevars) { }
: AnalyzerElement(STATE),
statevars_(statevars) {}
~AnalyzerState(); ~AnalyzerState();
StateVarList *statevars() const { return statevars_; } StateVarList* statevars() const { return statevars_; }
private: private:
StateVarList *statevars_; StateVarList* statevars_;
}; };
// A collection of embedded C++ code // A collection of embedded C++ code
class AnalyzerHelper : public AnalyzerElement class AnalyzerHelper : public AnalyzerElement
{ {
public: public:
enum Type { enum Type
{
MEMBER_DECLS, MEMBER_DECLS,
INIT_CODE, INIT_CODE,
CLEANUP_CODE, CLEANUP_CODE,
EOF_CODE, EOF_CODE,
}; };
AnalyzerHelper(Type helper_type, EmbeddedCode *code) AnalyzerHelper(Type helper_type, EmbeddedCode* code)
: AnalyzerElement(HELPER), : AnalyzerElement(HELPER), helper_type_(helper_type), code_(code)
helper_type_(helper_type), {
code_(code) {} }
~AnalyzerHelper(); ~AnalyzerHelper();
Type helper_type() const { return helper_type_; } Type helper_type() const { return helper_type_; }
void GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl); void GenCode(Output* out_h, Output* out_cc, AnalyzerDecl* decl);
EmbeddedCode *code() const { return code_; } EmbeddedCode* code() const { return code_; }
private: private:
Type helper_type_; Type helper_type_;
EmbeddedCode *code_; EmbeddedCode* code_;
}; };
// The type and parameters of (uni-directional) flows of a connection. // The type and parameters of (uni-directional) flows of a connection.
class FlowField : public Field class FlowField : public Field
{ {
public: public:
FlowField(ID *flow_id, ParameterizedType *flow_type); FlowField(ID* flow_id, ParameterizedType* flow_type);
void GenInitCode(Output *out, Env *env); void GenInitCode(Output* out, Env* env);
}; };
class AnalyzerFlow : public AnalyzerElement class AnalyzerFlow : public AnalyzerElement
{ {
public: public:
enum Direction { UP, DOWN }; enum Direction
AnalyzerFlow(Direction dir, ID *type_id, ExprList *params); {
UP,
DOWN
};
AnalyzerFlow(Direction dir, ID* type_id, ExprList* params);
~AnalyzerFlow(); ~AnalyzerFlow();
Direction dir() const { return dir_; } Direction dir() const { return dir_; }
FlowField *flow_field() const { return flow_field_; } FlowField* flow_field() const { return flow_field_; }
FlowDecl *flow_decl(); FlowDecl* flow_decl();
private: private:
Direction dir_; Direction dir_;
ID *type_id_; ID* type_id_;
FlowField *flow_field_; FlowField* flow_field_;
FlowDecl *flow_decl_; FlowDecl* flow_decl_;
}; };
#endif // pac_analyzer_h #endif // pac_analyzer_h

View file

@ -1,3 +1,5 @@
#include "pac_array.h"
#include "pac_attr.h" #include "pac_attr.h"
#include "pac_dataptr.h" #include "pac_dataptr.h"
#include "pac_exception.h" #include "pac_exception.h"
@ -9,9 +11,7 @@
#include "pac_utils.h" #include "pac_utils.h"
#include "pac_varfield.h" #include "pac_varfield.h"
#include "pac_array.h" ArrayType::ArrayType(Type* elemtype, Expr* length)
ArrayType::ArrayType(Type *elemtype, Expr *length)
: Type(ARRAY), elemtype_(elemtype), length_(length) : Type(ARRAY), elemtype_(elemtype), length_(length)
{ {
init(); init();
@ -67,9 +67,9 @@ ArrayType::~ArrayType()
delete elem_dataptr_until_expr_; delete elem_dataptr_until_expr_;
} }
Type *ArrayType::DoClone() const Type* ArrayType::DoClone() const
{ {
Type *elemtype = elemtype_->Clone(); Type* elemtype = elemtype_->Clone();
if ( ! elemtype ) if ( ! elemtype )
return 0; return 0;
return new ArrayType(elemtype, length_); return new ArrayType(elemtype, length_);
@ -85,12 +85,12 @@ string ArrayType::DataTypeStr() const
return datatype_str_; return datatype_str_;
} }
Type *ArrayType::ElementDataType() const Type* ArrayType::ElementDataType() const
{ {
return elemtype_; return elemtype_;
} }
string ArrayType::EvalElement(const string &array, const string &index) const string ArrayType::EvalElement(const string& array, const string& index) const
{ {
if ( attr_transient_ ) if ( attr_transient_ )
throw Exception(this, "cannot access element in &transient array"); throw Exception(this, "cannot access element in &transient array");
@ -98,32 +98,32 @@ string ArrayType::EvalElement(const string &array, const string &index) const
return strfmt("(*(%s))[%s]", array.c_str(), index.c_str()); return strfmt("(*(%s))[%s]", array.c_str(), index.c_str());
} }
const ID *ArrayType::arraylength_var() const const ID* ArrayType::arraylength_var() const
{ {
return arraylength_var_field_ ? arraylength_var_field_->id() : 0; return arraylength_var_field_ ? arraylength_var_field_->id() : 0;
} }
const ID *ArrayType::elem_it_var() const const ID* ArrayType::elem_it_var() const
{ {
return elem_it_var_field_ ? elem_it_var_field_->id() : 0; return elem_it_var_field_ ? elem_it_var_field_->id() : 0;
} }
const ID *ArrayType::elem_var() const const ID* ArrayType::elem_var() const
{ {
return elem_var_field_ ? elem_var_field_->id() : 0; return elem_var_field_ ? elem_var_field_->id() : 0;
} }
const ID *ArrayType::elem_dataptr_var() const const ID* ArrayType::elem_dataptr_var() const
{ {
return elem_dataptr_var_field_ ? elem_dataptr_var_field_->id() : 0; return elem_dataptr_var_field_ ? elem_dataptr_var_field_->id() : 0;
} }
const ID *ArrayType::elem_input_var() const const ID* ArrayType::elem_input_var() const
{ {
return elem_input_var_field_ ? elem_input_var_field_->id() : 0; return elem_input_var_field_ ? elem_input_var_field_->id() : 0;
} }
void ArrayType::ProcessAttr(Attr *a) void ArrayType::ProcessAttr(Attr* a)
{ {
Type::ProcessAttr(a); Type::ProcessAttr(a);
@ -133,14 +133,12 @@ void ArrayType::ProcessAttr(Attr *a)
{ {
if ( elemtype_->StaticSize(env()) != 1 ) if ( elemtype_->StaticSize(env()) != 1 )
{ {
throw Exception(elemtype_, throw Exception(elemtype_, "&restofdata can be applied"
"&restofdata can be applied"
" to only byte arrays"); " to only byte arrays");
} }
if ( length_ ) if ( length_ )
{ {
throw Exception(length_, throw Exception(length_, "&restofdata cannot be applied"
"&restofdata cannot be applied"
" to arrays with specified length"); " to arrays with specified length");
} }
attr_restofdata_ = true; attr_restofdata_ = true;
@ -161,8 +159,7 @@ void ArrayType::ProcessAttr(Attr *a)
bool ref_input = a->expr()->HasReference(input_macro_id); bool ref_input = a->expr()->HasReference(input_macro_id);
if ( ref_element && ref_input ) if ( ref_element && ref_input )
{ {
throw Exception(a->expr(), throw Exception(a->expr(), "cannot reference both $element and $input "
"cannot reference both $element and $input "
"in the same &until---please separate them."); "in the same &until---please separate them.");
} }
@ -170,8 +167,7 @@ void ArrayType::ProcessAttr(Attr *a)
{ {
if ( attr_until_element_expr_ ) if ( attr_until_element_expr_ )
{ {
throw Exception(a->expr(), throw Exception(a->expr(), "multiple &until on $element");
"multiple &until on $element");
} }
attr_until_element_expr_ = a->expr(); attr_until_element_expr_ = a->expr();
} }
@ -179,8 +175,7 @@ void ArrayType::ProcessAttr(Attr *a)
{ {
if ( attr_until_input_expr_ ) if ( attr_until_input_expr_ )
{ {
throw Exception(a->expr(), throw Exception(a->expr(), "multiple &until on $input");
"multiple &until on $input");
} }
attr_until_input_expr_ = a->expr(); attr_until_input_expr_ = a->expr();
} }
@ -188,8 +183,7 @@ void ArrayType::ProcessAttr(Attr *a)
{ {
if ( attr_generic_until_expr_ ) if ( attr_generic_until_expr_ )
{ {
throw Exception(a->expr(), throw Exception(a->expr(), "multiple &until condition");
"multiple &until condition");
} }
attr_generic_until_expr_ = a->expr(); attr_generic_until_expr_ = a->expr();
} }
@ -201,50 +195,41 @@ void ArrayType::ProcessAttr(Attr *a)
} }
} }
void ArrayType::Prepare(Env *env, int flags) void ArrayType::Prepare(Env* env, int flags)
{ {
if ( flags & TO_BE_PARSED ) if ( flags & TO_BE_PARSED )
{ {
ID *arraylength_var = new ID(strfmt("%s__arraylength", value_var()->Name())); ID* arraylength_var = new ID(strfmt("%s__arraylength", value_var()->Name()));
ID *elem_var = new ID(strfmt("%s__elem", value_var()->Name())); ID* elem_var = new ID(strfmt("%s__elem", value_var()->Name()));
ID *elem_it_var = new ID(strfmt("%s__it", elem_var->Name())); ID* elem_it_var = new ID(strfmt("%s__it", elem_var->Name()));
elem_var_field_ = elem_var_field_ = new ParseVarField(Field::CLASS_MEMBER, elem_var, elemtype_);
new ParseVarField(Field::CLASS_MEMBER, elem_var, elemtype_);
AddField(elem_var_field_); AddField(elem_var_field_);
if ( incremental_parsing() ) if ( incremental_parsing() )
{ {
arraylength_var_field_ = arraylength_var_field_ = new PrivVarField(arraylength_var, extern_type_int->Clone());
new PrivVarField(arraylength_var, extern_type_int->Clone()); elem_it_var_field_ = new PrivVarField(elem_it_var, extern_type_int->Clone());
elem_it_var_field_ =
new PrivVarField(elem_it_var, extern_type_int->Clone());
AddField(arraylength_var_field_); AddField(arraylength_var_field_);
AddField(elem_it_var_field_); AddField(elem_it_var_field_);
} }
else else
{ {
arraylength_var_field_ = arraylength_var_field_ = new TempVarField(arraylength_var, extern_type_int->Clone());
new TempVarField(arraylength_var, extern_type_int->Clone()); elem_it_var_field_ = new TempVarField(elem_it_var, extern_type_int->Clone());
elem_it_var_field_ =
new TempVarField(elem_it_var, extern_type_int->Clone());
arraylength_var_field_->Prepare(env); arraylength_var_field_->Prepare(env);
elem_it_var_field_->Prepare(env); elem_it_var_field_->Prepare(env);
// Add elem_dataptr_var only when not parsing incrementally // Add elem_dataptr_var only when not parsing incrementally
ID *elem_dataptr_var = ID* elem_dataptr_var = new ID(strfmt("%s__dataptr", elem_var->Name()));
new ID(strfmt("%s__dataptr", elem_var->Name())); elem_dataptr_var_field_ = new TempVarField(elem_dataptr_var,
elem_dataptr_var_field_ = new TempVarField(
elem_dataptr_var,
extern_type_const_byteptr->Clone()); extern_type_const_byteptr->Clone());
elem_dataptr_var_field_->Prepare(env); elem_dataptr_var_field_->Prepare(env);
// until(dataptr >= end_of_data) // until(dataptr >= end_of_data)
elem_dataptr_until_expr_ = new Expr( elem_dataptr_until_expr_ = new Expr(Expr::EXPR_GE, new Expr(elem_dataptr_var->clone()),
Expr::EXPR_GE,
new Expr(elem_dataptr_var->clone()),
new Expr(end_of_data->clone())); new Expr(end_of_data->clone()));
} }
@ -259,7 +244,7 @@ void ArrayType::Prepare(Env *env, int flags)
Type::Prepare(env, flags); Type::Prepare(env, flags);
} }
void ArrayType::GenArrayLength(Output *out_cc, Env *env, const DataPtr& data) void ArrayType::GenArrayLength(Output* out_cc, Env* env, const DataPtr& data)
{ {
if ( env->Evaluated(arraylength_var()) ) if ( env->Evaluated(arraylength_var()) )
return; return;
@ -272,23 +257,17 @@ void ArrayType::GenArrayLength(Output *out_cc, Env *env, const DataPtr& data)
if ( length_ ) if ( length_ )
{ {
out_cc->println("%s = %s;", out_cc->println("%s = %s;", env->LValue(arraylength_var()), length_->EvalExpr(out_cc, env));
env->LValue(arraylength_var()),
length_->EvalExpr(out_cc, env));
env->SetEvaluated(arraylength_var()); env->SetEvaluated(arraylength_var());
// Check negative array length // Check negative array length
out_cc->println("if ( %s < 0 )", out_cc->println("if ( %s < 0 )", env->LValue(arraylength_var()));
env->LValue(arraylength_var()));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", data_id_str_.c_str());
data_id_str_.c_str()); out_cc->println(" %s, (%s) - (%s));", env->LValue(arraylength_var()),
out_cc->println(" %s, (%s) - (%s));", env->RValue(end_of_data), env->RValue(begin_of_data));
env->LValue(arraylength_var()),
env->RValue(end_of_data),
env->RValue(begin_of_data));
out_cc->println("}"); out_cc->println("}");
out_cc->dec_indent(); out_cc->dec_indent();
@ -305,15 +284,13 @@ void ArrayType::GenArrayLength(Output *out_cc, Env *env, const DataPtr& data)
// with it. Note that this check is *not* looking for whether the // with it. Note that this check is *not* looking for whether the
// contents of the array will extend past the end of the data // contents of the array will extend past the end of the data
// buffer. // buffer.
out_cc->println("// Check array element quantity: %s", out_cc->println("// Check array element quantity: %s", data_id_str_.c_str());
data_id_str_.c_str());
element_size = 1; element_size = 1;
} }
else else
{ {
// Boundary check the entire array if elements have static size. // Boundary check the entire array if elements have static size.
out_cc->println("// Check bounds for static-size array: %s", out_cc->println("// Check bounds for static-size array: %s", data_id_str_.c_str());
data_id_str_.c_str());
elemtype_->SetBoundaryChecked(); elemtype_->SetBoundaryChecked();
element_size = elemtype_->StaticSize(env); element_size = elemtype_->StaticSize(env);
@ -325,40 +302,33 @@ void ArrayType::GenArrayLength(Output *out_cc, Env *env, const DataPtr& data)
// arbitrary number of empty records (i.e. cheap for them, // arbitrary number of empty records (i.e. cheap for them,
// but costly for us unless we have special optimization // but costly for us unless we have special optimization
// for this scenario to forgo the usual allocation). // for this scenario to forgo the usual allocation).
throw Exception(this, "using an array of known-to-be-empty elements is possibly a bad idea"); throw Exception(
this, "using an array of known-to-be-empty elements is possibly a bad idea");
} }
} }
const char* array_ptr_expr = data.ptr_expr(); const char* array_ptr_expr = data.ptr_expr();
string max_elements_available = strfmt("((%s - %s) / %d)", string max_elements_available = strfmt("((%s - %s) / %d)", env->RValue(end_of_data),
env->RValue(end_of_data), array_ptr_expr, element_size);
array_ptr_expr,
element_size);
out_cc->println("if ( %s > %s )", out_cc->println("if ( %s > %s )", env->RValue(arraylength_var()),
env->RValue(arraylength_var()),
max_elements_available.c_str()); max_elements_available.c_str());
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", data_id_str_.c_str());
data_id_str_.c_str()); out_cc->println(" %s, (%s) - (%s));", env->RValue(arraylength_var()),
out_cc->println(" %s, (%s) - (%s));", env->RValue(end_of_data), array_ptr_expr);
env->RValue(arraylength_var()),
env->RValue(end_of_data),
array_ptr_expr);
out_cc->dec_indent(); out_cc->dec_indent();
} }
else if ( attr_restofdata_ ) else if ( attr_restofdata_ )
{ {
ASSERT(elemtype_->StaticSize(env) == 1); ASSERT(elemtype_->StaticSize(env) == 1);
out_cc->println("%s = (%s) - (%s);", out_cc->println("%s = (%s) - (%s);", env->LValue(arraylength_var()),
env->LValue(arraylength_var()), env->RValue(end_of_data), data.ptr_expr());
env->RValue(end_of_data),
data.ptr_expr());
env->SetEvaluated(arraylength_var()); env->SetEvaluated(arraylength_var());
} }
} }
void ArrayType::GenPubDecls(Output *out_h, Env *env) void ArrayType::GenPubDecls(Output* out_h, Env* env)
{ {
Type::GenPubDecls(out_h, env); Type::GenPubDecls(out_h, env);
@ -368,23 +338,21 @@ void ArrayType::GenPubDecls(Output *out_h, Env *env)
throw Exception(this, "cannot access element in &transient array"); throw Exception(this, "cannot access element in &transient array");
out_h->println("int size() const { return %s ? %s->size() : 0; }", out_h->println("int size() const { return %s ? %s->size() : 0; }",
env->RValue(value_var()), env->RValue(value_var()), env->RValue(value_var()));
env->RValue(value_var()));
out_h->println("%s operator[](int index) const { BINPAC_ASSERT(%s); return (*%s)[index]; }", out_h->println("%s operator[](int index) const { BINPAC_ASSERT(%s); return (*%s)[index]; }",
elemtype_->DataTypeConstRefStr().c_str(), elemtype_->DataTypeConstRefStr().c_str(), env->RValue(value_var()),
env->RValue(value_var()),
env->RValue(value_var())); env->RValue(value_var()));
} }
} }
void ArrayType::GenPrivDecls(Output *out_h, Env *env) void ArrayType::GenPrivDecls(Output* out_h, Env* env)
{ {
ASSERT(elem_var_field_->type() == elemtype_); ASSERT(elem_var_field_->type() == elemtype_);
ASSERT(elemtype_->value_var()); ASSERT(elemtype_->value_var());
Type::GenPrivDecls(out_h, env); Type::GenPrivDecls(out_h, env);
} }
void ArrayType::GenInitCode(Output *out_cc, Env *env) void ArrayType::GenInitCode(Output* out_cc, Env* env)
{ {
// Do not initiate the array here // Do not initiate the array here
// out_cc->println("%s = new %s;", lvalue(), vector_str_.c_str()); // out_cc->println("%s = new %s;", lvalue(), vector_str_.c_str());
@ -393,24 +361,19 @@ void ArrayType::GenInitCode(Output *out_cc, Env *env)
Type::GenInitCode(out_cc, env); Type::GenInitCode(out_cc, env);
if ( incremental_parsing() ) if ( incremental_parsing() )
{ {
out_cc->println("%s = -1;", out_cc->println("%s = -1;", env->LValue(elem_it_var()));
env->LValue(elem_it_var()));
} }
} }
void ArrayType::GenCleanUpCode(Output *out_cc, Env *env) void ArrayType::GenCleanUpCode(Output* out_cc, Env* env)
{ {
Type::GenCleanUpCode(out_cc, env); Type::GenCleanUpCode(out_cc, env);
if ( elemtype_->NeedsCleanUp() ) if ( elemtype_->NeedsCleanUp() )
{ {
if ( ! elem_var_field_ ) if ( ! elem_var_field_ )
{ {
ID *elem_var = new ID(strfmt("%s__elem", value_var()->Name())); ID* elem_var = new ID(strfmt("%s__elem", value_var()->Name()));
elem_var_field_ = elem_var_field_ = new ParseVarField(Field::NOT_CLASS_MEMBER, elem_var, elemtype_);
new ParseVarField(
Field::NOT_CLASS_MEMBER,
elem_var,
elemtype_);
elem_var_field_->Prepare(env); elem_var_field_->Prepare(env);
} }
@ -418,14 +381,11 @@ void ArrayType::GenCleanUpCode(Output *out_cc, Env *env)
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
out_cc->println("for ( int i = 0; i < (int) %s->size(); ++i )", out_cc->println("for ( int i = 0; i < (int) %s->size(); ++i )", env->RValue(value_var()));
env->RValue(value_var()));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
out_cc->println("%s %s = (*%s)[i];", out_cc->println("%s %s = (*%s)[i];", elemtype_->DataTypeStr().c_str(),
elemtype_->DataTypeStr().c_str(), env->LValue(elem_var()), lvalue());
env->LValue(elem_var()),
lvalue());
elemtype_->GenCleanUpCode(out_cc, env); elemtype_->GenCleanUpCode(out_cc, env);
out_cc->println("}"); out_cc->println("}");
out_cc->dec_indent(); out_cc->dec_indent();
@ -436,28 +396,25 @@ void ArrayType::GenCleanUpCode(Output *out_cc, Env *env)
out_cc->println("delete %s;", lvalue()); out_cc->println("delete %s;", lvalue());
} }
string ArrayType::GenArrayInit(Output *out_cc, Env *env, bool known_array_length) string ArrayType::GenArrayInit(Output* out_cc, Env* env, bool known_array_length)
{ {
string array_str; string array_str;
array_str = lvalue(); array_str = lvalue();
if ( incremental_parsing() ) if ( incremental_parsing() )
{ {
out_cc->println("if ( %s < 0 )", out_cc->println("if ( %s < 0 )", env->LValue(elem_it_var()));
env->LValue(elem_it_var()));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
out_cc->println("// Initialize only once"); out_cc->println("// Initialize only once");
out_cc->println("%s = 0;", env->LValue(elem_it_var())); out_cc->println("%s = 0;", env->LValue(elem_it_var()));
} }
out_cc->println("%s = new %s;", out_cc->println("%s = new %s;", lvalue(), vector_str_.c_str());
lvalue(), vector_str_.c_str());
if ( known_array_length ) if ( known_array_length )
{ {
out_cc->println("%s->reserve(%s);", out_cc->println("%s->reserve(%s);", lvalue(), env->RValue(arraylength_var()));
lvalue(), env->RValue(arraylength_var()));
} }
if ( incremental_parsing() ) if ( incremental_parsing() )
@ -469,8 +426,8 @@ string ArrayType::GenArrayInit(Output *out_cc, Env *env, bool known_array_length
return array_str; return array_str;
} }
void ArrayType::GenElementAssignment(Output *out_cc, Env *env, void ArrayType::GenElementAssignment(Output* out_cc, Env* env, string const& array_str,
string const &array_str, bool use_vector) bool use_vector)
{ {
if ( attr_transient_ ) if ( attr_transient_ )
{ {
@ -482,21 +439,16 @@ void ArrayType::GenElementAssignment(Output *out_cc, Env *env,
// Assign the element // Assign the element
if ( ! use_vector ) if ( ! use_vector )
{ {
out_cc->println("%s[%s] = %s;", out_cc->println("%s[%s] = %s;", array_str.c_str(), env->LValue(elem_it_var()),
array_str.c_str(),
env->LValue(elem_it_var()),
env->LValue(elem_var())); env->LValue(elem_var()));
} }
else else
{ {
out_cc->println("%s->push_back(%s);", out_cc->println("%s->push_back(%s);", array_str.c_str(), env->LValue(elem_var()));
array_str.c_str(),
env->LValue(elem_var()));
} }
} }
void ArrayType::DoGenParseCode(Output *out_cc, Env *env, void ArrayType::DoGenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags)
const DataPtr& data, int flags)
{ {
GenArrayLength(out_cc, env, data); GenArrayLength(out_cc, env, data);
@ -529,9 +481,8 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
compute_size_var = false; compute_size_var = false;
if ( ! incremental_parsing() && if ( ! incremental_parsing() &&
( StaticSize(env) >= 0 || (StaticSize(env) >= 0 ||
( env->Evaluated(arraylength_var()) && (env->Evaluated(arraylength_var()) && elemtype_->StaticSize(env) >= 0)) )
elemtype_->StaticSize(env) >= 0 ) ) )
{ {
GenBoundaryCheck(out_cc, env, data); GenBoundaryCheck(out_cc, env, data);
} }
@ -552,22 +503,17 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
if ( elem_dataptr_var() ) if ( elem_dataptr_var() )
{ {
out_cc->println("const_byteptr %s = %s;", out_cc->println("const_byteptr %s = %s;", env->LValue(elem_dataptr_var()), data.ptr_expr());
env->LValue(elem_dataptr_var()), data.ptr_expr());
env->SetEvaluated(elem_dataptr_var()); env->SetEvaluated(elem_dataptr_var());
elem_data = DataPtr(env, elem_dataptr_var(), 0); elem_data = DataPtr(env, elem_dataptr_var(), 0);
} }
string for_condition = known_array_length ? string for_condition = known_array_length ? strfmt("%s < %s", env->LValue(elem_it_var()),
strfmt("%s < %s", env->RValue(arraylength_var()))
env->LValue(elem_it_var()), : "/* forever */";
env->RValue(arraylength_var())) :
"/* forever */";
out_cc->println("for (; %s; ++%s)", out_cc->println("for (; %s; ++%s)", for_condition.c_str(), env->LValue(elem_it_var()));
for_condition.c_str(),
env->LValue(elem_it_var()));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
@ -597,8 +543,7 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
if ( incremental_parsing() ) if ( incremental_parsing() )
{ {
out_cc->println("if ( ! %s )", out_cc->println("if ( ! %s )", elemtype_->parsing_complete(env).c_str());
elemtype_->parsing_complete(env).c_str());
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("goto %s;", kNeedMoreData); out_cc->println("goto %s;", kNeedMoreData);
out_cc->dec_indent(); out_cc->dec_indent();
@ -608,11 +553,9 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
if ( elem_dataptr_var() ) if ( elem_dataptr_var() )
{ {
out_cc->println("%s += %s;", out_cc->println("%s += %s;", env->LValue(elem_dataptr_var()),
env->LValue(elem_dataptr_var()),
elemtype_->DataSize(0, env, elem_data).c_str()); elemtype_->DataSize(0, env, elem_data).c_str());
out_cc->println("BINPAC_ASSERT(%s <= %s);", out_cc->println("BINPAC_ASSERT(%s <= %s);", env->RValue(elem_dataptr_var()),
env->RValue(elem_dataptr_var()),
env->RValue(end_of_data)); env->RValue(end_of_data));
} }
@ -632,55 +575,45 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
if ( compute_size_var && elem_dataptr_var() && ! env->Evaluated(size_var()) ) if ( compute_size_var && elem_dataptr_var() && ! env->Evaluated(size_var()) )
{ {
// Compute the data size // Compute the data size
out_cc->println("%s = %s - (%s);", out_cc->println("%s = %s - (%s);", env->LValue(size_var()), env->RValue(elem_dataptr_var()),
env->LValue(size_var()),
env->RValue(elem_dataptr_var()),
data.ptr_expr()); data.ptr_expr());
env->SetEvaluated(size_var()); env->SetEvaluated(size_var());
} }
} }
void ArrayType::GenUntilInputCheck(Output *out_cc, Env *env) void ArrayType::GenUntilInputCheck(Output* out_cc, Env* env)
{ {
ID *elem_input_var_id = new ID( ID* elem_input_var_id = new ID(strfmt("%s__elem_input", value_var()->Name()));
strfmt("%s__elem_input", value_var()->Name())); elem_input_var_field_ = new TempVarField(elem_input_var_id,
elem_input_var_field_ = new TempVarField( extern_type_const_bytestring->Clone());
elem_input_var_id, extern_type_const_bytestring->Clone());
elem_input_var_field_->Prepare(env); elem_input_var_field_->Prepare(env);
out_cc->println("%s %s(%s, %s);", out_cc->println("%s %s(%s, %s);", extern_type_const_bytestring->DataTypeStr().c_str(),
extern_type_const_bytestring->DataTypeStr().c_str(), env->LValue(elem_input_var()), env->RValue(begin_of_data),
env->LValue(elem_input_var()),
env->RValue(begin_of_data),
env->RValue(end_of_data)); env->RValue(end_of_data));
env->SetEvaluated(elem_input_var()); env->SetEvaluated(elem_input_var());
GenUntilCheck(out_cc, env, attr_until_input_expr_, true); GenUntilCheck(out_cc, env, attr_until_input_expr_, true);
} }
void ArrayType::GenUntilCheck(Output *out_cc, Env *env, void ArrayType::GenUntilCheck(Output* out_cc, Env* env, Expr* until_expr, bool delete_elem)
Expr *until_expr, bool delete_elem)
{ {
ASSERT(until_expr); ASSERT(until_expr);
Env check_env(env, this); Env check_env(env, this);
check_env.AddMacro(element_macro_id, check_env.AddMacro(element_macro_id, new Expr(elem_var()->clone()));
new Expr(elem_var()->clone()));
if ( elem_input_var() ) if ( elem_input_var() )
{ {
check_env.AddMacro(input_macro_id, check_env.AddMacro(input_macro_id, new Expr(elem_input_var()->clone()));
new Expr(elem_input_var()->clone()));
} }
out_cc->println("// Check &until(%s)", until_expr->orig()); out_cc->println("// Check &until(%s)", until_expr->orig());
out_cc->println("if ( %s )", out_cc->println("if ( %s )", until_expr->EvalExpr(out_cc, &check_env));
until_expr->EvalExpr(out_cc, &check_env));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
if ( parsing_complete_var() ) if ( parsing_complete_var() )
{ {
out_cc->println("%s = true;", out_cc->println("%s = true;", env->LValue(parsing_complete_var()));
env->LValue(parsing_complete_var()));
} }
if ( elemtype_->IsPointerType() ) if ( elemtype_->IsPointerType() )
@ -696,18 +629,14 @@ void ArrayType::GenUntilCheck(Output *out_cc, Env *env,
out_cc->dec_indent(); out_cc->dec_indent();
} }
void ArrayType::GenDynamicSize(Output *out_cc, Env *env, void ArrayType::GenDynamicSize(Output* out_cc, Env* env, const DataPtr& data)
const DataPtr& data)
{ {
ASSERT(! incremental_input()); ASSERT(! incremental_input());
DEBUG_MSG("Generating dynamic size for array `%s'\n", DEBUG_MSG("Generating dynamic size for array `%s'\n", value_var()->Name());
value_var()->Name());
int elem_w = elemtype_->StaticSize(env); int elem_w = elemtype_->StaticSize(env);
if ( elem_w >= 0 && if ( elem_w >= 0 && ! attr_until_element_expr_ && ! attr_until_input_expr_ &&
! attr_until_element_expr_ && (length_ || attr_restofdata_) )
! attr_until_input_expr_ &&
( length_ || attr_restofdata_ ) )
{ {
// If the elements have a fixed size, // If the elements have a fixed size,
// we only need to compute the number of elements // we only need to compute the number of elements
@ -715,8 +644,8 @@ void ArrayType::GenDynamicSize(Output *out_cc, Env *env,
ASSERT(compute_size_var); ASSERT(compute_size_var);
GenArrayLength(out_cc, env, data); GenArrayLength(out_cc, env, data);
ASSERT(env->Evaluated(arraylength_var())); ASSERT(env->Evaluated(arraylength_var()));
out_cc->println("%s = %d * %s;", out_cc->println("%s = %d * %s;", env->LValue(size_var()), elem_w,
env->LValue(size_var()), elem_w, env->RValue(arraylength_var())); env->RValue(arraylength_var()));
env->SetEvaluated(size_var()); env->SetEvaluated(size_var());
} }
else else
@ -726,7 +655,7 @@ void ArrayType::GenDynamicSize(Output *out_cc, Env *env,
} }
} }
int ArrayType::StaticSize(Env *env) const int ArrayType::StaticSize(Env* env) const
{ {
int num = 0; int num = 0;
@ -737,8 +666,7 @@ int ArrayType::StaticSize(Env *env) const
if ( elem_w < 0 ) if ( elem_w < 0 )
return -1; return -1;
DEBUG_MSG("static size of %s:%s = %d * %d\n", DEBUG_MSG("static size of %s:%s = %d * %d\n", decl_id()->Name(), lvalue(), elem_w, num);
decl_id()->Name(), lvalue(), elem_w, num);
return num * elem_w; return num * elem_w;
} }
@ -767,12 +695,11 @@ void ArrayType::DoMarkIncrementalInput()
bool ArrayType::RequiresAnalyzerContext() bool ArrayType::RequiresAnalyzerContext()
{ {
return Type::RequiresAnalyzerContext() || return Type::RequiresAnalyzerContext() || (length_ && length_->RequiresAnalyzerContext()) ||
( length_ && length_->RequiresAnalyzerContext() ) ||
elemtype_->RequiresAnalyzerContext(); elemtype_->RequiresAnalyzerContext();
} }
bool ArrayType::DoTraverse(DataDepVisitor *visitor) bool ArrayType::DoTraverse(DataDepVisitor* visitor)
{ {
if ( ! Type::DoTraverse(visitor) ) if ( ! Type::DoTraverse(visitor) )
return false; return false;

View file

@ -7,86 +7,81 @@
// Fixed-length array and variable length sequence with an ending pattern // Fixed-length array and variable length sequence with an ending pattern
class ArrayType : public Type class ArrayType : public Type
{ {
public: public:
ArrayType(Type *arg_elemtype, Expr *arg_length = 0); ArrayType(Type* arg_elemtype, Expr* arg_length = 0);
~ArrayType(); ~ArrayType();
bool DefineValueVar() const; bool DefineValueVar() const;
string DataTypeStr() const; string DataTypeStr() const;
string DefaultValue() const { return "0"; } string DefaultValue() const { return "0"; }
Type *ElementDataType() const; Type* ElementDataType() const;
string EvalElement(const string &array, const string &index) const; string EvalElement(const string& array, const string& index) const;
void ProcessAttr(Attr *a); void ProcessAttr(Attr* a);
void Prepare(Env *env, int flags); void Prepare(Env* env, int flags);
void GenPubDecls(Output *out, Env *env); void GenPubDecls(Output* out, Env* env);
void GenPrivDecls(Output *out, Env *env); void GenPrivDecls(Output* out, Env* env);
void GenInitCode(Output *out, Env *env); void GenInitCode(Output* out, Env* env);
void GenCleanUpCode(Output *out, Env *env); void GenCleanUpCode(Output* out, Env* env);
int StaticSize(Env *env) const; int StaticSize(Env* env) const;
void SetBoundaryChecked(); void SetBoundaryChecked();
void GenUntilInputCheck(Output *out_cc, Env *env); void GenUntilInputCheck(Output* out_cc, Env* env);
bool IsPointerType() const { return true; } bool IsPointerType() const { return true; }
protected: protected:
void init(); void init();
void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags); void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags);
void GenDynamicSize(Output *out, Env *env, const DataPtr& data); void GenDynamicSize(Output* out, Env* env, const DataPtr& data);
void GenArrayLength(Output *out_cc, Env *env, const DataPtr& data); void GenArrayLength(Output* out_cc, Env* env, const DataPtr& data);
string GenArrayInit(Output *out_cc, Env *env, bool known_array_length); string GenArrayInit(Output* out_cc, Env* env, bool known_array_length);
void GenElementAssignment(Output *out_cc, Env *env, void GenElementAssignment(Output* out_cc, Env* env, string const& array_str, bool use_vector);
string const &array_str, bool use_vector); void GenUntilCheck(Output* out_cc, Env* env, Expr* until_condition, bool delete_elem);
void GenUntilCheck(Output *out_cc, Env *env,
Expr *until_condition, bool delete_elem);
bool ByteOrderSensitive() const bool ByteOrderSensitive() const { return elemtype_->RequiresByteOrder(); }
{
return elemtype_->RequiresByteOrder();
}
bool RequiresAnalyzerContext(); bool RequiresAnalyzerContext();
Type *DoClone() const; Type* DoClone() const;
void DoMarkIncrementalInput(); void DoMarkIncrementalInput();
const ID *arraylength_var() const; const ID* arraylength_var() const;
const ID *elem_it_var() const; const ID* elem_it_var() const;
const ID *elem_var() const; const ID* elem_var() const;
const ID *elem_dataptr_var() const; const ID* elem_dataptr_var() const;
const ID *elem_input_var() const; const ID* elem_input_var() const;
protected: protected:
bool DoTraverse(DataDepVisitor *visitor); bool DoTraverse(DataDepVisitor* visitor);
private: private:
Type *elemtype_; Type* elemtype_;
Expr *length_; Expr* length_;
string vector_str_; string vector_str_;
string datatype_str_; string datatype_str_;
string end_of_array_loop_label_; string end_of_array_loop_label_;
Field *arraylength_var_field_; Field* arraylength_var_field_;
Field *elem_it_var_field_; Field* elem_it_var_field_;
Field *elem_var_field_; Field* elem_var_field_;
Field *elem_dataptr_var_field_; Field* elem_dataptr_var_field_;
Field *elem_input_var_field_; Field* elem_input_var_field_;
// This does not come from &until, but is internally generated // This does not come from &until, but is internally generated
Expr *elem_dataptr_until_expr_; Expr* elem_dataptr_until_expr_;
Expr *attr_generic_until_expr_; Expr* attr_generic_until_expr_;
Expr *attr_until_element_expr_; Expr* attr_until_element_expr_;
Expr *attr_until_input_expr_; Expr* attr_until_input_expr_;
}; };
#endif // pac_array_h #endif // pac_array_h

View file

@ -1,7 +1,8 @@
#include "pac_attr.h" #include "pac_attr.h"
#include "pac_expr.h" #include "pac_expr.h"
bool Attr::DoTraverse(DataDepVisitor *visitor) bool Attr::DoTraverse(DataDepVisitor* visitor)
{ {
if ( expr_ && ! expr_->Traverse(visitor) ) if ( expr_ && ! expr_->Traverse(visitor) )
return false; return false;
@ -20,23 +21,20 @@ void Attr::init()
delete_expr_ = false; delete_expr_ = false;
} }
Attr::Attr(AttrType type) Attr::Attr(AttrType type) : DataDepElement(DataDepElement::ATTR)
: DataDepElement(DataDepElement::ATTR)
{ {
type_ = type; type_ = type;
init(); init();
} }
Attr::Attr(AttrType type, Expr *expr) Attr::Attr(AttrType type, Expr* expr) : DataDepElement(DataDepElement::ATTR)
: DataDepElement(DataDepElement::ATTR)
{ {
type_ = type; type_ = type;
init(); init();
expr_ = expr; expr_ = expr;
} }
Attr::Attr(AttrType type, ExprList *exprlist) Attr::Attr(AttrType type, ExprList* exprlist) : DataDepElement(DataDepElement::ATTR)
: DataDepElement(DataDepElement::ATTR)
{ {
type_ = type; type_ = type;
init(); init();
@ -44,8 +42,7 @@ Attr::Attr(AttrType type, ExprList *exprlist)
delete_expr_ = true; delete_expr_ = true;
} }
Attr::Attr(AttrType type, SeqEnd *seqend) Attr::Attr(AttrType type, SeqEnd* seqend) : DataDepElement(DataDepElement::ATTR)
: DataDepElement(DataDepElement::ATTR)
{ {
type_ = type; type_ = type;
init(); init();
@ -58,8 +55,7 @@ Attr::~Attr()
delete expr_; delete expr_;
} }
LetAttr::LetAttr(FieldList *letfields) LetAttr::LetAttr(FieldList* letfields) : Attr(ATTR_LET)
: Attr(ATTR_LET)
{ {
letfields_ = letfields; letfields_ = letfields;
} }

View file

@ -4,7 +4,8 @@
#include "pac_common.h" #include "pac_common.h"
#include "pac_datadep.h" #include "pac_datadep.h"
enum AttrType { enum AttrType
{
ATTR_BYTEORDER, ATTR_BYTEORDER,
ATTR_CHECK, ATTR_CHECK,
ATTR_CHUNKED, ATTR_CHUNKED,
@ -22,44 +23,44 @@ enum AttrType {
ATTR_RESTOFFLOW, ATTR_RESTOFFLOW,
ATTR_TRANSIENT, ATTR_TRANSIENT,
ATTR_UNTIL, ATTR_UNTIL,
}; };
class Attr : public Object, public DataDepElement class Attr : public Object, public DataDepElement
{ {
public: public:
Attr(AttrType type); Attr(AttrType type);
Attr(AttrType type, Expr *expr); Attr(AttrType type, Expr* expr);
Attr(AttrType type, ExprList *exprlist); Attr(AttrType type, ExprList* exprlist);
Attr(AttrType type, SeqEnd *seqend); Attr(AttrType type, SeqEnd* seqend);
virtual ~Attr(); virtual ~Attr();
AttrType type() const { return type_; } AttrType type() const { return type_; }
Expr *expr() const { return expr_; } Expr* expr() const { return expr_; }
SeqEnd *seqend() const { return seqend_; } SeqEnd* seqend() const { return seqend_; }
bool RequiresAnalyzerContext() const; bool RequiresAnalyzerContext() const;
protected: protected:
bool DoTraverse(DataDepVisitor *visitor); bool DoTraverse(DataDepVisitor* visitor);
protected: protected:
void init(); void init();
AttrType type_; AttrType type_;
Expr *expr_; Expr* expr_;
SeqEnd *seqend_; SeqEnd* seqend_;
bool delete_expr_; bool delete_expr_;
}; };
class LetAttr : public Attr class LetAttr : public Attr
{ {
public: public:
LetAttr(FieldList *letfields); LetAttr(FieldList* letfields);
FieldList *letfields() const { return letfields_; } FieldList* letfields() const { return letfields_; }
private: private:
FieldList *letfields_; FieldList* letfields_;
}; };
#endif // pac_attr_h #endif // pac_attr_h

View file

@ -1,9 +1,10 @@
#include "pac_btype.h" #include "pac_btype.h"
#include "pac_dataptr.h" #include "pac_dataptr.h"
#include "pac_id.h" #include "pac_id.h"
#include "pac_output.h" #include "pac_output.h"
Type *BuiltInType::DoClone() const Type* BuiltInType::DoClone() const
{ {
return new BuiltInType(bit_type()); return new BuiltInType(bit_type());
} }
@ -11,20 +12,19 @@ Type *BuiltInType::DoClone() const
bool BuiltInType::IsNumericType() const bool BuiltInType::IsNumericType() const
{ {
BITType t = bit_type(); BITType t = bit_type();
return (t == INT8 || t == INT16 || t == INT32 || t == INT64 || return (t == INT8 || t == INT16 || t == INT32 || t == INT64 || t == UINT8 || t == UINT16 ||
t == UINT8 || t == UINT16 || t == UINT32 || t == UINT64); t == UINT32 || t == UINT64);
} }
bool BuiltInType::CompatibleBuiltInTypes(BuiltInType *type1, bool BuiltInType::CompatibleBuiltInTypes(BuiltInType* type1, BuiltInType* type2)
BuiltInType *type2)
{ {
return type1->IsNumericType() && type2->IsNumericType(); return type1->IsNumericType() && type2->IsNumericType();
} }
static const char* basic_pactype_name[] = { static const char* basic_pactype_name[] = {
# define TYPE_DEF(name, pactype, ctype, size) pactype, #define TYPE_DEF(name, pactype, ctype, size) pactype,
# include "pac_type.def" #include "pac_type.def"
# undef TYPE_DEF #undef TYPE_DEF
0, 0,
}; };
@ -32,9 +32,7 @@ void BuiltInType::static_init()
{ {
for ( int bit_type = 0; basic_pactype_name[bit_type]; ++bit_type ) for ( int bit_type = 0; basic_pactype_name[bit_type]; ++bit_type )
{ {
Type::AddPredefinedType( Type::AddPredefinedType(basic_pactype_name[bit_type], new BuiltInType((BITType)bit_type));
basic_pactype_name[bit_type],
new BuiltInType((BITType) bit_type));
} }
} }
@ -48,9 +46,9 @@ int BuiltInType::LookUpByName(const char* name)
} }
static const char* basic_ctype_name[] = { static const char* basic_ctype_name[] = {
# define TYPE_DEF(name, pactype, ctype, size) ctype, #define TYPE_DEF(name, pactype, ctype, size) ctype,
# include "pac_type.def" #include "pac_type.def"
# undef TYPE_DEF #undef TYPE_DEF
0, 0,
}; };
@ -66,11 +64,10 @@ string BuiltInType::DataTypeStr() const
int BuiltInType::StaticSize(Env* /* env */) const int BuiltInType::StaticSize(Env* /* env */) const
{ {
static const size_t basic_type_size[] = static const size_t basic_type_size[] = {
{ #define TYPE_DEF(name, pactype, ctype, size) size,
# define TYPE_DEF(name, pactype, ctype, size) size, #include "pac_type.def"
# include "pac_type.def" #undef TYPE_DEF
# undef TYPE_DEF
}; };
return basic_type_size[bit_type_]; return basic_type_size[bit_type_];
@ -96,8 +93,7 @@ void BuiltInType::GenDynamicSize(Output* out_cc, Env* env, const DataPtr& data)
ASSERT(0); ASSERT(0);
} }
void BuiltInType::DoGenParseCode(Output* out_cc, Env* env, void BuiltInType::DoGenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags)
const DataPtr& data, int flags)
{ {
if ( bit_type_ == EMPTY ) if ( bit_type_ == EMPTY )
return; return;
@ -118,8 +114,8 @@ void BuiltInType::DoGenParseCode(Output* out_cc, Env* env,
case INT8: case INT8:
case UINT8: case UINT8:
out_cc->println("%s = *((%s const *) (%s));", out_cc->println("%s = *((%s const *) (%s));", lvalue(), DataTypeStr().c_str(),
lvalue(), DataTypeStr().c_str(), data.ptr_expr()); data.ptr_expr());
break; break;
case INT16: case INT16:
case UINT16: case UINT16:
@ -134,13 +130,10 @@ void BuiltInType::DoGenParseCode(Output* out_cc, Env* env,
data.ptr_expr(), data.ptr_expr(),
EvalByteOrder(out_cc, env).c_str()); EvalByteOrder(out_cc, env).c_str());
#else #else
out_cc->println("%s = FixByteOrder(%s, *((%s const *) (%s)));", out_cc->println("%s = FixByteOrder(%s, *((%s const *) (%s)));", lvalue(),
lvalue(), EvalByteOrder(out_cc, env).c_str(), DataTypeStr().c_str(),
EvalByteOrder(out_cc, env).c_str(),
DataTypeStr().c_str(),
data.ptr_expr()); data.ptr_expr());
#endif #endif
break; break;
} }
} }

View file

@ -4,19 +4,21 @@
#include "pac_type.h" #include "pac_type.h"
class BuiltInType : public Type class BuiltInType : public Type
{ {
public: public:
enum BITType { enum BITType
# define TYPE_DEF(name, pactype, ctype, size) name, {
# include "pac_type.def" #define TYPE_DEF(name, pactype, ctype, size) name,
# undef TYPE_DEF #include "pac_type.def"
#undef TYPE_DEF
}; };
static int LookUpByName(const char *name); static int LookUpByName(const char* name);
BuiltInType(BITType bit_type) BuiltInType(BITType bit_type)
: Type(bit_type == BuiltInType::EMPTY ? Type::EMPTY : BUILTIN), : Type(bit_type == BuiltInType::EMPTY ? Type::EMPTY : BUILTIN), bit_type_(bit_type)
bit_type_(bit_type) {} {
}
BITType bit_type() const { return bit_type_; } BITType bit_type() const { return bit_type_; }
@ -26,27 +28,26 @@ public:
string DataTypeStr() const; string DataTypeStr() const;
string DefaultValue() const { return "0"; } string DefaultValue() const { return "0"; }
int StaticSize(Env *env) const; int StaticSize(Env* env) const;
bool IsPointerType() const { return false; } bool IsPointerType() const { return false; }
bool ByteOrderSensitive() const { return StaticSize(0) >= 2; } bool ByteOrderSensitive() const { return StaticSize(0) >= 2; }
void GenInitCode(Output *out_cc, Env *env); void GenInitCode(Output* out_cc, Env* env);
void DoMarkIncrementalInput(); void DoMarkIncrementalInput();
protected: protected:
void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags); void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags);
void GenDynamicSize(Output *out, Env *env, const DataPtr& data); void GenDynamicSize(Output* out, Env* env, const DataPtr& data);
Type *DoClone() const; Type* DoClone() const;
BITType bit_type_; BITType bit_type_;
public: public:
static void static_init(); static void static_init();
static bool CompatibleBuiltInTypes(BuiltInType *type1, static bool CompatibleBuiltInTypes(BuiltInType* type1, BuiltInType* type2);
BuiltInType *type2); };
};
#endif // pac_btype_h #endif // pac_btype_h

View file

@ -1,3 +1,9 @@
#include "pac_case.h"
#include <stdint.h>
#include <limits>
#include "pac_btype.h"
#include "pac_exception.h" #include "pac_exception.h"
#include "pac_expr.h" #include "pac_expr.h"
#include "pac_exttype.h" #include "pac_exttype.h"
@ -5,18 +11,12 @@
#include "pac_output.h" #include "pac_output.h"
#include "pac_typedecl.h" #include "pac_typedecl.h"
#include "pac_utils.h" #include "pac_utils.h"
#include "pac_btype.h"
#include "pac_case.h"
#include <limits>
#include <stdint.h>
CaseType::CaseType(Expr* index_expr, CaseFieldList* cases) CaseType::CaseType(Expr* index_expr, CaseFieldList* cases)
: Type(CASE), index_expr_(index_expr), cases_(cases) : Type(CASE), index_expr_(index_expr), cases_(cases)
{ {
index_var_ = 0; index_var_ = 0;
foreach(i, CaseFieldList, cases_) foreach (i, CaseFieldList, cases_)
AddField(*i); AddField(*i);
} }
@ -27,10 +27,10 @@ CaseType::~CaseType()
delete cases_; delete cases_;
} }
void CaseType::AddCaseField(CaseField *f) void CaseType::AddCaseField(CaseField* f)
{ {
// All fields must be added before Prepare() // All fields must be added before Prepare()
ASSERT(!env()); ASSERT(! env());
AddField(f); AddField(f);
cases_->push_back(f); cases_->push_back(f);
@ -47,11 +47,11 @@ string CaseType::DataTypeStr() const
return strfmt("%s *", type_decl()->class_name().c_str()); return strfmt("%s *", type_decl()->class_name().c_str());
} }
Type *CaseType::ValueType() const Type* CaseType::ValueType() const
{ {
foreach (i, CaseFieldList, cases_) foreach (i, CaseFieldList, cases_)
{ {
CaseField *c = *i; CaseField* c = *i;
return c->type(); return c->type();
} }
ASSERT(0); ASSERT(0);
@ -73,13 +73,12 @@ void CaseType::Prepare(Env* env, int flags)
env->AddID(index_var_, MEMBER_VAR, 0); env->AddID(index_var_, MEMBER_VAR, 0);
// Sort the cases_ to put the default case at the end of the list // Sort the cases_ to put the default case at the end of the list
CaseFieldList::iterator default_case_it = CaseFieldList::iterator default_case_it = cases_->end(); // to avoid warning
cases_->end(); // to avoid warning CaseField* default_case = 0;
CaseField *default_case = 0;
foreach (i, CaseFieldList, cases_) foreach (i, CaseFieldList, cases_)
{ {
CaseField *c = *i; CaseField* c = *i;
if ( ! c->index() ) if ( ! c->index() )
{ {
if ( default_case ) if ( default_case )
@ -96,7 +95,7 @@ void CaseType::Prepare(Env* env, int flags)
foreach (i, CaseFieldList, cases_) foreach (i, CaseFieldList, cases_)
{ {
CaseField *c = *i; CaseField* c = *i;
c->set_index_var(index_var_); c->set_index_var(index_var_);
c->set_case_type(this); c->set_case_type(this);
} }
@ -124,8 +123,8 @@ void CaseType::GenPubDecls(Output* out_h, Env* env)
if ( t->tot() != Type::BUILTIN ) if ( t->tot() != Type::BUILTIN )
t = extern_type_int; t = extern_type_int;
out_h->println("%s %s const { return %s; }", t->DataTypeStr().c_str(), out_h->println("%s %s const { return %s; }", t->DataTypeStr().c_str(), env->RValue(index_var_),
env->RValue(index_var_), env->LValue(index_var_)); env->LValue(index_var_));
Type::GenPubDecls(out_h, env); Type::GenPubDecls(out_h, env);
} }
@ -145,7 +144,7 @@ void CaseType::GenCleanUpCode(Output* out_cc, Env* env)
out_cc->println("{"); out_cc->println("{");
foreach (i, CaseFieldList, cases_) foreach (i, CaseFieldList, cases_)
{ {
CaseField *c = *i; CaseField* c = *i;
c->GenCleanUpCode(out_cc, env); c->GenCleanUpCode(out_cc, env);
} }
out_cc->println("}"); out_cc->println("}");
@ -153,8 +152,7 @@ void CaseType::GenCleanUpCode(Output* out_cc, Env* env)
env->set_in_branch(false); env->set_in_branch(false);
} }
void CaseType::DoGenParseCode(Output* out_cc, Env* env, void CaseType::DoGenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags)
const DataPtr& data, int flags)
{ {
if ( StaticSize(env) >= 0 ) if ( StaticSize(env) >= 0 )
GenBoundaryCheck(out_cc, env, data); GenBoundaryCheck(out_cc, env, data);
@ -164,8 +162,7 @@ void CaseType::DoGenParseCode(Output* out_cc, Env* env,
if ( ! incremental_input() ) if ( ! incremental_input() )
compute_size_var = AddSizeVar(out_cc, env); compute_size_var = AddSizeVar(out_cc, env);
out_cc->println("%s = %s;", out_cc->println("%s = %s;", env->LValue(index_var_), index_expr_->EvalExpr(out_cc, env));
env->LValue(index_var_), index_expr_->EvalExpr(out_cc, env));
env->SetEvaluated(index_var_); env->SetEvaluated(index_var_);
env->set_in_branch(true); env->set_in_branch(true);
@ -175,9 +172,8 @@ void CaseType::DoGenParseCode(Output* out_cc, Env* env,
bool has_default_case = false; bool has_default_case = false;
foreach (i, CaseFieldList, cases_) foreach (i, CaseFieldList, cases_)
{ {
CaseField *c = *i; CaseField* c = *i;
c->GenParseCode(out_cc, env, data, c->GenParseCode(out_cc, env, data, compute_size_var ? size_var() : 0);
compute_size_var ? size_var() : 0);
if ( c->IsDefaultCase() ) if ( c->IsDefaultCase() )
has_default_case = true; has_default_case = true;
} }
@ -199,8 +195,7 @@ void CaseType::DoGenParseCode(Output* out_cc, Env* env,
env->SetEvaluated(size_var()); env->SetEvaluated(size_var());
} }
void CaseType::GenDynamicSize(Output* out_cc, Env* env, void CaseType::GenDynamicSize(Output* out_cc, Env* env, const DataPtr& data)
const DataPtr& data)
{ {
GenParseCode(out_cc, env, data, 0); GenParseCode(out_cc, env, data, 0);
} }
@ -210,9 +205,9 @@ int CaseType::StaticSize(Env* env) const
int static_w = -1; int static_w = -1;
foreach (i, CaseFieldList, cases_) foreach (i, CaseFieldList, cases_)
{ {
CaseField *c = *i; CaseField* c = *i;
int w = c->StaticSize(env); int w = c->StaticSize(env);
if ( w < 0 || ( static_w >= 0 && w != static_w ) ) if ( w < 0 || (static_w >= 0 && w != static_w) )
return -1; return -1;
static_w = w; static_w = w;
} }
@ -224,7 +219,7 @@ void CaseType::SetBoundaryChecked()
Type::SetBoundaryChecked(); Type::SetBoundaryChecked();
foreach (i, CaseFieldList, cases_) foreach (i, CaseFieldList, cases_)
{ {
CaseField *c = *i; CaseField* c = *i;
c->SetBoundaryChecked(); c->SetBoundaryChecked();
} }
} }
@ -233,7 +228,7 @@ void CaseType::DoMarkIncrementalInput()
{ {
foreach (i, CaseFieldList, cases_) foreach (i, CaseFieldList, cases_)
{ {
CaseField *c = *i; CaseField* c = *i;
c->type()->MarkIncrementalInput(); c->type()->MarkIncrementalInput();
} }
} }
@ -242,7 +237,7 @@ bool CaseType::ByteOrderSensitive() const
{ {
foreach (i, CaseFieldList, cases_) foreach (i, CaseFieldList, cases_)
{ {
CaseField *c = *i; CaseField* c = *i;
if ( c->RequiresByteOrder() ) if ( c->RequiresByteOrder() )
return true; return true;
} }
@ -250,10 +245,7 @@ bool CaseType::ByteOrderSensitive() const
} }
CaseField::CaseField(ExprList* index, ID* id, Type* type) CaseField::CaseField(ExprList* index, ID* id, Type* type)
: Field(CASE_FIELD, : Field(CASE_FIELD, TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type), index_(index)
TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
id, type),
index_(index)
{ {
ASSERT(type_); ASSERT(type_);
type_->set_value_var(id, MEMBER_VAR); type_->set_value_var(id, MEMBER_VAR);
@ -266,13 +258,13 @@ CaseField::~CaseField()
delete_list(ExprList, index_); delete_list(ExprList, index_);
} }
void GenCaseStr(ExprList *index_list, Output *out_cc, Env *env, Type* switch_type) void GenCaseStr(ExprList* index_list, Output* out_cc, Env* env, Type* switch_type)
{ {
if ( index_list ) if ( index_list )
{ {
foreach(i, ExprList, index_list) foreach (i, ExprList, index_list)
{ {
Expr *index_expr = *i; Expr* index_expr = *i;
Type* case_type = index_expr->DataType(env); Type* case_type = index_expr->DataType(env);
@ -338,8 +330,7 @@ void GenCaseStr(ExprList *index_list, Output *out_cc, Env *env, Type* switch_typ
// We're always using "int" for storage, so ok to just // We're always using "int" for storage, so ok to just
// cast into the type used by the switch statement since // cast into the type used by the switch statement since
// some unsafe stuff is already checked above. // some unsafe stuff is already checked above.
out_cc->println("case ((%s) %d):", out_cc->println("case ((%s) %d):", switch_type->DataTypeStr().c_str(), index_const);
switch_type->DataTypeStr().c_str(), index_const);
} }
} }
else else
@ -363,8 +354,7 @@ void CaseField::GenPubDecls(Output* out_h, Env* env)
if ( type_->DataTypeStr().empty() ) if ( type_->DataTypeStr().empty() )
return; return;
out_h->println("%s %s const", out_h->println("%s %s const", type_->DataTypeConstRefStr().c_str(), env->RValue(id_));
type_->DataTypeConstRefStr().c_str(), env->RValue(id_));
out_h->inc_indent(); out_h->inc_indent();
out_h->println("{"); out_h->println("{");
@ -383,11 +373,8 @@ void CaseField::GenPubDecls(Output* out_h, Env* env)
out_h->println("default:"); out_h->println("default:");
out_h->inc_indent(); out_h->inc_indent();
out_h->println( out_h->println("throw binpac::ExceptionInvalidCase(\"%s\", (int64)%s, \"%s\");",
"throw binpac::ExceptionInvalidCase(\"%s\", (int64)%s, \"%s\");", id_->LocName(), env->RValue(index_var_), OrigExprList(index_).c_str());
id_->LocName(),
env->RValue(index_var_),
OrigExprList(index_).c_str());
out_h->println("break;"); out_h->println("break;");
out_h->dec_indent(); out_h->dec_indent();
@ -426,8 +413,7 @@ void CaseField::GenCleanUpCode(Output* out_cc, Env* env)
out_cc->dec_indent(); out_cc->dec_indent();
} }
void CaseField::GenParseCode(Output* out_cc, Env* env, void CaseField::GenParseCode(Output* out_cc, Env* env, const DataPtr& data, const ID* size_var)
const DataPtr& data, const ID* size_var)
{ {
GenCaseStr(index_, out_cc, env, case_type()->IndexExpr()->DataType(env)); GenCaseStr(index_, out_cc, env, case_type()->IndexExpr()->DataType(env));
out_cc->inc_indent(); out_cc->inc_indent();
@ -441,15 +427,13 @@ void CaseField::GenParseCode(Output* out_cc, Env* env,
type_->GenParseCode(out_cc, &case_env, data, 0); type_->GenParseCode(out_cc, &case_env, data, 0);
if ( size_var ) if ( size_var )
{ {
out_cc->println("%s = %s;", out_cc->println("%s = %s;", case_env.LValue(size_var),
case_env.LValue(size_var),
type_->DataSize(out_cc, &case_env, data).c_str()); type_->DataSize(out_cc, &case_env, data).c_str());
} }
if ( type_->incremental_input() ) if ( type_->incremental_input() )
{ {
ASSERT(case_type()->parsing_complete_var()); ASSERT(case_type()->parsing_complete_var());
out_cc->println("%s = %s;", out_cc->println("%s = %s;", case_env.LValue(case_type()->parsing_complete_var()),
case_env.LValue(case_type()->parsing_complete_var()),
case_env.RValue(type_->parsing_complete_var())); case_env.RValue(type_->parsing_complete_var()));
} }
out_cc->println("}"); out_cc->println("}");
@ -459,14 +443,12 @@ void CaseField::GenParseCode(Output* out_cc, Env* env,
out_cc->dec_indent(); out_cc->dec_indent();
} }
bool CaseField::DoTraverse(DataDepVisitor *visitor) bool CaseField::DoTraverse(DataDepVisitor* visitor)
{ {
return Field::DoTraverse(visitor) && return Field::DoTraverse(visitor) && type()->Traverse(visitor);
type()->Traverse(visitor);
} }
bool CaseField::RequiresAnalyzerContext() const bool CaseField::RequiresAnalyzerContext() const
{ {
return Field::RequiresAnalyzerContext() || return Field::RequiresAnalyzerContext() || type()->RequiresAnalyzerContext();
type()->RequiresAnalyzerContext();
} }

View file

@ -7,77 +7,76 @@
#include "pac_type.h" #include "pac_type.h"
class CaseType : public Type class CaseType : public Type
{ {
public: public:
CaseType(Expr *index, CaseFieldList *cases); CaseType(Expr* index, CaseFieldList* cases);
~CaseType(); ~CaseType();
void AddCaseField(CaseField *f); void AddCaseField(CaseField* f);
bool DefineValueVar() const; bool DefineValueVar() const;
string DataTypeStr() const; string DataTypeStr() const;
string DefaultValue() const; string DefaultValue() const;
void Prepare(Env *env, int flags); void Prepare(Env* env, int flags);
void GenPubDecls(Output *out, Env *env); void GenPubDecls(Output* out, Env* env);
void GenPrivDecls(Output *out, Env *env); void GenPrivDecls(Output* out, Env* env);
void GenInitCode(Output *out, Env *env); void GenInitCode(Output* out, Env* env);
void GenCleanUpCode(Output *out, Env *env); void GenCleanUpCode(Output* out, Env* env);
int StaticSize(Env *env) const; int StaticSize(Env* env) const;
void SetBoundaryChecked(); void SetBoundaryChecked();
Type *ValueType() const; Type* ValueType() const;
Expr* IndexExpr() const { return index_expr_; } Expr* IndexExpr() const { return index_expr_; }
bool IsPointerType() const { return ValueType()->IsPointerType(); } bool IsPointerType() const { return ValueType()->IsPointerType(); }
protected: protected:
void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags); void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags);
void GenDynamicSize(Output *out, Env *env, const DataPtr& data); void GenDynamicSize(Output* out, Env* env, const DataPtr& data);
Type *DoClone() const { return 0; } Type* DoClone() const { return 0; }
void DoMarkIncrementalInput(); void DoMarkIncrementalInput();
bool ByteOrderSensitive() const; bool ByteOrderSensitive() const;
Expr *index_expr_; Expr* index_expr_;
ID *index_var_; ID* index_var_;
CaseFieldList *cases_; CaseFieldList* cases_;
typedef map<const ID*, CaseField*, ID_ptr_cmp> member_map_t; typedef map<const ID*, CaseField*, ID_ptr_cmp> member_map_t;
member_map_t member_map_; member_map_t member_map_;
}; };
class CaseField : public Field class CaseField : public Field
{ {
public: public:
CaseField(ExprList *index, ID *id, Type *type); CaseField(ExprList* index, ID* id, Type* type);
~CaseField(); ~CaseField();
CaseType *case_type() const { return case_type_; } CaseType* case_type() const { return case_type_; }
void set_case_type(CaseType *t) { case_type_ = t; } void set_case_type(CaseType* t) { case_type_ = t; }
ExprList *index() const { return index_; } ExprList* index() const { return index_; }
const char *lvalue() const { return type_->lvalue(); } const char* lvalue() const { return type_->lvalue(); }
const char *CaseStr(Env *env); const char* CaseStr(Env* env);
void set_index_var(const ID *var) { index_var_ = var; } void set_index_var(const ID* var) { index_var_ = var; }
void Prepare(Env *env); void Prepare(Env* env);
void GenPubDecls(Output *out, Env *env); void GenPubDecls(Output* out, Env* env);
void GenInitCode(Output *out, Env *env); void GenInitCode(Output* out, Env* env);
void GenCleanUpCode(Output *out, Env *env); void GenCleanUpCode(Output* out, Env* env);
void GenParseCode(Output *out, Env *env, void GenParseCode(Output* out, Env* env, const DataPtr& data, const ID* size_var);
const DataPtr& data, const ID *size_var);
int StaticSize(Env *env) const { return type_->StaticSize(env); } int StaticSize(Env* env) const { return type_->StaticSize(env); }
bool IsDefaultCase() const { return ! index_; } bool IsDefaultCase() const { return ! index_; }
void SetBoundaryChecked() { type_->SetBoundaryChecked(); } void SetBoundaryChecked() { type_->SetBoundaryChecked(); }
@ -86,16 +85,16 @@ public:
bool RequiresAnalyzerContext() const; bool RequiresAnalyzerContext() const;
protected: protected:
bool DoTraverse(DataDepVisitor *visitor); bool DoTraverse(DataDepVisitor* visitor);
protected: protected:
CaseType *case_type_; CaseType* case_type_;
ExprList *index_; ExprList* index_;
const ID *index_var_; const ID* index_var_;
}; };
// Generate a list of "case X:" lines from index_list. Each index // Generate a list of "case X:" lines from index_list. Each index
// expression must be constant foldable. // expression must be constant foldable.
void GenCaseStr(ExprList *index_list, Output *out_cc, Env *env, Type* switch_type); void GenCaseStr(ExprList* index_list, Output* out_cc, Env* env, Type* switch_type);
#endif // pac_case_h #endif // pac_case_h

View file

@ -7,9 +7,9 @@ class CClassMethod;
class CType; class CType;
class CVariable; class CVariable;
typedef vector<CClassMember *> CClassMemberList; typedef vector<CClassMember*> CClassMemberList;
typedef vector<CClassMethod *> CClassMethodList; typedef vector<CClassMethod*> CClassMethodList;
typedef vector<CVariable *> CVariableList; typedef vector<CVariable*> CVariableList;
#include "pac_common.h" #include "pac_common.h"
@ -25,57 +25,57 @@ typedef vector<CVariable *> CVariableList;
// 3. We do not check repeated names. // 3. We do not check repeated names.
class CClass class CClass
{ {
public: public:
CClass(const string &class_name); CClass(const string& class_name);
void AddMember(CClassMember *member); void AddMember(CClassMember* member);
void AddMethod(CClassMember *method); void AddMethod(CClassMember* method);
void GenForwardDeclaration(Output *out_h); void GenForwardDeclaration(Output* out_h);
void GenCode(Output *out_h, Output *out_cc); void GenCode(Output* out_h, Output* out_cc);
protected: protected:
string class_name_; string class_name_;
CClassMemberList *members_; CClassMemberList* members_;
CClassMethodList *methods_; CClassMethodList* methods_;
}; };
class CVariable class CVariable
{ {
public: public:
CClassMember(const string &name, CType *type); CClassMember(const string& name, CType* type);
string name() const { return name_; } string name() const { return name_; }
CType *type() const { return type_; } CType* type() const { return type_; }
protected: protected:
string name_; string name_;
CType *type_; CType* type_;
}; };
class CClassMember class CClassMember
{ {
public: public:
CClassMember(CVariable *var); CClassMember(CVariable* var);
void GenCode(Output *out_h, Output *out_cc); void GenCode(Output* out_h, Output* out_cc);
string decl() const; string decl() const;
protected: protected:
CVariable *var_; CVariable* var_;
}; };
class CClassMethod class CClassMethod
{ {
public: public:
CClassMethod(CVariable *var, CVariableList *params); CClassMethod(CVariable* var, CVariableList* params);
string decl() const; string decl() const;
protected: protected:
CVariable *var_; CVariable* var_;
CVariableList *params_; CVariableList* params_;
}; };
#endif // pac_cclass_h #endif // pac_cclass_h

View file

@ -1,13 +1,12 @@
#ifndef pac_common_h #ifndef pac_common_h
#define pac_common_h #define pac_common_h
#include "pac_utils.h" #include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <vector> #include <vector>
#include <ctype.h> #include "pac_utils.h"
#include <string.h>
#include <stdlib.h>
using namespace std; using namespace std;
@ -22,7 +21,7 @@ extern int line_number;
// etc. // etc.
class Object class Object
{ {
public: public:
Object() Object()
{ {
@ -31,9 +30,7 @@ public:
location = strfmt("%s:%d", filename.c_str(), line_number); location = strfmt("%s:%d", filename.c_str(), line_number);
} }
~Object() ~Object() { }
{
}
const char* Location() const { return location.c_str(); } const char* Location() const { return location.c_str(); }
@ -41,7 +38,7 @@ protected:
string filename; string filename;
int line_num; int line_num;
string location; string location;
}; };
class ActionParam; class ActionParam;
class ActionParamType; class ActionParamType;
@ -112,24 +109,24 @@ typedef vector<StateVar*> StateVarList;
#define delete_list(ct, pc) \ #define delete_list(ct, pc) \
{ \ { \
foreach(delete_list_i, ct, pc) \ foreach (delete_list_i, ct, pc) \
delete *delete_list_i; \ delete *delete_list_i; \
delete pc; \ delete pc; \
pc = 0; \ pc = 0; \
} }
// Constants // Constants
const char * const kComputeFrameLength = "compute_frame_length"; const char* const kComputeFrameLength = "compute_frame_length";
const char * const kFlowBufferClass = "FlowBuffer"; const char* const kFlowBufferClass = "FlowBuffer";
const char * const kFlowBufferVar = "flow_buffer"; const char* const kFlowBufferVar = "flow_buffer";
const char * const kFlowEOF = "FlowEOF"; const char* const kFlowEOF = "FlowEOF";
const char * const kFlowGap = "NewGap"; const char* const kFlowGap = "NewGap";
const char * const kInitialBufferLengthFunc = "initial_buffer_length"; const char* const kInitialBufferLengthFunc = "initial_buffer_length";
const char * const kNeedMoreData = "need_more_data"; const char* const kNeedMoreData = "need_more_data";
const char * const kNewData = "NewData"; const char* const kNewData = "NewData";
const char * const kParseFuncWithBuffer = "ParseBuffer"; const char* const kParseFuncWithBuffer = "ParseBuffer";
const char * const kParseFuncWithoutBuffer = "Parse"; const char* const kParseFuncWithoutBuffer = "Parse";
const char * const kRefCountClass = "binpac::RefCount"; const char* const kRefCountClass = "binpac::RefCount";
const char * const kTypeWithLengthClass = "binpac::TypeWithLength"; const char* const kTypeWithLengthClass = "binpac::TypeWithLength";
#endif // pac_common_h #endif // pac_common_h

View file

@ -1,3 +1,5 @@
#include "pac_conn.h"
#include "pac_analyzer.h" #include "pac_analyzer.h"
#include "pac_dataunit.h" #include "pac_dataunit.h"
#include "pac_embedded.h" #include "pac_embedded.h"
@ -8,11 +10,7 @@
#include "pac_paramtype.h" #include "pac_paramtype.h"
#include "pac_type.h" #include "pac_type.h"
#include "pac_conn.h" ConnDecl::ConnDecl(ID* conn_id, ParamList* params, AnalyzerElementList* elemlist)
ConnDecl::ConnDecl(ID *conn_id,
ParamList *params,
AnalyzerElementList *elemlist)
: AnalyzerDecl(conn_id, CONN, params) : AnalyzerDecl(conn_id, CONN, params)
{ {
flows_[0] = flows_[1] = 0; flows_[0] = flows_[1] = 0;
@ -27,12 +25,12 @@ ConnDecl::~ConnDecl()
delete data_type_; delete data_type_;
} }
void ConnDecl::AddBaseClass(vector<string> *base_classes) const void ConnDecl::AddBaseClass(vector<string>* base_classes) const
{ {
base_classes->push_back("binpac::ConnectionAnalyzer"); base_classes->push_back("binpac::ConnectionAnalyzer");
} }
void ConnDecl::ProcessFlowElement(AnalyzerFlow *flow_elem) void ConnDecl::ProcessFlowElement(AnalyzerFlow* flow_elem)
{ {
int flow_index; int flow_index;
@ -44,19 +42,16 @@ void ConnDecl::ProcessFlowElement(AnalyzerFlow *flow_elem)
if ( flows_[flow_index] ) if ( flows_[flow_index] )
{ {
throw Exception(flow_elem, throw Exception(flow_elem,
strfmt("%sflow already defined", strfmt("%sflow already defined", flow_index == 0 ? "up" : "down"));
flow_index == 0 ? "up" : "down"));
} }
flows_[flow_index] = flow_elem; flows_[flow_index] = flow_elem;
type_->AddField(flow_elem->flow_field()); type_->AddField(flow_elem->flow_field());
} }
void ConnDecl::ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem) void ConnDecl::ProcessDataUnitElement(AnalyzerDataUnit* dataunit_elem)
{ {
throw Exception( throw Exception(dataunit_elem, "dataunit should be defined in only a flow declaration");
dataunit_elem,
"dataunit should be defined in only a flow declaration");
} }
void ConnDecl::Prepare() void ConnDecl::Prepare()
@ -67,17 +62,17 @@ void ConnDecl::Prepare()
flows_[1]->flow_decl()->set_conn_decl(this); flows_[1]->flow_decl()->set_conn_decl(this);
} }
void ConnDecl::GenPubDecls(Output *out_h, Output *out_cc) void ConnDecl::GenPubDecls(Output* out_h, Output* out_cc)
{ {
AnalyzerDecl::GenPubDecls(out_h, out_cc); AnalyzerDecl::GenPubDecls(out_h, out_cc);
} }
void ConnDecl::GenPrivDecls(Output *out_h, Output *out_cc) void ConnDecl::GenPrivDecls(Output* out_h, Output* out_cc)
{ {
AnalyzerDecl::GenPrivDecls(out_h, out_cc); AnalyzerDecl::GenPrivDecls(out_h, out_cc);
} }
void ConnDecl::GenEOFFunc(Output *out_h, Output *out_cc) void ConnDecl::GenEOFFunc(Output* out_h, Output* out_cc)
{ {
string proto = strfmt("%s(bool is_orig)", kFlowEOF); string proto = strfmt("%s(bool is_orig)", kFlowEOF);
@ -89,17 +84,13 @@ void ConnDecl::GenEOFFunc(Output *out_h, Output *out_cc)
out_cc->println("if ( is_orig )"); out_cc->println("if ( is_orig )");
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("%s->%s();", out_cc->println("%s->%s();", env_->LValue(upflow_id), kFlowEOF);
env_->LValue(upflow_id),
kFlowEOF);
out_cc->dec_indent(); out_cc->dec_indent();
out_cc->println("else"); out_cc->println("else");
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("%s->%s();", out_cc->println("%s->%s();", env_->LValue(downflow_id), kFlowEOF);
env_->LValue(downflow_id),
kFlowEOF);
foreach(i, AnalyzerHelperList, eof_helpers_) foreach (i, AnalyzerHelperList, eof_helpers_)
{ {
(*i)->GenCode(0, out_cc, this); (*i)->GenCode(0, out_cc, this);
} }
@ -111,7 +102,7 @@ void ConnDecl::GenEOFFunc(Output *out_h, Output *out_cc)
out_cc->println(""); out_cc->println("");
} }
void ConnDecl::GenGapFunc(Output *out_h, Output *out_cc) void ConnDecl::GenGapFunc(Output* out_h, Output* out_cc)
{ {
string proto = strfmt("%s(bool is_orig, int gap_length)", kFlowGap); string proto = strfmt("%s(bool is_orig, int gap_length)", kFlowGap);
@ -123,15 +114,11 @@ void ConnDecl::GenGapFunc(Output *out_h, Output *out_cc)
out_cc->println("if ( is_orig )"); out_cc->println("if ( is_orig )");
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("%s->%s(gap_length);", out_cc->println("%s->%s(gap_length);", env_->LValue(upflow_id), kFlowGap);
env_->LValue(upflow_id),
kFlowGap);
out_cc->dec_indent(); out_cc->dec_indent();
out_cc->println("else"); out_cc->println("else");
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("%s->%s(gap_length);", out_cc->println("%s->%s(gap_length);", env_->LValue(downflow_id), kFlowGap);
env_->LValue(downflow_id),
kFlowGap);
out_cc->dec_indent(); out_cc->dec_indent();
out_cc->println("}"); out_cc->println("}");
@ -139,11 +126,9 @@ void ConnDecl::GenGapFunc(Output *out_h, Output *out_cc)
out_cc->println(""); out_cc->println("");
} }
void ConnDecl::GenProcessFunc(Output *out_h, Output *out_cc) void ConnDecl::GenProcessFunc(Output* out_h, Output* out_cc)
{ {
string proto = string proto = strfmt("%s(bool is_orig, const_byteptr begin, const_byteptr end)", kNewData);
strfmt("%s(bool is_orig, const_byteptr begin, const_byteptr end)",
kNewData);
out_h->println("void %s;", proto.c_str()); out_h->println("void %s;", proto.c_str());
@ -153,15 +138,11 @@ void ConnDecl::GenProcessFunc(Output *out_h, Output *out_cc)
out_cc->println("if ( is_orig )"); out_cc->println("if ( is_orig )");
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("%s->%s(begin, end);", out_cc->println("%s->%s(begin, end);", env_->LValue(upflow_id), kNewData);
env_->LValue(upflow_id),
kNewData);
out_cc->dec_indent(); out_cc->dec_indent();
out_cc->println("else"); out_cc->println("else");
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("%s->%s(begin, end);", out_cc->println("%s->%s(begin, end);", env_->LValue(downflow_id), kNewData);
env_->LValue(downflow_id),
kNewData);
out_cc->dec_indent(); out_cc->dec_indent();
out_cc->println("}"); out_cc->println("}");

View file

@ -1,13 +1,13 @@
#ifndef pac_conn_h #ifndef pac_conn_h
#define pac_conn_h #define pac_conn_h
#include "pac_decl.h"
#include "pac_analyzer.h" #include "pac_analyzer.h"
#include "pac_decl.h"
class ConnDecl : public AnalyzerDecl class ConnDecl : public AnalyzerDecl
{ {
public: public:
ConnDecl(ID *conn_id, ParamList *params, AnalyzerElementList *elemlist); ConnDecl(ID* conn_id, ParamList* params, AnalyzerElementList* elemlist);
~ConnDecl(); ~ConnDecl();
void Prepare(); void Prepare();
@ -15,20 +15,20 @@ public:
Type* DataType() const { return data_type_; } Type* DataType() const { return data_type_; }
protected: protected:
void AddBaseClass(vector<string> *base_classes) const; void AddBaseClass(vector<string>* base_classes) const;
void GenProcessFunc(Output *out_h, Output *out_cc); void GenProcessFunc(Output* out_h, Output* out_cc);
void GenGapFunc(Output *out_h, Output *out_cc); void GenGapFunc(Output* out_h, Output* out_cc);
void GenEOFFunc(Output *out_h, Output *out_cc); void GenEOFFunc(Output* out_h, Output* out_cc);
void GenPubDecls(Output *out_h, Output *out_cc); void GenPubDecls(Output* out_h, Output* out_cc);
void GenPrivDecls(Output *out_h, Output *out_cc); void GenPrivDecls(Output* out_h, Output* out_cc);
void ProcessFlowElement(AnalyzerFlow *flow_elem); void ProcessFlowElement(AnalyzerFlow* flow_elem);
void ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem); void ProcessDataUnitElement(AnalyzerDataUnit* dataunit_elem);
AnalyzerFlow *flows_[2]; AnalyzerFlow* flows_[2];
Type *data_type_; Type* data_type_;
}; };
#endif // pac_conn_h #endif // pac_conn_h

View file

@ -1,3 +1,5 @@
#include "pac_context.h"
#include "pac_analyzer.h" #include "pac_analyzer.h"
#include "pac_exception.h" #include "pac_exception.h"
#include "pac_exttype.h" #include "pac_exttype.h"
@ -9,45 +11,36 @@
#include "pac_type.h" #include "pac_type.h"
#include "pac_utils.h" #include "pac_utils.h"
#include "pac_context.h" ContextField::ContextField(ID* id, Type* type)
: Field(CONTEXT_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type)
ContextField::ContextField(ID *id, Type *type)
: Field(CONTEXT_FIELD,
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
id, type)
{ {
} }
AnalyzerContextDecl *AnalyzerContextDecl::current_analyzer_context_ = 0; AnalyzerContextDecl* AnalyzerContextDecl::current_analyzer_context_ = 0;
namespace { namespace
ParamList *ContextFieldsToParams(ContextFieldList *context_fields) {
ParamList* ContextFieldsToParams(ContextFieldList* context_fields)
{ {
// Convert context fields to parameters // Convert context fields to parameters
ParamList *params = new ParamList(); ParamList* params = new ParamList();
foreach(i, ContextFieldList, context_fields) foreach (i, ContextFieldList, context_fields)
{ {
ContextField *f = *i; ContextField* f = *i;
params->push_back( params->push_back(new Param(f->id()->clone(), f->type()));
new Param(f->id()->clone(),
f->type()));
} }
return params; return params;
} }
} // namespace private } // namespace private
AnalyzerContextDecl::AnalyzerContextDecl( AnalyzerContextDecl::AnalyzerContextDecl(ID* id, ContextFieldList* context_fields)
ID *id, : TypeDecl(new ID(strfmt("Context%s", id->Name())), ContextFieldsToParams(context_fields),
ContextFieldList *context_fields)
: TypeDecl(new ID(strfmt("Context%s", id->Name())),
ContextFieldsToParams(context_fields),
new DummyType()) new DummyType())
{ {
context_name_id_ = id; context_name_id_ = id;
if ( current_analyzer_context_ != 0 ) if ( current_analyzer_context_ != 0 )
{ {
throw Exception(this, throw Exception(this, strfmt("multiple declaration of analyzer context; "
strfmt("multiple declaration of analyzer context; "
"the previous one is `%s'", "the previous one is `%s'",
current_analyzer_context_->id()->Name())); current_analyzer_context_->id()->Name()));
} }
@ -70,25 +63,25 @@ AnalyzerContextDecl::~AnalyzerContextDecl()
delete_list(ContextFieldList, context_fields_); delete_list(ContextFieldList, context_fields_);
} }
void AnalyzerContextDecl::GenForwardDeclaration(Output *out_h) void AnalyzerContextDecl::GenForwardDeclaration(Output* out_h)
{ {
GenNamespaceBegin(out_h); GenNamespaceBegin(out_h);
TypeDecl::GenForwardDeclaration(out_h); TypeDecl::GenForwardDeclaration(out_h);
} }
void AnalyzerContextDecl::GenCode(Output *out_h, Output *out_cc) void AnalyzerContextDecl::GenCode(Output* out_h, Output* out_cc)
{ {
GenNamespaceBegin(out_h); GenNamespaceBegin(out_h);
GenNamespaceBegin(out_cc); GenNamespaceBegin(out_cc);
TypeDecl::GenCode(out_h, out_cc); TypeDecl::GenCode(out_h, out_cc);
} }
void AnalyzerContextDecl::GenNamespaceBegin(Output *out) const void AnalyzerContextDecl::GenNamespaceBegin(Output* out) const
{ {
out->println("namespace %s {", context_name_id()->Name()); out->println("namespace %s {", context_name_id()->Name());
} }
void AnalyzerContextDecl::GenNamespaceEnd(Output *out) const void AnalyzerContextDecl::GenNamespaceEnd(Output* out) const
{ {
out->println("} // namespace %s", context_name_id()->Name()); out->println("} // namespace %s", context_name_id()->Name());
} }
@ -98,23 +91,19 @@ void AnalyzerContextDecl::AddFlowBuffer()
if ( flow_buffer_added_ ) if ( flow_buffer_added_ )
return; return;
AddParam(new Param( AddParam(new Param(new ID(kFlowBufferVar), FlowDecl::flow_buffer_type()->Clone()));
new ID(kFlowBufferVar),
FlowDecl::flow_buffer_type()->Clone()));
flow_buffer_added_ = true; flow_buffer_added_ = true;
} }
string AnalyzerContextDecl::mb_buffer(Env *env) string AnalyzerContextDecl::mb_buffer(Env* env)
{ {
// A hack. The orthodox way would be to build an Expr of // A hack. The orthodox way would be to build an Expr of
// context.flow_buffer_var, and then EvalExpr. // context.flow_buffer_var, and then EvalExpr.
return strfmt("%s->%s()", return strfmt("%s->%s()", env->RValue(analyzer_context_id), kFlowBufferVar);
env->RValue(analyzer_context_id),
kFlowBufferVar);
} }
Type *DummyType::DoClone() const Type* DummyType::DoClone() const
{ {
// Fields will be copied in Type::Clone(). // Fields will be copied in Type::Clone().
return new DummyType(); return new DummyType();

View file

@ -24,74 +24,80 @@
// ``binpac_context.connection''. // ``binpac_context.connection''.
class ContextField : public Field class ContextField : public Field
{ {
public: public:
ContextField(ID *id, Type *type); ContextField(ID* id, Type* type);
}; };
class AnalyzerContextDecl : public TypeDecl class AnalyzerContextDecl : public TypeDecl
{ {
public: public:
AnalyzerContextDecl(ID *id, ContextFieldList *context_fields); AnalyzerContextDecl(ID* id, ContextFieldList* context_fields);
~AnalyzerContextDecl(); ~AnalyzerContextDecl();
void AddFlowBuffer(); void AddFlowBuffer();
const ID *context_name_id() const { return context_name_id_; } const ID* context_name_id() const { return context_name_id_; }
// The type of analyzer context as a parameter // The type of analyzer context as a parameter
ParameterizedType *param_type() const { return param_type_; } ParameterizedType* param_type() const { return param_type_; }
void GenForwardDeclaration(Output *out_h); void GenForwardDeclaration(Output* out_h);
void GenCode(Output *out_h, Output *out_cc); void GenCode(Output* out_h, Output* out_cc);
void GenNamespaceBegin(Output *out) const; void GenNamespaceBegin(Output* out) const;
void GenNamespaceEnd(Output *out) const; void GenNamespaceEnd(Output* out) const;
private: private:
ID *context_name_id_; ID* context_name_id_;
ContextFieldList *context_fields_; ContextFieldList* context_fields_;
ParameterizedType *param_type_; ParameterizedType* param_type_;
bool flow_buffer_added_; bool flow_buffer_added_;
// static members // static members
public: public:
static AnalyzerContextDecl *current_analyzer_context() static AnalyzerContextDecl* current_analyzer_context() { return current_analyzer_context_; }
{
return current_analyzer_context_;
}
static string mb_buffer(Env *env); static string mb_buffer(Env* env);
private: private:
static AnalyzerContextDecl *current_analyzer_context_; static AnalyzerContextDecl* current_analyzer_context_;
}; };
class DummyType : public Type class DummyType : public Type
{ {
public: public:
DummyType() : Type(DUMMY) {} DummyType() : Type(DUMMY) { }
bool DefineValueVar() const { return false; } bool DefineValueVar() const { return false; }
string DataTypeStr() const { ASSERT(0); return ""; } string DataTypeStr() const
{
ASSERT(0);
return "";
}
int StaticSize(Env* env) const { ASSERT(0); return -1; } int StaticSize(Env* env) const
{
ASSERT(0);
return -1;
}
bool ByteOrderSensitive() const { return false; } bool ByteOrderSensitive() const { return false; }
bool IsPointerType() const { ASSERT(0); return false; } bool IsPointerType() const
{
ASSERT(0);
return false;
}
void DoGenParseCode(Output* out, Env* env, void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags) { ASSERT(0); }
const DataPtr& data, int flags)
{ ASSERT(0); }
// Generate code for computing the dynamic size of the type // Generate code for computing the dynamic size of the type
void GenDynamicSize(Output* out, Env* env, const DataPtr& data) void GenDynamicSize(Output* out, Env* env, const DataPtr& data) { ASSERT(0); }
{ ASSERT(0); }
protected: protected:
Type *DoClone() const; Type* DoClone() const;
void DoMarkIncrementalInput() { ASSERT(0); } void DoMarkIncrementalInput() { ASSERT(0); }
}; };
#endif // pac_context_h #endif // pac_context_h

View file

@ -1,37 +1,50 @@
#include "pac_cstr.h" #include "pac_cstr.h"
#include "pac_dbg.h" #include "pac_dbg.h"
#include "pac_exception.h" #include "pac_exception.h"
namespace { namespace
{
class EscapeException class EscapeException
{
public:
explicit EscapeException(const string &s)
{ {
msg_ = s; public:
} explicit EscapeException(const string& s) { msg_ = s; }
const string &msg() const { return msg_; } const string& msg() const { return msg_; }
private: private:
string msg_; string msg_;
}; };
// Copied from util.cc of Zeek // Copied from util.cc of Zeek
int expand_escape(const char*& s) int expand_escape(const char*& s)
{ {
switch ( *(s++) ) { switch ( *(s++) )
case 'b': return '\b'; {
case 'f': return '\f'; case 'b':
case 'n': return '\n'; return '\b';
case 'r': return '\r'; case 'f':
case 't': return '\t'; return '\f';
case 'a': return '\a'; case 'n':
case 'v': return '\v'; return '\n';
case 'r':
return '\r';
case 't':
return '\t';
case 'a':
return '\a';
case 'v':
return '\v';
case '0': case '1': case '2': case '3': case '4': case '0':
case '5': case '6': case '7': case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
{ // \<octal>{1,3} { // \<octal>{1,3}
--s; // put back the first octal digit --s; // put back the first octal digit
const char* start = s; const char* start = s;
@ -44,7 +57,7 @@ int expand_escape(const char*& s)
// to allow easy handling of string like: "^H0" as // to allow easy handling of string like: "^H0" as
// "\0100". // "\0100".
for ( int len = 0; len < 3 && isascii(*s) && isdigit(*s); ++s, ++len) for ( int len = 0; len < 3 && isascii(*s) && isdigit(*s); ++s, ++len )
; ;
int result; int result;
@ -59,8 +72,7 @@ int expand_escape(const char*& s)
const char* start = s; const char* start = s;
// Look at most 2 characters, so that "\x0ddir" -> "^Mdir". // Look at most 2 characters, so that "\x0ddir" -> "^Mdir".
for ( int len = 0; len < 2 && isascii(*s) && isxdigit(*s); for ( int len = 0; len < 2 && isascii(*s) && isxdigit(*s); ++s, ++len )
++s, ++len)
; ;
int result; int result;
@ -75,10 +87,9 @@ int expand_escape(const char*& s)
} }
} }
} // private namespace } // private namespace
ConstString::ConstString(const string &s) ConstString::ConstString(const string& s) : str_(s)
: str_(s)
{ {
// Copied from scan.l of Zeek // Copied from scan.l of Zeek
try try
@ -106,16 +117,15 @@ ConstString::ConstString(const string &s)
ASSERT(i < len); ASSERT(i < len);
// Get rid of trailing quote. // Get rid of trailing quote.
ASSERT(new_s[i-1] == '"'); ASSERT(new_s[i - 1] == '"');
new_s[i-1] = '\0'; new_s[i - 1] = '\0';
unescaped_ = new_s; unescaped_ = new_s;
delete [] new_s; delete[] new_s;
} }
catch(EscapeException const &e) catch ( EscapeException const& e )
{ {
// Throw again with the object // Throw again with the object
throw Exception(this, e.msg().c_str()); throw Exception(this, e.msg().c_str());
} }
} }

View file

@ -4,20 +4,20 @@
#include "pac_common.h" #include "pac_common.h"
class ConstString : public Object class ConstString : public Object
{ {
public: public:
ConstString(const string &s); ConstString(const string& s);
// The string in its escaped form, with surrounding '"'s // The string in its escaped form, with surrounding '"'s
const string &str() const { return str_; } const string& str() const { return str_; }
const char *c_str() const { return str_.c_str(); } const char* c_str() const { return str_.c_str(); }
// The unescaped string, without surrounding '"'s // The unescaped string, without surrounding '"'s
const string &unescaped() const { return unescaped_; } const string& unescaped() const { return unescaped_; }
private: private:
string str_; string str_;
string unescaped_; string unescaped_;
}; };
#endif // pac_cstr_h #endif // pac_cstr_h

View file

@ -1,21 +1,21 @@
#include "pac_ctype.h" #include "pac_ctype.h"
string CType::DeclareInstance(const string &var) const string CType::DeclareInstance(const string& var) const
{ {
return strfmt("%s %s", name().c_str(), var.c_str()); return strfmt("%s %s", name().c_str(), var.c_str());
} }
string CType::DeclareConstReference(const string &var) const string CType::DeclareConstReference(const string& var) const
{ {
return strfmt("%s const &%s", name().c_str(), var.c_str()); return strfmt("%s const &%s", name().c_str(), var.c_str());
} }
string CType::DeclareConstPointer(const string &var) const string CType::DeclareConstPointer(const string& var) const
{ {
return strfmt("%s const *%s", name().c_str(), var.c_str()); return strfmt("%s const *%s", name().c_str(), var.c_str());
} }
string CType::DeclarePointer(const string &var) const string CType::DeclarePointer(const string& var) const
{ {
return strfmt("%s *%s", name().c_str(), var.c_str()); return strfmt("%s *%s", name().c_str(), var.c_str());
} }

View file

@ -5,19 +5,19 @@
// Represents a C++ type // Represents a C++ type
class CType class CType
{ {
public: public:
CType(const string &name); CType(const string& name);
string name() const { return name_; } string name() const { return name_; }
string DeclareInstance(const string &var) const; string DeclareInstance(const string& var) const;
string DeclareConstReference(const string &var) const; string DeclareConstReference(const string& var) const;
string DeclareConstPointer(const string &var) const; string DeclareConstPointer(const string& var) const;
string DeclarePointer(const string &var) const; string DeclarePointer(const string& var) const;
protected: protected:
string name_; string name_;
}; };
#endif // pac_ctype_h #endif // pac_ctype_h

View file

@ -1,14 +1,12 @@
#include "pac_datadep.h" #include "pac_datadep.h"
#include "pac_expr.h" #include "pac_expr.h"
#include "pac_id.h" #include "pac_id.h"
#include "pac_type.h" #include "pac_type.h"
DataDepElement::DataDepElement(DDE_Type type) DataDepElement::DataDepElement(DDE_Type type) : dde_type_(type), in_traversal(false) { }
: dde_type_(type), in_traversal(false)
{
}
bool DataDepElement::Traverse(DataDepVisitor *visitor) bool DataDepElement::Traverse(DataDepVisitor* visitor)
{ {
// Avoid infinite loop // Avoid infinite loop
if ( in_traversal ) if ( in_traversal )
@ -27,17 +25,17 @@ bool DataDepElement::Traverse(DataDepVisitor *visitor)
return true; return true;
} }
Expr *DataDepElement::expr() Expr* DataDepElement::expr()
{ {
return static_cast<Expr *>(this); return static_cast<Expr*>(this);
} }
Type *DataDepElement::type() Type* DataDepElement::type()
{ {
return static_cast<Type *>(this); return static_cast<Type*>(this);
} }
bool RequiresAnalyzerContext::PreProcess(DataDepElement *element) bool RequiresAnalyzerContext::PreProcess(DataDepElement* element)
{ {
switch ( element->dde_type() ) switch ( element->dde_type() )
{ {
@ -52,23 +50,22 @@ bool RequiresAnalyzerContext::PreProcess(DataDepElement *element)
return ! requires_analyzer_context_; return ! requires_analyzer_context_;
} }
bool RequiresAnalyzerContext::PostProcess(DataDepElement *element) bool RequiresAnalyzerContext::PostProcess(DataDepElement* element)
{ {
return ! requires_analyzer_context_; return ! requires_analyzer_context_;
} }
void RequiresAnalyzerContext::ProcessExpr(Expr *expr) void RequiresAnalyzerContext::ProcessExpr(Expr* expr)
{ {
if ( expr->expr_type() == Expr::EXPR_ID ) if ( expr->expr_type() == Expr::EXPR_ID )
{ {
requires_analyzer_context_ = requires_analyzer_context_ = (requires_analyzer_context_ ||
(requires_analyzer_context_ ||
*expr->id() == *analyzer_context_id || *expr->id() == *analyzer_context_id ||
*expr->id() == *context_macro_id); *expr->id() == *context_macro_id);
} }
} }
bool RequiresAnalyzerContext::compute(DataDepElement *element) bool RequiresAnalyzerContext::compute(DataDepElement* element)
{ {
RequiresAnalyzerContext visitor; RequiresAnalyzerContext visitor;
element->Traverse(&visitor); element->Traverse(&visitor);

View file

@ -9,9 +9,11 @@
class DataDepVisitor; class DataDepVisitor;
class DataDepElement { class DataDepElement
{
public: public:
enum DDE_Type { enum DDE_Type
{
ATTR, ATTR,
CASEEXPR, CASEEXPR,
EXPR, EXPR,
@ -22,50 +24,49 @@ public:
}; };
DataDepElement(DDE_Type type); DataDepElement(DDE_Type type);
virtual ~DataDepElement() {} virtual ~DataDepElement() { }
// Returns whether to continue traversal // Returns whether to continue traversal
bool Traverse(DataDepVisitor *visitor); bool Traverse(DataDepVisitor* visitor);
// Returns whether to continue traversal // Returns whether to continue traversal
virtual bool DoTraverse(DataDepVisitor *visitor) = 0; virtual bool DoTraverse(DataDepVisitor* visitor) = 0;
DDE_Type dde_type() const { return dde_type_; } DDE_Type dde_type() const { return dde_type_; }
Expr *expr(); Expr* expr();
Type *type(); Type* type();
protected: protected:
DDE_Type dde_type_; DDE_Type dde_type_;
bool in_traversal; bool in_traversal;
}; };
class DataDepVisitor { class DataDepVisitor
public:
virtual ~DataDepVisitor() {}
// Returns whether to continue traversal
virtual bool PreProcess(DataDepElement *element) = 0;
virtual bool PostProcess(DataDepElement *element) = 0;
};
class RequiresAnalyzerContext : public DataDepVisitor {
public:
RequiresAnalyzerContext() : requires_analyzer_context_(false) {}
// Returns whether to continue traversal
bool PreProcess(DataDepElement *element);
bool PostProcess(DataDepElement *element);
bool requires_analyzer_context() const
{ {
return requires_analyzer_context_; public:
} virtual ~DataDepVisitor() { }
// Returns whether to continue traversal
virtual bool PreProcess(DataDepElement* element) = 0;
virtual bool PostProcess(DataDepElement* element) = 0;
};
static bool compute(DataDepElement *element); class RequiresAnalyzerContext : public DataDepVisitor
{
public:
RequiresAnalyzerContext() : requires_analyzer_context_(false) { }
// Returns whether to continue traversal
bool PreProcess(DataDepElement* element);
bool PostProcess(DataDepElement* element);
bool requires_analyzer_context() const { return requires_analyzer_context_; }
static bool compute(DataDepElement* element);
protected: protected:
void ProcessExpr(Expr *expr); void ProcessExpr(Expr* expr);
bool requires_analyzer_context_; bool requires_analyzer_context_;
}; };
#endif // pac_datadep_h #endif // pac_datadep_h

View file

@ -1,12 +1,11 @@
#include "pac_dataptr.h"
#include "pac_exception.h" #include "pac_exception.h"
#include "pac_id.h" #include "pac_id.h"
#include "pac_output.h" #include "pac_output.h"
#include "pac_utils.h" #include "pac_utils.h"
#include "pac_dataptr.h" DataPtr::DataPtr(Env* env, const ID* id, const int offset) : id_(id), offset_(offset)
DataPtr::DataPtr(Env* env, const ID* id, const int offset)
: id_(id), offset_(offset)
{ {
if ( id_ ) if ( id_ )
{ {
@ -24,7 +23,7 @@ DataPtr::DataPtr(Env* env, const ID* id, const int offset)
int DataPtr::AbsOffset(const ID* base_ptr) const int DataPtr::AbsOffset(const ID* base_ptr) const
{ {
return ( id() == base_ptr ) ? offset() : -1; return (id() == base_ptr) ? offset() : -1;
} }
char* DataPtr::AbsOffsetExpr(Env* env, const ID* base_ptr) const char* DataPtr::AbsOffsetExpr(Env* env, const ID* base_ptr) const
@ -35,19 +34,14 @@ char* DataPtr::AbsOffsetExpr(Env* env, const ID* base_ptr) const
return nfmt("(%s - %s)", ptr_expr(), env->RValue(base_ptr)); return nfmt("(%s - %s)", ptr_expr(), env->RValue(base_ptr));
} }
void DataPtr::GenBoundaryCheck(Output* out_cc, Env* env, void DataPtr::GenBoundaryCheck(Output* out_cc, Env* env, const char* data_size,
const char* data_size, const char* data_name) const const char* data_name) const
{ {
ASSERT(id_); ASSERT(id_);
out_cc->println("// Checking out-of-bound for \"%s\"", data_name); out_cc->println("// Checking out-of-bound for \"%s\"", data_name);
out_cc->println("if ( %s + (%s) > %s || %s + (%s) < %s )", out_cc->println("if ( %s + (%s) > %s || %s + (%s) < %s )", ptr_expr(), data_size,
ptr_expr(), env->RValue(end_of_data), ptr_expr(), data_size, ptr_expr());
data_size,
env->RValue(end_of_data),
ptr_expr(),
data_size,
ptr_expr());
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
@ -56,14 +50,11 @@ void DataPtr::GenBoundaryCheck(Output* out_cc, Env* env,
out_cc->println("// Handle out-of-bound condition"); out_cc->println("// Handle out-of-bound condition");
out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", data_name); out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", data_name);
out_cc->println(" (%s) + (%s), ", out_cc->println(" (%s) + (%s), ", data_offset, data_size);
data_offset, data_size); out_cc->println(" (%s) - (%s));", env->RValue(end_of_data), env->RValue(begin_of_data));
out_cc->println(" (%s) - (%s));",
env->RValue(end_of_data), env->RValue(begin_of_data));
delete [] data_offset; delete[] data_offset;
out_cc->println("}"); out_cc->println("}");
out_cc->dec_indent(); out_cc->dec_indent();
} }

View file

@ -2,18 +2,20 @@
#define pac_dataptr_h #define pac_dataptr_h
#include <string> #include <string>
#include "pac_common.h" #include "pac_common.h"
#include "pac_dbg.h"
// A data pointer is represented by an data pointer variable // A data pointer is represented by an data pointer variable
// plus a constant offset. // plus a constant offset.
class DataPtr class DataPtr
{ {
public: public:
DataPtr(Env* env, const ID* arg_id, const int arg_off); DataPtr(Env* env, const ID* arg_id, const int arg_off);
DataPtr(DataPtr const& x) { *this = x; } DataPtr(DataPtr const& x) { *this = x; }
DataPtr const &operator=(DataPtr const &x) DataPtr const& operator=(DataPtr const& x)
{ {
id_ = x.id(); id_ = x.id();
offset_ = x.offset(); offset_ = x.offset();
@ -34,15 +36,13 @@ public:
int AbsOffset(const ID* base_ptr) const; int AbsOffset(const ID* base_ptr) const;
char* AbsOffsetExpr(Env* env, const ID* base_ptr) const; char* AbsOffsetExpr(Env* env, const ID* base_ptr) const;
void GenBoundaryCheck(Output* out, void GenBoundaryCheck(Output* out, Env* env, const char* data_size,
Env* env,
const char* data_size,
const char* data_name) const; const char* data_name) const;
protected: protected:
const ID* id_; const ID* id_;
int offset_; int offset_;
string ptr_expr_; string ptr_expr_;
}; };
#endif // pac_dataptr_h #endif // pac_dataptr_h

View file

@ -1,32 +1,21 @@
#include "pac_context.h"
#include "pac_dataunit.h" #include "pac_dataunit.h"
#include "pac_context.h"
#include "pac_output.h" #include "pac_output.h"
#include "pac_paramtype.h" #include "pac_paramtype.h"
#include "pac_varfield.h" #include "pac_varfield.h"
AnalyzerDataUnit::AnalyzerDataUnit( AnalyzerDataUnit::AnalyzerDataUnit(DataUnitType type, ID* id, ExprList* type_params,
DataUnitType type, ExprList* context_params)
ID *id, : AnalyzerElement(DATAUNIT), type_(type), id_(id), type_params_(type_params),
ExprList *type_params,
ExprList *context_params)
: AnalyzerElement(DATAUNIT),
type_(type),
id_(id),
type_params_(type_params),
context_params_(context_params) context_params_(context_params)
{ {
data_type_ = new ParameterizedType(id_, type_params_); data_type_ = new ParameterizedType(id_, type_params_);
context_type_ = new ParameterizedType( context_type_ = new ParameterizedType(
AnalyzerContextDecl::current_analyzer_context()->id()->clone(), AnalyzerContextDecl::current_analyzer_context()->id()->clone(), context_params_);
context_params_);
dataunit_var_field_ = new ParseVarField( dataunit_var_field_ = new ParseVarField(Field::CLASS_MEMBER, dataunit_id->clone(), data_type());
Field::CLASS_MEMBER, context_var_field_ = new PrivVarField(analyzer_context_id->clone(), context_type());
dataunit_id->clone(),
data_type());
context_var_field_ = new PrivVarField(
analyzer_context_id->clone(),
context_type());
} }
AnalyzerDataUnit::~AnalyzerDataUnit() AnalyzerDataUnit::~AnalyzerDataUnit()
@ -35,26 +24,22 @@ AnalyzerDataUnit::~AnalyzerDataUnit()
delete context_var_field_; delete context_var_field_;
} }
void AnalyzerDataUnit::Prepare(Env *env) void AnalyzerDataUnit::Prepare(Env* env)
{ {
dataunit_var_field_->Prepare(env); dataunit_var_field_->Prepare(env);
context_var_field_->Prepare(env); context_var_field_->Prepare(env);
} }
void AnalyzerDataUnit::GenNewDataUnit(Output *out_cc, Env *env) void AnalyzerDataUnit::GenNewDataUnit(Output* out_cc, Env* env)
{ {
out_cc->println("%s = new %s(%s);", out_cc->println("%s = new %s(%s);", env->LValue(dataunit_id), data_type()->class_name().c_str(),
env->LValue(dataunit_id),
data_type()->class_name().c_str(),
data_type()->EvalParameters(out_cc, env).c_str()); data_type()->EvalParameters(out_cc, env).c_str());
} }
void AnalyzerDataUnit::GenNewContext(Output *out_cc, Env *env) void AnalyzerDataUnit::GenNewContext(Output* out_cc, Env* env)
{ {
out_cc->println("%s = new %s(%s);", out_cc->println("%s = new %s(%s);", env->LValue(analyzer_context_id),
env->LValue(analyzer_context_id),
context_type()->class_name().c_str(), context_type()->class_name().c_str(),
context_type()->EvalParameters(out_cc, env).c_str()); context_type()->EvalParameters(out_cc, env).c_str());
env->SetEvaluated(analyzer_context_id); env->SetEvaluated(analyzer_context_id);
} }

View file

@ -7,43 +7,43 @@
// data unit of a DCE/RPC flow is DCE_RPC_PDU. // data unit of a DCE/RPC flow is DCE_RPC_PDU.
class AnalyzerDataUnit : public AnalyzerElement class AnalyzerDataUnit : public AnalyzerElement
{ {
public: public:
enum DataUnitType { DATAGRAM, FLOWUNIT }; enum DataUnitType
AnalyzerDataUnit( {
DataUnitType type, DATAGRAM,
ID *id, FLOWUNIT
ExprList *type_params, };
ExprList *context_params); AnalyzerDataUnit(DataUnitType type, ID* id, ExprList* type_params, ExprList* context_params);
~AnalyzerDataUnit(); ~AnalyzerDataUnit();
void Prepare(Env *env); void Prepare(Env* env);
// Initializes dataunit_id // Initializes dataunit_id
void GenNewDataUnit(Output *out_cc, Env *env); void GenNewDataUnit(Output* out_cc, Env* env);
// Initializes analyzer_context_id // Initializes analyzer_context_id
void GenNewContext(Output *out_cc, Env *env); void GenNewContext(Output* out_cc, Env* env);
DataUnitType type() const { return type_; } DataUnitType type() const { return type_; }
const ID *id() const { return id_; } const ID* id() const { return id_; }
ExprList *type_params() const { return type_params_; } ExprList* type_params() const { return type_params_; }
ExprList *context_params() const { return context_params_; } ExprList* context_params() const { return context_params_; }
ParameterizedType *data_type() const { return data_type_; } ParameterizedType* data_type() const { return data_type_; }
ParameterizedType *context_type() const { return context_type_; } ParameterizedType* context_type() const { return context_type_; }
Field *dataunit_var_field() const { return dataunit_var_field_; } Field* dataunit_var_field() const { return dataunit_var_field_; }
Field *context_var_field() const { return context_var_field_; } Field* context_var_field() const { return context_var_field_; }
private: private:
DataUnitType type_; DataUnitType type_;
ID *id_; ID* id_;
ExprList *type_params_; ExprList* type_params_;
ExprList *context_params_; ExprList* context_params_;
ParameterizedType *data_type_; ParameterizedType* data_type_;
ParameterizedType *context_type_; ParameterizedType* context_type_;
Field *dataunit_var_field_; Field* dataunit_var_field_;
Field *context_var_field_; Field* context_var_field_;
}; };
#endif // pac_dataunit_h #endif // pac_dataunit_h

View file

@ -7,6 +7,8 @@
extern bool FLAGS_pac_debug; extern bool FLAGS_pac_debug;
#define ASSERT(x) assert(x) #define ASSERT(x) assert(x)
#define DEBUG_MSG(x...) if ( FLAGS_pac_debug ) fprintf(stderr, x) #define DEBUG_MSG(x...) \
if ( FLAGS_pac_debug ) \
fprintf(stderr, x)
#endif /* pac_dbg_h */ #endif /* pac_dbg_h */

View file

@ -1,3 +1,5 @@
#include "pac_decl.h"
#include "pac_attr.h" #include "pac_attr.h"
#include "pac_context.h" #include "pac_context.h"
#include "pac_dataptr.h" #include "pac_dataptr.h"
@ -12,13 +14,10 @@
#include "pac_type.h" #include "pac_type.h"
#include "pac_utils.h" #include "pac_utils.h"
#include "pac_decl.h" DeclList* Decl::decl_list_ = 0;
DeclList *Decl::decl_list_ = 0;
Decl::DeclMap Decl::decl_map_; Decl::DeclMap Decl::decl_map_;
Decl::Decl(ID* id, DeclType decl_type) Decl::Decl(ID* id, DeclType decl_type) : id_(id), decl_type_(decl_type), attrlist_(0)
: id_(id), decl_type_(decl_type), attrlist_(0)
{ {
decl_map_[id_] = this; decl_map_[id_] = this;
if ( ! decl_list_ ) if ( ! decl_list_ )
@ -42,44 +41,42 @@ void Decl::AddAttrs(AttrList* attrs)
return; return;
if ( ! attrlist_ ) if ( ! attrlist_ )
attrlist_ = new AttrList(); attrlist_ = new AttrList();
foreach ( i, AttrList, attrs ) foreach (i, AttrList, attrs)
{ {
attrlist_->push_back(*i); attrlist_->push_back(*i);
ProcessAttr(*i); ProcessAttr(*i);
} }
} }
void Decl::ProcessAttr(Attr *attr) void Decl::ProcessAttr(Attr* attr)
{ {
throw Exception(attr, "unhandled attribute"); throw Exception(attr, "unhandled attribute");
} }
void Decl::SetAnalyzerContext() void Decl::SetAnalyzerContext()
{ {
analyzer_context_ = analyzer_context_ = AnalyzerContextDecl::current_analyzer_context();
AnalyzerContextDecl::current_analyzer_context();
if ( ! analyzer_context_ ) if ( ! analyzer_context_ )
{ {
throw Exception(this, throw Exception(this, "analyzer context not defined");
"analyzer context not defined");
} }
} }
void Decl::ProcessDecls(Output *out_h, Output *out_cc) void Decl::ProcessDecls(Output* out_h, Output* out_cc)
{ {
if ( ! decl_list_ ) if ( ! decl_list_ )
return; return;
foreach(i, DeclList, decl_list_) foreach (i, DeclList, decl_list_)
{ {
Decl *decl = *i; Decl* decl = *i;
current_decl_id = decl->id(); current_decl_id = decl->id();
decl->Prepare(); decl->Prepare();
} }
foreach(i, DeclList, decl_list_) foreach (i, DeclList, decl_list_)
{ {
Decl *decl = *i; Decl* decl = *i;
current_decl_id = decl->id(); current_decl_id = decl->id();
decl->GenExternDeclaration(out_h); decl->GenExternDeclaration(out_h);
} }
@ -87,12 +84,11 @@ void Decl::ProcessDecls(Output *out_h, Output *out_cc)
out_h->println("namespace binpac {\n"); out_h->println("namespace binpac {\n");
out_cc->println("namespace binpac {\n"); out_cc->println("namespace binpac {\n");
AnalyzerContextDecl *analyzer_context = AnalyzerContextDecl* analyzer_context = AnalyzerContextDecl::current_analyzer_context();
AnalyzerContextDecl::current_analyzer_context();
foreach(i, DeclList, decl_list_) foreach (i, DeclList, decl_list_)
{ {
Decl *decl = *i; Decl* decl = *i;
current_decl_id = decl->id(); current_decl_id = decl->id();
decl->GenForwardDeclaration(out_h); decl->GenForwardDeclaration(out_h);
} }
@ -102,9 +98,9 @@ void Decl::ProcessDecls(Output *out_h, Output *out_cc)
out_h->println(""); out_h->println("");
foreach(i, DeclList, decl_list_) foreach (i, DeclList, decl_list_)
{ {
Decl *decl = *i; Decl* decl = *i;
current_decl_id = decl->id(); current_decl_id = decl->id();
decl->GenCode(out_h, out_cc); decl->GenCode(out_h, out_cc);
} }
@ -129,13 +125,9 @@ Decl* Decl::LookUpDecl(const ID* id)
int HelperDecl::helper_id_seq = 0; int HelperDecl::helper_id_seq = 0;
HelperDecl::HelperDecl(HelperType helper_type, HelperDecl::HelperDecl(HelperType helper_type, ID* context_id, EmbeddedCode* code)
ID* context_id, : Decl(new ID(strfmt("helper_%d", ++helper_id_seq)), HELPER), helper_type_(helper_type),
EmbeddedCode* code) context_id_(context_id), code_(code)
: Decl(new ID(strfmt("helper_%d", ++helper_id_seq)), HELPER),
helper_type_(helper_type),
context_id_(context_id),
code_(code)
{ {
} }
@ -150,15 +142,15 @@ void HelperDecl::Prepare()
// Do nothing // Do nothing
} }
void HelperDecl::GenExternDeclaration(Output *out_h) void HelperDecl::GenExternDeclaration(Output* out_h)
{ {
if ( helper_type_ == EXTERN ) if ( helper_type_ == EXTERN )
code_->GenCode(out_h, global_env()); code_->GenCode(out_h, global_env());
} }
void HelperDecl::GenCode(Output *out_h, Output *out_cc) void HelperDecl::GenCode(Output* out_h, Output* out_cc)
{ {
Env *env = global_env(); Env* env = global_env();
#if 0 #if 0
if ( context_id_ ) if ( context_id_ )

View file

@ -5,75 +5,92 @@
#include "pac_id.h" #include "pac_id.h"
class Decl : public Object class Decl : public Object
{ {
public: public:
// Note: ANALYZER is not for AnalyzerDecl (which is an // Note: ANALYZER is not for AnalyzerDecl (which is an
// abstract class) , but for AnalyzerContextDecl. // abstract class) , but for AnalyzerContextDecl.
enum DeclType { ENUM, LET, TYPE, FUNC, CONN, FLOW, ANALYZER, HELPER, REGEX }; enum DeclType
{
ENUM,
LET,
TYPE,
FUNC,
CONN,
FLOW,
ANALYZER,
HELPER,
REGEX
};
Decl(ID *id, DeclType decl_type); Decl(ID* id, DeclType decl_type);
virtual ~Decl(); virtual ~Decl();
const ID *id() const { return id_; } const ID* id() const { return id_; }
DeclType decl_type() const { return decl_type_; } DeclType decl_type() const { return decl_type_; }
AnalyzerContextDecl *analyzer_context() const AnalyzerContextDecl* analyzer_context() const { return analyzer_context_; }
{ return analyzer_context_; }
// NULL except for TypeDecl or AnalyzerDecl // NULL except for TypeDecl or AnalyzerDecl
virtual Env *env() const { return 0; } virtual Env* env() const { return 0; }
virtual void Prepare() = 0; virtual void Prepare() = 0;
// Generate declarations out of the "binpac" namespace // Generate declarations out of the "binpac" namespace
virtual void GenExternDeclaration(Output *out_h) { /* do nothing */ } virtual void GenExternDeclaration(Output* out_h)
{ /* do nothing */
}
// Generate declarations before definition of classes // Generate declarations before definition of classes
virtual void GenForwardDeclaration(Output *out_h) = 0; virtual void GenForwardDeclaration(Output* out_h) = 0;
virtual void GenCode(Output *out_h, Output *out_cc) = 0; virtual void GenCode(Output* out_h, Output* out_cc) = 0;
void TakeExprList(); void TakeExprList();
void AddAttrs(AttrList *attrlist); void AddAttrs(AttrList* attrlist);
void SetAnalyzerContext(); void SetAnalyzerContext();
protected: protected:
virtual void ProcessAttr(Attr *a); virtual void ProcessAttr(Attr* a);
ID *id_; ID* id_;
DeclType decl_type_; DeclType decl_type_;
AttrList *attrlist_; AttrList* attrlist_;
AnalyzerContextDecl *analyzer_context_; AnalyzerContextDecl* analyzer_context_;
public: public:
static void ProcessDecls(Output *out_h, Output *out_cc); static void ProcessDecls(Output* out_h, Output* out_cc);
static Decl *LookUpDecl(const ID *id); static Decl* LookUpDecl(const ID* id);
private: private:
static DeclList *decl_list_; static DeclList* decl_list_;
typedef map<const ID *, Decl*, ID_ptr_cmp> DeclMap; typedef map<const ID*, Decl*, ID_ptr_cmp> DeclMap;
static DeclMap decl_map_; static DeclMap decl_map_;
}; };
class HelperDecl : public Decl class HelperDecl : public Decl
{ {
public: public:
enum HelperType { enum HelperType
HEADER, CODE, EXTERN, {
HEADER,
CODE,
EXTERN,
}; };
HelperDecl(HelperType type, ID *context_id, EmbeddedCode *code); HelperDecl(HelperType type, ID* context_id, EmbeddedCode* code);
~HelperDecl(); ~HelperDecl();
void Prepare(); void Prepare();
void GenExternDeclaration(Output *out_h); void GenExternDeclaration(Output* out_h);
void GenForwardDeclaration(Output *out_h) { /* do nothing */ } void GenForwardDeclaration(Output* out_h)
void GenCode(Output *out_h, Output *out_cc); { /* do nothing */
}
void GenCode(Output* out_h, Output* out_cc);
private: private:
HelperType helper_type_; HelperType helper_type_;
ID *context_id_; ID* context_id_;
EmbeddedCode *code_; EmbeddedCode* code_;
static int helper_id_seq; static int helper_id_seq;
}; };
#endif // pac_decl_h #endif // pac_decl_h

View file

@ -1,25 +1,20 @@
#include "pac_id.h"
#include "pac_primitive.h"
#include "pac_output.h"
#include "pac_embedded.h" #include "pac_embedded.h"
EmbeddedCodeSegment::EmbeddedCodeSegment(const string &s) #include "pac_id.h"
: s_(s), primitive_(0) #include "pac_output.h"
{ #include "pac_primitive.h"
}
EmbeddedCodeSegment::EmbeddedCodeSegment(PacPrimitive *primitive) EmbeddedCodeSegment::EmbeddedCodeSegment(const string& s) : s_(s), primitive_(0) { }
: s_(""), primitive_(primitive)
{ EmbeddedCodeSegment::EmbeddedCodeSegment(PacPrimitive* primitive)
} : s_(""), primitive_(primitive) { }
EmbeddedCodeSegment::~EmbeddedCodeSegment() EmbeddedCodeSegment::~EmbeddedCodeSegment()
{ {
delete primitive_; delete primitive_;
} }
string EmbeddedCodeSegment::ToCode(Env *env) string EmbeddedCodeSegment::ToCode(Env* env)
{ {
if ( primitive_ && s_.empty() ) if ( primitive_ && s_.empty() )
s_ = primitive_->ToCode(env); s_ = primitive_->ToCode(env);
@ -41,12 +36,12 @@ void EmbeddedCode::Append(int atom)
current_segment_ += static_cast<char>(atom); current_segment_ += static_cast<char>(atom);
} }
void EmbeddedCode::Append(const char *str) void EmbeddedCode::Append(const char* str)
{ {
current_segment_ += str; current_segment_ += str;
} }
void EmbeddedCode::Append(PacPrimitive *primitive) void EmbeddedCode::Append(PacPrimitive* primitive)
{ {
if ( ! current_segment_.empty() ) if ( ! current_segment_.empty() )
{ {
@ -56,7 +51,7 @@ void EmbeddedCode::Append(PacPrimitive *primitive)
segments_->push_back(new EmbeddedCodeSegment(primitive)); segments_->push_back(new EmbeddedCodeSegment(primitive));
} }
void EmbeddedCode::GenCode(Output *out, Env *env) void EmbeddedCode::GenCode(Output* out, Env* env)
{ {
if ( ! current_segment_.empty() ) if ( ! current_segment_.empty() )
{ {
@ -71,9 +66,9 @@ void EmbeddedCode::GenCode(Output *out, Env *env)
// ID's name is used as its RValue // ID's name is used as its RValue
env->set_allow_undefined_id(true); env->set_allow_undefined_id(true);
foreach(i, EmbeddedCodeSegmentList, segments_) foreach (i, EmbeddedCodeSegmentList, segments_)
{ {
EmbeddedCodeSegment *segment = *i; EmbeddedCodeSegment* segment = *i;
out->print("%s", segment->ToCode(env).c_str()); out->print("%s", segment->ToCode(env).c_str());
} }

View file

@ -4,39 +4,39 @@
#include "pac_common.h" #include "pac_common.h"
class EmbeddedCodeSegment class EmbeddedCodeSegment
{ {
public: public:
explicit EmbeddedCodeSegment(const string &s); explicit EmbeddedCodeSegment(const string& s);
explicit EmbeddedCodeSegment(PacPrimitive *primitive); explicit EmbeddedCodeSegment(PacPrimitive* primitive);
~EmbeddedCodeSegment(); ~EmbeddedCodeSegment();
string ToCode(Env *env); string ToCode(Env* env);
private: private:
string s_; string s_;
PacPrimitive *primitive_; PacPrimitive* primitive_;
}; };
typedef vector<EmbeddedCodeSegment *> EmbeddedCodeSegmentList; typedef vector<EmbeddedCodeSegment*> EmbeddedCodeSegmentList;
class EmbeddedCode : public Object class EmbeddedCode : public Object
{ {
public: public:
EmbeddedCode(); EmbeddedCode();
~EmbeddedCode(); ~EmbeddedCode();
// Append a character // Append a character
void Append(int atom); void Append(int atom);
void Append(const char *str); void Append(const char* str);
// Append a PAC primitive // Append a PAC primitive
void Append(PacPrimitive *primitive); void Append(PacPrimitive* primitive);
void GenCode(Output *out, Env *env); void GenCode(Output* out, Env* env);
private: private:
string current_segment_; string current_segment_;
EmbeddedCodeSegmentList *segments_; EmbeddedCodeSegmentList* segments_;
}; };
#endif // pac_embedded_h #endif // pac_embedded_h

View file

@ -1,14 +1,12 @@
#include "pac_exception.h"
#include "pac_enum.h" #include "pac_enum.h"
#include "pac_exception.h"
#include "pac_expr.h" #include "pac_expr.h"
#include "pac_exttype.h" #include "pac_exttype.h"
#include "pac_output.h" #include "pac_output.h"
#include "pac_typedecl.h" #include "pac_typedecl.h"
Enum::Enum(ID* id, Expr* expr) Enum::Enum(ID* id, Expr* expr) : id_(id), expr_(expr) { }
: id_(id), expr_(expr)
{
}
Enum::~Enum() Enum::~Enum()
{ {
@ -16,7 +14,7 @@ Enum::~Enum()
delete expr_; delete expr_;
} }
void Enum::GenHeader(Output* out_h, int *pval) void Enum::GenHeader(Output* out_h, int* pval)
{ {
ASSERT(pval); ASSERT(pval);
if ( expr_ ) if ( expr_ )
@ -30,10 +28,9 @@ void Enum::GenHeader(Output* out_h, int *pval)
global_env()->AddConstID(id_, *pval); global_env()->AddConstID(id_, *pval);
} }
EnumDecl::EnumDecl(ID *id, EnumList *enumlist) EnumDecl::EnumDecl(ID* id, EnumList* enumlist) : Decl(id, ENUM), enumlist_(enumlist)
: Decl(id, ENUM), enumlist_(enumlist)
{ {
ID *type_id = id->clone(); ID* type_id = id->clone();
datatype_ = new ExternType(type_id, ExternType::NUMBER); datatype_ = new ExternType(type_id, ExternType::NUMBER);
extern_typedecl_ = new TypeDecl(type_id, 0, datatype_); extern_typedecl_ = new TypeDecl(type_id, 0, datatype_);
} }
@ -49,12 +46,12 @@ void EnumDecl::Prepare()
// Do nothing // Do nothing
} }
void EnumDecl::GenForwardDeclaration(Output *out_h) void EnumDecl::GenForwardDeclaration(Output* out_h)
{ {
out_h->println("enum %s {", id_->Name()); out_h->println("enum %s {", id_->Name());
out_h->inc_indent(); out_h->inc_indent();
int c = 0; int c = 0;
foreach(i, EnumList, enumlist_) foreach (i, EnumList, enumlist_)
{ {
(*i)->GenHeader(out_h, &c); (*i)->GenHeader(out_h, &c);
++c; ++c;
@ -67,4 +64,3 @@ void EnumDecl::GenCode(Output* out_h, Output* /* out_cc */)
{ {
// Do nothing // Do nothing
} }

View file

@ -4,34 +4,34 @@
#include "pac_decl.h" #include "pac_decl.h"
class Enum class Enum
{ {
public: public:
Enum(ID *id, Expr *expr = 0); Enum(ID* id, Expr* expr = 0);
~Enum(); ~Enum();
void GenHeader(Output *out_h, int *pval); void GenHeader(Output* out_h, int* pval);
private: private:
ID *id_; ID* id_;
Expr *expr_; Expr* expr_;
}; };
class EnumDecl : public Decl class EnumDecl : public Decl
{ {
public: public:
EnumDecl(ID *id, EnumList *enumlist); EnumDecl(ID* id, EnumList* enumlist);
~EnumDecl(); ~EnumDecl();
Type *DataType() const { return datatype_; } Type* DataType() const { return datatype_; }
void Prepare(); void Prepare();
void GenForwardDeclaration(Output *out_h); void GenForwardDeclaration(Output* out_h);
void GenCode(Output *out_h, Output *out_cc); void GenCode(Output* out_h, Output* out_cc);
private: private:
EnumList *enumlist_; EnumList* enumlist_;
Type *datatype_; Type* datatype_;
TypeDecl *extern_typedecl_; TypeDecl* extern_typedecl_;
}; };
#endif // pac_enum_h #endif // pac_enum_h

View file

@ -1,4 +1,5 @@
#include "pac_exception.h" #include "pac_exception.h"
#include "pac_expr.h" #include "pac_expr.h"
#include "pac_id.h" #include "pac_id.h"
#include "pac_utils.h" #include "pac_utils.h"
@ -20,52 +21,43 @@ Exception::Exception(const Object* o, string msg)
} }
} }
ExceptionIDNotFound::ExceptionIDNotFound(const ID* id) ExceptionIDNotFound::ExceptionIDNotFound(const ID* id) : Exception(id), id_(id)
: Exception(id), id_(id)
{ {
append(strfmt("`%s' undeclared", id_->Name())); append(strfmt("`%s' undeclared", id_->Name()));
} }
ExceptionIDRedefinition::ExceptionIDRedefinition(const ID* id) ExceptionIDRedefinition::ExceptionIDRedefinition(const ID* id) : Exception(id), id_(id)
: Exception(id), id_(id)
{ {
append(strfmt("`%s' redefined", id_->Name())); append(strfmt("`%s' redefined", id_->Name()));
} }
ExceptionIDNotEvaluated::ExceptionIDNotEvaluated(const ID* id) ExceptionIDNotEvaluated::ExceptionIDNotEvaluated(const ID* id) : Exception(id), id_(id)
: Exception(id), id_(id)
{ {
append(strfmt("ID `%s' not evaluated before used", id->Name())); append(strfmt("ID `%s' not evaluated before used", id->Name()));
} }
ExceptionIDNotField::ExceptionIDNotField(const ID* id) ExceptionIDNotField::ExceptionIDNotField(const ID* id) : Exception(id), id_(id)
: Exception(id), id_(id)
{ {
append(strfmt("ID `%s' is not a field", id_->Name())); append(strfmt("ID `%s' is not a field", id_->Name()));
} }
ExceptionMemberNotFound::ExceptionMemberNotFound(const ID* type_id, ExceptionMemberNotFound::ExceptionMemberNotFound(const ID* type_id, const ID* member_id)
const ID *member_id)
: Exception(member_id), type_id_(type_id), member_id_(member_id) : Exception(member_id), type_id_(type_id), member_id_(member_id)
{ {
append(strfmt("type %s does not have member `%s'", append(strfmt("type %s does not have member `%s'", type_id_->Name(), member_id_->Name()));
type_id_->Name(), member_id_->Name()));
} }
ExceptionCyclicDependence::ExceptionCyclicDependence(const ID* id) ExceptionCyclicDependence::ExceptionCyclicDependence(const ID* id) : Exception(id), id_(id)
: Exception(id), id_(id)
{ {
append(strfmt("cyclic dependence through `%s'", id_->Name())); append(strfmt("cyclic dependence through `%s'", id_->Name()));
} }
ExceptionPaddingError::ExceptionPaddingError(const Object* o, string msg) ExceptionPaddingError::ExceptionPaddingError(const Object* o, string msg) : Exception(o)
: Exception(o)
{ {
append(msg.c_str()); append(msg.c_str());
} }
ExceptionNonConstExpr::ExceptionNonConstExpr(const Expr* expr) ExceptionNonConstExpr::ExceptionNonConstExpr(const Expr* expr) : Exception(expr), expr(expr)
: Exception(expr), expr(expr)
{ {
append(strfmt("Expression `%s' is not constant", expr->orig())); append(strfmt("Expression `%s' is not constant", expr->orig()));
} }
@ -73,11 +65,14 @@ ExceptionNonConstExpr::ExceptionNonConstExpr(const Expr* expr)
ExceptionInvalidCaseSizeExpr::ExceptionInvalidCaseSizeExpr(const Expr* expr) ExceptionInvalidCaseSizeExpr::ExceptionInvalidCaseSizeExpr(const Expr* expr)
: Exception(expr), expr(expr) : Exception(expr), expr(expr)
{ {
append(strfmt("Expression `%s' is greater than the 32-bit limit for use as a case index", expr->orig())); append(strfmt("Expression `%s' is greater than the 32-bit limit for use as a case index",
expr->orig()));
} }
ExceptionInvalidCaseLimitExpr::ExceptionInvalidCaseLimitExpr(const Expr* expr) ExceptionInvalidCaseLimitExpr::ExceptionInvalidCaseLimitExpr(const Expr* expr)
: Exception(expr), expr(expr) : Exception(expr), expr(expr)
{ {
append(strfmt("Expression `%s' as a case index is outside the numeric limit of the type used for the switch expression", expr->orig())); append(strfmt("Expression `%s' as a case index is outside the numeric limit of the type used "
"for the switch expression",
expr->orig()));
} }

View file

@ -7,7 +7,7 @@ using namespace std;
#include "pac_common.h" #include "pac_common.h"
class Exception class Exception
{ {
public: public:
Exception(const Object* o, string msg = ""); Exception(const Object* o, string msg = "");
@ -16,98 +16,98 @@ public:
private: private:
string msg_; string msg_;
}; };
class ExceptionIDNotFound : public Exception class ExceptionIDNotFound : public Exception
{ {
public: public:
ExceptionIDNotFound(const ID* id); ExceptionIDNotFound(const ID* id);
const ID* id() const { return id_; } const ID* id() const { return id_; }
private: private:
const ID* id_; const ID* id_;
}; };
class ExceptionIDRedefinition : public Exception class ExceptionIDRedefinition : public Exception
{ {
public: public:
ExceptionIDRedefinition(const ID* id); ExceptionIDRedefinition(const ID* id);
const ID* id() const { return id_; } const ID* id() const { return id_; }
private: private:
const ID* id_; const ID* id_;
}; };
class ExceptionIDNotEvaluated : public Exception class ExceptionIDNotEvaluated : public Exception
{ {
public: public:
ExceptionIDNotEvaluated(const ID* id); ExceptionIDNotEvaluated(const ID* id);
const ID* id() const { return id_; } const ID* id() const { return id_; }
private: private:
const ID* id_; const ID* id_;
}; };
class ExceptionCyclicDependence : public Exception class ExceptionCyclicDependence : public Exception
{ {
public: public:
ExceptionCyclicDependence(const ID* id); ExceptionCyclicDependence(const ID* id);
const ID* id() const { return id_; } const ID* id() const { return id_; }
private: private:
const ID* id_; const ID* id_;
}; };
class ExceptionPaddingError : public Exception class ExceptionPaddingError : public Exception
{ {
public: public:
ExceptionPaddingError(const Object* o, string msg); ExceptionPaddingError(const Object* o, string msg);
}; };
class ExceptionIDNotField : public Exception class ExceptionIDNotField : public Exception
{ {
public: public:
ExceptionIDNotField(const ID* id); ExceptionIDNotField(const ID* id);
const ID* id() const { return id_; } const ID* id() const { return id_; }
private: private:
const ID* id_; const ID* id_;
}; };
class ExceptionMemberNotFound : public Exception class ExceptionMemberNotFound : public Exception
{ {
public: public:
ExceptionMemberNotFound(const ID* type_id, const ID *member_id); ExceptionMemberNotFound(const ID* type_id, const ID* member_id);
private: private:
const ID *type_id_, *member_id_; const ID *type_id_, *member_id_;
}; };
class ExceptionNonConstExpr : public Exception class ExceptionNonConstExpr : public Exception
{ {
public: public:
ExceptionNonConstExpr(const Expr* expr); ExceptionNonConstExpr(const Expr* expr);
private: private:
const Expr *expr; const Expr* expr;
}; };
class ExceptionInvalidCaseSizeExpr : public Exception class ExceptionInvalidCaseSizeExpr : public Exception
{ {
public: public:
ExceptionInvalidCaseSizeExpr(const Expr* expr); ExceptionInvalidCaseSizeExpr(const Expr* expr);
private: private:
const Expr *expr; const Expr* expr;
}; };
class ExceptionInvalidCaseLimitExpr : public Exception class ExceptionInvalidCaseLimitExpr : public Exception
{ {
public: public:
ExceptionInvalidCaseLimitExpr(const Expr* expr); ExceptionInvalidCaseLimitExpr(const Expr* expr);
private: private:
const Expr *expr; const Expr* expr;
}; };
#endif /* pac_exception_h */ #endif /* pac_exception_h */

View file

@ -1,7 +1,8 @@
#include "pac_expr.h"
#include "pac_case.h" #include "pac_case.h"
#include "pac_cstr.h" #include "pac_cstr.h"
#include "pac_exception.h" #include "pac_exception.h"
#include "pac_expr.h"
#include "pac_exttype.h" #include "pac_exttype.h"
#include "pac_id.h" #include "pac_id.h"
#include "pac_number.h" #include "pac_number.h"
@ -12,13 +13,13 @@
#include "pac_typedecl.h" #include "pac_typedecl.h"
#include "pac_utils.h" #include "pac_utils.h"
string OrigExprList(ExprList *list) string OrigExprList(ExprList* list)
{ {
bool first = true; bool first = true;
string str; string str;
foreach(i, ExprList, list) foreach (i, ExprList, list)
{ {
Expr *expr = *i; Expr* expr = *i;
if ( first ) if ( first )
first = false; first = false;
else else
@ -28,12 +29,12 @@ string OrigExprList(ExprList *list)
return str; return str;
} }
string EvalExprList(ExprList *exprlist, Output *out, Env *env) string EvalExprList(ExprList* exprlist, Output* out, Env* env)
{ {
string val_list(""); string val_list("");
bool first = true; bool first = true;
foreach(i, ExprList, exprlist) foreach (i, ExprList, exprlist)
{ {
if ( ! first ) if ( ! first )
val_list += ", "; val_list += ", ";
@ -44,11 +45,10 @@ string EvalExprList(ExprList *exprlist, Output *out, Env *env)
return val_list; return val_list;
} }
static const char* expr_fmt[] = static const char* expr_fmt[] = {
{ #define EXPR_DEF(type, num_op, fmt) fmt,
# define EXPR_DEF(type, num_op, fmt) fmt, #include "pac_expr.def"
# include "pac_expr.def" #undef EXPR_DEF
# undef EXPR_DEF
}; };
void Expr::init() void Expr::init()
@ -65,8 +65,7 @@ void Expr::init()
cases_ = 0; cases_ = 0;
} }
Expr::Expr(ID* arg_id) Expr::Expr(ID* arg_id) : DataDepElement(EXPR)
: DataDepElement(EXPR)
{ {
init(); init();
expr_type_ = EXPR_ID; expr_type_ = EXPR_ID;
@ -75,8 +74,7 @@ Expr::Expr(ID* arg_id)
orig_ = strfmt("%s", id_->Name()); orig_ = strfmt("%s", id_->Name());
} }
Expr::Expr(Number* arg_num) Expr::Expr(Number* arg_num) : DataDepElement(EXPR)
: DataDepElement(EXPR)
{ {
init(); init();
expr_type_ = EXPR_NUM; expr_type_ = EXPR_NUM;
@ -85,8 +83,7 @@ Expr::Expr(Number* arg_num)
orig_ = strfmt("((int) %s)", num_->Str()); orig_ = strfmt("((int) %s)", num_->Str());
} }
Expr::Expr(ConstString *cstr) Expr::Expr(ConstString* cstr) : DataDepElement(EXPR)
: DataDepElement(EXPR)
{ {
init(); init();
expr_type_ = EXPR_CSTR; expr_type_ = EXPR_CSTR;
@ -95,8 +92,7 @@ Expr::Expr(ConstString *cstr)
orig_ = cstr_->str(); orig_ = cstr_->str();
} }
Expr::Expr(RegEx *regex) Expr::Expr(RegEx* regex) : DataDepElement(EXPR)
: DataDepElement(EXPR)
{ {
init(); init();
expr_type_ = EXPR_REGEX; expr_type_ = EXPR_REGEX;
@ -105,8 +101,7 @@ Expr::Expr(RegEx *regex)
orig_ = strfmt("/%s/", regex_->str().c_str()); orig_ = strfmt("/%s/", regex_->str().c_str());
} }
Expr::Expr(ExprType arg_type, Expr* op1) Expr::Expr(ExprType arg_type, Expr* op1) : DataDepElement(EXPR)
: DataDepElement(EXPR)
{ {
init(); init();
expr_type_ = arg_type; expr_type_ = arg_type;
@ -115,8 +110,7 @@ Expr::Expr(ExprType arg_type, Expr* op1)
orig_ = strfmt(expr_fmt[expr_type_], op1->orig()); orig_ = strfmt(expr_fmt[expr_type_], op1->orig());
} }
Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2) Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2) : DataDepElement(EXPR)
: DataDepElement(EXPR)
{ {
init(); init();
expr_type_ = arg_type; expr_type_ = arg_type;
@ -127,8 +121,7 @@ Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2)
orig_ = strfmt(expr_fmt[expr_type_], op1->orig(), op2->orig()); orig_ = strfmt(expr_fmt[expr_type_], op1->orig(), op2->orig());
} }
Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2, Expr* op3) Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2, Expr* op3) : DataDepElement(EXPR)
: DataDepElement(EXPR)
{ {
init(); init();
expr_type_ = arg_type; expr_type_ = arg_type;
@ -139,8 +132,7 @@ Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2, Expr* op3)
orig_ = strfmt(expr_fmt[expr_type_], op1->orig(), op2->orig(), op3->orig()); orig_ = strfmt(expr_fmt[expr_type_], op1->orig(), op2->orig(), op3->orig());
} }
Expr::Expr(ExprList *args) Expr::Expr(ExprList* args) : DataDepElement(EXPR)
: DataDepElement(EXPR)
{ {
init(); init();
expr_type_ = EXPR_CALLARGS; expr_type_ = EXPR_CALLARGS;
@ -150,8 +142,7 @@ Expr::Expr(ExprList *args)
orig_ = OrigExprList(args_); orig_ = OrigExprList(args_);
} }
Expr::Expr(Expr *index, CaseExprList *cases) Expr::Expr(Expr* index, CaseExprList* cases) : DataDepElement(EXPR)
: DataDepElement(EXPR)
{ {
init(); init();
expr_type_ = EXPR_CASE; expr_type_ = EXPR_CASE;
@ -160,12 +151,10 @@ Expr::Expr(Expr *index, CaseExprList *cases)
cases_ = cases; cases_ = cases;
orig_ = strfmt("case %s of { ", index->orig()); orig_ = strfmt("case %s of { ", index->orig());
foreach(i, CaseExprList, cases_) foreach (i, CaseExprList, cases_)
{ {
CaseExpr *c = *i; CaseExpr* c = *i;
orig_ += strfmt("%s => %s; ", orig_ += strfmt("%s => %s; ", OrigExprList(c->index()).c_str(), c->value()->orig());
OrigExprList(c->index()).c_str(),
c->value()->orig());
} }
orig_ += "}"; orig_ += "}";
} }
@ -180,7 +169,7 @@ Expr::~Expr()
delete_list(CaseExprList, cases_); delete_list(CaseExprList, cases_);
} }
void Expr::AddCaseExpr(CaseExpr *case_expr) void Expr::AddCaseExpr(CaseExpr* case_expr)
{ {
ASSERT(str_.empty()); ASSERT(str_.empty());
ASSERT(expr_type_ == EXPR_CASE); ASSERT(expr_type_ == EXPR_CASE);
@ -188,7 +177,7 @@ void Expr::AddCaseExpr(CaseExpr *case_expr)
cases_->push_back(case_expr); cases_->push_back(case_expr);
} }
void Expr::GenStrFromFormat(Env *env) void Expr::GenStrFromFormat(Env* env)
{ {
// The format != "@custom@" // The format != "@custom@"
ASSERT(*expr_fmt[expr_type_] != '@'); ASSERT(*expr_fmt[expr_type_] != '@');
@ -196,18 +185,13 @@ void Expr::GenStrFromFormat(Env *env)
switch ( num_operands_ ) switch ( num_operands_ )
{ {
case 1: case 1:
str_ = strfmt(expr_fmt[expr_type_], str_ = strfmt(expr_fmt[expr_type_], operand_[0]->str());
operand_[0]->str());
break; break;
case 2: case 2:
str_ = strfmt(expr_fmt[expr_type_], str_ = strfmt(expr_fmt[expr_type_], operand_[0]->str(), operand_[1]->str());
operand_[0]->str(),
operand_[1]->str());
break; break;
case 3: case 3:
str_ = strfmt(expr_fmt[expr_type_], str_ = strfmt(expr_fmt[expr_type_], operand_[0]->str(), operand_[1]->str(),
operand_[0]->str(),
operand_[1]->str(),
operand_[2]->str()); operand_[2]->str());
break; break;
default: default:
@ -217,43 +201,41 @@ void Expr::GenStrFromFormat(Env *env)
} }
} }
namespace { namespace
{
RecordField *GetRecordField(const ID *id, Env *env) RecordField* GetRecordField(const ID* id, Env* env)
{ {
Field* field = env->GetField(id); Field* field = env->GetField(id);
ASSERT(field); ASSERT(field);
if ( field->tof() != RECORD_FIELD && if ( field->tof() != RECORD_FIELD && field->tof() != PADDING_FIELD )
field->tof() != PADDING_FIELD )
throw Exception(id, "not a record field"); throw Exception(id, "not a record field");
RecordField *r = static_cast<RecordField *>(field); RecordField* r = static_cast<RecordField*>(field);
ASSERT(r); ASSERT(r);
return r; return r;
} }
} // private namespace } // private namespace
void Expr::GenCaseEval(Output *out_cc, Env *env) void Expr::GenCaseEval(Output* out_cc, Env* env)
{ {
ASSERT(expr_type_ == EXPR_CASE); ASSERT(expr_type_ == EXPR_CASE);
ASSERT(operand_[0]); ASSERT(operand_[0]);
ASSERT(cases_); ASSERT(cases_);
Type *val_type = DataType(env); Type* val_type = DataType(env);
ID *val_var = env->AddTempID(val_type); ID* val_var = env->AddTempID(val_type);
// DataType(env) can return a null pointer if an enum value is not // DataType(env) can return a null pointer if an enum value is not
// defined. // defined.
if ( ! val_type ) if ( ! val_type )
throw Exception(this, "undefined case value"); throw Exception(this, "undefined case value");
out_cc->println("%s %s;", out_cc->println("%s %s;", val_type->DataTypeStr().c_str(), env->LValue(val_var));
val_type->DataTypeStr().c_str(),
env->LValue(val_var));
// force evaluation of IDs appearing in case stmt // force evaluation of IDs appearing in case stmt
operand_[0]->ForceIDEval(out_cc, env); operand_[0]->ForceIDEval(out_cc, env);
foreach(i, CaseExprList, cases_) foreach (i, CaseExprList, cases_)
(*i)->value()->ForceIDEval(out_cc, env); (*i)->value()->ForceIDEval(out_cc, env);
out_cc->println("switch ( %s )", operand_[0]->EvalExpr(out_cc, env)); out_cc->println("switch ( %s )", operand_[0]->EvalExpr(out_cc, env));
@ -262,11 +244,11 @@ void Expr::GenCaseEval(Output *out_cc, Env *env)
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
CaseExpr *default_case = 0; CaseExpr* default_case = 0;
foreach(i, CaseExprList, cases_) foreach (i, CaseExprList, cases_)
{ {
CaseExpr *c = *i; CaseExpr* c = *i;
ExprList *index = c->index(); ExprList* index = c->index();
if ( ! index ) if ( ! index )
{ {
if ( default_case ) if ( default_case )
@ -277,9 +259,7 @@ void Expr::GenCaseEval(Output *out_cc, Env *env)
{ {
GenCaseStr(index, out_cc, env, switch_type); GenCaseStr(index, out_cc, env, switch_type);
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("%s = %s;", out_cc->println("%s = %s;", env->LValue(val_var), c->value()->EvalExpr(out_cc, env));
env->LValue(val_var),
c->value()->EvalExpr(out_cc, env));
out_cc->println("break;"); out_cc->println("break;");
out_cc->dec_indent(); out_cc->dec_indent();
} }
@ -290,14 +270,13 @@ void Expr::GenCaseEval(Output *out_cc, Env *env)
out_cc->inc_indent(); out_cc->inc_indent();
if ( default_case ) if ( default_case )
{ {
out_cc->println("%s = %s;", out_cc->println("%s = %s;", env->LValue(val_var),
env->LValue(val_var),
default_case->value()->EvalExpr(out_cc, env)); default_case->value()->EvalExpr(out_cc, env));
} }
else else
{ {
out_cc->println("throw binpac::ExceptionInvalidCaseIndex(\"%s\", (int64)%s);", out_cc->println("throw binpac::ExceptionInvalidCaseIndex(\"%s\", (int64)%s);", Location(),
Location(), operand_[0]->EvalExpr(out_cc, env)); operand_[0]->EvalExpr(out_cc, env));
} }
out_cc->println("break;"); out_cc->println("break;");
out_cc->dec_indent(); out_cc->dec_indent();
@ -333,20 +312,17 @@ void Expr::GenEval(Output* out_cc, Env* env)
*/ */
operand_[0]->GenEval(out_cc, env); operand_[0]->GenEval(out_cc, env);
Type *ty0 = operand_[0]->DataType(env); Type* ty0 = operand_[0]->DataType(env);
if ( ty0 ) if ( ty0 )
{ {
str_ = strfmt("%s%s", str_ = strfmt("%s%s", operand_[0]->EvalExpr(out_cc, env),
operand_[0]->EvalExpr(out_cc, env),
ty0->EvalMember(operand_[1]->id()).c_str()); ty0->EvalMember(operand_[1]->id()).c_str());
} }
else else
{ {
string tmp = strfmt("->%s()", operand_[1]->id()->Name()); string tmp = strfmt("->%s()", operand_[1]->id()->Name());
str_ = strfmt("%s%s", str_ = strfmt("%s%s", operand_[0]->EvalExpr(out_cc, env), tmp.c_str());
operand_[0]->EvalExpr(out_cc, env),
tmp.c_str());
} }
} }
break; break;
@ -359,7 +335,7 @@ void Expr::GenEval(Output* out_cc, Env* env)
string v0 = operand_[0]->EvalExpr(out_cc, env); string v0 = operand_[0]->EvalExpr(out_cc, env);
string v1 = operand_[1]->EvalExpr(out_cc, env); string v1 = operand_[1]->EvalExpr(out_cc, env);
Type *ty0 = operand_[0]->DataType(env); Type* ty0 = operand_[0]->DataType(env);
if ( ty0 ) if ( ty0 )
str_ = ty0->EvalElement(v0, v1); str_ = ty0->EvalElement(v0, v1);
else else
@ -369,9 +345,9 @@ void Expr::GenEval(Output* out_cc, Env* env)
case EXPR_SIZEOF: case EXPR_SIZEOF:
{ {
const ID *id = operand_[0]->id(); const ID* id = operand_[0]->id();
RecordField *rf; RecordField* rf;
Type *ty; Type* ty;
try try
{ {
@ -380,7 +356,7 @@ void Expr::GenEval(Output* out_cc, Env* env)
str_ = strfmt("%s", rf->FieldSize(out_cc, env)); str_ = strfmt("%s", rf->FieldSize(out_cc, env));
} }
} }
catch ( ExceptionIDNotFound &e ) catch ( ExceptionIDNotFound& e )
{ {
if ( (ty = TypeDecl::LookUpType(id)) != 0 ) if ( (ty = TypeDecl::LookUpType(id)) != 0 )
{ {
@ -398,8 +374,8 @@ void Expr::GenEval(Output* out_cc, Env* env)
case EXPR_OFFSETOF: case EXPR_OFFSETOF:
{ {
const ID *id = operand_[0]->id(); const ID* id = operand_[0]->id();
RecordField *rf = GetRecordField(id, env); RecordField* rf = GetRecordField(id, env);
str_ = strfmt("%s", rf->FieldOffset(out_cc, env)); str_ = strfmt("%s", rf->FieldOffset(out_cc, env));
} }
break; break;
@ -442,7 +418,7 @@ void Expr::ForceIDEval(Output* out_cc, Env* env)
case EXPR_CALLARGS: case EXPR_CALLARGS:
{ {
foreach(i, ExprList, args_) foreach (i, ExprList, args_)
(*i)->ForceIDEval(out_cc, env); (*i)->ForceIDEval(out_cc, env);
} }
break; break;
@ -450,7 +426,7 @@ void Expr::ForceIDEval(Output* out_cc, Env* env)
case EXPR_CASE: case EXPR_CASE:
{ {
operand_[0]->ForceIDEval(out_cc, env); operand_[0]->ForceIDEval(out_cc, env);
foreach(i, CaseExprList, cases_) foreach (i, CaseExprList, cases_)
(*i)->value()->ForceIDEval(out_cc, env); (*i)->value()->ForceIDEval(out_cc, env);
} }
break; break;
@ -464,16 +440,15 @@ void Expr::ForceIDEval(Output* out_cc, Env* env)
} }
} }
const char* Expr::EvalExpr(Output* out_cc, Env* env) const char* Expr::EvalExpr(Output* out_cc, Env* env)
{ {
GenEval(out_cc, env); GenEval(out_cc, env);
return str(); return str();
} }
Type *Expr::DataType(Env *env) const Type* Expr::DataType(Env* env) const
{ {
Type *data_type; Type* data_type;
switch ( expr_type_ ) switch ( expr_type_ )
{ {
@ -484,7 +459,7 @@ Type *Expr::DataType(Env *env) const
case EXPR_MEMBER: case EXPR_MEMBER:
{ {
// Get type of the parent // Get type of the parent
Type *parent_type = operand_[0]->DataType(env); Type* parent_type = operand_[0]->DataType(env);
if ( ! parent_type ) if ( ! parent_type )
return 0; return 0;
data_type = parent_type->MemberDataType(operand_[1]->id()); data_type = parent_type->MemberDataType(operand_[1]->id());
@ -494,7 +469,7 @@ Type *Expr::DataType(Env *env) const
case EXPR_SUBSCRIPT: case EXPR_SUBSCRIPT:
{ {
// Get type of the parent // Get type of the parent
Type *parent_type = operand_[0]->DataType(env); Type* parent_type = operand_[0]->DataType(env);
data_type = parent_type->ElementDataType(); data_type = parent_type->ElementDataType();
} }
break; break;
@ -505,13 +480,12 @@ Type *Expr::DataType(Env *env) const
case EXPR_COND: case EXPR_COND:
{ {
Type *type1 = operand_[1]->DataType(env); Type* type1 = operand_[1]->DataType(env);
Type *type2 = operand_[2]->DataType(env); Type* type2 = operand_[2]->DataType(env);
if ( ! Type::CompatibleTypes(type1, type2) ) if ( ! Type::CompatibleTypes(type1, type2) )
{ {
throw Exception(this, throw Exception(this,
strfmt("type mismatch: %s vs %s", strfmt("type mismatch: %s vs %s", type1->DataTypeStr().c_str(),
type1->DataTypeStr().c_str(),
type2->DataTypeStr().c_str())); type2->DataTypeStr().c_str()));
} }
data_type = type1; data_type = type1;
@ -526,18 +500,15 @@ Type *Expr::DataType(Env *env) const
{ {
if ( cases_ && ! cases_->empty() ) if ( cases_ && ! cases_->empty() )
{ {
Type *type1 = Type* type1 = cases_->front()->value()->DataType(env);
cases_->front()->value()->DataType(env);
Type* numeric_with_largest_width = 0; Type* numeric_with_largest_width = 0;
foreach(i, CaseExprList, cases_) foreach (i, CaseExprList, cases_)
{ {
Type *type2 = Type* type2 = (*i)->value()->DataType(env);
(*i)->value()->DataType(env);
if ( ! Type::CompatibleTypes(type1, type2) ) if ( ! Type::CompatibleTypes(type1, type2) )
{ {
throw Exception(this, throw Exception(this, strfmt("type mismatch: %s vs %s",
strfmt("type mismatch: %s vs %s",
type1->DataTypeStr().c_str(), type1->DataTypeStr().c_str(),
type2->DataTypeStr().c_str())); type2->DataTypeStr().c_str()));
} }
@ -611,21 +582,19 @@ Type *Expr::DataType(Env *env) const
return data_type; return data_type;
} }
string Expr::DataTypeStr(Env *env) const string Expr::DataTypeStr(Env* env) const
{ {
Type *type = DataType(env); Type* type = DataType(env);
if ( ! type ) if ( ! type )
{ {
throw Exception(this, throw Exception(this, strfmt("cannot find data type for expression `%s'", orig()));
strfmt("cannot find data type for expression `%s'",
orig()));
} }
return type->DataTypeStr(); return type->DataTypeStr();
} }
string Expr::SetFunc(Output *out, Env *env) string Expr::SetFunc(Output* out, Env* env)
{ {
switch ( expr_type_ ) switch ( expr_type_ )
{ {
@ -635,15 +604,13 @@ string Expr::SetFunc(Output *out, Env *env)
{ {
// Evaluate the parent // Evaluate the parent
string parent_val(operand_[0]->EvalExpr(out, env)); string parent_val(operand_[0]->EvalExpr(out, env));
return parent_val return parent_val + "->" + set_function(operand_[1]->id());
+ "->"
+ set_function(operand_[1]->id());
} }
break; break;
default: default:
throw Exception(this, throw Exception(this, strfmt("cannot generate set function "
strfmt("cannot generate set function " "for expression `%s'",
"for expression `%s'", orig())); orig()));
break; break;
} }
} }
@ -664,10 +631,11 @@ bool Expr::ConstFold(Env* env, int* pn) const
} }
// TODO: build a generic data dependency extraction process // TODO: build a generic data dependency extraction process
namespace { namespace
{
// Maximum of two minimal header sizes // Maximum of two minimal header sizes
int mhs_max(int h1, int h2) int mhs_max(int h1, int h2)
{ {
if ( h1 < 0 || h2 < 0 ) if ( h1 < 0 || h2 < 0 )
return -1; return -1;
@ -678,13 +646,13 @@ namespace {
} }
} }
// MHS required to evaluate the field // MHS required to evaluate the field
int mhs_letfield(Env* env, LetField* field) int mhs_letfield(Env* env, LetField* field)
{ {
return field->expr()->MinimalHeaderSize(env); return field->expr()->MinimalHeaderSize(env);
} }
int mhs_recordfield(Env* env, RecordField* field) int mhs_recordfield(Env* env, RecordField* field)
{ {
int offset = field->static_offset(); int offset = field->static_offset();
if ( offset < 0 ) // offset cannot be statically determined if ( offset < 0 ) // offset cannot be statically determined
@ -695,7 +663,7 @@ namespace {
return offset + size; return offset + size;
} }
int mhs_casefield(Env* env, CaseField* field) int mhs_casefield(Env* env, CaseField* field)
{ {
// TODO: deal with the index // TODO: deal with the index
int size = field->StaticSize(env); int size = field->StaticSize(env);
@ -704,15 +672,14 @@ namespace {
return size; return size;
} }
int mhs_field(Env* env, Field* field) int mhs_field(Env* env, Field* field)
{ {
int mhs = -1; int mhs = -1;
switch ( field->tof() ) switch ( field->tof() )
{ {
case LET_FIELD: case LET_FIELD:
{ {
LetField *f = LetField* f = static_cast<LetField*>(field);
static_cast<LetField *>(field);
ASSERT(f); ASSERT(f);
mhs = mhs_letfield(env, f); mhs = mhs_letfield(env, f);
} }
@ -730,8 +697,7 @@ namespace {
case RECORD_FIELD: case RECORD_FIELD:
case PADDING_FIELD: case PADDING_FIELD:
{ {
RecordField *f = RecordField* f = static_cast<RecordField*>(field);
static_cast<RecordField *>(field);
ASSERT(f); ASSERT(f);
mhs = mhs_recordfield(env, f); mhs = mhs_recordfield(env, f);
} }
@ -739,8 +705,7 @@ namespace {
case CASE_FIELD: case CASE_FIELD:
{ {
CaseField *f = CaseField* f = static_cast<CaseField*>(field);
static_cast<CaseField *>(field);
ASSERT(f); ASSERT(f);
mhs = mhs_casefield(env, f); mhs = mhs_casefield(env, f);
} }
@ -763,7 +728,7 @@ namespace {
return mhs; return mhs;
} }
int mhs_id(Env *env, const ID *id) int mhs_id(Env* env, const ID* id)
{ {
int mhs = -1; int mhs = -1;
switch ( env->GetIDType(id) ) switch ( env->GetIDType(id) )
@ -791,16 +756,16 @@ namespace {
break; break;
case MACRO: case MACRO:
{ {
Expr *e = env->GetMacro(id); Expr* e = env->GetMacro(id);
mhs = e->MinimalHeaderSize(env); mhs = e->MinimalHeaderSize(env);
} }
break; break;
} }
return mhs; return mhs;
} }
} }
int Expr::MinimalHeaderSize(Env *env) int Expr::MinimalHeaderSize(Env* env)
{ {
int mhs; int mhs;
@ -826,11 +791,10 @@ int Expr::MinimalHeaderSize(Env *env)
case EXPR_SUBSCRIPT: case EXPR_SUBSCRIPT:
{ {
int index; int index;
Type *array_type = operand_[0]->DataType(env); Type* array_type = operand_[0]->DataType(env);
Type *elem_type = array_type->ElementDataType(); Type* elem_type = array_type->ElementDataType();
int elem_size = elem_type->StaticSize(env); int elem_size = elem_type->StaticSize(env);
if ( elem_size >= 0 && if ( elem_size >= 0 && operand_[1]->ConstFold(env, &index) )
operand_[1]->ConstFold(env, &index) )
{ {
mhs = elem_size * index; mhs = elem_size * index;
} }
@ -845,8 +809,8 @@ int Expr::MinimalHeaderSize(Env *env)
{ {
const ID* id = operand_[0]->id(); const ID* id = operand_[0]->id();
ASSERT(id); ASSERT(id);
RecordField *rf; RecordField* rf;
Type *ty; Type* ty;
if ( (rf = GetRecordField(id, env)) != 0 ) if ( (rf = GetRecordField(id, env)) != 0 )
{ {
@ -870,7 +834,7 @@ int Expr::MinimalHeaderSize(Env *env)
{ {
const ID* id = operand_[0]->id(); const ID* id = operand_[0]->id();
ASSERT(id); ASSERT(id);
RecordField *field = GetRecordField(id, env); RecordField* field = GetRecordField(id, env);
mhs = field->static_offset(); mhs = field->static_offset();
if ( mhs < 0 ) if ( mhs < 0 )
@ -897,7 +861,7 @@ int Expr::MinimalHeaderSize(Env *env)
mhs = operand_[0]->MinimalHeaderSize(env); mhs = operand_[0]->MinimalHeaderSize(env);
for ( unsigned int i = 0; i < cases_->size(); ++i ) for ( unsigned int i = 0; i < cases_->size(); ++i )
{ {
CaseExpr * ce = (*cases_)[i]; CaseExpr* ce = (*cases_)[i];
if ( ce->index() ) if ( ce->index() )
for ( unsigned int j = 0; j < ce->index()->size(); ++j ) for ( unsigned int j = 0; j < ce->index()->size(); ++j )
mhs = mhs_max(mhs, (*ce->index())[j]->MinimalHeaderSize(env)); mhs = mhs_max(mhs, (*ce->index())[j]->MinimalHeaderSize(env));
@ -917,7 +881,7 @@ int Expr::MinimalHeaderSize(Env *env)
return mhs; return mhs;
} }
bool Expr::HasReference(const ID *id) const bool Expr::HasReference(const ID* id) const
{ {
switch ( expr_type_ ) switch ( expr_type_ )
{ {
@ -929,7 +893,7 @@ bool Expr::HasReference(const ID *id) const
case EXPR_CALLARGS: case EXPR_CALLARGS:
{ {
foreach(i, ExprList, args_) foreach (i, ExprList, args_)
if ( (*i)->HasReference(id) ) if ( (*i)->HasReference(id) )
return true; return true;
} }
@ -937,7 +901,7 @@ bool Expr::HasReference(const ID *id) const
case EXPR_CASE: case EXPR_CASE:
{ {
foreach(i, CaseExprList, cases_) foreach (i, CaseExprList, cases_)
if ( (*i)->HasReference(id) ) if ( (*i)->HasReference(id) )
return true; return true;
} }
@ -947,8 +911,7 @@ bool Expr::HasReference(const ID *id) const
// Evaluate every operand by default // Evaluate every operand by default
for ( int i = 0; i < 3; ++i ) for ( int i = 0; i < 3; ++i )
{ {
if ( operand_[i] && if ( operand_[i] && operand_[i]->HasReference(id) )
operand_[i]->HasReference(id) )
{ {
return true; return true;
} }
@ -957,7 +920,7 @@ bool Expr::HasReference(const ID *id) const
} }
} }
bool Expr::DoTraverse(DataDepVisitor *visitor) bool Expr::DoTraverse(DataDepVisitor* visitor)
{ {
switch ( expr_type_ ) switch ( expr_type_ )
{ {
@ -977,7 +940,7 @@ bool Expr::DoTraverse(DataDepVisitor *visitor)
case EXPR_CALLARGS: case EXPR_CALLARGS:
{ {
foreach(i, ExprList, args_) foreach (i, ExprList, args_)
if ( ! (*i)->Traverse(visitor) ) if ( ! (*i)->Traverse(visitor) )
return false; return false;
} }
@ -985,7 +948,7 @@ bool Expr::DoTraverse(DataDepVisitor *visitor)
case EXPR_CASE: case EXPR_CASE:
{ {
foreach(i, CaseExprList, cases_) foreach (i, CaseExprList, cases_)
if ( ! (*i)->Traverse(visitor) ) if ( ! (*i)->Traverse(visitor) )
return false; return false;
} }
@ -995,8 +958,7 @@ bool Expr::DoTraverse(DataDepVisitor *visitor)
// Evaluate every operand by default // Evaluate every operand by default
for ( int i = 0; i < 3; ++i ) for ( int i = 0; i < 3; ++i )
{ {
if ( operand_[i] && if ( operand_[i] && ! operand_[i]->Traverse(visitor) )
! operand_[i]->Traverse(visitor) )
{ {
return false; return false;
} }
@ -1025,7 +987,7 @@ bool Expr::RequiresAnalyzerContext() const
case EXPR_CALLARGS: case EXPR_CALLARGS:
{ {
foreach(i, ExprList, args_) foreach (i, ExprList, args_)
if ( (*i)->RequiresAnalyzerContext() ) if ( (*i)->RequiresAnalyzerContext() )
return true; return true;
} }
@ -1033,7 +995,7 @@ bool Expr::RequiresAnalyzerContext() const
case EXPR_CASE: case EXPR_CASE:
{ {
foreach(i, CaseExprList, cases_) foreach (i, CaseExprList, cases_)
if ( (*i)->RequiresAnalyzerContext() ) if ( (*i)->RequiresAnalyzerContext() )
return true; return true;
} }
@ -1042,8 +1004,7 @@ bool Expr::RequiresAnalyzerContext() const
default: default:
// Evaluate every operand by default // Evaluate every operand by default
for ( int i = 0; i < 3; ++i ) for ( int i = 0; i < 3; ++i )
if ( operand_[i] && if ( operand_[i] && operand_[i]->RequiresAnalyzerContext() )
operand_[i]->RequiresAnalyzerContext() )
{ {
DEBUG_MSG("'%s' requires analyzer context\n", operand_[i]->orig()); DEBUG_MSG("'%s' requires analyzer context\n", operand_[i]->orig());
return true; return true;
@ -1052,9 +1013,8 @@ bool Expr::RequiresAnalyzerContext() const
} }
} }
CaseExpr::CaseExpr(ExprList *index, Expr *value) CaseExpr::CaseExpr(ExprList* index, Expr* value)
: DataDepElement(DataDepElement::CASEEXPR), : DataDepElement(DataDepElement::CASEEXPR), index_(index), value_(value)
index_(index), value_(value)
{ {
} }
@ -1064,15 +1024,15 @@ CaseExpr::~CaseExpr()
delete value_; delete value_;
} }
bool CaseExpr::DoTraverse(DataDepVisitor *visitor) bool CaseExpr::DoTraverse(DataDepVisitor* visitor)
{ {
foreach(i, ExprList, index_) foreach (i, ExprList, index_)
if ( ! (*i)->Traverse(visitor) ) if ( ! (*i)->Traverse(visitor) )
return false; return false;
return value_->Traverse(visitor); return value_->Traverse(visitor);
} }
bool CaseExpr::HasReference(const ID *id) const bool CaseExpr::HasReference(const ID* id) const
{ {
return value_->HasReference(id); return value_->HasReference(id);
} }

View file

@ -7,42 +7,43 @@
class CaseExpr; class CaseExpr;
class Expr : public Object, public DataDepElement class Expr : public Object, public DataDepElement
{ {
public: public:
enum ExprType { enum ExprType
# define EXPR_DEF(type, x, y) type, {
# include "pac_expr.def" #define EXPR_DEF(type, x, y) type,
# undef EXPR_DEF #include "pac_expr.def"
#undef EXPR_DEF
}; };
void init(); void init();
Expr(ID *id); Expr(ID* id);
Expr(Number *num); Expr(Number* num);
Expr(ConstString *s); Expr(ConstString* s);
Expr(RegEx *regex); Expr(RegEx* regex);
Expr(ExprList *args); // for EXPR_CALLARGS Expr(ExprList* args); // for EXPR_CALLARGS
Expr(Expr *index, CaseExprList *cases); Expr(Expr* index, CaseExprList* cases);
Expr(ExprType type, Expr *op1); Expr(ExprType type, Expr* op1);
Expr(ExprType type, Expr *op1, Expr *op2); Expr(ExprType type, Expr* op1, Expr* op2);
Expr(ExprType type, Expr *op1, Expr *op2, Expr *op3); Expr(ExprType type, Expr* op1, Expr* op2, Expr* op3);
virtual ~Expr(); virtual ~Expr();
const char *orig() const { return orig_.c_str(); } const char* orig() const { return orig_.c_str(); }
const ID *id() const { return id_; } const ID* id() const { return id_; }
const char *str() const { return str_.c_str(); } const char* str() const { return str_.c_str(); }
ExprType expr_type() const { return expr_type_; } ExprType expr_type() const { return expr_type_; }
void AddCaseExpr(CaseExpr *case_expr); void AddCaseExpr(CaseExpr* case_expr);
// Returns the data "type" of the expression. Here we only // Returns the data "type" of the expression. Here we only
// do a serious job for the EXPR_MEMBER and EXPR_SUBSCRIPT // do a serious job for the EXPR_MEMBER and EXPR_SUBSCRIPT
// operators. For arithmetic operations, we fall back // operators. For arithmetic operations, we fall back
// to "int". // to "int".
Type *DataType(Env *env) const; Type* DataType(Env* env) const;
string DataTypeStr(Env *env) const; string DataTypeStr(Env* env) const;
// Note: EvalExpr() may generate C++ statements in order to evaluate // Note: EvalExpr() may generate C++ statements in order to evaluate
// variables in the expression, so the following is wrong: // variables in the expression, so the following is wrong:
@ -54,24 +55,24 @@ public:
// //
// out->println("int x = %s", expr->EvalExpr(out, env)); // out->println("int x = %s", expr->EvalExpr(out, env));
// //
const char *EvalExpr(Output *out, Env *env); const char* EvalExpr(Output* out, Env* env);
// force evaulation of IDs contained in this expression; // force evaulation of IDs contained in this expression;
// necessary with case expr and conditional let fields (&if) // necessary with case expr and conditional let fields (&if)
// for correct parsing of fields // for correct parsing of fields
void ForceIDEval(Output *out_cc, Env *env); void ForceIDEval(Output* out_cc, Env* env);
// Returns the set_* function of the expression. // Returns the set_* function of the expression.
// The expression must be of form ID or x.ID. // The expression must be of form ID or x.ID.
string SetFunc(Output *out, Env *env); string SetFunc(Output* out, Env* env);
// Returns true if the expression folds to an integer // Returns true if the expression folds to an integer
// constant with env, and puts the constant in *pn. // constant with env, and puts the constant in *pn.
// //
bool ConstFold(Env *env, int *pn) const; bool ConstFold(Env* env, int* pn) const;
// Whether id is referenced in the expression // Whether id is referenced in the expression
bool HasReference(const ID *id) const; bool HasReference(const ID* id) const;
// Suppose the data for type might be incomplete, what is // Suppose the data for type might be incomplete, what is
// the minimal number of bytes from data head required to // the minimal number of bytes from data head required to
@ -82,58 +83,58 @@ public:
// //
// Returns -1 if the number is not a constant. // Returns -1 if the number is not a constant.
// //
int MinimalHeaderSize(Env *env); int MinimalHeaderSize(Env* env);
// Whether evaluation of the expression requires the analyzer context // Whether evaluation of the expression requires the analyzer context
bool RequiresAnalyzerContext() const; bool RequiresAnalyzerContext() const;
protected: protected:
bool DoTraverse(DataDepVisitor *visitor); bool DoTraverse(DataDepVisitor* visitor);
private: private:
ExprType expr_type_; ExprType expr_type_;
int num_operands_; int num_operands_;
Expr *operand_[3]; Expr* operand_[3];
ID *id_; // EXPR_ID ID* id_; // EXPR_ID
Number *num_; // EXPR_NUM Number* num_; // EXPR_NUM
ConstString *cstr_; // EXPR_CSTR ConstString* cstr_; // EXPR_CSTR
RegEx *regex_; // EXPR_REGEX RegEx* regex_; // EXPR_REGEX
ExprList *args_; // EXPR_CALLARGS ExprList* args_; // EXPR_CALLARGS
CaseExprList *cases_; // EXPR_CASE CaseExprList* cases_; // EXPR_CASE
string str_; // value string string str_; // value string
string orig_; // original string for debugging info string orig_; // original string for debugging info
void GenStrFromFormat(Env *env); void GenStrFromFormat(Env* env);
void GenEval(Output *out, Env *env); void GenEval(Output* out, Env* env);
void GenCaseEval(Output *out_cc, Env *env); void GenCaseEval(Output* out_cc, Env* env);
}; };
string OrigExprList(ExprList *exprlist); string OrigExprList(ExprList* exprlist);
string EvalExprList(ExprList *exprlist, Output *out, Env *env); string EvalExprList(ExprList* exprlist, Output* out, Env* env);
// An entry of the case expression, consisting of one or more constant // An entry of the case expression, consisting of one or more constant
// expressions for the case index and a value expression. // expressions for the case index and a value expression.
class CaseExpr : public Object, public DataDepElement class CaseExpr : public Object, public DataDepElement
{ {
public: public:
CaseExpr(ExprList *index, Expr *value); CaseExpr(ExprList* index, Expr* value);
virtual ~CaseExpr(); virtual ~CaseExpr();
ExprList *index() const { return index_; } ExprList* index() const { return index_; }
Expr *value() const { return value_; } Expr* value() const { return value_; }
bool HasReference(const ID *id) const; bool HasReference(const ID* id) const;
bool RequiresAnalyzerContext() const; bool RequiresAnalyzerContext() const;
protected: protected:
bool DoTraverse(DataDepVisitor *visitor); bool DoTraverse(DataDepVisitor* visitor);
private: private:
ExprList *index_; ExprList* index_;
Expr *value_; Expr* value_;
}; };
#endif // pac_expr_h #endif // pac_expr_h

View file

@ -1,6 +1,7 @@
#include "pac_exttype.h" #include "pac_exttype.h"
#include "pac_id.h"
#include "pac_decl.h" #include "pac_decl.h"
#include "pac_id.h"
#include "pac_output.h" #include "pac_output.h"
bool ExternType::DefineValueVar() const bool ExternType::DefineValueVar() const
@ -34,11 +35,9 @@ bool ExternType::ByteOrderSensitive() const
return false; return false;
} }
string ExternType::EvalMember(const ID *member_id) const string ExternType::EvalMember(const ID* member_id) const
{ {
return strfmt("%s%s", return strfmt("%s%s", ext_type_ == POINTER ? "->" : ".", member_id->Name());
ext_type_ == POINTER ? "->" : ".",
member_id->Name());
} }
void ExternType::GenInitCode(Output* out_cc, Env* env) void ExternType::GenInitCode(Output* out_cc, Env* env)
@ -58,20 +57,20 @@ void ExternType::GenDynamicSize(Output* out, Env* env, const DataPtr& data)
ASSERT(0); ASSERT(0);
} }
Type *ExternType::DoClone() const Type* ExternType::DoClone() const
{ {
return new ExternType(id_->clone(), ext_type_); return new ExternType(id_->clone(), ext_type_);
} }
// Definitions of pre-defined external types // Definitions of pre-defined external types
#define EXTERNTYPE(name, ctype, exttype) ExternType *extern_type_##name = 0; #define EXTERNTYPE(name, ctype, exttype) ExternType* extern_type_##name = 0;
#include "pac_externtype.def" #include "pac_externtype.def"
#undef EXTERNTYPE #undef EXTERNTYPE
void ExternType::static_init() void ExternType::static_init()
{ {
ID *id; ID* id;
// TypeDecl *decl; // TypeDecl *decl;
// decl = new TypeDecl(id, 0, extern_type_##name); // decl = new TypeDecl(id, 0, extern_type_##name);

View file

@ -9,40 +9,42 @@
// literally to the compiled code. // literally to the compiled code.
class ExternType : public Type class ExternType : public Type
{ {
public: public:
enum EXTType { PLAIN, NUMBER, POINTER }; enum EXTType
ExternType(const ID *id, EXTType ext_type) {
: Type(EXTERN), PLAIN,
id_(id), NUMBER,
ext_type_(ext_type) {} POINTER
};
ExternType(const ID* id, EXTType ext_type) : Type(EXTERN), id_(id), ext_type_(ext_type) { }
bool DefineValueVar() const; bool DefineValueVar() const;
string DataTypeStr() const; string DataTypeStr() const;
int StaticSize(Env *env) const; int StaticSize(Env* env) const;
bool ByteOrderSensitive() const; bool ByteOrderSensitive() const;
string EvalMember(const ID *member_id) const; string EvalMember(const ID* member_id) const;
bool IsNumericType() const { return ext_type_ == NUMBER; } bool IsNumericType() const { return ext_type_ == NUMBER; }
bool IsPointerType() const { return ext_type_ == POINTER; } bool IsPointerType() const { return ext_type_ == POINTER; }
void GenInitCode(Output *out_cc, Env *env); void GenInitCode(Output* out_cc, Env* env);
protected: protected:
void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags); void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags);
void GenDynamicSize(Output *out, Env *env, const DataPtr& data); void GenDynamicSize(Output* out, Env* env, const DataPtr& data);
Type *DoClone() const; Type* DoClone() const;
private: private:
const ID *id_; const ID* id_;
EXTType ext_type_; EXTType ext_type_;
public: public:
static void static_init(); static void static_init();
}; };
#define EXTERNTYPE(name, ctype, exttype) extern ExternType *extern_type_##name; #define EXTERNTYPE(name, ctype, exttype) extern ExternType* extern_type_##name;
#include "pac_externtype.def" #include "pac_externtype.def"
#undef EXTERNTYPE #undef EXTERNTYPE

View file

@ -1,13 +1,13 @@
#include "pac_field.h"
#include "pac_attr.h" #include "pac_attr.h"
#include "pac_common.h" #include "pac_common.h"
#include "pac_exception.h" #include "pac_exception.h"
#include "pac_field.h"
#include "pac_id.h" #include "pac_id.h"
#include "pac_type.h" #include "pac_type.h"
Field::Field(FieldType tof, int flags, ID *id, Type *type) Field::Field(FieldType tof, int flags, ID* id, Type* type)
: DataDepElement(DataDepElement::FIELD), : DataDepElement(DataDepElement::FIELD), tof_(tof), flags_(flags), id_(id), type_(type)
tof_(tof), flags_(flags), id_(id), type_(type)
{ {
decl_id_ = current_decl_id; decl_id_ = current_decl_id;
field_id_str_ = strfmt("%s:%s", decl_id()->Name(), id_->Name()); field_id_str_ = strfmt("%s:%s", decl_id()->Name(), id_->Name());
@ -35,23 +35,21 @@ void Field::AddAttr(AttrList* attrs)
delete_attrs = true; delete_attrs = true;
} }
foreach(i, AttrList, attrs) foreach (i, AttrList, attrs)
ProcessAttr(*i); ProcessAttr(*i);
if ( delete_attrs ) if ( delete_attrs )
delete attrs; delete attrs;
} }
void Field::ProcessAttr(Attr *a) void Field::ProcessAttr(Attr* a)
{ {
switch ( a->type() ) switch ( a->type() )
{ {
case ATTR_IF: case ATTR_IF:
if ( tof() != LET_FIELD && if ( tof() != LET_FIELD && tof() != WITHINPUT_FIELD )
tof() != WITHINPUT_FIELD )
{ {
throw Exception(a, throw Exception(a, "&if can only be applied to a "
"&if can only be applied to a "
"let field"); "let field");
} }
break; break;
@ -76,7 +74,7 @@ int Field::ValueVarType() const
return TEMP_VAR; return TEMP_VAR;
} }
void Field::Prepare(Env *env) void Field::Prepare(Env* env)
{ {
if ( type_ ) if ( type_ )
{ {
@ -86,9 +84,7 @@ void Field::Prepare(Env *env)
flags_ &= (~PUBLIC_READABLE); flags_ &= (~PUBLIC_READABLE);
type_->set_value_var(id(), ValueVarType()); type_->set_value_var(id(), ValueVarType());
type_->Prepare(env, type_->Prepare(env, flags_ & TYPE_TO_BE_PARSED ? Type::TO_BE_PARSED : 0);
flags_ & TYPE_TO_BE_PARSED ?
Type::TO_BE_PARSED : 0);
env->SetField(id(), this); env->SetField(id(), this);
} }
} }
@ -109,7 +105,7 @@ void Field::GenPrivDecls(Output* out_h, Env* env)
void Field::GenTempDecls(Output* out_h, Env* env) void Field::GenTempDecls(Output* out_h, Env* env)
{ {
// Generate temp field // Generate temp field
if ( type_ && !(flags_ & CLASS_MEMBER) ) if ( type_ && ! (flags_ & CLASS_MEMBER) )
type_->GenPrivDecls(out_h, env); type_->GenPrivDecls(out_h, env);
} }
@ -125,12 +121,12 @@ void Field::GenCleanUpCode(Output* out_cc, Env* env)
type_->GenCleanUpCode(out_cc, env); type_->GenCleanUpCode(out_cc, env);
} }
bool Field::DoTraverse(DataDepVisitor *visitor) bool Field::DoTraverse(DataDepVisitor* visitor)
{ {
// Check parameterized type // Check parameterized type
if ( type_ && ! type_->Traverse(visitor) ) if ( type_ && ! type_->Traverse(visitor) )
return false; return false;
foreach(i, AttrList, attrs_) foreach (i, AttrList, attrs_)
if ( ! (*i)->Traverse(visitor) ) if ( ! (*i)->Traverse(visitor) )
return false; return false;
return true; return true;
@ -141,7 +137,7 @@ bool Field::RequiresAnalyzerContext() const
// Check parameterized type // Check parameterized type
if ( type_ && type_->RequiresAnalyzerContext() ) if ( type_ && type_->RequiresAnalyzerContext() )
return true; return true;
foreach(i, AttrList, attrs_) foreach (i, AttrList, attrs_)
if ( (*i)->RequiresAnalyzerContext() ) if ( (*i)->RequiresAnalyzerContext() )
return true; return true;
return false; return false;

View file

@ -6,7 +6,8 @@
// A "field" is a member of class. // A "field" is a member of class.
enum FieldType { enum FieldType
{
CASE_FIELD, CASE_FIELD,
CONTEXT_FIELD, CONTEXT_FIELD,
FLOW_FIELD, FLOW_FIELD,
@ -19,12 +20,12 @@ enum FieldType {
PUB_VAR_FIELD, PUB_VAR_FIELD,
TEMP_VAR_FIELD, TEMP_VAR_FIELD,
WITHINPUT_FIELD, WITHINPUT_FIELD,
}; };
class Field : public Object, public DataDepElement class Field : public Object, public DataDepElement
{ {
public: public:
Field(FieldType tof, int flags, ID *id, Type *type); Field(FieldType tof, int flags, ID* id, Type* type);
// Field flags // Field flags
// Whether the field will be evaluated by calling the Parse() // Whether the field will be evaluated by calling the Parse()
@ -45,7 +46,7 @@ public:
FieldType tof() const { return tof_; } FieldType tof() const { return tof_; }
const ID* id() const { return id_; } const ID* id() const { return id_; }
Type *type() const { return type_; } Type* type() const { return type_; }
const ID* decl_id() const { return decl_id_; } const ID* decl_id() const { return decl_id_; }
bool anonymous_field() const; bool anonymous_field() const;
@ -53,7 +54,7 @@ public:
void AddAttr(AttrList* attrs); void AddAttr(AttrList* attrs);
// The field interface // The field interface
virtual void ProcessAttr(Attr *attr); virtual void ProcessAttr(Attr* attr);
virtual void Prepare(Env* env); virtual void Prepare(Env* env);
virtual void GenPubDecls(Output* out, Env* env); virtual void GenPubDecls(Output* out, Env* env);
@ -69,16 +70,16 @@ protected:
int ValueVarType() const; int ValueVarType() const;
bool ToBeParsed() const; bool ToBeParsed() const;
bool DoTraverse(DataDepVisitor *visitor); bool DoTraverse(DataDepVisitor* visitor);
protected: protected:
FieldType tof_; FieldType tof_;
int flags_; int flags_;
ID* id_; ID* id_;
Type *type_; Type* type_;
const ID* decl_id_; const ID* decl_id_;
string field_id_str_; string field_id_str_;
AttrList* attrs_; AttrList* attrs_;
}; };
#endif // pac_field_h #endif // pac_field_h

View file

@ -1,3 +1,5 @@
#include "pac_flow.h"
#include "pac_analyzer.h" #include "pac_analyzer.h"
#include "pac_conn.h" #include "pac_conn.h"
#include "pac_context.h" #include "pac_context.h"
@ -7,17 +9,13 @@
#include "pac_exception.h" #include "pac_exception.h"
#include "pac_expr.h" #include "pac_expr.h"
#include "pac_exttype.h" #include "pac_exttype.h"
#include "pac_flow.h"
#include "pac_output.h" #include "pac_output.h"
#include "pac_param.h" #include "pac_param.h"
#include "pac_paramtype.h" #include "pac_paramtype.h"
#include "pac_type.h" #include "pac_type.h"
#include "pac_varfield.h" #include "pac_varfield.h"
FlowDecl::FlowDecl(ID* id, ParamList* params, AnalyzerElementList* elemlist)
FlowDecl::FlowDecl(ID *id,
ParamList *params,
AnalyzerElementList *elemlist)
: AnalyzerDecl(id, FLOW, params) : AnalyzerDecl(id, FLOW, params)
{ {
dataunit_ = 0; dataunit_ = 0;
@ -32,9 +30,9 @@ FlowDecl::~FlowDecl()
delete dataunit_; delete dataunit_;
} }
ParameterizedType *FlowDecl::flow_buffer_type_ = 0; ParameterizedType* FlowDecl::flow_buffer_type_ = 0;
ParameterizedType *FlowDecl::flow_buffer_type() ParameterizedType* FlowDecl::flow_buffer_type()
{ {
if ( ! flow_buffer_type_ ) if ( ! flow_buffer_type_ )
{ {
@ -43,24 +41,21 @@ ParameterizedType *FlowDecl::flow_buffer_type()
return flow_buffer_type_; return flow_buffer_type_;
} }
void FlowDecl::AddBaseClass(vector<string> *base_classes) const void FlowDecl::AddBaseClass(vector<string>* base_classes) const
{ {
base_classes->push_back("binpac::FlowAnalyzer"); base_classes->push_back("binpac::FlowAnalyzer");
} }
void FlowDecl::ProcessFlowElement(AnalyzerFlow *flow_elem) void FlowDecl::ProcessFlowElement(AnalyzerFlow* flow_elem)
{ {
throw Exception( throw Exception(flow_elem, "flow should be defined in only a connection declaration");
flow_elem,
"flow should be defined in only a connection declaration");
} }
void FlowDecl::ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem) void FlowDecl::ProcessDataUnitElement(AnalyzerDataUnit* dataunit_elem)
{ {
if ( dataunit_ ) if ( dataunit_ )
{ {
throw Exception(dataunit_elem, throw Exception(dataunit_elem, "dataunit already defined");
"dataunit already defined");
} }
dataunit_ = dataunit_elem; dataunit_ = dataunit_elem;
@ -68,8 +63,7 @@ void FlowDecl::ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem)
{ {
dataunit_->data_type()->MarkIncrementalInput(); dataunit_->data_type()->MarkIncrementalInput();
flow_buffer_var_field_ = new PubVarField( flow_buffer_var_field_ = new PubVarField(flow_buffer_id->clone(),
flow_buffer_id->clone(),
FlowDecl::flow_buffer_type()->Clone()); FlowDecl::flow_buffer_type()->Clone());
type_->AddField(flow_buffer_var_field_); type_->AddField(flow_buffer_var_field_);
@ -77,8 +71,7 @@ void FlowDecl::ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem)
AnalyzerContextDecl::current_analyzer_context()->AddFlowBuffer(); AnalyzerContextDecl::current_analyzer_context()->AddFlowBuffer();
// Add an argument to the context initiation // Add an argument to the context initiation
dataunit_->context_type()->AddParamArg( dataunit_->context_type()->AddParamArg(new Expr(flow_buffer_var_field_->id()->clone()));
new Expr(flow_buffer_var_field_->id()->clone()));
} }
} }
@ -87,28 +80,25 @@ void FlowDecl::Prepare()
// Add the connection parameter // Add the connection parameter
if ( ! conn_decl_ ) if ( ! conn_decl_ )
{ {
throw Exception(this, throw Exception(this, "no connection is not declared for the flow");
"no connection is not declared for the flow");
} }
if ( ! params_ ) if ( ! params_ )
params_ = new ParamList(); params_ = new ParamList();
params_->insert(params_->begin(), params_->insert(params_->begin(), new Param(connection_id->clone(), conn_decl_->DataType()));
new Param(connection_id->clone(),
conn_decl_->DataType()));
AnalyzerDecl::Prepare(); AnalyzerDecl::Prepare();
dataunit_->Prepare(env_); dataunit_->Prepare(env_);
} }
void FlowDecl::GenPubDecls(Output *out_h, Output *out_cc) void FlowDecl::GenPubDecls(Output* out_h, Output* out_cc)
{ {
AnalyzerDecl::GenPubDecls(out_h, out_cc); AnalyzerDecl::GenPubDecls(out_h, out_cc);
} }
void FlowDecl::GenPrivDecls(Output *out_h, Output *out_cc) void FlowDecl::GenPrivDecls(Output* out_h, Output* out_cc)
{ {
// Declare the data unit // Declare the data unit
dataunit_->dataunit_var_field()->GenPrivDecls(out_h, env_); dataunit_->dataunit_var_field()->GenPrivDecls(out_h, env_);
@ -119,14 +109,12 @@ void FlowDecl::GenPrivDecls(Output *out_h, Output *out_cc)
AnalyzerDecl::GenPrivDecls(out_h, out_cc); AnalyzerDecl::GenPrivDecls(out_h, out_cc);
} }
void FlowDecl::GenInitCode(Output *out_cc) void FlowDecl::GenInitCode(Output* out_cc)
{ {
AnalyzerDecl::GenInitCode(out_cc); AnalyzerDecl::GenInitCode(out_cc);
out_cc->println("%s = 0;", out_cc->println("%s = 0;", env_->LValue(dataunit_id));
env_->LValue(dataunit_id)); out_cc->println("%s = 0;", env_->LValue(analyzer_context_id));
out_cc->println("%s = 0;",
env_->LValue(analyzer_context_id));
if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT ) if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT )
{ {
@ -135,13 +123,13 @@ void FlowDecl::GenInitCode(Output *out_cc)
} }
} }
void FlowDecl::GenCleanUpCode(Output *out_cc) void FlowDecl::GenCleanUpCode(Output* out_cc)
{ {
GenDeleteDataUnit(out_cc); GenDeleteDataUnit(out_cc);
AnalyzerDecl::GenCleanUpCode(out_cc); AnalyzerDecl::GenCleanUpCode(out_cc);
} }
void FlowDecl::GenEOFFunc(Output *out_h, Output *out_cc) void FlowDecl::GenEOFFunc(Output* out_h, Output* out_cc)
{ {
string proto = strfmt("%s()", kFlowEOF); string proto = strfmt("%s()", kFlowEOF);
@ -151,15 +139,14 @@ void FlowDecl::GenEOFFunc(Output *out_h, Output *out_cc)
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
foreach(i, AnalyzerHelperList, eof_helpers_) foreach (i, AnalyzerHelperList, eof_helpers_)
{ {
(*i)->GenCode(0, out_cc, this); (*i)->GenCode(0, out_cc, this);
} }
if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT ) if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT )
{ {
out_cc->println("%s->set_eof();", out_cc->println("%s->set_eof();", env_->LValue(flow_buffer_id));
env_->LValue(flow_buffer_id));
out_cc->println("%s(0, 0);", kNewData); out_cc->println("%s(0, 0);", kNewData);
} }
@ -167,7 +154,7 @@ void FlowDecl::GenEOFFunc(Output *out_h, Output *out_cc)
out_cc->dec_indent(); out_cc->dec_indent();
} }
void FlowDecl::GenGapFunc(Output *out_h, Output *out_cc) void FlowDecl::GenGapFunc(Output* out_h, Output* out_cc)
{ {
string proto = strfmt("%s(int gap_length)", kFlowGap); string proto = strfmt("%s(int gap_length)", kFlowGap);
@ -179,24 +166,20 @@ void FlowDecl::GenGapFunc(Output *out_h, Output *out_cc)
if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT ) if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT )
{ {
out_cc->println("%s->NewGap(gap_length);", out_cc->println("%s->NewGap(gap_length);", env_->LValue(flow_buffer_id));
env_->LValue(flow_buffer_id));
} }
out_cc->println("}"); out_cc->println("}");
out_cc->dec_indent(); out_cc->dec_indent();
} }
void FlowDecl::GenProcessFunc(Output *out_h, Output *out_cc) void FlowDecl::GenProcessFunc(Output* out_h, Output* out_cc)
{ {
env_->AddID(begin_of_data, TEMP_VAR, extern_type_const_byteptr); env_->AddID(begin_of_data, TEMP_VAR, extern_type_const_byteptr);
env_->AddID(end_of_data, TEMP_VAR, extern_type_const_byteptr); env_->AddID(end_of_data, TEMP_VAR, extern_type_const_byteptr);
string proto = string proto = strfmt("%s(const_byteptr %s, const_byteptr %s)", kNewData,
strfmt("%s(const_byteptr %s, const_byteptr %s)", env_->LValue(begin_of_data), env_->LValue(end_of_data));
kNewData,
env_->LValue(begin_of_data),
env_->LValue(end_of_data));
out_h->println("void %s;", proto.c_str()); out_h->println("void %s;", proto.c_str());
@ -232,8 +215,7 @@ void FlowDecl::GenProcessFunc(Output *out_h, Output *out_cc)
GenCleanUpCode(out_cc); GenCleanUpCode(out_cc);
if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT ) if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT )
{ {
out_cc->println("%s->DiscardData();", out_cc->println("%s->DiscardData();", env_->LValue(flow_buffer_id));
env_->LValue(flow_buffer_id));
} }
out_cc->println("throw;"); out_cc->println("throw;");
out_cc->println("}"); out_cc->println("}");
@ -244,21 +226,19 @@ void FlowDecl::GenProcessFunc(Output *out_h, Output *out_cc)
out_cc->println(""); out_cc->println("");
} }
void FlowDecl::GenNewDataUnit(Output *out_cc) void FlowDecl::GenNewDataUnit(Output* out_cc)
{ {
Type *unit_datatype = dataunit_->data_type(); Type* unit_datatype = dataunit_->data_type();
// dataunit_->data_type()->GenPreParsing(out_cc, env_); // dataunit_->data_type()->GenPreParsing(out_cc, env_);
dataunit_->GenNewDataUnit(out_cc, env_); dataunit_->GenNewDataUnit(out_cc, env_);
if ( unit_datatype->buffer_input() && if ( unit_datatype->buffer_input() && unit_datatype->buffer_mode() == Type::BUFFER_BY_LENGTH )
unit_datatype->buffer_mode() == Type::BUFFER_BY_LENGTH )
{ {
out_cc->println("%s->NewFrame(0, false);", out_cc->println("%s->NewFrame(0, false);", env_->LValue(flow_buffer_id));
env_->LValue(flow_buffer_id));
} }
dataunit_->GenNewContext(out_cc, env_); dataunit_->GenNewContext(out_cc, env_);
} }
void FlowDecl::GenDeleteDataUnit(Output *out_cc) void FlowDecl::GenDeleteDataUnit(Output* out_cc)
{ {
// Do not just delete dataunit, because we may just want to Unref it. // Do not just delete dataunit, because we may just want to Unref it.
// out_cc->println("delete %s;", env_->LValue(dataunit_id)); // out_cc->println("delete %s;", env_->LValue(dataunit_id));
@ -266,17 +246,14 @@ void FlowDecl::GenDeleteDataUnit(Output *out_cc)
dataunit_->context_type()->GenCleanUpCode(out_cc, env_); dataunit_->context_type()->GenCleanUpCode(out_cc, env_);
} }
void FlowDecl::GenCodeFlowUnit(Output *out_cc) void FlowDecl::GenCodeFlowUnit(Output* out_cc)
{ {
Type *unit_datatype = dataunit_->data_type(); Type* unit_datatype = dataunit_->data_type();
out_cc->println("%s->NewData(%s, %s);", out_cc->println("%s->NewData(%s, %s);", env_->LValue(flow_buffer_id),
env_->LValue(flow_buffer_id), env_->RValue(begin_of_data), env_->RValue(end_of_data));
env_->RValue(begin_of_data),
env_->RValue(end_of_data));
out_cc->println("while ( %s->data_available() && ", out_cc->println("while ( %s->data_available() && ", env_->LValue(flow_buffer_id));
env_->LValue(flow_buffer_id));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("( !%s->have_pending_request() || %s->ready() ) )", out_cc->println("( !%s->have_pending_request() || %s->ready() ) )",
env_->LValue(flow_buffer_id), env_->LValue(flow_buffer_id)); env_->LValue(flow_buffer_id), env_->LValue(flow_buffer_id));
@ -286,8 +263,7 @@ void FlowDecl::GenCodeFlowUnit(Output *out_cc)
out_cc->println("if ( ! %s )", env_->LValue(dataunit_id)); out_cc->println("if ( ! %s )", env_->LValue(dataunit_id));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
out_cc->println("BINPAC_ASSERT(!%s);", out_cc->println("BINPAC_ASSERT(!%s);", env_->LValue(analyzer_context_id));
env_->LValue(analyzer_context_id));
GenNewDataUnit(out_cc); GenNewDataUnit(out_cc);
out_cc->println("}"); out_cc->println("}");
out_cc->dec_indent(); out_cc->dec_indent();
@ -295,8 +271,7 @@ void FlowDecl::GenCodeFlowUnit(Output *out_cc)
DataPtr data(env_, 0, 0); DataPtr data(env_, 0, 0);
unit_datatype->GenParseCode(out_cc, env_, data, 0); unit_datatype->GenParseCode(out_cc, env_, data, 0);
out_cc->println("if ( %s )", out_cc->println("if ( %s )", unit_datatype->parsing_complete(env_).c_str());
unit_datatype->parsing_complete(env_).c_str());
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
out_cc->println("// Clean up the flow unit after parsing"); out_cc->println("// Clean up the flow unit after parsing");
@ -308,8 +283,7 @@ void FlowDecl::GenCodeFlowUnit(Output *out_cc)
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
out_cc->println("// Resume upon next input segment"); out_cc->println("// Resume upon next input segment");
out_cc->println("BINPAC_ASSERT(!%s->ready());", out_cc->println("BINPAC_ASSERT(!%s->ready());", env_->RValue(flow_buffer_id));
env_->RValue(flow_buffer_id));
out_cc->println("break;"); out_cc->println("break;");
out_cc->println("}"); out_cc->println("}");
out_cc->dec_indent(); out_cc->dec_indent();
@ -318,14 +292,12 @@ void FlowDecl::GenCodeFlowUnit(Output *out_cc)
out_cc->dec_indent(); out_cc->dec_indent();
} }
void FlowDecl::GenCodeDatagram(Output *out_cc) void FlowDecl::GenCodeDatagram(Output* out_cc)
{ {
Type *unit_datatype = dataunit_->data_type(); Type* unit_datatype = dataunit_->data_type();
GenNewDataUnit(out_cc); GenNewDataUnit(out_cc);
string parse_params = strfmt("%s, %s", string parse_params = strfmt("%s, %s", env_->RValue(begin_of_data), env_->RValue(end_of_data));
env_->RValue(begin_of_data),
env_->RValue(end_of_data));
if ( RequiresAnalyzerContext::compute(unit_datatype) ) if ( RequiresAnalyzerContext::compute(unit_datatype) )
{ {

View file

@ -4,44 +4,44 @@
#include "pac_analyzer.h" #include "pac_analyzer.h"
class FlowDecl : public AnalyzerDecl class FlowDecl : public AnalyzerDecl
{ {
public: public:
FlowDecl(ID *flow_id, ParamList *params, AnalyzerElementList *elemlist); FlowDecl(ID* flow_id, ParamList* params, AnalyzerElementList* elemlist);
~FlowDecl(); ~FlowDecl();
void Prepare(); void Prepare();
void set_conn_decl(ConnDecl *c) { conn_decl_ = c; } void set_conn_decl(ConnDecl* c) { conn_decl_ = c; }
static ParameterizedType *flow_buffer_type(); static ParameterizedType* flow_buffer_type();
protected: protected:
void AddBaseClass(vector<string> *base_classes) const; void AddBaseClass(vector<string>* base_classes) const;
void GenInitCode(Output *out_cc); void GenInitCode(Output* out_cc);
void GenCleanUpCode(Output *out_cc); void GenCleanUpCode(Output* out_cc);
void GenProcessFunc(Output *out_h, Output *out_cc); void GenProcessFunc(Output* out_h, Output* out_cc);
void GenEOFFunc(Output *out_h, Output *out_cc); void GenEOFFunc(Output* out_h, Output* out_cc);
void GenGapFunc(Output *out_h, Output *out_cc); void GenGapFunc(Output* out_h, Output* out_cc);
void GenPubDecls(Output *out_h, Output *out_cc); void GenPubDecls(Output* out_h, Output* out_cc);
void GenPrivDecls(Output *out_h, Output *out_cc); void GenPrivDecls(Output* out_h, Output* out_cc);
void ProcessFlowElement(AnalyzerFlow *flow_elem); void ProcessFlowElement(AnalyzerFlow* flow_elem);
void ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem); void ProcessDataUnitElement(AnalyzerDataUnit* dataunit_elem);
private: private:
void GenNewDataUnit(Output *out_cc); void GenNewDataUnit(Output* out_cc);
void GenDeleteDataUnit(Output *out_cc); void GenDeleteDataUnit(Output* out_cc);
void GenCodeFlowUnit(Output *out_cc); void GenCodeFlowUnit(Output* out_cc);
void GenCodeDatagram(Output *out_cc); void GenCodeDatagram(Output* out_cc);
AnalyzerDataUnit *dataunit_; AnalyzerDataUnit* dataunit_;
ConnDecl *conn_decl_; ConnDecl* conn_decl_;
Field *flow_buffer_var_field_; Field* flow_buffer_var_field_;
static ParameterizedType *flow_buffer_type_; static ParameterizedType* flow_buffer_type_;
}; };
#endif // pac_flow_h #endif // pac_flow_h

View file

@ -1,11 +1,12 @@
#include "pac_func.h"
#include "pac_embedded.h" #include "pac_embedded.h"
#include "pac_expr.h" #include "pac_expr.h"
#include "pac_func.h"
#include "pac_output.h" #include "pac_output.h"
#include "pac_param.h" #include "pac_param.h"
#include "pac_type.h" #include "pac_type.h"
Function::Function(ID *id, Type *type, ParamList *params) Function::Function(ID* id, Type* type, ParamList* params)
: id_(id), type_(type), params_(params), expr_(0), code_(0) : id_(id), type_(type), params_(params), expr_(0), code_(0)
{ {
analyzer_decl_ = 0; analyzer_decl_ = 0;
@ -22,16 +23,16 @@ Function::~Function()
delete code_; delete code_;
} }
void Function::Prepare(Env *env) void Function::Prepare(Env* env)
{ {
env->AddID(id_, FUNC_ID, type_); env->AddID(id_, FUNC_ID, type_);
env->SetEvaluated(id_); env->SetEvaluated(id_);
env_ = new Env(env, this); env_ = new Env(env, this);
foreach(i, ParamList, params_) foreach (i, ParamList, params_)
{ {
Param *p = *i; Param* p = *i;
env_->AddID(p->id(), FUNC_PARAM, p->type()); env_->AddID(p->id(), FUNC_PARAM, p->type());
env_->SetEvaluated(p->id()); env_->SetEvaluated(p->id());
} }
@ -44,22 +45,17 @@ void Function::GenForwardDeclaration(Output* out_h)
void Function::GenCode(Output* out_h, Output* out_cc) void Function::GenCode(Output* out_h, Output* out_cc)
{ {
out_h->println("%s %s(%s);", out_h->println("%s %s(%s);", type_->DataTypeStr().c_str(), id_->Name(),
type_->DataTypeStr().c_str(),
id_->Name(),
ParamDecls(params_).c_str()); ParamDecls(params_).c_str());
string class_str = ""; string class_str = "";
if ( analyzer_decl_ ) if ( analyzer_decl_ )
class_str = strfmt("%s::", analyzer_decl_->id()->Name()); class_str = strfmt("%s::", analyzer_decl_->id()->Name());
string proto_str = strfmt("%s %s%s(%s)", string proto_str = strfmt("%s %s%s(%s)", type_->DataTypeStr().c_str(), class_str.c_str(),
type_->DataTypeStr().c_str(), id_->Name(), ParamDecls(params_).c_str());
class_str.c_str(),
id_->Name(),
ParamDecls(params_).c_str());
ASSERT(!(expr_ && code_)); ASSERT(! (expr_ && code_));
if ( expr_ ) if ( expr_ )
{ {
@ -68,8 +64,7 @@ void Function::GenCode(Output* out_h, Output* out_cc)
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
out_cc->println("return static_cast<%s>(%s);", out_cc->println("return static_cast<%s>(%s);", type_->DataTypeStr().c_str(),
type_->DataTypeStr().c_str(),
expr_->EvalExpr(out_cc, env_)); expr_->EvalExpr(out_cc, env_));
out_cc->println("}"); out_cc->println("}");
@ -92,8 +87,7 @@ void Function::GenCode(Output* out_h, Output* out_cc)
out_cc->println(""); out_cc->println("");
} }
FuncDecl::FuncDecl(Function *function) FuncDecl::FuncDecl(Function* function) : Decl(function->id()->clone(), FUNC), function_(function)
: Decl(function->id()->clone(), FUNC), function_(function)
{ {
function_->Prepare(global_env()); function_->Prepare(global_env());
} }
@ -103,21 +97,19 @@ FuncDecl::~FuncDecl()
delete function_; delete function_;
} }
void FuncDecl::Prepare() void FuncDecl::Prepare() { }
{
}
void FuncDecl::GenForwardDeclaration(Output *out_h) void FuncDecl::GenForwardDeclaration(Output* out_h)
{ {
function_->GenForwardDeclaration(out_h); function_->GenForwardDeclaration(out_h);
} }
void FuncDecl::GenCode(Output *out_h, Output *out_cc) void FuncDecl::GenCode(Output* out_h, Output* out_cc)
{ {
function_->GenCode(out_h, out_cc); function_->GenCode(out_h, out_cc);
} }
AnalyzerFunction::AnalyzerFunction(Function *function) AnalyzerFunction::AnalyzerFunction(Function* function)
: AnalyzerElement(FUNCTION), function_(function) : AnalyzerElement(FUNCTION), function_(function)
{ {
} }

View file

@ -1,68 +1,68 @@
#ifndef pac_func_h #ifndef pac_func_h
#define pac_func_h #define pac_func_h
#include "pac_decl.h"
#include "pac_analyzer.h" #include "pac_analyzer.h"
#include "pac_decl.h"
class Function : public Object class Function : public Object
{ {
public: public:
Function(ID *id, Type *type, ParamList *params); Function(ID* id, Type* type, ParamList* params);
~Function(); ~Function();
ID *id() const { return id_; } ID* id() const { return id_; }
AnalyzerDecl *analyzer_decl() const { return analyzer_decl_; } AnalyzerDecl* analyzer_decl() const { return analyzer_decl_; }
void set_analyzer_decl(AnalyzerDecl *decl) { analyzer_decl_ = decl; } void set_analyzer_decl(AnalyzerDecl* decl) { analyzer_decl_ = decl; }
Expr *expr() const { return expr_; } Expr* expr() const { return expr_; }
void set_expr(Expr *expr) { expr_ = expr; } void set_expr(Expr* expr) { expr_ = expr; }
EmbeddedCode *code() const { return code_; } EmbeddedCode* code() const { return code_; }
void set_code(EmbeddedCode *code) { code_ = code; } void set_code(EmbeddedCode* code) { code_ = code; }
void Prepare(Env *env); void Prepare(Env* env);
void GenForwardDeclaration(Output *out_h); void GenForwardDeclaration(Output* out_h);
void GenCode(Output *out_h, Output *out_cc); void GenCode(Output* out_h, Output* out_cc);
private: private:
Env *env_; Env* env_;
ID *id_; ID* id_;
Type *type_; Type* type_;
ParamList *params_; ParamList* params_;
AnalyzerDecl *analyzer_decl_; AnalyzerDecl* analyzer_decl_;
Expr *expr_; Expr* expr_;
EmbeddedCode *code_; EmbeddedCode* code_;
}; };
class FuncDecl : public Decl class FuncDecl : public Decl
{ {
public: public:
FuncDecl(Function *function); FuncDecl(Function* function);
~FuncDecl(); ~FuncDecl();
Function *function() const { return function_; } Function* function() const { return function_; }
void Prepare(); void Prepare();
void GenForwardDeclaration(Output *out_h); void GenForwardDeclaration(Output* out_h);
void GenCode(Output *out_h, Output *out_cc); void GenCode(Output* out_h, Output* out_cc);
private: private:
Function *function_; Function* function_;
}; };
class AnalyzerFunction : public AnalyzerElement class AnalyzerFunction : public AnalyzerElement
{ {
public: public:
AnalyzerFunction(Function *function); AnalyzerFunction(Function* function);
Function *function() const { return function_; } Function* function() const { return function_; }
private: private:
Function *function_; Function* function_;
}; };
#endif // pac_func_h #endif // pac_func_h

View file

@ -1,56 +1,57 @@
#include "pac_id.h"
#include "pac_exception.h" #include "pac_exception.h"
#include "pac_expr.h" #include "pac_expr.h"
#include "pac_exttype.h" #include "pac_exttype.h"
#include "pac_field.h" #include "pac_field.h"
#include "pac_id.h"
#include "pac_type.h" #include "pac_type.h"
#include "pac_utils.h" #include "pac_utils.h"
const ID *default_value_var = 0; const ID* default_value_var = 0;
const ID *null_id = 0; const ID* null_id = 0;
const ID *null_byteseg_id = 0; const ID* null_byteseg_id = 0;
const ID *null_decl_id = 0; const ID* null_decl_id = 0;
const ID *begin_of_data = 0; const ID* begin_of_data = 0;
const ID *end_of_data = 0; const ID* end_of_data = 0;
const ID *len_of_data = 0; const ID* len_of_data = 0;
const ID *byteorder_id = 0; const ID* byteorder_id = 0;
const ID *bigendian_id = 0; const ID* bigendian_id = 0;
const ID *littleendian_id = 0; const ID* littleendian_id = 0;
const ID *unspecified_byteorder_id = 0; const ID* unspecified_byteorder_id = 0;
const ID *const_true_id = 0; const ID* const_true_id = 0;
const ID *const_false_id = 0; const ID* const_false_id = 0;
const ID *analyzer_context_id = 0; const ID* analyzer_context_id = 0;
const ID *context_macro_id = 0; const ID* context_macro_id = 0;
const ID *this_id = 0; const ID* this_id = 0;
const ID *sourcedata_id = 0; const ID* sourcedata_id = 0;
const ID *connection_id = 0; const ID* connection_id = 0;
const ID *upflow_id = 0; const ID* upflow_id = 0;
const ID *downflow_id = 0; const ID* downflow_id = 0;
const ID *dataunit_id = 0; const ID* dataunit_id = 0;
const ID *flow_buffer_id = 0; const ID* flow_buffer_id = 0;
const ID *element_macro_id = 0; const ID* element_macro_id = 0;
const ID *input_macro_id = 0; const ID* input_macro_id = 0;
const ID *cxt_connection_id = 0; const ID* cxt_connection_id = 0;
const ID *cxt_flow_id = 0; const ID* cxt_flow_id = 0;
const ID *parsing_state_id = 0; const ID* parsing_state_id = 0;
const ID *buffering_state_id = 0; const ID* buffering_state_id = 0;
int ID::anonymous_id_seq = 0; int ID::anonymous_id_seq = 0;
ID *ID::NewAnonymousID(const string &prefix) ID* ID::NewAnonymousID(const string& prefix)
{ {
ID *id = new ID(strfmt("%s%03d", prefix.c_str(), ++anonymous_id_seq)); ID* id = new ID(strfmt("%s%03d", prefix.c_str(), ++anonymous_id_seq));
id->anonymous_id_ = true; id->anonymous_id_ = true;
return id; return id;
} }
IDRecord::IDRecord(Env *arg_env, const ID* arg_id, IDType arg_id_type) IDRecord::IDRecord(Env* arg_env, const ID* arg_id, IDType arg_id_type)
: env(arg_env), id(arg_id), id_type(arg_id_type) : env(arg_env), id(arg_id), id_type(arg_id_type)
{ {
eval = 0; eval = 0;
evaluated = in_evaluation = false; evaluated = in_evaluation = false;
setfunc = ""; // except for STATE_VAR setfunc = ""; // except for STATE_VAR
switch (id_type) switch ( id_type )
{ {
case MEMBER_VAR: case MEMBER_VAR:
rvalue = strfmt("%s()", id->Name()); rvalue = strfmt("%s()", id->Name());
@ -96,9 +97,7 @@ IDRecord::IDRecord(Env *arg_env, const ID* arg_id, IDType arg_id_type)
macro = 0; macro = 0;
} }
IDRecord::~IDRecord() IDRecord::~IDRecord() { }
{
}
void IDRecord::SetConstant(int c) void IDRecord::SetConstant(int c)
{ {
@ -107,20 +106,20 @@ void IDRecord::SetConstant(int c)
constant = c; constant = c;
} }
bool IDRecord::GetConstant(int *pc) const bool IDRecord::GetConstant(int* pc) const
{ {
if ( constant_set ) if ( constant_set )
*pc = constant; *pc = constant;
return constant_set; return constant_set;
} }
void IDRecord::SetMacro(Expr *e) void IDRecord::SetMacro(Expr* e)
{ {
ASSERT(id_type == MACRO); ASSERT(id_type == MACRO);
macro = e; macro = e;
} }
Expr *IDRecord::GetMacro() const Expr* IDRecord::GetMacro() const
{ {
ASSERT(id_type == MACRO); ASSERT(id_type == MACRO);
return macro; return macro;
@ -187,7 +186,7 @@ Env::~Env()
} }
} }
void Env::AddID(const ID* id, IDType id_type, Type *data_type) void Env::AddID(const ID* id, IDType id_type, Type* data_type)
{ {
DEBUG_MSG("To add ID `%s'...\n", id->Name()); DEBUG_MSG("To add ID `%s'...\n", id->Name());
id_map_t::iterator it = id_map.find(id); id_map_t::iterator it = id_map.find(id);
@ -202,7 +201,7 @@ void Env::AddID(const ID* id, IDType id_type, Type *data_type)
SetDataType(id, data_type); SetDataType(id, data_type);
} }
void Env::AddConstID(const ID* id, const int c, Type *type) void Env::AddConstID(const ID* id, const int c, Type* type)
{ {
if ( ! type ) if ( ! type )
type = extern_type_int; type = extern_type_int;
@ -211,16 +210,16 @@ void Env::AddConstID(const ID* id, const int c, Type *type)
SetEvaluated(id); // a constant is always evaluated SetEvaluated(id); // a constant is always evaluated
} }
void Env::AddMacro(const ID *id, Expr *macro) void Env::AddMacro(const ID* id, Expr* macro)
{ {
AddID(id, MACRO, macro->DataType(this)); AddID(id, MACRO, macro->DataType(this));
SetMacro(id, macro); SetMacro(id, macro);
SetEvaluated(id); SetEvaluated(id);
} }
ID *Env::AddTempID(Type *type) ID* Env::AddTempID(Type* type)
{ {
ID *id = ID::NewAnonymousID("t_var_"); ID* id = ID::NewAnonymousID("t_var_");
AddID(id, TEMP_VAR, type); AddID(id, TEMP_VAR, type);
return id; return id;
} }
@ -249,7 +248,7 @@ IDType Env::GetIDType(const ID* id) const
const char* Env::RValue(const ID* id) const const char* Env::RValue(const ID* id) const
{ {
IDRecord *r = lookup(id, true, false); IDRecord* r = lookup(id, true, false);
if ( r ) if ( r )
return r->RValue(); return r->RValue();
else else
@ -273,14 +272,14 @@ void Env::SetEvalMethod(const ID* id, Evaluatable* eval)
void Env::Evaluate(Output* out, const ID* id) void Env::Evaluate(Output* out, const ID* id)
{ {
IDRecord *r = lookup(id, true, !allow_undefined_id()); IDRecord* r = lookup(id, true, ! allow_undefined_id());
if ( r ) if ( r )
r->Evaluate(out, this); r->Evaluate(out, this);
} }
bool Env::Evaluated(const ID* id) const bool Env::Evaluated(const ID* id) const
{ {
IDRecord *r = lookup(id, true, !allow_undefined_id()); IDRecord* r = lookup(id, true, ! allow_undefined_id());
if ( r ) if ( r )
return r->Evaluated(); return r->Evaluated();
else else
@ -292,23 +291,20 @@ void Env::SetEvaluated(const ID* id, bool v)
{ {
if ( in_branch() ) if ( in_branch() )
{ {
Field *f = GetField(id); Field* f = GetField(id);
if (f && f->tof() == LET_FIELD) if ( f && f->tof() == LET_FIELD )
{ {
throw Exception( throw Exception(context_object_, strfmt("INTERNAL ERROR: "
context_object_,
strfmt("INTERNAL ERROR: "
"evaluating let field '%s' in a branch! " "evaluating let field '%s' in a branch! "
"To work around this problem, " "To work around this problem, "
"add '&requires(%s)' to the case type. " "add '&requires(%s)' to the case type. "
"Sorry for the inconvenience.\n", "Sorry for the inconvenience.\n",
id->Name(), id->Name(), id->Name()));
id->Name()));
ASSERT(0); ASSERT(0);
} }
} }
IDRecord *r = lookup(id, false, false); IDRecord* r = lookup(id, false, false);
if ( r ) if ( r )
r->SetEvaluated(v); r->SetEvaluated(v);
else if ( parent ) else if ( parent )
@ -334,16 +330,16 @@ void Env::SetDataType(const ID* id, Type* type)
Type* Env::GetDataType(const ID* id) const Type* Env::GetDataType(const ID* id) const
{ {
IDRecord *r = lookup(id, true, false); IDRecord* r = lookup(id, true, false);
if ( r ) if ( r )
return r->GetDataType(); return r->GetDataType();
else else
return 0; return 0;
} }
string Env::DataTypeStr(const ID *id) const string Env::DataTypeStr(const ID* id) const
{ {
Type *type = GetDataType(id); Type* type = GetDataType(id);
if ( ! type ) if ( ! type )
throw Exception(id, "data type not defined"); throw Exception(id, "data type not defined");
return type->DataTypeStr(); return type->DataTypeStr();
@ -365,7 +361,7 @@ bool Env::GetConstant(const ID* id, int* pc) const
return false; return false;
} }
void Env::SetMacro(const ID* id, Expr *macro) void Env::SetMacro(const ID* id, Expr* macro)
{ {
lookup(id, true, true)->SetMacro(macro); lookup(id, true, true)->SetMacro(macro);
} }
@ -409,7 +405,7 @@ void init_builtin_identifiers()
Env* global_env() Env* global_env()
{ {
static Env *the_global_env = 0; static Env* the_global_env = 0;
if ( ! the_global_env ) if ( ! the_global_env )
{ {
@ -436,7 +432,7 @@ Env* global_env()
return the_global_env; return the_global_env;
} }
string set_function(const ID *id) string set_function(const ID* id)
{ {
return strfmt("set_%s", id->Name()); return strfmt("set_%s", id->Name());
} }

View file

@ -22,7 +22,8 @@ using namespace std;
// Env -- a mapping from ID names to their L/R-value expressions and evaluation // Env -- a mapping from ID names to their L/R-value expressions and evaluation
// methods. // methods.
enum IDType { enum IDType
{
CONST, CONST,
GLOBAL_VAR, GLOBAL_VAR,
TEMP_VAR, TEMP_VAR,
@ -33,7 +34,7 @@ enum IDType {
MACRO, MACRO,
FUNC_ID, FUNC_ID,
FUNC_PARAM, FUNC_PARAM,
}; };
class ID; class ID;
class IDRecord; class IDRecord;
@ -41,112 +42,109 @@ class Env;
class Evaluatable; class Evaluatable;
class ID : public Object class ID : public Object
{ {
public: public:
ID(string arg_name) ID(string arg_name) : name(arg_name), anonymous_id_(false)
: name(arg_name), anonymous_id_(false)
{ {
locname = nfmt("%s:%s", Location(), Name()); locname = nfmt("%s:%s", Location(), Name());
} }
~ID() ~ID() { delete[] locname; }
{
delete [] locname;
}
bool operator==(ID const &x) const { return name == x.Name(); } bool operator==(ID const& x) const { return name == x.Name(); }
const char *Name() const { return name.c_str(); } const char* Name() const { return name.c_str(); }
const char *LocName() const { return locname; } const char* LocName() const { return locname; }
bool is_anonymous() const { return anonymous_id_; } bool is_anonymous() const { return anonymous_id_; }
ID *clone() const { return new ID(Name()); } ID* clone() const { return new ID(Name()); }
protected: protected:
string name; string name;
bool anonymous_id_; bool anonymous_id_;
char *locname; char* locname;
friend class ID_ptr_cmp; friend class ID_ptr_cmp;
public: public:
static ID *NewAnonymousID(const string &prefix); static ID* NewAnonymousID(const string& prefix);
private: private:
static int anonymous_id_seq; static int anonymous_id_seq;
}; };
// A comparison operator for pointers to ID's. // A comparison operator for pointers to ID's.
class ID_ptr_cmp class ID_ptr_cmp
{ {
public: public:
bool operator()(const ID *const & id1, const ID *const & id2) const bool operator()(const ID* const& id1, const ID* const& id2) const
{ {
ASSERT(id1); ASSERT(id1);
ASSERT(id2); ASSERT(id2);
return id1->name < id2->name; return id1->name < id2->name;
} }
}; };
class IDRecord class IDRecord
{ {
public: public:
IDRecord(Env *env, const ID *id, IDType id_type); IDRecord(Env* env, const ID* id, IDType id_type);
~IDRecord(); ~IDRecord();
IDType GetType() const { return id_type; } IDType GetType() const { return id_type; }
void SetDataType(Type *type) { data_type = type; } void SetDataType(Type* type) { data_type = type; }
Type *GetDataType() const { return data_type; } Type* GetDataType() const { return data_type; }
void SetEvalMethod(Evaluatable *arg_eval) { eval = arg_eval; } void SetEvalMethod(Evaluatable* arg_eval) { eval = arg_eval; }
void Evaluate(Output *out, Env *env); void Evaluate(Output* out, Env* env);
void SetEvaluated(bool v); void SetEvaluated(bool v);
bool Evaluated() const { return evaluated; } bool Evaluated() const { return evaluated; }
void SetField(Field *f) { field = f; } void SetField(Field* f) { field = f; }
Field *GetField() const { return field; } Field* GetField() const { return field; }
void SetConstant(int c); void SetConstant(int c);
bool GetConstant(int *pc) const; bool GetConstant(int* pc) const;
void SetMacro(Expr *expr); void SetMacro(Expr* expr);
Expr *GetMacro() const; Expr* GetMacro() const;
const char * RValue() const; const char* RValue() const;
const char * LValue() const; const char* LValue() const;
protected: protected:
Env *env; Env* env;
const ID *id; const ID* id;
IDType id_type; IDType id_type;
string rvalue; string rvalue;
string lvalue; string lvalue;
string setfunc; string setfunc;
Type *data_type; Type* data_type;
Field *field; Field* field;
int constant; int constant;
bool constant_set; bool constant_set;
Expr *macro; Expr* macro;
bool evaluated; bool evaluated;
bool in_evaluation; // to detect cyclic dependence bool in_evaluation; // to detect cyclic dependence
Evaluatable *eval; Evaluatable* eval;
}; };
class Evaluatable class Evaluatable
{ {
public: public:
virtual ~Evaluatable() {} virtual ~Evaluatable() { }
virtual void GenEval(Output *out, Env *env) = 0; virtual void GenEval(Output* out, Env* env) = 0;
}; };
class Env class Env
{ {
public: public:
Env(Env *parent_env, Object *context_object); Env(Env* parent_env, Object* context_object);
~Env(); ~Env();
bool allow_undefined_id() const { return allow_undefined_id_; } bool allow_undefined_id() const { return allow_undefined_id_; }
@ -155,92 +153,90 @@ public:
bool in_branch() const { return in_branch_; } bool in_branch() const { return in_branch_; }
void set_in_branch(bool x) { in_branch_ = x; } void set_in_branch(bool x) { in_branch_ = x; }
void AddID(const ID *id, IDType id_type, Type *type); void AddID(const ID* id, IDType id_type, Type* type);
void AddConstID(const ID *id, const int c, Type *type = 0); void AddConstID(const ID* id, const int c, Type* type = 0);
void AddMacro(const ID *id, Expr *expr); void AddMacro(const ID* id, Expr* expr);
// Generate a temp ID with a unique name // Generate a temp ID with a unique name
ID *AddTempID(Type *type); ID* AddTempID(Type* type);
IDType GetIDType(const ID *id) const; IDType GetIDType(const ID* id) const;
const char * RValue(const ID *id) const; const char* RValue(const ID* id) const;
const char * LValue(const ID *id) const; const char* LValue(const ID* id) const;
// const char *SetFunc(const ID *id) const; // const char *SetFunc(const ID *id) const;
// Set evaluation method for the ID // Set evaluation method for the ID
void SetEvalMethod(const ID *id, Evaluatable *eval); void SetEvalMethod(const ID* id, Evaluatable* eval);
// Evaluate the ID according to the evaluation method. It // Evaluate the ID according to the evaluation method. It
// assumes the ID has an evaluation emthod. It does nothing // assumes the ID has an evaluation emthod. It does nothing
// if the ID has already been evaluated. // if the ID has already been evaluated.
void Evaluate(Output *out, const ID *id); void Evaluate(Output* out, const ID* id);
// Whether the ID has already been evaluated. // Whether the ID has already been evaluated.
bool Evaluated(const ID *id) const; bool Evaluated(const ID* id) const;
// Set the ID as evaluated (or not). // Set the ID as evaluated (or not).
void SetEvaluated(const ID *id, bool v = true); void SetEvaluated(const ID* id, bool v = true);
void SetField(const ID *id, Field *field); void SetField(const ID* id, Field* field);
Field *GetField(const ID *id) const; Field* GetField(const ID* id) const;
bool GetConstant(const ID *id, int *pc) const; bool GetConstant(const ID* id, int* pc) const;
Expr *GetMacro(const ID *id) const; Expr* GetMacro(const ID* id) const;
Type *GetDataType(const ID *id) const; Type* GetDataType(const ID* id) const;
string DataTypeStr(const ID *id) const; string DataTypeStr(const ID* id) const;
protected: protected:
IDRecord *lookup(const ID *id, IDRecord* lookup(const ID* id, bool recursive, bool raise_exception) const;
bool recursive,
bool raise_exception) const;
void SetDataType(const ID *id, Type *type); void SetDataType(const ID* id, Type* type);
void SetConstant(const ID *id, int constant); void SetConstant(const ID* id, int constant);
void SetMacro(const ID *id, Expr *macro); void SetMacro(const ID* id, Expr* macro);
private: private:
Env *parent; Env* parent;
Object *context_object_; Object* context_object_;
typedef map<const ID*, IDRecord*, ID_ptr_cmp> id_map_t; typedef map<const ID*, IDRecord*, ID_ptr_cmp> id_map_t;
id_map_t id_map; id_map_t id_map;
bool allow_undefined_id_; bool allow_undefined_id_;
bool in_branch_; bool in_branch_;
}; };
extern const ID *default_value_var; extern const ID* default_value_var;
extern const ID *null_id; extern const ID* null_id;
extern const ID *null_byteseg_id; extern const ID* null_byteseg_id;
extern const ID *begin_of_data; extern const ID* begin_of_data;
extern const ID *end_of_data; extern const ID* end_of_data;
extern const ID *len_of_data; extern const ID* len_of_data;
extern const ID *byteorder_id; extern const ID* byteorder_id;
extern const ID *bigendian_id; extern const ID* bigendian_id;
extern const ID *littleendian_id; extern const ID* littleendian_id;
extern const ID *unspecified_byteorder_id; extern const ID* unspecified_byteorder_id;
extern const ID *analyzer_context_id; extern const ID* analyzer_context_id;
extern const ID *context_macro_id; extern const ID* context_macro_id;
extern const ID *this_id; extern const ID* this_id;
extern const ID *sourcedata_id; extern const ID* sourcedata_id;
// extern const ID *sourcedata_begin_id; // extern const ID *sourcedata_begin_id;
// extern const ID *sourcedata_end_id; // extern const ID *sourcedata_end_id;
extern const ID *connection_id; extern const ID* connection_id;
extern const ID *upflow_id; extern const ID* upflow_id;
extern const ID *downflow_id; extern const ID* downflow_id;
extern const ID *dataunit_id; extern const ID* dataunit_id;
extern const ID *flow_buffer_id; extern const ID* flow_buffer_id;
extern const ID *element_macro_id; extern const ID* element_macro_id;
extern const ID *cxt_connection_id; extern const ID* cxt_connection_id;
extern const ID *cxt_flow_id; extern const ID* cxt_flow_id;
extern const ID *input_macro_id; extern const ID* input_macro_id;
extern const ID *parsing_state_id; extern const ID* parsing_state_id;
extern const ID *buffering_state_id; extern const ID* buffering_state_id;
extern void init_builtin_identifiers(); extern void init_builtin_identifiers();
extern Env *global_env(); extern Env* global_env();
extern string set_function(const ID *id); extern string set_function(const ID* id);
#endif // pac_id_h #endif // pac_id_h

View file

@ -1,16 +1,14 @@
#include "pac_inputbuf.h"
#include "pac_expr.h" #include "pac_expr.h"
#include "pac_exttype.h" #include "pac_exttype.h"
#include "pac_id.h" #include "pac_id.h"
#include "pac_inputbuf.h"
#include "pac_output.h" #include "pac_output.h"
#include "pac_type.h" #include "pac_type.h"
InputBuffer::InputBuffer(Expr *expr) InputBuffer::InputBuffer(Expr* expr) : DataDepElement(INPUT_BUFFER), expr_(expr) { }
: DataDepElement(INPUT_BUFFER), expr_(expr)
{
}
bool InputBuffer::DoTraverse(DataDepVisitor *visitor) bool InputBuffer::DoTraverse(DataDepVisitor* visitor)
{ {
if ( expr_ && ! expr_->Traverse(visitor) ) if ( expr_ && ! expr_->Traverse(visitor) )
return false; return false;
@ -22,20 +20,16 @@ bool InputBuffer::RequiresAnalyzerContext() const
return expr_->RequiresAnalyzerContext(); return expr_->RequiresAnalyzerContext();
} }
DataPtr InputBuffer::GenDataBeginEnd(Output *out_cc, Env *env) DataPtr InputBuffer::GenDataBeginEnd(Output* out_cc, Env* env)
{ {
env->AddID(begin_of_data, TEMP_VAR, extern_type_const_byteptr); env->AddID(begin_of_data, TEMP_VAR, extern_type_const_byteptr);
env->AddID(end_of_data, TEMP_VAR, extern_type_const_byteptr); env->AddID(end_of_data, TEMP_VAR, extern_type_const_byteptr);
out_cc->println("%s %s, %s;", out_cc->println("%s %s, %s;", extern_type_const_byteptr->DataTypeStr().c_str(),
extern_type_const_byteptr->DataTypeStr().c_str(), env->LValue(begin_of_data), env->LValue(end_of_data));
env->LValue(begin_of_data),
env->LValue(end_of_data));
out_cc->println("get_pointers(%s, &%s, &%s);", out_cc->println("get_pointers(%s, &%s, &%s);", expr_->EvalExpr(out_cc, env),
expr_->EvalExpr(out_cc, env), env->LValue(begin_of_data), env->LValue(end_of_data));
env->LValue(begin_of_data),
env->LValue(end_of_data));
env->SetEvaluated(begin_of_data); env->SetEvaluated(begin_of_data);
env->SetEvaluated(end_of_data); env->SetEvaluated(end_of_data);

View file

@ -7,18 +7,18 @@
class Expr; class Expr;
class InputBuffer : public Object, public DataDepElement class InputBuffer : public Object, public DataDepElement
{ {
public: public:
InputBuffer(Expr *expr); InputBuffer(Expr* expr);
bool RequiresAnalyzerContext() const; bool RequiresAnalyzerContext() const;
DataPtr GenDataBeginEnd(Output *out_cc, Env *env); DataPtr GenDataBeginEnd(Output* out_cc, Env* env);
protected: protected:
bool DoTraverse(DataDepVisitor *visitor); bool DoTraverse(DataDepVisitor* visitor);
private: private:
Expr *expr_; Expr* expr_;
}; };
#endif // pac_inputbuf_h #endif // pac_inputbuf_h

View file

@ -1,21 +1,19 @@
#include "pac_let.h"
#include "pac_expr.h" #include "pac_expr.h"
#include "pac_exttype.h" #include "pac_exttype.h"
#include "pac_let.h"
#include "pac_output.h" #include "pac_output.h"
#include "pac_type.h" #include "pac_type.h"
namespace { namespace
void GenLetEval(const ID *id, Expr *expr, string prefix, Output* out, Env* env)
{ {
}
} // private namespace void GenLetEval(const ID* id, Expr* expr, string prefix, Output* out, Env* env) { }
LetField::LetField(ID* id, Type *type, Expr* expr) } // private namespace
: Field(LET_FIELD,
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, LetField::LetField(ID* id, Type* type, Expr* expr)
id, type), : Field(LET_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type),
expr_(expr) expr_(expr)
{ {
ASSERT(expr_); ASSERT(expr_);
@ -26,16 +24,14 @@ LetField::~LetField()
delete expr_; delete expr_;
} }
bool LetField::DoTraverse(DataDepVisitor *visitor) bool LetField::DoTraverse(DataDepVisitor* visitor)
{ {
return Field::DoTraverse(visitor) && return Field::DoTraverse(visitor) && expr()->Traverse(visitor);
expr()->Traverse(visitor);
} }
bool LetField::RequiresAnalyzerContext() const bool LetField::RequiresAnalyzerContext() const
{ {
return Field::RequiresAnalyzerContext() || return Field::RequiresAnalyzerContext() || (expr() && expr()->RequiresAnalyzerContext());
(expr() && expr()->RequiresAnalyzerContext());
} }
void LetField::Prepare(Env* env) void LetField::Prepare(Env* env)
@ -49,7 +45,7 @@ void LetField::Prepare(Env* env)
else else
type_ = extern_type_int->Clone(); type_ = extern_type_int->Clone();
foreach(i, AttrList, attrs_) foreach (i, AttrList, attrs_)
ProcessAttr(*i); ProcessAttr(*i);
} }
@ -83,15 +79,12 @@ void LetField::GenParseCode(Output* out_cc, Env* env)
// force evaluation of IDs contained in this expr // force evaluation of IDs contained in this expr
expr()->ForceIDEval(out_cc, env); expr()->ForceIDEval(out_cc, env);
out_cc->println("if ( %s )", out_cc->println("if ( %s )", env->RValue(type_->has_value_var()));
env->RValue(type_->has_value_var()));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
} }
out_cc->println("%s = %s;", out_cc->println("%s = %s;", env->LValue(id_), expr()->EvalExpr(out_cc, env));
env->LValue(id_),
expr()->EvalExpr(out_cc, env));
if ( ! env->Evaluated(id_) ) if ( ! env->Evaluated(id_) )
env->SetEvaluated(id_); env->SetEvaluated(id_);
@ -107,8 +100,7 @@ void LetField::GenEval(Output* out_cc, Env* env)
GenParseCode(out_cc, env); GenParseCode(out_cc, env);
} }
LetDecl::LetDecl(ID *id, Type *type, Expr *expr) LetDecl::LetDecl(ID* id, Type* type, Expr* expr) : Decl(id, LET), type_(type), expr_(expr)
: Decl(id, LET), type_(type), expr_(expr)
{ {
if ( ! type_ ) if ( ! type_ )
{ {
@ -120,7 +112,7 @@ LetDecl::LetDecl(ID *id, Type *type, Expr *expr)
type_ = extern_type_int->Clone(); type_ = extern_type_int->Clone();
} }
Env *env = global_env(); Env* env = global_env();
int c; int c;
if ( expr_ && expr_->ConstFold(env, &c) ) if ( expr_ && expr_->ConstFold(env, &c) )
env->AddConstID(id_, c, type); env->AddConstID(id_, c, type);
@ -134,30 +126,21 @@ LetDecl::~LetDecl()
delete expr_; delete expr_;
} }
void LetDecl::Prepare() void LetDecl::Prepare() { }
{
}
void LetDecl::GenForwardDeclaration(Output* out_h) void LetDecl::GenForwardDeclaration(Output* out_h) { }
{
}
void LetDecl::GenCode(Output * out_h, Output *out_cc) void LetDecl::GenCode(Output* out_h, Output* out_cc)
{ {
out_h->println("extern %s const %s;", out_h->println("extern %s const %s;", type_->DataTypeStr().c_str(), global_env()->RValue(id_));
type_->DataTypeStr().c_str(),
global_env()->RValue(id_));
GenEval(out_cc, global_env()); GenEval(out_cc, global_env());
} }
void LetDecl::GenEval(Output *out_cc, Env * /* env */) void LetDecl::GenEval(Output* out_cc, Env* /* env */)
{ {
Env *env = global_env(); Env* env = global_env();
string tmp = strfmt("%s const", type_->DataTypeStr().c_str()); string tmp = strfmt("%s const", type_->DataTypeStr().c_str());
out_cc->println("%s %s = %s;", out_cc->println("%s %s = %s;", tmp.c_str(), env->LValue(id_), expr_->EvalExpr(out_cc, env));
tmp.c_str(),
env->LValue(id_),
expr_->EvalExpr(out_cc, env));
if ( ! env->Evaluated(id_) ) if ( ! env->Evaluated(id_) )
env->SetEvaluated(id_); env->SetEvaluated(id_);

View file

@ -5,12 +5,12 @@
#include "pac_field.h" #include "pac_field.h"
class LetField : public Field, Evaluatable class LetField : public Field, Evaluatable
{ {
public: public:
LetField(ID* arg_id, Type *type, Expr* arg_expr); LetField(ID* arg_id, Type* type, Expr* arg_expr);
~LetField(); ~LetField();
Expr *expr() const { return expr_; } Expr* expr() const { return expr_; }
void Prepare(Env* env); void Prepare(Env* env);
@ -21,28 +21,28 @@ public:
bool RequiresAnalyzerContext() const; bool RequiresAnalyzerContext() const;
protected: protected:
bool DoTraverse(DataDepVisitor *visitor); bool DoTraverse(DataDepVisitor* visitor);
protected: protected:
Expr* expr_; Expr* expr_;
}; };
class LetDecl : public Decl, Evaluatable class LetDecl : public Decl, Evaluatable
{ {
public: public:
LetDecl(ID *id, Type *type, Expr *expr); LetDecl(ID* id, Type* type, Expr* expr);
~LetDecl(); ~LetDecl();
Expr *expr() const { return expr_; } Expr* expr() const { return expr_; }
void Prepare(); void Prepare();
void GenForwardDeclaration(Output *out_h); void GenForwardDeclaration(Output* out_h);
void GenCode(Output *out_h, Output *out_cc); void GenCode(Output* out_h, Output* out_cc);
void GenEval(Output* out, Env* env); void GenEval(Output* out, Env* env);
private: private:
Type *type_; Type* type_;
Expr *expr_; Expr* expr_;
}; };
#endif // pac_let_h #endif // pac_let_h

View file

@ -1,17 +1,16 @@
#include <unistd.h>
#include <ctype.h> #include <ctype.h>
#include <unistd.h>
#include "config.h"
#include "pac_common.h" #include "pac_common.h"
#include "pac_decl.h" #include "pac_decl.h"
#include "pac_exception.h"
#include "pac_exttype.h" #include "pac_exttype.h"
#include "pac_id.h" #include "pac_id.h"
#include "pac_output.h" #include "pac_output.h"
#include "pac_parse.h" #include "pac_parse.h"
#include "pac_type.h" #include "pac_type.h"
#include "pac_utils.h" #include "pac_utils.h"
#include "pac_exception.h"
#include "config.h"
extern int yydebug; extern int yydebug;
extern int yyparse(); extern int yyparse();
@ -31,7 +30,7 @@ void add_to_include_directories(string dirs)
unsigned int dir_begin = 0, dir_end; unsigned int dir_begin = 0, dir_end;
while ( dir_begin < dirs.length() ) while ( dir_begin < dirs.length() )
{ {
for ( dir_end = dir_begin; dir_end < dirs.length(); ++dir_end) for ( dir_end = dir_begin; dir_end < dirs.length(); ++dir_end )
if ( dirs[dir_end] == ':' ) if ( dirs[dir_end] == ':' )
break; break;
@ -54,8 +53,7 @@ void pac_init()
void insert_comments(Output* out, const char* source_filename) void insert_comments(Output* out, const char* source_filename)
{ {
out->println("// This file is automatically generated from %s.\n", out->println("// This file is automatically generated from %s.\n", source_filename);
source_filename);
} }
void insert_basictype_defs(Output* out) void insert_basictype_defs(Output* out)
@ -90,7 +88,7 @@ const char* to_id(const char* s)
{ {
static char t[1024]; static char t[1024];
int i; int i;
for ( i = 0; s[i] && i < (int) sizeof(t) - 1; ++i ) for ( i = 0; s[i] && i < (int)sizeof(t) - 1; ++i )
t[i] = isalnum(s[i]) ? s[i] : '_'; t[i] = isalnum(s[i]) ? s[i] : '_';
if ( isdigit(t[0]) ) if ( isdigit(t[0]) )
t[0] = '_'; t[0] = '_';
@ -114,7 +112,7 @@ int compile(const char* filename)
if ( ! FLAGS_output_directory.empty() ) if ( ! FLAGS_output_directory.empty() )
{ {
// Strip leading directories of filename // Strip leading directories of filename
const char *last_slash = strrchr(filename, '/'); const char* last_slash = strrchr(filename, '/');
if ( last_slash ) if ( last_slash )
basename = last_slash + 1; basename = last_slash + 1;
else else
@ -125,8 +123,7 @@ int compile(const char* filename)
basename = filename; basename = filename;
// If the file name ends with ".pac" // If the file name ends with ".pac"
if ( basename.length() > 4 && if ( basename.length() > 4 && basename.substr(basename.length() - 4) == ".pac" )
basename.substr(basename.length() - 4) == ".pac" )
{ {
basename = basename.substr(0, basename.length() - 4); basename = basename.substr(0, basename.length() - 4);
} }
@ -176,8 +173,7 @@ int compile(const char* filename)
} }
catch ( OutputException& e ) catch ( OutputException& e )
{ {
fprintf(stderr, "Error in compiling %s: %s\n", fprintf(stderr, "Error in compiling %s: %s\n", filename, e.errmsg());
filename, e.errmsg());
ret = 1; ret = 1;
} }
catch ( Exception& e ) catch ( Exception& e )
@ -211,21 +207,21 @@ void usage()
// GCC uses __SANITIZE_ADDRESS__, Clang uses __has_feature // GCC uses __SANITIZE_ADDRESS__, Clang uses __has_feature
#if defined(__SANITIZE_ADDRESS__) #if defined(__SANITIZE_ADDRESS__)
#define USING_ASAN #define USING_ASAN
#endif #endif
#if defined(__has_feature) #if defined(__has_feature)
#if __has_feature(address_sanitizer) #if __has_feature(address_sanitizer)
#define USING_ASAN #define USING_ASAN
#endif #endif
#endif #endif
// FreeBSD doesn't support LeakSanitizer // FreeBSD doesn't support LeakSanitizer
#if defined(USING_ASAN) && !defined(__FreeBSD__) #if defined(USING_ASAN) && ! defined(__FreeBSD__)
#include <sanitizer/lsan_interface.h> #include <sanitizer/lsan_interface.h>
#define BINPAC_LSAN_DISABLE(x) __lsan_disable(x) #define BINPAC_LSAN_DISABLE(x) __lsan_disable(x)
#else #else
#define BINPAC_LSAN_DISABLE(x) #define BINPAC_LSAN_DISABLE(x)
#endif #endif
int main(int argc, char* argv[]) int main(int argc, char* argv[])
@ -236,12 +232,12 @@ int main(int argc, char* argv[])
BINPAC_LSAN_DISABLE(); BINPAC_LSAN_DISABLE();
#ifdef HAVE_MALLOC_OPTIONS #ifdef HAVE_MALLOC_OPTIONS
extern char *malloc_options; extern char* malloc_options;
#endif #endif
int o; int o;
while ( (o = getopt(argc, argv, "DqI:d:h")) != -1 ) while ( (o = getopt(argc, argv, "DqI:d:h")) != -1 )
{ {
switch(o) switch ( o )
{ {
case 'D': case 'D':
yydebug = 1; yydebug = 1;
@ -271,10 +267,9 @@ int main(int argc, char* argv[])
} }
// Strip the trailing '/'s // Strip the trailing '/'s
while ( ! FLAGS_output_directory.empty() && while ( ! FLAGS_output_directory.empty() && *(FLAGS_output_directory.end() - 1) == '/' )
*(FLAGS_output_directory.end() - 1) == '/' )
{ {
FLAGS_output_directory.erase(FLAGS_output_directory.end()-1); FLAGS_output_directory.erase(FLAGS_output_directory.end() - 1);
} }
// Add the current directory to FLAGS_include_directories // Add the current directory to FLAGS_include_directories
@ -294,4 +289,3 @@ int main(int argc, char* argv[])
return ret; return ret;
} }

View file

@ -4,18 +4,16 @@
#include "pac_common.h" #include "pac_common.h"
class Number : public Object class Number : public Object
{ {
public: public:
Number(int arg_n) Number(int arg_n) : s(strfmt("%d", arg_n)), n(arg_n) { }
: s(strfmt("%d", arg_n)), n(arg_n) {} Number(const char* arg_s, int arg_n) : s(arg_s), n(arg_n) { }
Number(const char* arg_s, int arg_n)
: s(arg_s), n(arg_n) {}
const char* Str() const { return s.c_str(); } const char* Str() const { return s.c_str(); }
int Num() const { return n; } int Num() const { return n; }
protected: protected:
const string s; const string s;
const int n; const int n;
}; };
#endif // pac_number_h #endif // pac_number_h

View file

@ -1,19 +1,18 @@
#include <string.h> #include "pac_output.h"
#include <errno.h> #include <errno.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "pac_utils.h" #include "pac_utils.h"
#include "pac_output.h"
OutputException::OutputException(const char* arg_msg) OutputException::OutputException(const char* arg_msg)
{ {
msg = arg_msg; msg = arg_msg;
} }
OutputException::~OutputException() OutputException::~OutputException() { }
{
}
Output::Output(string filename) Output::Output(string filename)
{ {

View file

@ -1,13 +1,14 @@
#ifndef pac_output_h #ifndef pac_output_h
#define pac_output_h #define pac_output_h
#include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h>
#include <string> #include <string>
using namespace std; using namespace std;
class OutputException { class OutputException
{
public: public:
OutputException(const char* arg_msg); OutputException(const char* arg_msg);
~OutputException(); ~OutputException();
@ -15,9 +16,10 @@ public:
protected: protected:
string msg; string msg;
}; };
class Output { class Output
{
public: public:
Output(string filename); Output(string filename);
~Output(); ~Output();
@ -35,6 +37,6 @@ protected:
FILE* fp; FILE* fp;
int indent_; int indent_;
}; };
#endif /* pac_output_h */ #endif /* pac_output_h */

View file

@ -1,3 +1,5 @@
#include "pac_param.h"
#include "pac_decl.h" #include "pac_decl.h"
#include "pac_exttype.h" #include "pac_exttype.h"
#include "pac_field.h" #include "pac_field.h"
@ -6,32 +8,25 @@
#include "pac_type.h" #include "pac_type.h"
#include "pac_utils.h" #include "pac_utils.h"
#include "pac_param.h" Param::Param(ID* id, Type* type) : id_(id), type_(type)
Param::Param(ID* id, Type *type)
: id_(id), type_(type)
{ {
if ( ! type_ ) if ( ! type_ )
type_ = extern_type_int->Clone(); type_ = extern_type_int->Clone();
decl_str_ = strfmt("%s %s", decl_str_ = strfmt("%s %s", type_->DataTypeConstRefStr().c_str(), id_->Name());
type_->DataTypeConstRefStr().c_str(),
id_->Name());
param_field_ = new ParamField(this); param_field_ = new ParamField(this);
} }
Param::~Param() Param::~Param() { }
{
}
const string &Param::decl_str() const const string& Param::decl_str() const
{ {
ASSERT(!decl_str_.empty()); ASSERT(! decl_str_.empty());
return decl_str_; return decl_str_;
} }
string ParamDecls(ParamList *params) string ParamDecls(ParamList* params)
{ {
string param_decls; string param_decls;
@ -49,18 +44,15 @@ string ParamDecls(ParamList *params)
return param_decls; return param_decls;
} }
ParamField::ParamField(const Param *param) ParamField::ParamField(const Param* param)
: Field(PARAM_FIELD, : Field(PARAM_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, param->id(),
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
param->id(),
param->type()) param->type())
{ {
} }
void ParamField::GenInitCode(Output *out_cc, Env *env) void ParamField::GenInitCode(Output* out_cc, Env* env)
{ {
out_cc->println("%s = %s;", out_cc->println("%s = %s;", env->LValue(id()), id()->Name());
env->LValue(id()), id()->Name());
env->SetEvaluated(id()); env->SetEvaluated(id());
} }

View file

@ -5,34 +5,34 @@
#include "pac_field.h" #include "pac_field.h"
class Param : public Object class Param : public Object
{ {
public: public:
Param(ID* id, Type* type); Param(ID* id, Type* type);
~Param(); ~Param();
ID *id() const { return id_; } ID* id() const { return id_; }
Type *type() const { return type_; } Type* type() const { return type_; }
const string & decl_str() const; const string& decl_str() const;
Field *param_field() const { return param_field_; } Field* param_field() const { return param_field_; }
private: private:
ID* id_; ID* id_;
Type* type_; Type* type_;
string decl_str_; string decl_str_;
Field *param_field_; Field* param_field_;
}; };
class ParamField : public Field class ParamField : public Field
{ {
public: public:
ParamField(const Param *param); ParamField(const Param* param);
void GenInitCode(Output *out, Env *env); void GenInitCode(Output* out, Env* env);
void GenCleanUpCode(Output* out, Env* env); void GenCleanUpCode(Output* out, Env* env);
}; };
// Returns the string with a list of param declarations separated by ','. // Returns the string with a list of param declarations separated by ','.
string ParamDecls(ParamList *params); string ParamDecls(ParamList* params);
#if 0 #if 0
// Generate assignments to parameters, in the form of "%s_ = %s;" % (id, id). // Generate assignments to parameters, in the form of "%s_ = %s;" % (id, id).

View file

@ -1,9 +1,10 @@
#include "pac_paramtype.h"
#include "pac_context.h" #include "pac_context.h"
#include "pac_dataptr.h" #include "pac_dataptr.h"
#include "pac_exception.h" #include "pac_exception.h"
#include "pac_expr.h" #include "pac_expr.h"
#include "pac_output.h" #include "pac_output.h"
#include "pac_paramtype.h"
#include "pac_typedecl.h" #include "pac_typedecl.h"
ParameterizedType::ParameterizedType(ID* type_id, ExprList* args) ParameterizedType::ParameterizedType(ID* type_id, ExprList* args)
@ -12,13 +13,11 @@ ParameterizedType::ParameterizedType(ID* type_id, ExprList* args)
checking_requires_analyzer_context_ = false; checking_requires_analyzer_context_ = false;
} }
ParameterizedType::~ParameterizedType() ParameterizedType::~ParameterizedType() { }
{
}
string ParameterizedType::EvalMember(const ID *member_id) const string ParameterizedType::EvalMember(const ID* member_id) const
{ {
Type *ty = ReferredDataType(true); Type* ty = ReferredDataType(true);
return strfmt("->%s", ty->env()->RValue(member_id)); return strfmt("->%s", ty->env()->RValue(member_id));
} }
@ -27,12 +26,12 @@ string ParameterizedType::class_name() const
return type_id_->Name(); return type_id_->Name();
} }
Type *ParameterizedType::DoClone() const Type* ParameterizedType::DoClone() const
{ {
return new ParameterizedType(type_id_->clone(), args_); return new ParameterizedType(type_id_->clone(), args_);
} }
void ParameterizedType::AddParamArg(Expr *arg) void ParameterizedType::AddParamArg(Expr* arg)
{ {
args_->push_back(arg); args_->push_back(arg);
} }
@ -47,21 +46,20 @@ string ParameterizedType::DataTypeStr() const
return strfmt("%s *", type_id_->Name()); return strfmt("%s *", type_id_->Name());
} }
Type *ParameterizedType::MemberDataType(const ID *member_id) const Type* ParameterizedType::MemberDataType(const ID* member_id) const
{ {
Type *ref_type = TypeDecl::LookUpType(type_id_); Type* ref_type = TypeDecl::LookUpType(type_id_);
if ( ! ref_type ) if ( ! ref_type )
return 0; return 0;
return ref_type->MemberDataType(member_id); return ref_type->MemberDataType(member_id);
} }
Type *ParameterizedType::ReferredDataType(bool throw_exception) const Type* ParameterizedType::ReferredDataType(bool throw_exception) const
{ {
Type* type = TypeDecl::LookUpType(type_id_); Type* type = TypeDecl::LookUpType(type_id_);
if ( ! type ) if ( ! type )
{ {
DEBUG_MSG("WARNING: cannot find referenced type for %s\n", DEBUG_MSG("WARNING: cannot find referenced type for %s\n", type_id_->Name());
type_id_->Name());
if ( throw_exception ) if ( throw_exception )
throw ExceptionIDNotFound(type_id_); throw ExceptionIDNotFound(type_id_);
} }
@ -75,7 +73,7 @@ int ParameterizedType::StaticSize(Env* env) const
void ParameterizedType::DoMarkIncrementalInput() void ParameterizedType::DoMarkIncrementalInput()
{ {
Type *ty = ReferredDataType(true); Type* ty = ReferredDataType(true);
ty->MarkIncrementalInput(); ty->MarkIncrementalInput();
@ -93,7 +91,7 @@ Type::BufferMode ParameterizedType::buffer_mode() const
// use &length. // use &length.
// //
BufferMode mode = Type::buffer_mode(); BufferMode mode = Type::buffer_mode();
Type *ty = ReferredDataType(true); Type* ty = ReferredDataType(true);
if ( mode != NOT_BUFFERABLE ) if ( mode != NOT_BUFFERABLE )
return mode; return mode;
@ -110,16 +108,16 @@ bool ParameterizedType::ByteOrderSensitive() const
return ReferredDataType(true)->RequiresByteOrder(); return ReferredDataType(true)->RequiresByteOrder();
} }
bool ParameterizedType::DoTraverse(DataDepVisitor *visitor) bool ParameterizedType::DoTraverse(DataDepVisitor* visitor)
{ {
if ( ! Type::DoTraverse(visitor) ) if ( ! Type::DoTraverse(visitor) )
return false; return false;
foreach(i, ExprList, args_) foreach (i, ExprList, args_)
if ( ! (*i)->Traverse(visitor) ) if ( ! (*i)->Traverse(visitor) )
return false; return false;
Type *ty = ReferredDataType(false); Type* ty = ReferredDataType(false);
if ( ty && ! ty->Traverse(visitor) ) if ( ty && ! ty->Traverse(visitor) )
return false; return false;
@ -134,18 +132,17 @@ bool ParameterizedType::RequiresAnalyzerContext()
bool ret = false; bool ret = false;
// If any argument expression refers to analyzer context // If any argument expression refers to analyzer context
foreach(i, ExprList, args_) foreach (i, ExprList, args_)
if ( (*i)->RequiresAnalyzerContext() ) if ( (*i)->RequiresAnalyzerContext() )
{ {
ret = true; ret = true;
break; break;
} }
ret = ret || ret = ret || Type::RequiresAnalyzerContext();
Type::RequiresAnalyzerContext();
if ( ! ret ) if ( ! ret )
{ {
Type *ty = ReferredDataType(false); Type* ty = ReferredDataType(false);
if ( ty ) if ( ty )
ret = ty->RequiresAnalyzerContext(); ret = ty->RequiresAnalyzerContext();
} }
@ -163,7 +160,7 @@ void ParameterizedType::GenInitCode(Output* out_cc, Env* env)
void ParameterizedType::GenCleanUpCode(Output* out_cc, Env* env) void ParameterizedType::GenCleanUpCode(Output* out_cc, Env* env)
{ {
Type *ty = ReferredDataType(false); Type* ty = ReferredDataType(false);
if ( ty && ty->attr_refcount() ) if ( ty && ty->attr_refcount() )
out_cc->println("Unref(%s);", lvalue()); out_cc->println("Unref(%s);", lvalue());
else else
@ -172,7 +169,7 @@ void ParameterizedType::GenCleanUpCode(Output* out_cc, Env* env)
Type::GenCleanUpCode(out_cc, env); Type::GenCleanUpCode(out_cc, env);
} }
string ParameterizedType::EvalParameters(Output* out_cc, Env *env) const string ParameterizedType::EvalParameters(Output* out_cc, Env* env) const
{ {
string arg_str; string arg_str;
@ -190,27 +187,24 @@ string ParameterizedType::EvalParameters(Output* out_cc, Env *env) const
return arg_str; return arg_str;
} }
void ParameterizedType::GenNewInstance(Output *out_cc, Env *env) void ParameterizedType::GenNewInstance(Output* out_cc, Env* env)
{ {
out_cc->println("%s = new %s(%s);", out_cc->println("%s = new %s(%s);", lvalue(), type_id_->Name(),
lvalue(),
type_id_->Name(),
EvalParameters(out_cc, env).c_str()); EvalParameters(out_cc, env).c_str());
} }
void ParameterizedType::DoGenParseCode(Output* out_cc, Env* env, void ParameterizedType::DoGenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags)
const DataPtr& data, int flags)
{ {
DEBUG_MSG("DoGenParseCode for %s\n", type_id_->Name()); DEBUG_MSG("DoGenParseCode for %s\n", type_id_->Name());
Type *ref_type = ReferredDataType(true); Type* ref_type = ReferredDataType(true);
const char *parse_func; const char* parse_func;
string parse_params; string parse_params;
if ( buffer_mode() == BUFFER_NOTHING ) if ( buffer_mode() == BUFFER_NOTHING )
{ {
ASSERT(!ref_type->incremental_input()); ASSERT(! ref_type->incremental_input());
parse_func = kParseFuncWithoutBuffer; parse_func = kParseFuncWithoutBuffer;
parse_params = "0, 0"; parse_params = "0, 0";
} }
@ -222,9 +216,7 @@ void ParameterizedType::DoGenParseCode(Output* out_cc, Env* env,
else else
{ {
parse_func = kParseFuncWithoutBuffer; parse_func = kParseFuncWithoutBuffer;
parse_params = strfmt("%s, %s", parse_params = strfmt("%s, %s", data.ptr_expr(), env->RValue(end_of_data));
data.ptr_expr(),
env->RValue(end_of_data));
} }
if ( RequiresAnalyzerContext::compute(ref_type) ) if ( RequiresAnalyzerContext::compute(ref_type) )
@ -240,22 +232,19 @@ void ParameterizedType::DoGenParseCode(Output* out_cc, Env* env,
string call_parse_func = strfmt("%s->%s(%s)", string call_parse_func = strfmt("%s->%s(%s)",
lvalue(), // parse() needs an LValue lvalue(), // parse() needs an LValue
parse_func, parse_func, parse_params.c_str());
parse_params.c_str());
if ( incremental_input() ) if ( incremental_input() )
{ {
if ( buffer_mode() == BUFFER_NOTHING ) if ( buffer_mode() == BUFFER_NOTHING )
{ {
out_cc->println("%s;", call_parse_func.c_str()); out_cc->println("%s;", call_parse_func.c_str());
out_cc->println("%s = true;", out_cc->println("%s = true;", env->LValue(parsing_complete_var()));
env->LValue(parsing_complete_var()));
} }
else else
{ {
ASSERT(parsing_complete_var()); ASSERT(parsing_complete_var());
out_cc->println("%s = %s;", out_cc->println("%s = %s;", env->LValue(parsing_complete_var()),
env->LValue(parsing_complete_var()),
call_parse_func.c_str()); call_parse_func.c_str());
// parsing_complete_var might have been already // parsing_complete_var might have been already
@ -268,22 +257,17 @@ void ParameterizedType::DoGenParseCode(Output* out_cc, Env* env,
{ {
if ( AddSizeVar(out_cc, env) ) if ( AddSizeVar(out_cc, env) )
{ {
out_cc->println("%s = %s;", out_cc->println("%s = %s;", env->LValue(size_var()), call_parse_func.c_str());
env->LValue(size_var()),
call_parse_func.c_str());
env->SetEvaluated(size_var()); env->SetEvaluated(size_var());
} }
else else
{ {
out_cc->println("%s;", out_cc->println("%s;", call_parse_func.c_str());
call_parse_func.c_str());
} }
} }
} }
void ParameterizedType::GenDynamicSize(Output* out_cc, Env* env, void ParameterizedType::GenDynamicSize(Output* out_cc, Env* env, const DataPtr& data)
const DataPtr& data)
{ {
GenParseCode(out_cc, env, data, 0); GenParseCode(out_cc, env, data, 0);
} }

View file

@ -5,57 +5,57 @@
// An instantiated type: ID + expression list // An instantiated type: ID + expression list
class ParameterizedType : public Type class ParameterizedType : public Type
{ {
public: public:
ParameterizedType(ID *type_id, ExprList *args); ParameterizedType(ID* type_id, ExprList* args);
~ParameterizedType(); ~ParameterizedType();
Type *clone() const; Type* clone() const;
string EvalMember(const ID *member_id) const; string EvalMember(const ID* member_id) const;
// Env *member_env() const; // Env *member_env() const;
void AddParamArg(Expr *arg); void AddParamArg(Expr* arg);
bool DefineValueVar() const; bool DefineValueVar() const;
string DataTypeStr() const; string DataTypeStr() const;
string DefaultValue() const { return "0"; } string DefaultValue() const { return "0"; }
Type *MemberDataType(const ID *member_id) const; Type* MemberDataType(const ID* member_id) const;
// "throw_exception" specifies whether to throw an exception // "throw_exception" specifies whether to throw an exception
// if the referred data type is not found // if the referred data type is not found
Type *ReferredDataType(bool throw_exception) const; Type* ReferredDataType(bool throw_exception) const;
void GenCleanUpCode(Output *out, Env *env); void GenCleanUpCode(Output* out, Env* env);
int StaticSize(Env *env) const; int StaticSize(Env* env) const;
bool IsPointerType() const { return true; } bool IsPointerType() const { return true; }
bool ByteOrderSensitive() const; bool ByteOrderSensitive() const;
bool RequiresAnalyzerContext(); bool RequiresAnalyzerContext();
void GenInitCode(Output *out_cc, Env *env); void GenInitCode(Output* out_cc, Env* env);
string class_name() const; string class_name() const;
string EvalParameters(Output *out_cc, Env *env) const; string EvalParameters(Output* out_cc, Env* env) const;
BufferMode buffer_mode() const; BufferMode buffer_mode() const;
protected: protected:
void GenNewInstance(Output *out, Env *env); void GenNewInstance(Output* out, Env* env);
bool DoTraverse(DataDepVisitor *visitor); bool DoTraverse(DataDepVisitor* visitor);
Type *DoClone() const; Type* DoClone() const;
void DoMarkIncrementalInput(); void DoMarkIncrementalInput();
private: private:
ID *type_id_; ID* type_id_;
ExprList *args_; ExprList* args_;
bool checking_requires_analyzer_context_; bool checking_requires_analyzer_context_;
void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags); void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags);
void GenDynamicSize(Output *out, Env *env, const DataPtr& data); void GenDynamicSize(Output* out, Env* env, const DataPtr& data);
}; };
#endif // pac_paramtype_h #endif // pac_paramtype_h

View file

@ -1,36 +1,34 @@
#include "pac_primitive.h"
#include "pac_dbg.h" #include "pac_dbg.h"
#include "pac_expr.h" #include "pac_expr.h"
#include "pac_id.h" #include "pac_id.h"
#include "pac_primitive.h"
#include "pac_type.h" #include "pac_type.h"
string PPVal::ToCode(Env *env) string PPVal::ToCode(Env* env)
{ {
ASSERT(expr_); ASSERT(expr_);
return string(expr_->EvalExpr(0, env)); return string(expr_->EvalExpr(0, env));
} }
string PPSet::ToCode(Env *env) string PPSet::ToCode(Env* env)
{ {
ASSERT(expr_); ASSERT(expr_);
return expr_->SetFunc(0, env); return expr_->SetFunc(0, env);
} }
string PPType::ToCode(Env *env) string PPType::ToCode(Env* env)
{ {
Type *type = expr_->DataType(env); Type* type = expr_->DataType(env);
return type->DataTypeStr(); return type->DataTypeStr();
} }
string PPConstDef::ToCode(Env *env) string PPConstDef::ToCode(Env* env)
{ {
Type *type = expr_->DataType(env); Type* type = expr_->DataType(env);
env->AddID(id_, TEMP_VAR, type); env->AddID(id_, TEMP_VAR, type);
env->SetEvaluated(id_); env->SetEvaluated(id_);
string type_str = type->DataTypeStr(); string type_str = type->DataTypeStr();
return strfmt("%s %s = %s", return strfmt("%s %s = %s", type_str.c_str(), env->LValue(id_), expr_->EvalExpr(0, env));
type_str.c_str(),
env->LValue(id_),
expr_->EvalExpr(0, env));
} }

View file

@ -4,72 +4,75 @@
#include "pac_common.h" #include "pac_common.h"
class PacPrimitive class PacPrimitive
{ {
public: public:
enum PrimitiveType { VAL, SET, TYPE, CONST_DEF }; enum PrimitiveType
{
VAL,
SET,
TYPE,
CONST_DEF
};
explicit PacPrimitive(PrimitiveType type) : type_(type) {} explicit PacPrimitive(PrimitiveType type) : type_(type) { }
virtual ~PacPrimitive() {} virtual ~PacPrimitive() { }
PrimitiveType type() const { return type_; } PrimitiveType type() const { return type_; }
virtual string ToCode(Env *env) = 0; virtual string ToCode(Env* env) = 0;
private: private:
PrimitiveType type_; PrimitiveType type_;
}; };
class PPVal : public PacPrimitive class PPVal : public PacPrimitive
{ {
public: public:
PPVal(Expr *expr) : PacPrimitive(VAL), expr_(expr) {} PPVal(Expr* expr) : PacPrimitive(VAL), expr_(expr) { }
Expr *expr() const { return expr_; } Expr* expr() const { return expr_; }
string ToCode(Env *env); string ToCode(Env* env);
private: private:
Expr *expr_; Expr* expr_;
}; };
class PPSet : public PacPrimitive class PPSet : public PacPrimitive
{ {
public: public:
PPSet(Expr *expr) : PacPrimitive(SET), expr_(expr) {} PPSet(Expr* expr) : PacPrimitive(SET), expr_(expr) { }
Expr *expr() const { return expr_; } Expr* expr() const { return expr_; }
string ToCode(Env *env); string ToCode(Env* env);
private: private:
Expr *expr_; Expr* expr_;
}; };
class PPType : public PacPrimitive class PPType : public PacPrimitive
{ {
public: public:
PPType(Expr *expr) : PacPrimitive(TYPE), expr_(expr) {} PPType(Expr* expr) : PacPrimitive(TYPE), expr_(expr) { }
Expr *expr() const { return expr_; } Expr* expr() const { return expr_; }
string ToCode(Env *env); string ToCode(Env* env);
private: private:
Expr *expr_; Expr* expr_;
}; };
class PPConstDef : public PacPrimitive class PPConstDef : public PacPrimitive
{ {
public: public:
PPConstDef(const ID *id, Expr *expr) PPConstDef(const ID* id, Expr* expr) : PacPrimitive(CONST_DEF), id_(id), expr_(expr) { }
: PacPrimitive(CONST_DEF), const ID* id() const { return id_; }
id_(id), Expr* expr() const { return expr_; }
expr_(expr) {}
const ID *id() const { return id_; }
Expr *expr() const { return expr_; }
string ToCode(Env *env); string ToCode(Env* env);
private: private:
const ID *id_; const ID* id_;
Expr *expr_; Expr* expr_;
}; };
#endif // pac_primitive_h #endif // pac_primitive_h

View file

@ -1,3 +1,5 @@
#include "pac_record.h"
#include "pac_attr.h" #include "pac_attr.h"
#include "pac_dataptr.h" #include "pac_dataptr.h"
#include "pac_exception.h" #include "pac_exception.h"
@ -5,15 +7,12 @@
#include "pac_exttype.h" #include "pac_exttype.h"
#include "pac_field.h" #include "pac_field.h"
#include "pac_output.h" #include "pac_output.h"
#include "pac_record.h"
#include "pac_type.h" #include "pac_type.h"
#include "pac_typedecl.h" #include "pac_typedecl.h"
#include "pac_utils.h" #include "pac_utils.h"
#include "pac_varfield.h" #include "pac_varfield.h"
RecordType::RecordType(RecordFieldList* record_fields) : Type(RECORD)
RecordType::RecordType(RecordFieldList* record_fields)
: Type(RECORD)
{ {
// Here we assume that the type is a standalone type. // Here we assume that the type is a standalone type.
value_var_ = 0; value_var_ = 0;
@ -36,10 +35,9 @@ RecordType::~RecordType()
delete parsing_dataptr_var_field_; delete parsing_dataptr_var_field_;
} }
const ID *RecordType::parsing_dataptr_var() const const ID* RecordType::parsing_dataptr_var() const
{ {
return parsing_dataptr_var_field_ ? return parsing_dataptr_var_field_ ? parsing_dataptr_var_field_->id() : 0;
parsing_dataptr_var_field_->id() : 0;
} }
bool RecordType::DefineValueVar() const bool RecordType::DefineValueVar() const
@ -57,12 +55,12 @@ void RecordType::Prepare(Env* env, int flags)
{ {
ASSERT(flags & TO_BE_PARSED); ASSERT(flags & TO_BE_PARSED);
RecordField *prev = 0; RecordField* prev = 0;
int offset = 0; int offset = 0;
int seq = 0; int seq = 0;
foreach (i, RecordFieldList, record_fields_) foreach (i, RecordFieldList, record_fields_)
{ {
RecordField *f = *i; RecordField* f = *i;
f->set_record_type(this); f->set_record_type(this);
f->set_prev(prev); f->set_prev(prev);
if ( prev ) if ( prev )
@ -120,71 +118,62 @@ void RecordType::GenCleanUpCode(Output* out_cc, Env* env)
Type::GenCleanUpCode(out_cc, env); Type::GenCleanUpCode(out_cc, env);
} }
void RecordType::DoGenParseCode(Output* out_cc, Env* env, void RecordType::DoGenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags)
const DataPtr& data, int flags)
{ {
if ( !incremental_input() && StaticSize(env) >= 0 ) if ( ! incremental_input() && StaticSize(env) >= 0 )
GenBoundaryCheck(out_cc, env, data); GenBoundaryCheck(out_cc, env, data);
if ( incremental_parsing() ) if ( incremental_parsing() )
{ {
out_cc->println("switch ( %s ) {", out_cc->println("switch ( %s ) {", env->LValue(parsing_state_id));
env->LValue(parsing_state_id));
out_cc->println("case 0:"); out_cc->println("case 0:");
out_cc->inc_indent(); out_cc->inc_indent();
foreach (i, RecordFieldList, record_fields_) foreach (i, RecordFieldList, record_fields_)
{ {
RecordField *f = *i; RecordField* f = *i;
f->GenParseCode(out_cc, env); f->GenParseCode(out_cc, env);
out_cc->println(""); out_cc->println("");
} }
out_cc->println(""); out_cc->println("");
out_cc->println("%s = true;", out_cc->println("%s = true;", env->LValue(parsing_complete_var()));
env->LValue(parsing_complete_var()));
out_cc->dec_indent(); out_cc->dec_indent();
out_cc->println("}"); out_cc->println("}");
} }
else else
{ {
ASSERT( data.id() == begin_of_data && ASSERT(data.id() == begin_of_data && data.offset() == 0);
data.offset() == 0 );
foreach (i, RecordFieldList, record_fields_) foreach (i, RecordFieldList, record_fields_)
{ {
RecordField *f = *i; RecordField* f = *i;
f->GenParseCode(out_cc, env); f->GenParseCode(out_cc, env);
out_cc->println(""); out_cc->println("");
} }
if ( incremental_input() ) if ( incremental_input() )
{ {
ASSERT(parsing_complete_var()); ASSERT(parsing_complete_var());
out_cc->println("%s = true;", out_cc->println("%s = true;", env->LValue(parsing_complete_var()));
env->LValue(parsing_complete_var()));
} }
} }
if ( ! incremental_input() && AddSizeVar(out_cc, env) ) if ( ! incremental_input() && AddSizeVar(out_cc, env) )
{ {
const DataPtr& end_of_record_dataptr = const DataPtr& end_of_record_dataptr = record_fields_->back()->getFieldEnd(out_cc, env);
record_fields_->back()->getFieldEnd(out_cc, env);
out_cc->println("%s = %s - %s;", out_cc->println("%s = %s - %s;", env->LValue(size_var()), end_of_record_dataptr.ptr_expr(),
env->LValue(size_var()),
end_of_record_dataptr.ptr_expr(),
env->RValue(begin_of_data)); env->RValue(begin_of_data));
env->SetEvaluated(size_var()); env->SetEvaluated(size_var());
} }
if ( ! boundary_checked() ) if ( ! boundary_checked() )
{ {
RecordField *last_field = record_fields_->back(); RecordField* last_field = record_fields_->back();
if ( ! last_field->BoundaryChecked() ) if ( ! last_field->BoundaryChecked() )
GenBoundaryCheck(out_cc, env, data); GenBoundaryCheck(out_cc, env, data);
} }
} }
void RecordType::GenDynamicSize(Output* out_cc, Env* env, void RecordType::GenDynamicSize(Output* out_cc, Env* env, const DataPtr& data)
const DataPtr& data)
{ {
GenParseCode(out_cc, env, data, 0); GenParseCode(out_cc, env, data, 0);
} }
@ -194,7 +183,7 @@ int RecordType::StaticSize(Env* env) const
int tot_w = 0; int tot_w = 0;
foreach (i, RecordFieldList, record_fields_) foreach (i, RecordFieldList, record_fields_)
{ {
RecordField *f = *i; RecordField* f = *i;
int w = f->StaticSize(env, tot_w); int w = f->StaticSize(env, tot_w);
if ( w < 0 ) if ( w < 0 )
return -1; return -1;
@ -215,7 +204,7 @@ void RecordType::SetBoundaryChecked()
foreach (i, RecordFieldList, record_fields_) foreach (i, RecordFieldList, record_fields_)
{ {
RecordField *f = *i; RecordField* f = *i;
f->SetBoundaryChecked(); f->SetBoundaryChecked();
} }
} }
@ -224,12 +213,12 @@ void RecordType::DoMarkIncrementalInput()
{ {
foreach (i, RecordFieldList, record_fields_) foreach (i, RecordFieldList, record_fields_)
{ {
RecordField *f = *i; RecordField* f = *i;
f->type()->MarkIncrementalInput(); f->type()->MarkIncrementalInput();
} }
} }
bool RecordType::DoTraverse(DataDepVisitor *visitor) bool RecordType::DoTraverse(DataDepVisitor* visitor)
{ {
return Type::DoTraverse(visitor); return Type::DoTraverse(visitor);
} }
@ -238,17 +227,15 @@ bool RecordType::ByteOrderSensitive() const
{ {
foreach (i, RecordFieldList, record_fields_) foreach (i, RecordFieldList, record_fields_)
{ {
RecordField *f = *i; RecordField* f = *i;
if ( f->RequiresByteOrder() ) if ( f->RequiresByteOrder() )
return true; return true;
} }
return false; return false;
} }
RecordField::RecordField(FieldType tof, ID *id, Type *type) RecordField::RecordField(FieldType tof, ID* id, Type* type)
: Field(tof, : Field(tof, TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type)
TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
id, type)
{ {
begin_of_field_dataptr = 0; begin_of_field_dataptr = 0;
end_of_field_dataptr = 0; end_of_field_dataptr = 0;
@ -267,8 +254,8 @@ RecordField::~RecordField()
{ {
delete begin_of_field_dataptr; delete begin_of_field_dataptr;
delete end_of_field_dataptr; delete end_of_field_dataptr;
delete [] field_size_expr; delete[] field_size_expr;
delete [] field_offset_expr; delete[] field_offset_expr;
delete end_of_field_dataptr_var; delete end_of_field_dataptr_var;
} }
@ -281,8 +268,7 @@ const DataPtr& RecordField::getFieldBegin(Output* out_cc, Env* env)
// The first field // The first field
if ( ! begin_of_field_dataptr ) if ( ! begin_of_field_dataptr )
{ {
begin_of_field_dataptr = begin_of_field_dataptr = new DataPtr(env, begin_of_data, 0);
new DataPtr(env, begin_of_data, 0);
} }
return *begin_of_field_dataptr; return *begin_of_field_dataptr;
} }
@ -300,12 +286,10 @@ const DataPtr& RecordField::getFieldEnd(Output* out_cc, Env* env)
ASSERT(0); ASSERT(0);
if ( ! end_of_field_dataptr ) if ( ! end_of_field_dataptr )
{ {
const ID *dataptr_var = const ID* dataptr_var = record_type()->parsing_dataptr_var();
record_type()->parsing_dataptr_var();
ASSERT(dataptr_var); ASSERT(dataptr_var);
end_of_field_dataptr = end_of_field_dataptr = new DataPtr(env, dataptr_var, 0);
new DataPtr(env, dataptr_var, 0);
} }
} }
else else
@ -319,26 +303,18 @@ const DataPtr& RecordField::getFieldEnd(Output* out_cc, Env* env)
int field_size = StaticSize(env, field_offset); int field_size = StaticSize(env, field_offset);
if ( field_size >= 0 ) // can be statically determinted if ( field_size >= 0 ) // can be statically determinted
{ {
end_of_field_dataptr = new DataPtr( end_of_field_dataptr = new DataPtr(env, begin_ptr.id(),
env,
begin_ptr.id(),
begin_ptr.offset() + field_size); begin_ptr.offset() + field_size);
} }
else else
{ {
// If not, we add a variable for the offset after the field // If not, we add a variable for the offset after the field
end_of_field_dataptr_var = new ID( end_of_field_dataptr_var = new ID(strfmt("dataptr_after_%s", id()->Name()));
strfmt("dataptr_after_%s", id()->Name())); env->AddID(end_of_field_dataptr_var, TEMP_VAR, extern_type_const_byteptr);
env->AddID(end_of_field_dataptr_var,
TEMP_VAR,
extern_type_const_byteptr);
GenFieldEnd(out_cc, env, begin_ptr); GenFieldEnd(out_cc, env, begin_ptr);
end_of_field_dataptr = new DataPtr( end_of_field_dataptr = new DataPtr(env, end_of_field_dataptr_var, 0);
env,
end_of_field_dataptr_var,
0);
} }
} }
@ -368,8 +344,7 @@ const char* RecordField::FieldOffset(Output* out_cc, Env* env)
if ( begin.id() == begin_of_data ) if ( begin.id() == begin_of_data )
field_offset_expr = nfmt("%d", begin.offset()); field_offset_expr = nfmt("%d", begin.offset());
else else
field_offset_expr = nfmt("(%s - %s)", field_offset_expr = nfmt("(%s - %s)", begin.ptr_expr(), env->RValue(begin_of_data));
begin.ptr_expr(), env->RValue(begin_of_data));
return field_offset_expr; return field_offset_expr;
} }
@ -400,15 +375,12 @@ bool RecordField::AttemptBoundaryCheck(Output* out_cc, Env* env)
return GenBoundaryCheck(out_cc, env); return GenBoundaryCheck(out_cc, env);
} }
RecordDataField::RecordDataField(ID* id, Type* type) RecordDataField::RecordDataField(ID* id, Type* type) : RecordField(RECORD_FIELD, id, type)
: RecordField(RECORD_FIELD, id, type)
{ {
ASSERT(type_); ASSERT(type_);
} }
RecordDataField::~RecordDataField() RecordDataField::~RecordDataField() { }
{
}
void RecordDataField::Prepare(Env* env) void RecordDataField::Prepare(Env* env)
{ {
@ -435,8 +407,7 @@ void RecordDataField::GenParseCode(Output* out_cc, Env* env)
Expr* len_expr = record_type()->attr_length_expr(); Expr* len_expr = record_type()->attr_length_expr();
int len; int len;
if ( ! record_type()->buffer_input() || if ( ! record_type()->buffer_input() || (len_expr && len_expr->ConstFold(env, &len)) )
(len_expr && len_expr->ConstFold(env, &len)) )
AttemptBoundaryCheck(out_cc, env); AttemptBoundaryCheck(out_cc, env);
} }
@ -449,9 +420,7 @@ void RecordDataField::GenParseCode(Output* out_cc, Env* env)
if ( type_->incremental_input() ) if ( type_->incremental_input() )
{ {
// The enclosing record type must be incrementally parsed // The enclosing record type must be incrementally parsed
out_cc->println("%s = %d;", out_cc->println("%s = %d;", env->LValue(parsing_state_id), parsing_state_seq());
env->LValue(parsing_state_id),
parsing_state_seq());
out_cc->println("/* fall through */"); out_cc->println("/* fall through */");
out_cc->dec_indent(); out_cc->dec_indent();
out_cc->println("case %d:", parsing_state_seq()); out_cc->println("case %d:", parsing_state_seq());
@ -465,8 +434,7 @@ void RecordDataField::GenParseCode(Output* out_cc, Env* env)
{ {
ASSERT(type_->incremental_input()); ASSERT(type_->incremental_input());
out_cc->println("if ( ! (%s) )", out_cc->println("if ( ! (%s) )", type_->parsing_complete(env).c_str());
type_->parsing_complete(env).c_str());
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("goto %s;", kNeedMoreData); out_cc->println("goto %s;", kNeedMoreData);
out_cc->dec_indent(); out_cc->dec_indent();
@ -493,17 +461,13 @@ void RecordDataField::GenEval(Output* out_cc, Env* env)
GenParseCode(out_cc, env); GenParseCode(out_cc, env);
} }
void RecordDataField::GenFieldEnd(Output* out_cc, Env* env, void RecordDataField::GenFieldEnd(Output* out_cc, Env* env, const DataPtr& field_begin)
const DataPtr& field_begin)
{ {
out_cc->println("const_byteptr const %s = %s + (%s);", out_cc->println("const_byteptr const %s = %s + (%s);", env->LValue(end_of_field_dataptr_var),
env->LValue(end_of_field_dataptr_var), field_begin.ptr_expr(), type_->DataSize(out_cc, env, field_begin).c_str());
field_begin.ptr_expr(),
type_->DataSize(out_cc, env, field_begin).c_str());
env->SetEvaluated(end_of_field_dataptr_var); env->SetEvaluated(end_of_field_dataptr_var);
out_cc->println("BINPAC_ASSERT(%s <= %s);", out_cc->println("BINPAC_ASSERT(%s <= %s);", env->RValue(end_of_field_dataptr_var),
env->RValue(end_of_field_dataptr_var),
env->RValue(end_of_data)); env->RValue(end_of_data));
} }
@ -524,15 +488,14 @@ bool RecordDataField::GenBoundaryCheck(Output* out_cc, Env* env)
return true; return true;
} }
bool RecordDataField::DoTraverse(DataDepVisitor *visitor) bool RecordDataField::DoTraverse(DataDepVisitor* visitor)
{ {
return Field::DoTraverse(visitor); return Field::DoTraverse(visitor);
} }
bool RecordDataField::RequiresAnalyzerContext() const bool RecordDataField::RequiresAnalyzerContext() const
{ {
return Field::RequiresAnalyzerContext() || return Field::RequiresAnalyzerContext() || type()->RequiresAnalyzerContext();
type()->RequiresAnalyzerContext();
} }
RecordPaddingField::RecordPaddingField(ID* id, PaddingType ptype, Expr* expr) RecordPaddingField::RecordPaddingField(ID* id, PaddingType ptype, Expr* expr)
@ -541,9 +504,7 @@ RecordPaddingField::RecordPaddingField(ID* id, PaddingType ptype, Expr* expr)
wordsize_ = -1; wordsize_ = -1;
} }
RecordPaddingField::~RecordPaddingField() RecordPaddingField::~RecordPaddingField() { }
{
}
void RecordPaddingField::Prepare(Env* env) void RecordPaddingField::Prepare(Env* env)
{ {
@ -551,8 +512,7 @@ void RecordPaddingField::Prepare(Env* env)
if ( ptype_ == PAD_TO_NEXT_WORD ) if ( ptype_ == PAD_TO_NEXT_WORD )
{ {
if ( ! expr_->ConstFold(env, &wordsize_) ) if ( ! expr_->ConstFold(env, &wordsize_) )
throw ExceptionPaddingError(this, throw ExceptionPaddingError(this, strfmt("padding word size not a constant"));
strfmt("padding word size not a constant"));
} }
} }
@ -589,9 +549,7 @@ int RecordPaddingField::StaticSize(Env* env, int offset) const
// can be statically computed, we can get its // can be statically computed, we can get its
// static size // static size
if ( offset > target_offset ) if ( offset > target_offset )
throw ExceptionPaddingError( throw ExceptionPaddingError(this, strfmt("current offset = %d, "
this,
strfmt("current offset = %d, "
"target offset = %d", "target offset = %d",
offset, target_offset)); offset, target_offset));
return target_offset - offset; return target_offset - offset;
@ -601,8 +559,7 @@ int RecordPaddingField::StaticSize(Env* env, int offset) const
return -1; return -1;
offset_in_word = offset % wordsize_; offset_in_word = offset % wordsize_;
return ( offset_in_word == 0 ) ? return (offset_in_word == 0) ? 0 : wordsize_ - offset_in_word;
0 : wordsize_ - offset_in_word;
} }
return -1; return -1;
@ -620,86 +577,67 @@ void RecordPaddingField::GenFieldEnd(Output* out_cc, Env* env, const DataPtr& fi
expr_->EvalExpr(out_cc, env)); expr_->EvalExpr(out_cc, env));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
out_cc->println("throw binpac::ExceptionInvalidStringLength(\"%s\", %s);", out_cc->println("throw binpac::ExceptionInvalidStringLength(\"%s\", %s);", Location(),
Location(), expr_->EvalExpr(out_cc, env)); expr_->EvalExpr(out_cc, env));
out_cc->println("}"); out_cc->println("}");
out_cc->dec_indent(); out_cc->dec_indent();
out_cc->println(""); out_cc->println("");
out_cc->println("const_byteptr const %s = %s + (%s);", out_cc->println("const_byteptr const %s = %s + (%s);",
env->LValue(end_of_field_dataptr_var), env->LValue(end_of_field_dataptr_var), field_begin.ptr_expr(),
field_begin.ptr_expr(),
expr_->EvalExpr(out_cc, env)); expr_->EvalExpr(out_cc, env));
out_cc->println("// Checking out-of-bound padding for \"%s\"", field_id_str_.c_str()); out_cc->println("// Checking out-of-bound padding for \"%s\"", field_id_str_.c_str());
out_cc->println("if ( %s > %s || %s < %s )", out_cc->println("if ( %s > %s || %s < %s )", env->LValue(end_of_field_dataptr_var),
env->LValue(end_of_field_dataptr_var), env->RValue(end_of_data), env->LValue(end_of_field_dataptr_var),
env->RValue(end_of_data),
env->LValue(end_of_field_dataptr_var),
field_begin.ptr_expr()); field_begin.ptr_expr());
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", field_id_str_.c_str()); out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", field_id_str_.c_str());
out_cc->println(" (%s), ", out_cc->println(" (%s), ", expr_->EvalExpr(out_cc, env));
expr_->EvalExpr(out_cc, env)); out_cc->println(" (%s) - (%s));", env->RValue(end_of_data),
out_cc->println(" (%s) - (%s));", env->LValue(end_of_field_dataptr_var));
env->RValue(end_of_data), env->LValue(end_of_field_dataptr_var));
out_cc->println("}"); out_cc->println("}");
out_cc->dec_indent(); out_cc->dec_indent();
out_cc->println(""); out_cc->println("");
break; break;
case PAD_TO_OFFSET: case PAD_TO_OFFSET:
out_cc->println("const_byteptr %s = %s + (%s);", out_cc->println("const_byteptr %s = %s + (%s);", env->LValue(end_of_field_dataptr_var),
env->LValue(end_of_field_dataptr_var), env->RValue(begin_of_data), expr_->EvalExpr(out_cc, env));
env->RValue(begin_of_data), out_cc->println("if ( %s < %s )", env->LValue(end_of_field_dataptr_var),
expr_->EvalExpr(out_cc, env));
out_cc->println("if ( %s < %s )",
env->LValue(end_of_field_dataptr_var),
field_begin.ptr_expr()); field_begin.ptr_expr());
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
out_cc->println("// throw binpac::ExceptionInvalidOffset(\"%s\", %s - %s, %s);", out_cc->println("// throw binpac::ExceptionInvalidOffset(\"%s\", %s - %s, %s);",
id_->LocName(), id_->LocName(), field_begin.ptr_expr(), env->RValue(begin_of_data),
field_begin.ptr_expr(),
env->RValue(begin_of_data),
expr_->EvalExpr(out_cc, env)); expr_->EvalExpr(out_cc, env));
out_cc->println("%s = %s;", out_cc->println("%s = %s;", env->LValue(end_of_field_dataptr_var),
env->LValue(end_of_field_dataptr_var),
field_begin.ptr_expr()); field_begin.ptr_expr());
out_cc->println("}"); out_cc->println("}");
out_cc->dec_indent(); out_cc->dec_indent();
out_cc->println("if ( %s > %s )", out_cc->println("if ( %s > %s )", env->LValue(end_of_field_dataptr_var),
env->LValue(end_of_field_dataptr_var),
env->RValue(end_of_data)); env->RValue(end_of_data));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", field_id_str_.c_str()); out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", field_id_str_.c_str());
out_cc->println(" (%s), ", out_cc->println(" (%s), ", expr_->EvalExpr(out_cc, env));
expr_->EvalExpr(out_cc, env)); out_cc->println(" (%s) - (%s));", env->RValue(end_of_data),
out_cc->println(" (%s) - (%s));", env->LValue(end_of_field_dataptr_var));
env->RValue(end_of_data), env->LValue(end_of_field_dataptr_var));
out_cc->println("}"); out_cc->println("}");
out_cc->dec_indent(); out_cc->dec_indent();
break; break;
case PAD_TO_NEXT_WORD: case PAD_TO_NEXT_WORD:
padding_var = nfmt("%s__size", id()->Name()); padding_var = nfmt("%s__size", id()->Name());
out_cc->println("int %s = (%s - %s) %% %d;", out_cc->println("int %s = (%s - %s) %% %d;", padding_var, field_begin.ptr_expr(),
padding_var, env->RValue(begin_of_data), wordsize_);
field_begin.ptr_expr(), out_cc->println("%s = (%s == 0) ? 0 : %d - %s;", padding_var, padding_var, wordsize_,
env->RValue(begin_of_data),
wordsize_);
out_cc->println("%s = (%s == 0) ? 0 : %d - %s;",
padding_var,
padding_var,
wordsize_,
padding_var); padding_var);
out_cc->println("const_byteptr const %s = %s + %s;", out_cc->println("const_byteptr const %s = %s + %s;",
env->LValue(end_of_field_dataptr_var), env->LValue(end_of_field_dataptr_var), field_begin.ptr_expr(),
field_begin.ptr_expr(),
padding_var); padding_var);
delete [] padding_var; delete[] padding_var;
break; break;
} }
@ -715,20 +653,18 @@ bool RecordPaddingField::GenBoundaryCheck(Output* out_cc, Env* env)
char* size; char* size;
int ss = StaticSize(env, begin.AbsOffset(begin_of_data)); int ss = StaticSize(env, begin.AbsOffset(begin_of_data));
ASSERT ( ss >= 0 ); ASSERT(ss >= 0);
size = nfmt("%d", ss); size = nfmt("%d", ss);
begin.GenBoundaryCheck(out_cc, env, size, field_id_str_.c_str()); begin.GenBoundaryCheck(out_cc, env, size, field_id_str_.c_str());
delete [] size; delete[] size;
SetBoundaryChecked(); SetBoundaryChecked();
return true; return true;
} }
bool RecordPaddingField::DoTraverse(DataDepVisitor *visitor) bool RecordPaddingField::DoTraverse(DataDepVisitor* visitor)
{ {
return Field::DoTraverse(visitor) && return Field::DoTraverse(visitor) && (! expr_ || expr_->Traverse(visitor));
(! expr_ || expr_->Traverse(visitor));
} }

View file

@ -8,7 +8,7 @@
#include "pac_type.h" #include "pac_type.h"
class RecordType : public Type class RecordType : public Type
{ {
public: public:
RecordType(RecordFieldList* fields); RecordType(RecordFieldList* fields);
~RecordType(); ~RecordType();
@ -28,37 +28,41 @@ public:
void SetBoundaryChecked(); void SetBoundaryChecked();
const ID *parsing_dataptr_var() const; const ID* parsing_dataptr_var() const;
bool IsPointerType() const { ASSERT(0); return false; } bool IsPointerType() const
{
ASSERT(0);
return false;
}
protected: protected:
void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags); void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags);
void GenDynamicSize(Output* out, Env* env, const DataPtr& data); void GenDynamicSize(Output* out, Env* env, const DataPtr& data);
Type *DoClone() const { return 0; } Type* DoClone() const { return 0; }
void DoMarkIncrementalInput(); void DoMarkIncrementalInput();
bool DoTraverse(DataDepVisitor *visitor); bool DoTraverse(DataDepVisitor* visitor);
bool ByteOrderSensitive() const; bool ByteOrderSensitive() const;
private: private:
Field *parsing_dataptr_var_field_; Field* parsing_dataptr_var_field_;
RecordFieldList* record_fields_; RecordFieldList* record_fields_;
}; };
// A data field of a record type. A RecordField corresponds to a // A data field of a record type. A RecordField corresponds to a
// segment of input data, and therefore RecordField's are ordered---each // segment of input data, and therefore RecordField's are ordered---each
// of them has a known previous and next field. // of them has a known previous and next field.
class RecordField : public Field class RecordField : public Field
{ {
public: public:
RecordField(FieldType tof, ID* id, Type *type); RecordField(FieldType tof, ID* id, Type* type);
~RecordField(); ~RecordField();
RecordType *record_type() const { return record_type_; } RecordType* record_type() const { return record_type_; }
void set_record_type(RecordType* ty) { record_type_ = ty; } void set_record_type(RecordType* ty) { record_type_ = ty; }
virtual void GenParseCode(Output* out, Env* env) = 0; virtual void GenParseCode(Output* out, Env* env) = 0;
@ -105,10 +109,10 @@ protected:
bool AttemptBoundaryCheck(Output* out_cc, Env* env); bool AttemptBoundaryCheck(Output* out_cc, Env* env);
virtual bool GenBoundaryCheck(Output* out_cc, Env* env) = 0; virtual bool GenBoundaryCheck(Output* out_cc, Env* env) = 0;
}; };
class RecordDataField : public RecordField, public Evaluatable class RecordDataField : public RecordField, public Evaluatable
{ {
public: public:
RecordDataField(ID* arg_id, Type* arg_type); RecordDataField(ID* arg_id, Type* arg_type);
~RecordDataField(); ~RecordDataField();
@ -124,31 +128,43 @@ public:
void SetBoundaryChecked(); void SetBoundaryChecked();
bool RequiresByteOrder() const bool RequiresByteOrder() const { return type()->RequiresByteOrder(); }
{ return type()->RequiresByteOrder(); }
bool RequiresAnalyzerContext() const; bool RequiresAnalyzerContext() const;
protected: protected:
void GenFieldEnd(Output* out, Env* env, const DataPtr& begin); void GenFieldEnd(Output* out, Env* env, const DataPtr& begin);
bool GenBoundaryCheck(Output* out_cc, Env* env); bool GenBoundaryCheck(Output* out_cc, Env* env);
bool DoTraverse(DataDepVisitor *visitor); bool DoTraverse(DataDepVisitor* visitor);
}; };
enum PaddingType { PAD_BY_LENGTH, PAD_TO_OFFSET, PAD_TO_NEXT_WORD }; enum PaddingType
{
PAD_BY_LENGTH,
PAD_TO_OFFSET,
PAD_TO_NEXT_WORD
};
class RecordPaddingField : public RecordField class RecordPaddingField : public RecordField
{ {
public: public:
RecordPaddingField(ID* id, PaddingType ptype, Expr* expr); RecordPaddingField(ID* id, PaddingType ptype, Expr* expr);
~RecordPaddingField(); ~RecordPaddingField();
void Prepare(Env* env); void Prepare(Env* env);
void GenPubDecls(Output* out, Env* env) { /* nothing */ } void GenPubDecls(Output* out, Env* env)
void GenPrivDecls(Output* out, Env* env) { /* nothing */ } { /* nothing */
}
void GenPrivDecls(Output* out, Env* env)
{ /* nothing */
}
void GenInitCode(Output* out, Env* env) { /* nothing */ } void GenInitCode(Output* out, Env* env)
void GenCleanUpCode(Output* out, Env* env) { /* nothing */ } { /* nothing */
}
void GenCleanUpCode(Output* out, Env* env)
{ /* nothing */
}
void GenParseCode(Output* out, Env* env); void GenParseCode(Output* out, Env* env);
int StaticSize(Env* env, int offset) const; int StaticSize(Env* env, int offset) const;
@ -158,12 +174,12 @@ public:
protected: protected:
void GenFieldEnd(Output* out, Env* env, const DataPtr& begin); void GenFieldEnd(Output* out, Env* env, const DataPtr& begin);
bool GenBoundaryCheck(Output* out_cc, Env* env); bool GenBoundaryCheck(Output* out_cc, Env* env);
bool DoTraverse(DataDepVisitor *visitor); bool DoTraverse(DataDepVisitor* visitor);
private: private:
PaddingType ptype_; PaddingType ptype_;
Expr* expr_; Expr* expr_;
int wordsize_; int wordsize_;
}; };
#endif // pac_record_h #endif // pac_record_h

View file

@ -1,151 +1,133 @@
#include "pac_redef.h"
#include "pac_analyzer.h" #include "pac_analyzer.h"
#include "pac_case.h" #include "pac_case.h"
#include "pac_exception.h" #include "pac_exception.h"
#include "pac_expr.h" #include "pac_expr.h"
#include "pac_func.h" #include "pac_func.h"
#include "pac_record.h" #include "pac_record.h"
#include "pac_redef.h"
#include "pac_type.h" #include "pac_type.h"
#include "pac_typedecl.h" #include "pac_typedecl.h"
namespace { namespace
Decl *find_decl(const ID *id)
{ {
Decl *decl = Decl::LookUpDecl(id);
Decl* find_decl(const ID* id)
{
Decl* decl = Decl::LookUpDecl(id);
if ( ! decl ) if ( ! decl )
{ {
throw Exception(id, throw Exception(id, strfmt("cannot find declaration for %s", id->Name()));
strfmt("cannot find declaration for %s",
id->Name()));
} }
return decl; return decl;
} }
} }
Decl *ProcessTypeRedef(const ID *id, FieldList *fieldlist) Decl* ProcessTypeRedef(const ID* id, FieldList* fieldlist)
{ {
Decl *decl = find_decl(id); Decl* decl = find_decl(id);
if ( decl->decl_type() != Decl::TYPE ) if ( decl->decl_type() != Decl::TYPE )
{ {
throw Exception(id, throw Exception(id, strfmt("not a type declaration: %s", id->Name()));
strfmt("not a type declaration: %s",
id->Name()));
} }
TypeDecl *type_decl = static_cast<TypeDecl *>(decl); TypeDecl* type_decl = static_cast<TypeDecl*>(decl);
ASSERT(type_decl); ASSERT(type_decl);
Type *type = type_decl->type(); Type* type = type_decl->type();
foreach(i, FieldList, fieldlist) foreach (i, FieldList, fieldlist)
{ {
Field *f = *i; Field* f = *i;
// One cannot change data layout in 'redef'. // One cannot change data layout in 'redef'.
// Only 'let' or 'action' can be added // Only 'let' or 'action' can be added
if ( f->tof() == LET_FIELD || if ( f->tof() == LET_FIELD || f->tof() == WITHINPUT_FIELD )
f->tof() == WITHINPUT_FIELD )
{ {
type->AddField(f); type->AddField(f);
} }
else if ( f->tof() == RECORD_FIELD || else if ( f->tof() == RECORD_FIELD || f->tof() == PADDING_FIELD )
f->tof() == PADDING_FIELD )
{ {
throw Exception(f, throw Exception(f, "cannot change data layout in redef");
"cannot change data layout in redef");
} }
else if ( f->tof() == CASE_FIELD ) else if ( f->tof() == CASE_FIELD )
{ {
throw Exception(f, throw Exception(f, "use 'redef case' adding cases");
"use 'redef case' adding cases");
} }
} }
return decl; return decl;
} }
Decl *ProcessCaseTypeRedef(const ID *id, CaseFieldList *casefieldlist) Decl* ProcessCaseTypeRedef(const ID* id, CaseFieldList* casefieldlist)
{ {
Decl *decl = find_decl(id); Decl* decl = find_decl(id);
if ( decl->decl_type() != Decl::TYPE ) if ( decl->decl_type() != Decl::TYPE )
{ {
throw Exception(id, throw Exception(id, strfmt("not a type declaration: %s", id->Name()));
strfmt("not a type declaration: %s",
id->Name()));
} }
TypeDecl *type_decl = static_cast<TypeDecl *>(decl); TypeDecl* type_decl = static_cast<TypeDecl*>(decl);
ASSERT(type_decl); ASSERT(type_decl);
Type *type = type_decl->type(); Type* type = type_decl->type();
if ( type->tot() != Type::CASE ) if ( type->tot() != Type::CASE )
{ {
throw Exception(id, throw Exception(id, strfmt("not a case type: %s", id->Name()));
strfmt("not a case type: %s",
id->Name()));
} }
CaseType *casetype = static_cast<CaseType*>(type); CaseType* casetype = static_cast<CaseType*>(type);
ASSERT(casetype); ASSERT(casetype);
foreach(i, CaseFieldList, casefieldlist) foreach (i, CaseFieldList, casefieldlist)
{ {
CaseField *f = *i; CaseField* f = *i;
casetype->AddCaseField(f); casetype->AddCaseField(f);
} }
return decl; return decl;
} }
Decl *ProcessCaseExprRedef(const ID *id, CaseExprList *caseexprlist) Decl* ProcessCaseExprRedef(const ID* id, CaseExprList* caseexprlist)
{ {
Decl *decl = find_decl(id); Decl* decl = find_decl(id);
if ( decl->decl_type() != Decl::FUNC ) if ( decl->decl_type() != Decl::FUNC )
{ {
throw Exception(id, throw Exception(id, strfmt("not a function declaration: %s", id->Name()));
strfmt("not a function declaration: %s",
id->Name()));
} }
FuncDecl *func_decl = static_cast<FuncDecl *>(decl); FuncDecl* func_decl = static_cast<FuncDecl*>(decl);
ASSERT(func_decl); ASSERT(func_decl);
Expr *expr = func_decl->function()->expr(); Expr* expr = func_decl->function()->expr();
if ( ! expr ||expr->expr_type() != Expr::EXPR_CASE ) if ( ! expr || expr->expr_type() != Expr::EXPR_CASE )
{ {
throw Exception(id, throw Exception(id, strfmt("function not defined by a case expression: %s", id->Name()));
strfmt("function not defined by a case expression: %s",
id->Name()));
} }
foreach(i, CaseExprList, caseexprlist) foreach (i, CaseExprList, caseexprlist)
{ {
CaseExpr *e = *i; CaseExpr* e = *i;
expr->AddCaseExpr(e); expr->AddCaseExpr(e);
} }
return decl; return decl;
} }
Decl *ProcessAnalyzerRedef(const ID *id, Decl* ProcessAnalyzerRedef(const ID* id, Decl::DeclType decl_type, AnalyzerElementList* elements)
Decl::DeclType decl_type,
AnalyzerElementList *elements)
{ {
Decl *decl = find_decl(id); Decl* decl = find_decl(id);
if ( decl->decl_type() != decl_type ) if ( decl->decl_type() != decl_type )
{ {
throw Exception(id, throw Exception(id, strfmt("not a connection/flow declaration: %s", id->Name()));
strfmt("not a connection/flow declaration: %s",
id->Name()));
} }
AnalyzerDecl *analyzer_decl = static_cast<AnalyzerDecl *>(decl); AnalyzerDecl* analyzer_decl = static_cast<AnalyzerDecl*>(decl);
ASSERT(analyzer_decl); ASSERT(analyzer_decl);
analyzer_decl->AddElements(elements); analyzer_decl->AddElements(elements);
@ -153,18 +135,16 @@ Decl *ProcessAnalyzerRedef(const ID *id,
return decl; return decl;
} }
Decl *ProcessTypeAttrRedef(const ID *id, AttrList *attrlist) Decl* ProcessTypeAttrRedef(const ID* id, AttrList* attrlist)
{ {
Decl *decl = find_decl(id); Decl* decl = find_decl(id);
if ( decl->decl_type() != Decl::TYPE ) if ( decl->decl_type() != Decl::TYPE )
{ {
throw Exception(id, throw Exception(id, strfmt("not a type declaration: %s", id->Name()));
strfmt("not a type declaration: %s",
id->Name()));
} }
TypeDecl *type_decl = static_cast<TypeDecl *>(decl); TypeDecl* type_decl = static_cast<TypeDecl*>(decl);
ASSERT(type_decl); ASSERT(type_decl);
type_decl->AddAttrs(attrlist); type_decl->AddAttrs(attrlist);

View file

@ -3,11 +3,9 @@
#include "pac_decl.h" #include "pac_decl.h"
Decl *ProcessCaseTypeRedef(const ID *id, CaseFieldList *casefieldlist); Decl* ProcessCaseTypeRedef(const ID* id, CaseFieldList* casefieldlist);
Decl *ProcessCaseExprRedef(const ID *id, CaseExprList *caseexprlist); Decl* ProcessCaseExprRedef(const ID* id, CaseExprList* caseexprlist);
Decl *ProcessAnalyzerRedef(const ID *id, Decl* ProcessAnalyzerRedef(const ID* id, Decl::DeclType decl_type, AnalyzerElementList* elements);
Decl::DeclType decl_type, Decl* ProcessTypeAttrRedef(const ID* id, AttrList* attrlist);
AnalyzerElementList *elements);
Decl *ProcessTypeAttrRedef(const ID *id, AttrList *attrlist);
#endif // pac_redef_h #endif // pac_redef_h

View file

@ -1,27 +1,28 @@
#include "pac_regex.h"
#include "pac_exttype.h" #include "pac_exttype.h"
#include "pac_id.h" #include "pac_id.h"
#include "pac_output.h" #include "pac_output.h"
#include "pac_regex.h"
#include "pac_type.h" #include "pac_type.h"
// Depends on the regular expression library we are using // Depends on the regular expression library we are using
const char *RegEx::kREMatcherType = "RegExMatcher"; const char* RegEx::kREMatcherType = "RegExMatcher";
const char *RegEx::kMatchPrefix = "MatchPrefix"; const char* RegEx::kMatchPrefix = "MatchPrefix";
string escape_char(const string &s) string escape_char(const string& s)
{ {
char* buf = new char[s.length() * 2 + 1]; char* buf = new char[s.length() * 2 + 1];
int j = 0; int j = 0;
for ( int i = 0; i < (int) s.length(); ++i ) for ( int i = 0; i < (int)s.length(); ++i )
{ {
if ( s[i] == '\\' ) if ( s[i] == '\\' )
{ {
if ( i + 1 < (int) s.length() ) if ( i + 1 < (int)s.length() )
{ {
buf[j++] = '\\'; buf[j++] = '\\';
if ( s[i+1] == '/' ) if ( s[i + 1] == '/' )
buf[j-1] = s[++i]; buf[j - 1] = s[++i];
else if ( s[i+1] == '/' || s[i+1] == '\\' || s[i+1] == '"' ) else if ( s[i + 1] == '/' || s[i + 1] == '\\' || s[i + 1] == '"' )
buf[j++] = s[++i]; buf[j++] = s[++i];
else else
buf[j++] = '\\'; buf[j++] = '\\';
@ -41,11 +42,11 @@ string escape_char(const string &s)
buf[j++] = '\0'; buf[j++] = '\0';
string rval = buf; string rval = buf;
delete [] buf; delete[] buf;
return rval; return rval;
} }
RegEx::RegEx(const string &s) RegEx::RegEx(const string& s)
{ {
str_ = escape_char(s); str_ = escape_char(s);
string prefix = strfmt("%s_re_", current_decl_id->Name()); string prefix = strfmt("%s_re_", current_decl_id->Name());
@ -53,12 +54,9 @@ RegEx::RegEx(const string &s)
decl_ = new RegExDecl(this); decl_ = new RegExDecl(this);
} }
RegEx::~RegEx() RegEx::~RegEx() { }
{
}
RegExDecl::RegExDecl(RegEx *regex) RegExDecl::RegExDecl(RegEx* regex) : Decl(regex->matcher_id(), REGEX)
: Decl(regex->matcher_id(), REGEX)
{ {
regex_ = regex; regex_ = regex;
} }
@ -68,17 +66,14 @@ void RegExDecl::Prepare()
global_env()->AddID(id(), GLOBAL_VAR, extern_type_re_matcher); global_env()->AddID(id(), GLOBAL_VAR, extern_type_re_matcher);
} }
void RegExDecl::GenForwardDeclaration(Output *out_h) void RegExDecl::GenForwardDeclaration(Output* out_h)
{ {
out_h->println("extern %s %s;\n", out_h->println("extern %s %s;\n", RegEx::kREMatcherType,
RegEx::kREMatcherType,
global_env()->LValue(regex_->matcher_id())); global_env()->LValue(regex_->matcher_id()));
} }
void RegExDecl::GenCode(Output *out_h, Output *out_cc) void RegExDecl::GenCode(Output* out_h, Output* out_cc)
{ {
out_cc->println("%s %s(\"%s\");\n", out_cc->println("%s %s(\"%s\");\n", RegEx::kREMatcherType,
RegEx::kREMatcherType, global_env()->LValue(regex_->matcher_id()), regex_->str().c_str());
global_env()->LValue(regex_->matcher_id()),
regex_->str().c_str());
} }

View file

@ -7,35 +7,35 @@
class RegExDecl; class RegExDecl;
class RegEx : public Object class RegEx : public Object
{ {
public: public:
RegEx(const string &str); RegEx(const string& str);
~RegEx(); ~RegEx();
const string &str() const { return str_; } const string& str() const { return str_; }
ID *matcher_id() const { return matcher_id_; } ID* matcher_id() const { return matcher_id_; }
private: private:
string str_; string str_;
ID *matcher_id_; ID* matcher_id_;
RegExDecl *decl_; RegExDecl* decl_;
public: public:
static const char *kREMatcherType; static const char* kREMatcherType;
static const char *kMatchPrefix; static const char* kMatchPrefix;
}; };
class RegExDecl : public Decl class RegExDecl : public Decl
{ {
public: public:
RegExDecl(RegEx *regex); RegExDecl(RegEx* regex);
void Prepare(); void Prepare();
void GenForwardDeclaration(Output *out_h); void GenForwardDeclaration(Output* out_h);
void GenCode(Output *out_h, Output *out_cc); void GenCode(Output* out_h, Output* out_cc);
private: private:
RegEx *regex_; RegEx* regex_;
}; };
#endif // pac_regex_h #endif // pac_regex_h

View file

@ -1,36 +1,26 @@
#include "pac_state.h"
#include "pac_id.h" #include "pac_id.h"
#include "pac_output.h" #include "pac_output.h"
#include "pac_type.h" #include "pac_type.h"
#include "pac_state.h" void StateVar::GenDecl(Output* out_h, Env* env)
void StateVar::GenDecl(Output *out_h, Env *env)
{ {
out_h->println("%s %s;", out_h->println("%s %s;", type_->DataTypeStr().c_str(), env->LValue(id_));
type_->DataTypeStr().c_str(),
env->LValue(id_));
} }
void StateVar::GenAccessFunction(Output *out_h, Env *env) void StateVar::GenAccessFunction(Output* out_h, Env* env)
{ {
out_h->println("%s %s const { return %s; }", out_h->println("%s %s const { return %s; }", type_->DataTypeConstRefStr().c_str(),
type_->DataTypeConstRefStr().c_str(), env->RValue(id_), env->LValue(id_));
env->RValue(id_),
env->LValue(id_));
} }
void StateVar::GenSetFunction(Output *out_h, Env *env) void StateVar::GenSetFunction(Output* out_h, Env* env)
{ {
out_h->println("void %s(%s x) { %s = x; }", out_h->println("void %s(%s x) { %s = x; }", set_function(id_).c_str(),
set_function(id_).c_str(), type_->DataTypeConstRefStr().c_str(), env->LValue(id_));
type_->DataTypeConstRefStr().c_str(),
env->LValue(id_));
} }
void StateVar::GenInitCode(Output *out_cc, Env *env) void StateVar::GenInitCode(Output* out_cc, Env* env) { }
{
}
void StateVar::GenCleanUpCode(Output *out_cc, Env *env) void StateVar::GenCleanUpCode(Output* out_cc, Env* env) { }
{
}

View file

@ -6,23 +6,22 @@
#include "pac_common.h" #include "pac_common.h"
class StateVar class StateVar
{ {
public: public:
StateVar(ID *id, Type *type) StateVar(ID* id, Type* type) : id_(id), type_(type) { }
: id_(id), type_(type) {}
const ID *id() const { return id_; } const ID* id() const { return id_; }
Type *type() const { return type_; } Type* type() const { return type_; }
void GenDecl(Output *out_h, Env *env); void GenDecl(Output* out_h, Env* env);
void GenAccessFunction(Output *out_h, Env *env); void GenAccessFunction(Output* out_h, Env* env);
void GenSetFunction(Output *out_h, Env *env); void GenSetFunction(Output* out_h, Env* env);
void GenInitCode(Output *out_cc, Env *env); void GenInitCode(Output* out_cc, Env* env);
void GenCleanUpCode(Output *out_cc, Env *env); void GenCleanUpCode(Output* out_cc, Env* env);
private: private:
ID *id_; ID* id_;
Type *type_; Type* type_;
}; };
#endif // pac_state_h #endif // pac_state_h

View file

@ -1,3 +1,5 @@
#include "pac_strtype.h"
#include "pac_attr.h" #include "pac_attr.h"
#include "pac_btype.h" #include "pac_btype.h"
#include "pac_cstr.h" #include "pac_cstr.h"
@ -8,27 +10,23 @@
#include "pac_id.h" #include "pac_id.h"
#include "pac_output.h" #include "pac_output.h"
#include "pac_regex.h" #include "pac_regex.h"
#include "pac_strtype.h"
#include "pac_varfield.h" #include "pac_varfield.h"
const char *StringType::kStringTypeName = "bytestring"; const char* StringType::kStringTypeName = "bytestring";
const char *StringType::kConstStringTypeName = "const_bytestring"; const char* StringType::kConstStringTypeName = "const_bytestring";
StringType::StringType(StringTypeEnum anystr) StringType::StringType(StringTypeEnum anystr) : Type(STRING), type_(ANYSTR), str_(0), regex_(0)
: Type(STRING), type_(ANYSTR), str_(0), regex_(0)
{ {
ASSERT(anystr == ANYSTR); ASSERT(anystr == ANYSTR);
init(); init();
} }
StringType::StringType(ConstString *str) StringType::StringType(ConstString* str) : Type(STRING), type_(CSTR), str_(str), regex_(0)
: Type(STRING), type_(CSTR), str_(str), regex_(0)
{ {
init(); init();
} }
StringType::StringType(RegEx *regex) StringType::StringType(RegEx* regex) : Type(STRING), type_(REGEX), str_(0), regex_(regex)
: Type(STRING), type_(REGEX), str_(0), regex_(regex)
{ {
ASSERT(regex_); ASSERT(regex_);
init(); init();
@ -52,9 +50,9 @@ StringType::~StringType()
delete elem_datatype_; delete elem_datatype_;
} }
Type *StringType::DoClone() const Type* StringType::DoClone() const
{ {
StringType *clone; StringType* clone;
switch ( type_ ) switch ( type_ )
{ {
@ -82,16 +80,15 @@ bool StringType::DefineValueVar() const
string StringType::DataTypeStr() const string StringType::DataTypeStr() const
{ {
return strfmt("%s", return strfmt("%s", persistent() ? kStringTypeName : kConstStringTypeName);
persistent() ? kStringTypeName : kConstStringTypeName);
} }
Type *StringType::ElementDataType() const Type* StringType::ElementDataType() const
{ {
return elem_datatype_; return elem_datatype_;
} }
void StringType::ProcessAttr(Attr *a) void StringType::ProcessAttr(Attr* a)
{ {
Type::ProcessAttr(a); Type::ProcessAttr(a);
@ -101,8 +98,7 @@ void StringType::ProcessAttr(Attr *a)
{ {
if ( type_ != ANYSTR ) if ( type_ != ANYSTR )
{ {
throw Exception(a, throw Exception(a, "&chunked can be applied"
"&chunked can be applied"
" to only type bytestring"); " to only type bytestring");
} }
attr_chunked_ = true; attr_chunked_ = true;
@ -114,8 +110,7 @@ void StringType::ProcessAttr(Attr *a)
{ {
if ( type_ != ANYSTR ) if ( type_ != ANYSTR )
{ {
throw Exception(a, throw Exception(a, "&restofdata can be applied"
"&restofdata can be applied"
" to only type bytestring"); " to only type bytestring");
} }
attr_restofdata_ = true; attr_restofdata_ = true;
@ -129,8 +124,7 @@ void StringType::ProcessAttr(Attr *a)
{ {
if ( type_ != ANYSTR ) if ( type_ != ANYSTR )
{ {
throw Exception(a, throw Exception(a, "&restofflow can be applied"
"&restofflow can be applied"
" to only type bytestring"); " to only type bytestring");
} }
attr_restofflow_ = true; attr_restofflow_ = true;
@ -149,10 +143,9 @@ void StringType::Prepare(Env* env, int flags)
{ {
if ( (flags & TO_BE_PARSED) && StaticSize(env) < 0 ) if ( (flags & TO_BE_PARSED) && StaticSize(env) < 0 )
{ {
ID *string_length_var = new ID(strfmt("%s_string_length", ID* string_length_var = new ID(
value_var() ? value_var()->Name() : "val")); strfmt("%s_string_length", value_var() ? value_var()->Name() : "val"));
string_length_var_field_ = new TempVarField( string_length_var_field_ = new TempVarField(string_length_var, extern_type_int->Clone());
string_length_var, extern_type_int->Clone());
string_length_var_field_->Prepare(env); string_length_var_field_->Prepare(env);
} }
Type::Prepare(env, flags); Type::Prepare(env, flags);
@ -211,17 +204,15 @@ int StringType::StaticSize(Env* env) const
} }
} }
const ID *StringType::string_length_var() const const ID* StringType::string_length_var() const
{ {
return string_length_var_field_ ? string_length_var_field_->id() : 0; return string_length_var_field_ ? string_length_var_field_->id() : 0;
} }
void StringType::GenDynamicSize(Output* out_cc, Env* env, void StringType::GenDynamicSize(Output* out_cc, Env* env, const DataPtr& data)
const DataPtr& data)
{ {
ASSERT(StaticSize(env) < 0); ASSERT(StaticSize(env) < 0);
DEBUG_MSG("Generating dynamic size for string `%s'\n", DEBUG_MSG("Generating dynamic size for string `%s'\n", value_var()->Name());
value_var()->Name());
if ( env->Evaluated(string_length_var()) ) if ( env->Evaluated(string_length_var()) )
return; return;
@ -244,15 +235,12 @@ void StringType::GenDynamicSize(Output* out_cc, Env* env,
if ( ! incremental_input() && AddSizeVar(out_cc, env) ) if ( ! incremental_input() && AddSizeVar(out_cc, env) )
{ {
out_cc->println("%s = %s;", out_cc->println("%s = %s;", env->LValue(size_var()), env->RValue(string_length_var()));
env->LValue(size_var()),
env->RValue(string_length_var()));
env->SetEvaluated(size_var()); env->SetEvaluated(size_var());
} }
} }
string StringType::GenStringSize(Output* out_cc, Env* env, string StringType::GenStringSize(Output* out_cc, Env* env, const DataPtr& data)
const DataPtr& data)
{ {
int static_size = StaticSize(env); int static_size = StaticSize(env);
if ( static_size >= 0 ) if ( static_size >= 0 )
@ -261,8 +249,7 @@ string StringType::GenStringSize(Output* out_cc, Env* env,
return env->RValue(string_length_var()); return env->RValue(string_length_var());
} }
void StringType::DoGenParseCode(Output* out_cc, Env* env, void StringType::DoGenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags)
const DataPtr& data, int flags)
{ {
string str_size = GenStringSize(out_cc, env, data); string str_size = GenStringSize(out_cc, env, data);
@ -283,8 +270,7 @@ void StringType::DoGenParseCode(Output* out_cc, Env* env,
int len; int len;
if ( type_ == ANYSTR && attr_length_expr_ && if ( type_ == ANYSTR && attr_length_expr_ && attr_length_expr_->ConstFold(env, &len) )
attr_length_expr_->ConstFold(env, &len) )
{ {
// can check for a negative length now // can check for a negative length now
if ( len < 0 ) if ( len < 0 )
@ -293,41 +279,31 @@ void StringType::DoGenParseCode(Output* out_cc, Env* env,
else else
{ {
out_cc->println("// check for negative sizes"); out_cc->println("// check for negative sizes");
out_cc->println("if ( %s < 0 )", out_cc->println("if ( %s < 0 )", str_size.c_str());
out_cc->println("throw binpac::ExceptionInvalidStringLength(\"%s\", %s);", Location(),
str_size.c_str()); str_size.c_str());
out_cc->println(
"throw binpac::ExceptionInvalidStringLength(\"%s\", %s);",
Location(), str_size.c_str());
} }
out_cc->println("%s.init(%s, %s);", out_cc->println("%s.init(%s, %s);", env->LValue(value_var()), data.ptr_expr(),
env->LValue(value_var()),
data.ptr_expr(),
str_size.c_str()); str_size.c_str());
} }
if ( parsing_complete_var() ) if ( parsing_complete_var() )
{ {
out_cc->println("%s = true;", out_cc->println("%s = true;", env->LValue(parsing_complete_var()));
env->LValue(parsing_complete_var()));
} }
} }
void StringType::GenStringMismatch(Output* out_cc, Env* env, void StringType::GenStringMismatch(Output* out_cc, Env* env, const DataPtr& data, string pattern)
const DataPtr& data, string pattern)
{ {
string tmp = string tmp = strfmt("string((const char *) (%s), (const char *) %s).c_str()", data.ptr_expr(),
strfmt("string((const char *) (%s), (const char *) %s).c_str()",
data.ptr_expr(),
env->RValue(end_of_data)); env->RValue(end_of_data));
out_cc->println("throw binpac::ExceptionStringMismatch(\"%s\", %s, %s);", out_cc->println("throw binpac::ExceptionStringMismatch(\"%s\", %s, %s);", Location(),
Location(), pattern.c_str(), tmp.c_str());
pattern.c_str(),
tmp.c_str());
} }
void StringType::GenCheckingCStr(Output* out_cc, Env* env, void StringType::GenCheckingCStr(Output* out_cc, Env* env, const DataPtr& data,
const DataPtr& data, const string &str_size) const string& str_size)
{ {
// TODO: extend it for dynamic strings // TODO: extend it for dynamic strings
ASSERT(type_ == CSTR); ASSERT(type_ == CSTR);
@ -337,9 +313,7 @@ void StringType::GenCheckingCStr(Output* out_cc, Env* env,
string str_val = str_->str(); string str_val = str_->str();
// Compare the string and report error on mismatch // Compare the string and report error on mismatch
out_cc->println("if ( memcmp(%s, %s, %s) != 0 )", out_cc->println("if ( memcmp(%s, %s, %s) != 0 )", data.ptr_expr(), str_val.c_str(),
data.ptr_expr(),
str_val.c_str(),
str_size.c_str()); str_size.c_str());
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
@ -348,36 +322,28 @@ void StringType::GenCheckingCStr(Output* out_cc, Env* env,
out_cc->dec_indent(); out_cc->dec_indent();
} }
void StringType::GenDynamicSizeRegEx(Output* out_cc, Env* env, void StringType::GenDynamicSizeRegEx(Output* out_cc, Env* env, const DataPtr& data)
const DataPtr& data)
{ {
// string_length_var = // string_length_var =
// matcher.match_prefix( // matcher.match_prefix(
// begin, // begin,
// end); // end);
out_cc->println("%s = ", out_cc->println("%s = ", env->LValue(string_length_var()));
env->LValue(string_length_var()));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("%s.%s(", out_cc->println("%s.%s(", env->RValue(regex_->matcher_id()), RegEx::kMatchPrefix);
env->RValue(regex_->matcher_id()),
RegEx::kMatchPrefix);
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("%s,", out_cc->println("%s,", data.ptr_expr());
data.ptr_expr()); out_cc->println("%s - %s);", env->RValue(end_of_data), data.ptr_expr());
out_cc->println("%s - %s);",
env->RValue(end_of_data),
data.ptr_expr());
out_cc->dec_indent(); out_cc->dec_indent();
out_cc->dec_indent(); out_cc->dec_indent();
env->SetEvaluated(string_length_var()); env->SetEvaluated(string_length_var());
out_cc->println("if ( %s < 0 )", out_cc->println("if ( %s < 0 )", env->RValue(string_length_var()));
env->RValue(string_length_var()));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
string tmp = strfmt("\"%s\"", regex_->str().c_str()); string tmp = strfmt("\"%s\"", regex_->str().c_str());
@ -386,41 +352,34 @@ void StringType::GenDynamicSizeRegEx(Output* out_cc, Env* env,
out_cc->dec_indent(); out_cc->dec_indent();
} }
void StringType::GenDynamicSizeAnyStr(Output* out_cc, Env* env, void StringType::GenDynamicSizeAnyStr(Output* out_cc, Env* env, const DataPtr& data)
const DataPtr& data)
{ {
ASSERT(type_ == ANYSTR); ASSERT(type_ == ANYSTR);
if ( attr_restofdata_ || attr_oneline_ ) if ( attr_restofdata_ || attr_oneline_ )
{ {
out_cc->println("%s = (%s) - (%s);", out_cc->println("%s = (%s) - (%s);", env->LValue(string_length_var()),
env->LValue(string_length_var()), env->RValue(end_of_data), data.ptr_expr());
env->RValue(end_of_data),
data.ptr_expr());
} }
else if ( attr_restofflow_ ) else if ( attr_restofflow_ )
{ {
out_cc->println("%s = (%s) - (%s);", out_cc->println("%s = (%s) - (%s);", env->LValue(string_length_var()),
env->LValue(string_length_var()), env->RValue(end_of_data), data.ptr_expr());
env->RValue(end_of_data),
data.ptr_expr());
} }
else if ( attr_length_expr_ ) else if ( attr_length_expr_ )
{ {
out_cc->println("%s = %s;", out_cc->println("%s = %s;", env->LValue(string_length_var()),
env->LValue(string_length_var()),
attr_length_expr_->EvalExpr(out_cc, env)); attr_length_expr_->EvalExpr(out_cc, env));
} }
else else
{ {
throw Exception(this, throw Exception(this, "cannot determine length of bytestring");
"cannot determine length of bytestring");
} }
env->SetEvaluated(string_length_var()); env->SetEvaluated(string_length_var());
} }
bool StringType::DoTraverse(DataDepVisitor *visitor) bool StringType::DoTraverse(DataDepVisitor* visitor)
{ {
if ( ! Type::DoTraverse(visitor) ) if ( ! Type::DoTraverse(visitor) )
return false; return false;

View file

@ -5,19 +5,24 @@
// TODO: question: shall we merge it with ArrayType? // TODO: question: shall we merge it with ArrayType?
class StringType : public Type class StringType : public Type
{ {
public: public:
enum StringTypeEnum { CSTR, REGEX, ANYSTR }; enum StringTypeEnum
{
CSTR,
REGEX,
ANYSTR
};
explicit StringType(StringTypeEnum anystr); explicit StringType(StringTypeEnum anystr);
explicit StringType(ConstString *str); explicit StringType(ConstString* str);
explicit StringType(RegEx *regex); explicit StringType(RegEx* regex);
~StringType(); ~StringType();
bool DefineValueVar() const; bool DefineValueVar() const;
string DataTypeStr() const; string DataTypeStr() const;
string DefaultValue() const { return "0"; } string DefaultValue() const { return "0"; }
Type *ElementDataType() const; Type* ElementDataType() const;
void Prepare(Env* env, int flags); void Prepare(Env* env, int flags);
@ -33,7 +38,7 @@ public:
bool IsPointerType() const { return false; } bool IsPointerType() const { return false; }
void ProcessAttr(Attr *a); void ProcessAttr(Attr* a);
protected: protected:
void init(); void init();
@ -43,40 +48,39 @@ protected:
string GenStringSize(Output* out_cc, Env* env, const DataPtr& data); string GenStringSize(Output* out_cc, Env* env, const DataPtr& data);
// Generate a string mismatch exception // Generate a string mismatch exception
void GenStringMismatch(Output* out_cc, Env* env, void GenStringMismatch(Output* out_cc, Env* env, const DataPtr& data, string pattern);
const DataPtr& data, string pattern);
void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags); void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags);
void GenCheckingCStr(Output* out, Env* env, void GenCheckingCStr(Output* out, Env* env, const DataPtr& data, const string& str_size);
const DataPtr& data, const string &str_size);
void GenDynamicSize(Output* out, Env* env, const DataPtr& data); void GenDynamicSize(Output* out, Env* env, const DataPtr& data);
void GenDynamicSizeAnyStr(Output* out_cc, Env* env, const DataPtr& data); void GenDynamicSizeAnyStr(Output* out_cc, Env* env, const DataPtr& data);
void GenDynamicSizeRegEx(Output* out_cc, Env* env, const DataPtr& data); void GenDynamicSizeRegEx(Output* out_cc, Env* env, const DataPtr& data);
Type *DoClone() const; Type* DoClone() const;
// TODO: insensitive towards byte order till we support unicode // TODO: insensitive towards byte order till we support unicode
bool ByteOrderSensitive() const { return false; } bool ByteOrderSensitive() const { return false; }
protected: protected:
bool DoTraverse(DataDepVisitor *visitor); bool DoTraverse(DataDepVisitor* visitor);
private: private:
const ID *string_length_var() const; const ID* string_length_var() const;
StringTypeEnum type_; StringTypeEnum type_;
ConstString *str_; ConstString* str_;
RegEx *regex_; RegEx* regex_;
Field *string_length_var_field_; Field* string_length_var_field_;
Type *elem_datatype_; Type* elem_datatype_;
public: public:
static void static_init(); static void static_init();
private: private:
static const char *kStringTypeName; static const char* kStringTypeName;
static const char *kConstStringTypeName; static const char* kConstStringTypeName;
}; };
#endif // pac_strtype_h #endif // pac_strtype_h

View file

@ -1,3 +1,5 @@
#include "pac_type.h"
#include "pac_action.h" #include "pac_action.h"
#include "pac_array.h" #include "pac_array.h"
#include "pac_attr.h" #include "pac_attr.h"
@ -14,16 +16,13 @@
#include "pac_output.h" #include "pac_output.h"
#include "pac_paramtype.h" #include "pac_paramtype.h"
#include "pac_strtype.h" #include "pac_strtype.h"
#include "pac_type.h"
#include "pac_utils.h" #include "pac_utils.h"
#include "pac_varfield.h" #include "pac_varfield.h"
#include "pac_withinput.h" #include "pac_withinput.h"
Type::type_map_t Type::type_map_; Type::type_map_t Type::type_map_;
Type::Type(TypeType tot) Type::Type(TypeType tot) : DataDepElement(DataDepElement::TYPE), tot_(tot)
: DataDepElement(DataDepElement::TYPE), tot_(tot)
{ {
type_decl_ = 0; type_decl_ = 0;
type_decl_id_ = current_decl_id; type_decl_id_ = current_decl_id;
@ -75,7 +74,7 @@ Type::~Type()
delete parsing_state_var_field_; delete parsing_state_var_field_;
delete buffering_state_var_field_; delete buffering_state_var_field_;
delete has_value_field_; delete has_value_field_;
delete [] size_expr_; delete[] size_expr_;
delete_list(FieldList, fields_); delete_list(FieldList, fields_);
delete attrs_; delete attrs_;
delete attr_byteorder_expr_; delete attr_byteorder_expr_;
@ -86,43 +85,43 @@ Type::~Type()
delete_list(ExprList, attr_requires_); delete_list(ExprList, attr_requires_);
} }
Type *Type::Clone() const Type* Type::Clone() const
{ {
Type *clone = DoClone(); Type* clone = DoClone();
if ( clone ) if ( clone )
{ {
foreach(i, FieldList, fields_) foreach (i, FieldList, fields_)
{ {
Field *f = *i; Field* f = *i;
clone->AddField(f); clone->AddField(f);
} }
foreach(i, AttrList, attrs_) foreach (i, AttrList, attrs_)
{ {
Attr *a = *i; Attr* a = *i;
clone->ProcessAttr(a); clone->ProcessAttr(a);
} }
} }
return clone; return clone;
} }
string Type::EvalMember(const ID *member_id) const string Type::EvalMember(const ID* member_id) const
{ {
ASSERT(0); ASSERT(0);
return "@@@"; return "@@@";
} }
string Type::EvalElement(const string &array, const string &index) const string Type::EvalElement(const string& array, const string& index) const
{ {
return strfmt("%s[%s]", array.c_str(), index.c_str()); return strfmt("%s[%s]", array.c_str(), index.c_str());
} }
const ID *Type::decl_id() const const ID* Type::decl_id() const
{ {
return type_decl_id_; return type_decl_id_;
} }
void Type::set_type_decl(const TypeDecl *decl, bool declared_as_type) void Type::set_type_decl(const TypeDecl* decl, bool declared_as_type)
{ {
type_decl_ = decl; type_decl_ = decl;
type_decl_id_ = decl->id(); type_decl_id_ = decl->id();
@ -138,12 +137,12 @@ void Type::set_value_var(const ID* arg_id, int arg_id_type)
anonymous_value_var_ = value_var_->is_anonymous(); anonymous_value_var_ = value_var_->is_anonymous();
} }
const ID *Type::size_var() const const ID* Type::size_var() const
{ {
return size_var_field_ ? size_var_field_->id() : 0; return size_var_field_ ? size_var_field_->id() : 0;
} }
void Type::AddField(Field *f) void Type::AddField(Field* f)
{ {
ASSERT(f); ASSERT(f);
fields_->push_back(f); fields_->push_back(f);
@ -179,23 +178,22 @@ void Type::ProcessAttr(Attr* a)
case ATTR_LET: case ATTR_LET:
{ {
LetAttr *letattr = static_cast<LetAttr *>(a); LetAttr* letattr = static_cast<LetAttr*>(a);
if ( ! attr_letfields_ ) if ( ! attr_letfields_ )
attr_letfields_ = letattr->letfields(); attr_letfields_ = letattr->letfields();
else else
{ {
// Append to attr_letfields_ // Append to attr_letfields_
attr_letfields_->insert( attr_letfields_->insert(attr_letfields_->end(), letattr->letfields()->begin(),
attr_letfields_->end(),
letattr->letfields()->begin(),
letattr->letfields()->end()); letattr->letfields()->end());
} }
} }
break; break;
case ATTR_LINEBREAKER: case ATTR_LINEBREAKER:
if (strlen(a->expr()->orig()) != 6 ) if ( strlen(a->expr()->orig()) != 6 )
throw Exception(this, "invalid line breaker length, must be a single ASCII character. (Ex: \"\\001\".)"); throw Exception(this, "invalid line breaker length, must be a single ASCII "
"character. (Ex: \"\\001\".)");
attr_linebreaker_ = a->expr(); attr_linebreaker_ = a->expr();
break; break;
@ -232,7 +230,7 @@ void Type::ProcessAttr(Attr* a)
attrs_->push_back(a); attrs_->push_back(a);
} }
string Type::EvalByteOrder(Output *out_cc, Env *env) const string Type::EvalByteOrder(Output* out_cc, Env* env) const
{ {
// If &byteorder is specified for a field, rather // If &byteorder is specified for a field, rather
// than a type declaration, we do not add a byteorder variable // than a type declaration, we do not add a byteorder variable
@ -251,8 +249,7 @@ void Type::Prepare(Env* env, int flags)
// The name of the value variable // The name of the value variable
if ( value_var() ) if ( value_var() )
{ {
data_id_str_ = strfmt("%s:%s", data_id_str_ = strfmt("%s:%s", decl_id()->Name(), value_var()->Name());
decl_id()->Name(), value_var()->Name());
} }
else else
{ {
@ -261,13 +258,11 @@ void Type::Prepare(Env* env, int flags)
if ( value_var() ) if ( value_var() )
{ {
env_->AddID(value_var(), env_->AddID(value_var(), static_cast<IDType>(value_var_type_), this);
static_cast<IDType>(value_var_type_),
this);
lvalue_ = strfmt("%s", env_->LValue(value_var())); lvalue_ = strfmt("%s", env_->LValue(value_var()));
} }
foreach(i, FieldList, attr_letfields_) foreach (i, FieldList, attr_letfields_)
{ {
AddField(*i); AddField(*i);
} }
@ -275,38 +270,31 @@ void Type::Prepare(Env* env, int flags)
if ( attr_exportsourcedata_ ) if ( attr_exportsourcedata_ )
{ {
ASSERT(flags & TO_BE_PARSED); ASSERT(flags & TO_BE_PARSED);
AddField(new PubVarField(sourcedata_id->clone(), AddField(new PubVarField(sourcedata_id->clone(), extern_type_const_bytestring->Clone()));
extern_type_const_bytestring->Clone()));
} }
// An optional field // An optional field
if ( attr_if_expr() ) if ( attr_if_expr() )
{ {
ASSERT(value_var()); ASSERT(value_var());
ID *has_value_id = new ID(strfmt("has_%s", value_var()->Name())); ID* has_value_id = new ID(strfmt("has_%s", value_var()->Name()));
has_value_field_ = new LetField(has_value_id, has_value_field_ = new LetField(has_value_id, extern_type_bool->Clone(), attr_if_expr());
extern_type_bool->Clone(),
attr_if_expr());
AddField(has_value_field_); AddField(has_value_field_);
} }
if ( incremental_input() ) if ( incremental_input() )
{ {
ASSERT(flags & TO_BE_PARSED); ASSERT(flags & TO_BE_PARSED);
ID *parsing_complete_var = ID* parsing_complete_var = new ID(
new ID(strfmt("%s_parsing_complete", strfmt("%s_parsing_complete", value_var() ? value_var()->Name() : "val"));
value_var() ? value_var()->Name() : "val")); DEBUG_MSG("Adding parsing complete var: %s\n", parsing_complete_var->Name());
DEBUG_MSG("Adding parsing complete var: %s\n", parsing_complete_var_field_ = new TempVarField(parsing_complete_var,
parsing_complete_var->Name()); extern_type_bool->Clone());
parsing_complete_var_field_ = new TempVarField(
parsing_complete_var, extern_type_bool->Clone());
parsing_complete_var_field_->Prepare(env); parsing_complete_var_field_->Prepare(env);
if ( NeedsBufferingStateVar() && if ( NeedsBufferingStateVar() && ! env->GetDataType(buffering_state_id) )
! env->GetDataType(buffering_state_id) )
{ {
buffering_state_var_field_ = new PrivVarField( buffering_state_var_field_ = new PrivVarField(buffering_state_id->clone(),
buffering_state_id->clone(),
extern_type_int->Clone()); extern_type_int->Clone());
AddField(buffering_state_var_field_); AddField(buffering_state_var_field_);
} }
@ -314,8 +302,7 @@ void Type::Prepare(Env* env, int flags)
if ( incremental_parsing() && tot_ == RECORD ) if ( incremental_parsing() && tot_ == RECORD )
{ {
ASSERT(! parsing_state_var_field_); ASSERT(! parsing_state_var_field_);
parsing_state_var_field_ = new PrivVarField( parsing_state_var_field_ = new PrivVarField(parsing_state_id->clone(),
parsing_state_id->clone(),
extern_type_int->Clone()); extern_type_int->Clone());
AddField(parsing_state_var_field_); AddField(parsing_state_var_field_);
} }
@ -323,7 +310,7 @@ void Type::Prepare(Env* env, int flags)
foreach (i, FieldList, fields_) foreach (i, FieldList, fields_)
{ {
Field *f = *i; Field* f = *i;
f->Prepare(env); f->Prepare(env);
} }
} }
@ -334,18 +321,16 @@ void Type::GenPubDecls(Output* out_h, Env* env)
{ {
if ( attr_if_expr_ ) if ( attr_if_expr_ )
out_h->println("%s %s const { BINPAC_ASSERT(%s); return %s; }", out_h->println("%s %s const { BINPAC_ASSERT(%s); return %s; }",
DataTypeConstRefStr().c_str(), DataTypeConstRefStr().c_str(), env->RValue(value_var()),
env->RValue(value_var()),
env->RValue(has_value_var()), lvalue()); env->RValue(has_value_var()), lvalue());
else else
out_h->println("%s %s const { return %s; }", out_h->println("%s %s const { return %s; }", DataTypeConstRefStr().c_str(),
DataTypeConstRefStr().c_str(),
env->RValue(value_var()), lvalue()); env->RValue(value_var()), lvalue());
} }
foreach (i, FieldList, fields_) foreach (i, FieldList, fields_)
{ {
Field *f = *i; Field* f = *i;
f->GenPubDecls(out_h, env); f->GenPubDecls(out_h, env);
} }
} }
@ -354,14 +339,12 @@ void Type::GenPrivDecls(Output* out_h, Env* env)
{ {
if ( DefineValueVar() ) if ( DefineValueVar() )
{ {
out_h->println("%s %s;", out_h->println("%s %s;", DataTypeStr().c_str(), env->LValue(value_var()));
DataTypeStr().c_str(),
env->LValue(value_var()));
} }
foreach (i, FieldList, fields_) foreach (i, FieldList, fields_)
{ {
Field *f = *i; Field* f = *i;
f->GenPrivDecls(out_h, env); f->GenPrivDecls(out_h, env);
} }
} }
@ -370,20 +353,18 @@ void Type::GenInitCode(Output* out_cc, Env* env)
{ {
foreach (i, FieldList, fields_) foreach (i, FieldList, fields_)
{ {
Field *f = *i; Field* f = *i;
f->GenInitCode(out_cc, env); f->GenInitCode(out_cc, env);
} }
if ( parsing_state_var_field_ ) if ( parsing_state_var_field_ )
{ {
out_cc->println("%s = 0;", out_cc->println("%s = 0;", env->LValue(parsing_state_var_field_->id()));
env->LValue(parsing_state_var_field_->id()));
} }
if ( buffering_state_var_field_ ) if ( buffering_state_var_field_ )
{ {
out_cc->println("%s = 0;", out_cc->println("%s = 0;", env->LValue(buffering_state_var_field_->id()));
env->LValue(buffering_state_var_field_->id()));
} }
} }
@ -391,13 +372,13 @@ void Type::GenCleanUpCode(Output* out_cc, Env* env)
{ {
foreach (i, FieldList, fields_) foreach (i, FieldList, fields_)
{ {
Field *f = *i; Field* f = *i;
if ( f->tof() != CASE_FIELD ) if ( f->tof() != CASE_FIELD )
f->GenCleanUpCode(out_cc, env); f->GenCleanUpCode(out_cc, env);
} }
} }
void Type::GenBufferConfiguration(Output *out_cc, Env *env) void Type::GenBufferConfiguration(Output* out_cc, Env* env)
{ {
ASSERT(buffer_input()); ASSERT(buffer_input());
@ -414,8 +395,7 @@ void Type::GenBufferConfiguration(Output *out_cc, Env *env)
if ( buffering_state_var_field_ ) if ( buffering_state_var_field_ )
{ {
out_cc->println("if ( %s == 0 )", out_cc->println("if ( %s == 0 )", env->RValue(buffering_state_id));
env->RValue(buffering_state_id));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
} }
@ -435,36 +415,30 @@ void Type::GenBufferConfiguration(Output *out_cc, Env *env)
ASSERT(0); ASSERT(0);
} }
out_cc->println("%s->NewFrame(%s, %s);", out_cc->println("%s->NewFrame(%s, %s);", env->LValue(flow_buffer_id),
env->LValue(flow_buffer_id), frame_buffer_arg.c_str(), attr_chunked() ? "true" : "false");
frame_buffer_arg.c_str(),
attr_chunked() ? "true" : "false");
if ( buffering_state_var_field_ ) if ( buffering_state_var_field_ )
{ {
out_cc->println("%s = 1;", out_cc->println("%s = 1;", env->LValue(buffering_state_id));
env->LValue(buffering_state_id));
out_cc->println("}"); out_cc->println("}");
out_cc->dec_indent(); out_cc->dec_indent();
} }
break; break;
case BUFFER_BY_LINE: case BUFFER_BY_LINE:
out_cc->println("if ( %s == 0 )", out_cc->println("if ( %s == 0 )", env->RValue(buffering_state_id));
env->RValue(buffering_state_id));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
if ( BufferableWithLineBreaker() ) if ( BufferableWithLineBreaker() )
out_cc->println("%s->SetLineBreaker((unsigned char*)%s);", out_cc->println("%s->SetLineBreaker((unsigned char*)%s);",
env->LValue(flow_buffer_id), LineBreaker()->orig()); env->LValue(flow_buffer_id), LineBreaker()->orig());
else else
out_cc->println("%s->UnsetLineBreaker();", out_cc->println("%s->UnsetLineBreaker();", env->LValue(flow_buffer_id));
env->LValue(flow_buffer_id));
out_cc->println("%s->NewLine();",
env->LValue(flow_buffer_id));
out_cc->println("%s = 1;", out_cc->println("%s->NewLine();", env->LValue(flow_buffer_id));
env->LValue(buffering_state_id));
out_cc->println("%s = 1;", env->LValue(buffering_state_id));
out_cc->println("}"); out_cc->println("}");
out_cc->dec_indent(); out_cc->dec_indent();
break; break;
@ -475,7 +449,7 @@ void Type::GenBufferConfiguration(Output *out_cc, Env *env)
} }
} }
void Type::GenPreParsing(Output *out_cc, Env *env) void Type::GenPreParsing(Output* out_cc, Env* env)
{ {
if ( incremental_input() && IsPointerType() ) if ( incremental_input() && IsPointerType() )
{ {
@ -519,14 +493,12 @@ void Type::GenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags
{ {
parsing_complete_var_field_->GenTempDecls(out_cc, env); parsing_complete_var_field_->GenTempDecls(out_cc, env);
out_cc->println("%s = false;", out_cc->println("%s = false;", env->LValue(parsing_complete_var()));
env->LValue(parsing_complete_var()));
env->SetEvaluated(parsing_complete_var()); env->SetEvaluated(parsing_complete_var());
if ( buffer_mode() == BUFFER_NOTHING ) if ( buffer_mode() == BUFFER_NOTHING )
{ {
out_cc->println("%s = true;", out_cc->println("%s = true;", env->LValue(parsing_complete_var()));
env->LValue(parsing_complete_var()));
} }
else if ( buffer_input() ) else if ( buffer_input() )
{ {
@ -540,19 +512,16 @@ void Type::GenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags
} }
else else
{ {
if ( attr_length_expr_) if ( attr_length_expr_ )
{ {
EvalLengthExpr(out_cc, env); EvalLengthExpr(out_cc, env);
GenBoundaryCheck(out_cc, env, data); GenBoundaryCheck(out_cc, env, data);
out_cc->println("{"); out_cc->println("{");
out_cc->println("// Setting %s with &length", out_cc->println("// Setting %s with &length", env->RValue(end_of_data));
env->RValue(end_of_data)); out_cc->println("%s %s = %s + %s;", extern_type_const_byteptr->DataTypeStr().c_str(),
out_cc->println("%s %s = %s + %s;", env->LValue(end_of_data), data.ptr_expr(),
extern_type_const_byteptr->DataTypeStr().c_str(),
env->LValue(end_of_data),
data.ptr_expr(),
EvalLengthExpr(out_cc, env).c_str()); EvalLengthExpr(out_cc, env).c_str());
GenParseCode2(out_cc, env, data, flags); GenParseCode2(out_cc, env, data, flags);
@ -568,8 +537,7 @@ void Type::GenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags
void Type::GenBufferingLoop(Output* out_cc, Env* env, int flags) void Type::GenBufferingLoop(Output* out_cc, Env* env, int flags)
{ {
out_cc->println("while ( ! %s && %s->ready() )", out_cc->println("while ( ! %s && %s->ready() )", env->LValue(parsing_complete_var()),
env->LValue(parsing_complete_var()),
env->LValue(flow_buffer_id)); env->LValue(flow_buffer_id));
out_cc->inc_indent(); out_cc->inc_indent();
@ -586,22 +554,18 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
{ {
ASSERT(incremental_input()); ASSERT(incremental_input());
const ID *data_begin; const ID* data_begin;
if ( ! incremental_parsing() ) if ( ! incremental_parsing() )
{ {
env->AddID(begin_of_data, TEMP_VAR, extern_type_const_byteptr); env->AddID(begin_of_data, TEMP_VAR, extern_type_const_byteptr);
env->AddID(end_of_data, TEMP_VAR, extern_type_const_byteptr); env->AddID(end_of_data, TEMP_VAR, extern_type_const_byteptr);
out_cc->println("%s %s = %s->begin();", out_cc->println("%s %s = %s->begin();", env->DataTypeStr(begin_of_data).c_str(),
env->DataTypeStr(begin_of_data).c_str(), env->LValue(begin_of_data), env->RValue(flow_buffer_id));
env->LValue(begin_of_data),
env->RValue(flow_buffer_id));
out_cc->println("%s %s = %s->end();", out_cc->println("%s %s = %s->end();", env->DataTypeStr(end_of_data).c_str(),
env->DataTypeStr(end_of_data).c_str(), env->LValue(end_of_data), env->RValue(flow_buffer_id));
env->LValue(end_of_data),
env->RValue(flow_buffer_id));
env->SetEvaluated(begin_of_data); env->SetEvaluated(begin_of_data);
env->SetEvaluated(end_of_data); env->SetEvaluated(end_of_data);
@ -615,8 +579,7 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
{ {
if ( incremental_parsing() ) if ( incremental_parsing() )
{ {
throw Exception(this, throw Exception(this, "cannot handle &until($input...) "
"cannot handle &until($input...) "
"for incrementally parsed type"); "for incrementally parsed type");
} }
array_until_input_->GenUntilInputCheck(out_cc, env); array_until_input_->GenUntilInputCheck(out_cc, env);
@ -627,8 +590,7 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
if ( attr_length_expr() ) if ( attr_length_expr() )
{ {
ASSERT(buffer_mode() == BUFFER_BY_LENGTH); ASSERT(buffer_mode() == BUFFER_BY_LENGTH);
out_cc->println("switch ( %s )", out_cc->println("switch ( %s )", env->LValue(buffering_state_id));
env->LValue(buffering_state_id));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
out_cc->println("case 0:"); out_cc->println("case 0:");
@ -646,8 +608,7 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
out_cc->println("%s = 2;", env->LValue(buffering_state_id)); out_cc->println("%s = 2;", env->LValue(buffering_state_id));
Env frame_length_env(env, this); Env frame_length_env(env, this);
out_cc->println("%s->GrowFrame(%s);", out_cc->println("%s->GrowFrame(%s);", env->LValue(flow_buffer_id),
env->LValue(flow_buffer_id),
attr_length_expr_->EvalExpr(out_cc, &frame_length_env)); attr_length_expr_->EvalExpr(out_cc, &frame_length_env));
out_cc->println("}"); out_cc->println("}");
out_cc->println("break;"); out_cc->println("break;");
@ -656,20 +617,16 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
out_cc->println("case 2:"); out_cc->println("case 2:");
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("BINPAC_ASSERT(%s->ready());", out_cc->println("BINPAC_ASSERT(%s->ready());", env->RValue(flow_buffer_id));
env->RValue(flow_buffer_id)); out_cc->println("if ( %s->ready() )", env->RValue(flow_buffer_id));
out_cc->println("if ( %s->ready() )",
env->RValue(flow_buffer_id));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
Env parse_env(env, this); Env parse_env(env, this);
GenParseCode2(out_cc, &parse_env, data, 0); GenParseCode2(out_cc, &parse_env, data, 0);
out_cc->println("BINPAC_ASSERT(%s);", out_cc->println("BINPAC_ASSERT(%s);", parsing_complete(env).c_str());
parsing_complete(env).c_str()); out_cc->println("%s = 0;", env->LValue(buffering_state_id));
out_cc->println("%s = 0;",
env->LValue(buffering_state_id));
out_cc->println("}"); out_cc->println("}");
out_cc->dec_indent(); out_cc->dec_indent();
@ -679,8 +636,7 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
out_cc->println("default:"); out_cc->println("default:");
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("BINPAC_ASSERT(%s <= 2);", out_cc->println("BINPAC_ASSERT(%s <= 2);", env->LValue(buffering_state_id));
env->LValue(buffering_state_id));
out_cc->println("break;"); out_cc->println("break;");
out_cc->dec_indent(); out_cc->dec_indent();
@ -689,8 +645,7 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
} }
else if ( attr_restofflow_ ) else if ( attr_restofflow_ )
{ {
out_cc->println("BINPAC_ASSERT(%s->eof());", out_cc->println("BINPAC_ASSERT(%s->eof());", env->RValue(flow_buffer_id));
env->RValue(flow_buffer_id));
GenParseCode2(out_cc, env, data, 0); GenParseCode2(out_cc, env, data, 0);
} }
else if ( buffer_mode() == BUFFER_BY_LINE ) else if ( buffer_mode() == BUFFER_BY_LINE )
@ -702,8 +657,7 @@ void Type::GenParseBuffer(Output* out_cc, Env* env, int flags)
GenParseCode2(out_cc, env, data, 0); GenParseCode2(out_cc, env, data, 0);
} }
void Type::GenParseCode2(Output* out_cc, Env* env, void Type::GenParseCode2(Output* out_cc, Env* env, const DataPtr& data, int flags)
const DataPtr& data, int flags)
{ {
DEBUG_MSG("GenParseCode2 for %s\n", data_id_str_.c_str()); DEBUG_MSG("GenParseCode2 for %s\n", data_id_str_.c_str());
@ -711,22 +665,17 @@ void Type::GenParseCode2(Output* out_cc, Env* env,
{ {
if ( incremental_parsing() ) if ( incremental_parsing() )
{ {
throw Exception(this, throw Exception(this, "cannot export raw data for incrementally parsed types");
"cannot export raw data for incrementally parsed types");
} }
out_cc->println("%s = const_bytestring(%s, %s);", out_cc->println("%s = const_bytestring(%s, %s);", env->LValue(sourcedata_id),
env->LValue(sourcedata_id), data.ptr_expr(), env->RValue(end_of_data));
data.ptr_expr(),
env->RValue(end_of_data));
env->SetEvaluated(sourcedata_id); env->SetEvaluated(sourcedata_id);
GenParseCode3(out_cc, env, data, flags); GenParseCode3(out_cc, env, data, flags);
string datasize_str = DataSize(out_cc, env, data); string datasize_str = DataSize(out_cc, env, data);
out_cc->println("%s.set_end(%s + %s);", out_cc->println("%s.set_end(%s + %s);", env->LValue(sourcedata_id), data.ptr_expr(),
env->LValue(sourcedata_id),
data.ptr_expr(),
datasize_str.c_str()); datasize_str.c_str());
} }
else else
@ -737,15 +686,15 @@ void Type::GenParseCode2(Output* out_cc, Env* env,
void Type::GenParseCode3(Output* out_cc, Env* env, const DataPtr& data, int flags) void Type::GenParseCode3(Output* out_cc, Env* env, const DataPtr& data, int flags)
{ {
foreach(i, ExprList, attr_requires_) foreach (i, ExprList, attr_requires_)
{ {
Expr *req = *i; Expr* req = *i;
req->EvalExpr(out_cc, env); req->EvalExpr(out_cc, env);
} }
foreach(i, FieldList, fields_) foreach (i, FieldList, fields_)
{ {
Field *f = *i; Field* f = *i;
f->GenTempDecls(out_cc, env); f->GenTempDecls(out_cc, env);
} }
@ -759,17 +708,17 @@ void Type::GenParseCode3(Output* out_cc, Env* env, const DataPtr& data, int flag
} }
out_cc->println("// Evaluate 'let' and 'withinput' fields"); out_cc->println("// Evaluate 'let' and 'withinput' fields");
foreach(i, FieldList, fields_) foreach (i, FieldList, fields_)
{ {
Field *f = *i; Field* f = *i;
if ( f->tof() == LET_FIELD ) if ( f->tof() == LET_FIELD )
{ {
LetField *lf = static_cast<LetField *>(f); LetField* lf = static_cast<LetField*>(f);
lf->GenParseCode(out_cc, env); lf->GenParseCode(out_cc, env);
} }
else if ( f->tof() == WITHINPUT_FIELD ) else if ( f->tof() == WITHINPUT_FIELD )
{ {
WithInputField *af = static_cast<WithInputField *>(f); WithInputField* af = static_cast<WithInputField*>(f);
af->GenParseCode(out_cc, env); af->GenParseCode(out_cc, env);
} }
} }
@ -791,7 +740,7 @@ void Type::GenParseCode3(Output* out_cc, Env* env, const DataPtr& data, int flag
if ( size_var() ) if ( size_var() )
ASSERT(env->Evaluated(size_var())); ASSERT(env->Evaluated(size_var()));
foreach(i, ExprList, attr_enforces_) foreach (i, ExprList, attr_enforces_)
{ {
Expr* enforce = *i; Expr* enforce = *i;
const char* enforce_expr = enforce->EvalExpr(out_cc, env); const char* enforce_expr = enforce->EvalExpr(out_cc, env);
@ -803,20 +752,19 @@ void Type::GenParseCode3(Output* out_cc, Env* env, const DataPtr& data, int flag
out_cc->println("}"); out_cc->println("}");
out_cc->dec_indent(); out_cc->dec_indent();
} }
} }
Type *Type::MemberDataType(const ID *member_id) const Type* Type::MemberDataType(const ID* member_id) const
{ {
DEBUG_MSG("MemberDataType: %s::%s\n", type_decl_id_->Name(), member_id->Name()); DEBUG_MSG("MemberDataType: %s::%s\n", type_decl_id_->Name(), member_id->Name());
ASSERT(env_); ASSERT(env_);
env_->set_allow_undefined_id(true); env_->set_allow_undefined_id(true);
Type *t = env_->GetDataType(member_id); Type* t = env_->GetDataType(member_id);
env_->set_allow_undefined_id(false); env_->set_allow_undefined_id(false);
return t; return t;
} }
Type *Type::ElementDataType() const Type* Type::ElementDataType() const
{ {
return 0; return 0;
} }
@ -837,13 +785,12 @@ bool Type::AddSizeVar(Output* out_cc, Env* env)
ASSERT(! incremental_input()); ASSERT(! incremental_input());
ID *size_var_id = new ID(strfmt("%s__size", ID* size_var_id = new ID(
value_var() ? value_var()->Name() : decl_id()->Name())); strfmt("%s__size", value_var() ? value_var()->Name() : decl_id()->Name()));
DEBUG_MSG("adding size var `%s' to env %p\n", size_var_id->Name(), env); DEBUG_MSG("adding size var `%s' to env %p\n", size_var_id->Name(), env);
size_var_field_ = new TempVarField( size_var_field_ = new TempVarField(size_var_id, extern_type_int->Clone());
size_var_id, extern_type_int->Clone());
size_var_field_->Prepare(env); size_var_field_->Prepare(env);
size_var_field_->GenTempDecls(out_cc, env); size_var_field_->GenTempDecls(out_cc, env);
@ -852,7 +799,7 @@ bool Type::AddSizeVar(Output* out_cc, Env* env)
string Type::EvalLengthExpr(Output* out_cc, Env* env) string Type::EvalLengthExpr(Output* out_cc, Env* env)
{ {
ASSERT(!incremental_input()); ASSERT(! incremental_input());
ASSERT(attr_length_expr_); ASSERT(attr_length_expr_);
int static_length; int static_length;
if ( attr_length_expr_->ConstFold(env, &static_length) ) if ( attr_length_expr_->ConstFold(env, &static_length) )
@ -860,8 +807,7 @@ string Type::EvalLengthExpr(Output* out_cc, Env* env)
// How do we make sure size_var is evaluated with attr_length_expr_? // How do we make sure size_var is evaluated with attr_length_expr_?
if ( AddSizeVar(out_cc, env) ) if ( AddSizeVar(out_cc, env) )
{ {
out_cc->println("%s = %s;", out_cc->println("%s = %s;", env->LValue(size_var()),
env->LValue(size_var()),
attr_length_expr_->EvalExpr(out_cc, env)); attr_length_expr_->EvalExpr(out_cc, env));
env->SetEvaluated(size_var()); env->SetEvaluated(size_var());
} }
@ -890,15 +836,12 @@ string Type::DataSize(Output* out_cc, Env* env, const DataPtr& data)
} }
} }
void Type::GenBoundaryCheck(Output* out_cc, Env* env, void Type::GenBoundaryCheck(Output* out_cc, Env* env, const DataPtr& data)
const DataPtr& data)
{ {
if ( boundary_checked() ) if ( boundary_checked() )
return; return;
data.GenBoundaryCheck(out_cc, env, data.GenBoundaryCheck(out_cc, env, DataSize(out_cc, env, data).c_str(), data_id_str_.c_str());
DataSize(out_cc, env, data).c_str(),
data_id_str_.c_str());
SetBoundaryChecked(); SetBoundaryChecked();
} }
@ -928,7 +871,7 @@ bool Type::RequiresByteOrder() const
bool Type::NeedsBufferingStateVar() const bool Type::NeedsBufferingStateVar() const
{ {
if ( !incremental_input() ) if ( ! incremental_input() )
return false; return false;
switch ( buffer_mode() ) switch ( buffer_mode() )
{ {
@ -938,14 +881,14 @@ bool Type::NeedsBufferingStateVar() const
case BUFFER_BY_LINE: case BUFFER_BY_LINE:
return true; return true;
case BUFFER_BY_LENGTH: case BUFFER_BY_LENGTH:
return ( attr_length_expr_ || attr_restofflow_ ); return (attr_length_expr_ || attr_restofflow_);
default: default:
ASSERT(0); ASSERT(0);
return false; return false;
} }
} }
bool Type::DoTraverse(DataDepVisitor *visitor) bool Type::DoTraverse(DataDepVisitor* visitor)
{ {
foreach (i, FieldList, fields_) foreach (i, FieldList, fields_)
{ {
@ -953,7 +896,7 @@ bool Type::DoTraverse(DataDepVisitor *visitor)
return false; return false;
} }
foreach(i, AttrList, attrs_) foreach (i, AttrList, attrs_)
{ {
if ( ! (*i)->Traverse(visitor) ) if ( ! (*i)->Traverse(visitor) )
return false; return false;
@ -971,12 +914,12 @@ bool Type::RequiresAnalyzerContext()
foreach (i, FieldList, fields_) foreach (i, FieldList, fields_)
{ {
Field *f = *i; Field* f = *i;
if ( f->RequiresAnalyzerContext() ) if ( f->RequiresAnalyzerContext() )
return true; return true;
} }
foreach(i, AttrList, attrs_) foreach (i, AttrList, attrs_)
if ( (*i)->RequiresAnalyzerContext() ) if ( (*i)->RequiresAnalyzerContext() )
return true; return true;
@ -985,13 +928,12 @@ bool Type::RequiresAnalyzerContext()
bool Type::IsEmptyType() const bool Type::IsEmptyType() const
{ {
return ( StaticSize(global_env()) == 0 ); return (StaticSize(global_env()) == 0);
} }
void Type::MarkIncrementalInput() void Type::MarkIncrementalInput()
{ {
DEBUG_MSG("Handle incremental input for %s.%s\n", DEBUG_MSG("Handle incremental input for %s.%s\n", decl_id()->Name(),
decl_id()->Name(),
value_var() ? value_var()->Name() : "*"); value_var() ? value_var()->Name() : "*");
incremental_input_ = true; incremental_input_ = true;
@ -1049,7 +991,7 @@ Type::BufferMode Type::buffer_mode() const
return NOT_BUFFERABLE; return NOT_BUFFERABLE;
} }
const ID *Type::parsing_complete_var() const const ID* Type::parsing_complete_var() const
{ {
if ( parsing_complete_var_field_ ) if ( parsing_complete_var_field_ )
return parsing_complete_var_field_->id(); return parsing_complete_var_field_->id();
@ -1057,13 +999,13 @@ const ID *Type::parsing_complete_var() const
return 0; return 0;
} }
string Type::parsing_complete(Env *env) const string Type::parsing_complete(Env* env) const
{ {
ASSERT(parsing_complete_var()); ASSERT(parsing_complete_var());
return env->RValue(parsing_complete_var()); return env->RValue(parsing_complete_var());
} }
const ID *Type::has_value_var() const const ID* Type::has_value_var() const
{ {
if ( has_value_field_ ) if ( has_value_field_ )
return has_value_field_->id(); return has_value_field_->id();
@ -1078,7 +1020,7 @@ int Type::InitialBufferLength() const
return attr_length_expr_->MinimalHeaderSize(env()); return attr_length_expr_->MinimalHeaderSize(env());
} }
bool Type::CompatibleTypes(Type *type1, Type *type2) bool Type::CompatibleTypes(Type* type1, Type* type2)
{ {
// If we cannot deduce one of the data types, assume that // If we cannot deduce one of the data types, assume that
// they are compatible. // they are compatible.
@ -1097,17 +1039,15 @@ bool Type::CompatibleTypes(Type *type1, Type *type2)
return false; return false;
} }
switch( type1->tot() ) switch ( type1->tot() )
{ {
case UNDEF: case UNDEF:
case EMPTY: case EMPTY:
return true; return true;
case BUILTIN: case BUILTIN:
{ {
BuiltInType *t1 = BuiltInType* t1 = static_cast<BuiltInType*>(type1);
static_cast<BuiltInType *>(type1); BuiltInType* t2 = static_cast<BuiltInType*>(type2);
BuiltInType *t2 =
static_cast<BuiltInType *>(type2);
return BuiltInType::CompatibleBuiltInTypes(t1, t2); return BuiltInType::CompatibleBuiltInTypes(t1, t2);
} }
@ -1120,12 +1060,9 @@ bool Type::CompatibleTypes(Type *type1, Type *type2)
case ARRAY: case ARRAY:
{ {
ArrayType *t1 = ArrayType* t1 = static_cast<ArrayType*>(type1);
static_cast<ArrayType *>(type1); ArrayType* t2 = static_cast<ArrayType*>(type2);
ArrayType *t2 = return CompatibleTypes(t1->ElementDataType(), t2->ElementDataType());
static_cast<ArrayType *>(type2);
return CompatibleTypes(t1->ElementDataType(),
t2->ElementDataType());
} }
default: default:
@ -1134,7 +1071,7 @@ bool Type::CompatibleTypes(Type *type1, Type *type2)
} }
} }
Type *Type::LookUpByID(ID *id) Type* Type::LookUpByID(ID* id)
{ {
// 1. Is it a pre-defined type? // 1. Is it a pre-defined type?
string name = id->Name(); string name = id->Name();
@ -1144,7 +1081,7 @@ Type *Type::LookUpByID(ID *id)
} }
// 2. Is it a simple declared type? // 2. Is it a simple declared type?
Type *type = TypeDecl::LookUpType(id); Type* type = TypeDecl::LookUpType(id);
if ( type ) if ( type )
{ {
// Note: as a Type is always associated with a variable, // Note: as a Type is always associated with a variable,
@ -1165,7 +1102,7 @@ Type *Type::LookUpByID(ID *id)
return new ParameterizedType(id, 0); return new ParameterizedType(id, 0);
} }
void Type::AddPredefinedType(const string &type_name, Type *type) void Type::AddPredefinedType(const string& type_name, Type* type)
{ {
ASSERT(type_map_.find(type_name) == type_map_.end()); ASSERT(type_map_.find(type_name) == type_map_.end());
type_map_[type_name] = type; type_map_[type_name] = type;

View file

@ -9,9 +9,10 @@ using namespace std;
#include "pac_dbg.h" #include "pac_dbg.h"
class Type : public Object, public DataDepElement class Type : public Object, public DataDepElement
{ {
public: public:
enum TypeType { enum TypeType
{
UNDEF = -1, UNDEF = -1,
EMPTY, EMPTY,
BUILTIN, BUILTIN,
@ -27,26 +28,26 @@ public:
explicit Type(TypeType tot); explicit Type(TypeType tot);
virtual ~Type(); virtual ~Type();
Type *Clone() const; Type* Clone() const;
// Type of type // Type of type
TypeType tot() const { return tot_; } TypeType tot() const { return tot_; }
//////////////////////////////////////// ////////////////////////////////////////
// Code generation // Code generation
virtual void Prepare(Env *env, int flags); virtual void Prepare(Env* env, int flags);
// Flag(s) for Prepare() // Flag(s) for Prepare()
static const int TO_BE_PARSED = 1; static const int TO_BE_PARSED = 1;
virtual void GenPubDecls(Output *out, Env *env); virtual void GenPubDecls(Output* out, Env* env);
virtual void GenPrivDecls(Output *out, Env *env); virtual void GenPrivDecls(Output* out, Env* env);
virtual void GenInitCode(Output *out, Env *env); virtual void GenInitCode(Output* out, Env* env);
virtual void GenCleanUpCode(Output *out, Env *env); virtual void GenCleanUpCode(Output* out, Env* env);
void GenPreParsing(Output *out, Env *env); void GenPreParsing(Output* out, Env* env);
void GenParseCode(Output *out, Env *env, const DataPtr& data, int flags); void GenParseCode(Output* out, Env* env, const DataPtr& data, int flags);
//////////////////////////////////////// ////////////////////////////////////////
// TODO: organize the various methods below // TODO: organize the various methods below
@ -57,12 +58,12 @@ public:
// if the type appears in a type decl, then the lvalue is the // if the type appears in a type decl, then the lvalue is the
// default value var. // default value var.
// //
const char *lvalue() const { return lvalue_.c_str(); } const char* lvalue() const { return lvalue_.c_str(); }
// The TypeDecl that defined the type. // The TypeDecl that defined the type.
// //
const TypeDecl *type_decl() const { return type_decl_; } const TypeDecl* type_decl() const { return type_decl_; }
void set_type_decl(const TypeDecl *decl, bool declared_as_type); void set_type_decl(const TypeDecl* decl, bool declared_as_type);
// Returns whether the type appears in a type declaration // Returns whether the type appears in a type declaration
// (true) or as type specification of a field (false). // (true) or as type specification of a field (false).
@ -71,36 +72,37 @@ public:
// The ID of the decl in which the type appear. // The ID of the decl in which the type appear.
// //
const ID *decl_id() const; const ID* decl_id() const;
Env *env() const { return env_; } Env* env() const { return env_; }
string EvalByteOrder(Output *out_cc, Env *env) const; string EvalByteOrder(Output* out_cc, Env* env) const;
virtual string EvalMember(const ID *member_id) const; virtual string EvalMember(const ID* member_id) const;
virtual string EvalElement(const string &array, virtual string EvalElement(const string& array, const string& index) const;
const string &index) const;
// The variable defined by the type // The variable defined by the type
const ID *value_var() const { return value_var_; } const ID* value_var() const { return value_var_; }
void set_value_var(const ID *arg_id, int arg_id_type); void set_value_var(const ID* arg_id, int arg_id_type);
bool anonymous_value_var() const { return anonymous_value_var_; } bool anonymous_value_var() const { return anonymous_value_var_; }
const ID *size_var() const; const ID* size_var() const;
// Adds a variable to env to represent the size of this type. // Adds a variable to env to represent the size of this type.
// Returns false if we do not need a size variable (because // Returns false if we do not need a size variable (because
// the type has a static size) or the size variable is already added. // the type has a static size) or the size variable is already added.
bool AddSizeVar(Output *out, Env *env); bool AddSizeVar(Output* out, Env* env);
const ID *parsing_state_var() const; const ID* parsing_state_var() const;
const ID *has_value_var() const; const ID* has_value_var() const;
void AddField(Field *f); void AddField(Field* f);
void AddCheck(Expr *expr) { /* TODO */ } void AddCheck(Expr* expr)
{ /* TODO */
}
virtual bool DefineValueVar() const = 0; virtual bool DefineValueVar() const = 0;
@ -120,14 +122,15 @@ public:
// Returns a default value for the type // Returns a default value for the type
virtual string DefaultValue() const virtual string DefaultValue() const
{ {
ASSERT(0); return "@@@"; ASSERT(0);
return "@@@";
} }
// Returns the data type of the member field/case // Returns the data type of the member field/case
virtual Type *MemberDataType(const ID *member_id) const; virtual Type* MemberDataType(const ID* member_id) const;
// Returns the data type of the element type of an array // Returns the data type of the element type of an array
virtual Type *ElementDataType() const; virtual Type* ElementDataType() const;
// Whether the type needs clean-up at deallocation. // Whether the type needs clean-up at deallocation.
bool NeedsCleanUp() const; bool NeedsCleanUp() const;
@ -144,32 +147,29 @@ public:
//////////////////////////////////////// ////////////////////////////////////////
// Attributes // Attributes
virtual void ProcessAttr(Attr *a); virtual void ProcessAttr(Attr* a);
bool attr_chunked() const { return attr_chunked_; } bool attr_chunked() const { return attr_chunked_; }
Expr *attr_byteorder_expr() const { return attr_byteorder_expr_; } Expr* attr_byteorder_expr() const { return attr_byteorder_expr_; }
Expr *attr_if_expr() const { return attr_if_expr_; } Expr* attr_if_expr() const { return attr_if_expr_; }
// TODO: generate the length expression automatically. // TODO: generate the length expression automatically.
Expr *attr_length_expr() const { return attr_length_expr_; } Expr* attr_length_expr() const { return attr_length_expr_; }
bool attr_refcount() const { return attr_refcount_; } bool attr_refcount() const { return attr_refcount_; }
bool attr_transient() const { return attr_transient_; } bool attr_transient() const { return attr_transient_; }
// Whether the value remains valid outside the parse function // Whether the value remains valid outside the parse function
bool persistent() const bool persistent() const { return ! attr_transient() && ! attr_chunked(); }
{
return ! attr_transient() && ! attr_chunked();
}
void SetUntilCheck(ArrayType *t) { array_until_input_ = t; } void SetUntilCheck(ArrayType* t) { array_until_input_ = t; }
//////////////////////////////////////// ////////////////////////////////////////
// Size and boundary checking // Size and boundary checking
virtual int StaticSize(Env *env) const = 0; virtual int StaticSize(Env* env) const = 0;
string DataSize(Output *out, Env *env, const DataPtr& data); string DataSize(Output* out, Env* env, const DataPtr& data);
bool boundary_checked() const { return boundary_checked_; } bool boundary_checked() const { return boundary_checked_; }
virtual void SetBoundaryChecked() { boundary_checked_ = true; } virtual void SetBoundaryChecked() { boundary_checked_ = true; }
void GenBoundaryCheck(Output *out, Env *env, const DataPtr& data); void GenBoundaryCheck(Output* out, Env* env, const DataPtr& data);
//////////////////////////////////////// ////////////////////////////////////////
// Handling incremental input // Handling incremental input
@ -194,8 +194,8 @@ public:
bool buffer_input() const { return buffer_input_; } bool buffer_input() const { return buffer_input_; }
// Whether parsing of the type is completed // Whether parsing of the type is completed
const ID *parsing_complete_var() const; const ID* parsing_complete_var() const;
string parsing_complete(Env *env) const; string parsing_complete(Env* env) const;
// Whether the input is bufferable // Whether the input is bufferable
bool Bufferable() const; bool Bufferable() const;
@ -204,7 +204,8 @@ public:
bool BufferableWithLineBreaker() const; bool BufferableWithLineBreaker() const;
Expr* LineBreaker() const; Expr* LineBreaker() const;
enum BufferMode { enum BufferMode
{
NOT_BUFFERABLE, NOT_BUFFERABLE,
BUFFER_NOTHING, // for type "empty" BUFFER_NOTHING, // for type "empty"
BUFFER_BY_LENGTH, BUFFER_BY_LENGTH,
@ -212,12 +213,12 @@ public:
}; };
virtual BufferMode buffer_mode() const; virtual BufferMode buffer_mode() const;
void GenBufferConfiguration(Output *out, Env *env); void GenBufferConfiguration(Output* out, Env* env);
int InitialBufferLength() const; int InitialBufferLength() const;
protected: protected:
virtual void GenNewInstance(Output *out, Env *env) {} virtual void GenNewInstance(Output* out, Env* env) { }
virtual bool ByteOrderSensitive() const = 0; virtual bool ByteOrderSensitive() const = 0;
@ -228,86 +229,83 @@ protected:
void GenParseCode2(Output* out_cc, Env* env, const DataPtr& data, int flags); void GenParseCode2(Output* out_cc, Env* env, const DataPtr& data, int flags);
void GenParseCode3(Output* out_cc, Env* env, const DataPtr& data, int flags); void GenParseCode3(Output* out_cc, Env* env, const DataPtr& data, int flags);
virtual void DoGenParseCode(Output *out, Env *env, virtual void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags) = 0;
const DataPtr& data,
int flags) = 0;
string EvalLengthExpr(Output* out_cc, Env* env); string EvalLengthExpr(Output* out_cc, Env* env);
// Generate code for computing the dynamic size of the type // Generate code for computing the dynamic size of the type
virtual void GenDynamicSize(Output *out, Env *env, virtual void GenDynamicSize(Output* out, Env* env, const DataPtr& data) = 0;
const DataPtr& data) = 0;
bool DoTraverse(DataDepVisitor *visitor); bool DoTraverse(DataDepVisitor* visitor);
virtual Type *DoClone() const = 0; virtual Type* DoClone() const = 0;
protected: protected:
TypeType tot_; TypeType tot_;
const TypeDecl *type_decl_; const TypeDecl* type_decl_;
bool declared_as_type_; bool declared_as_type_;
const ID *type_decl_id_; const ID* type_decl_id_;
Env *env_; Env* env_;
const ID *value_var_; const ID* value_var_;
bool anonymous_value_var_; // whether the ID is anonymous bool anonymous_value_var_; // whether the ID is anonymous
string data_id_str_; string data_id_str_;
int value_var_type_; int value_var_type_;
Field *size_var_field_; Field* size_var_field_;
char *size_expr_; char* size_expr_;
bool boundary_checked_; bool boundary_checked_;
string lvalue_; string lvalue_;
FieldList *fields_; FieldList* fields_;
bool incremental_input_; bool incremental_input_;
bool incremental_parsing_; bool incremental_parsing_;
bool buffer_input_; bool buffer_input_;
// A boolean variable on whether parsing of the type is completed // A boolean variable on whether parsing of the type is completed
Field *parsing_complete_var_field_; Field* parsing_complete_var_field_;
// An integer variable holding the parsing state // An integer variable holding the parsing state
Field *parsing_state_var_field_; Field* parsing_state_var_field_;
Field *buffering_state_var_field_; Field* buffering_state_var_field_;
// The array type with &until($input...) condition, if // The array type with &until($input...) condition, if
// "this" is the element type // "this" is the element type
ArrayType *array_until_input_; ArrayType* array_until_input_;
// A "has_*" member var for fields with &if // A "has_*" member var for fields with &if
LetField *has_value_field_; LetField* has_value_field_;
// Attributes // Attributes
AttrList *attrs_; AttrList* attrs_;
Expr *attr_byteorder_expr_; Expr* attr_byteorder_expr_;
ExprList *attr_checks_; ExprList* attr_checks_;
ExprList *attr_enforces_; ExprList* attr_enforces_;
bool attr_chunked_; bool attr_chunked_;
bool attr_exportsourcedata_; bool attr_exportsourcedata_;
Expr *attr_if_expr_; Expr* attr_if_expr_;
Expr *attr_length_expr_; Expr* attr_length_expr_;
FieldList *attr_letfields_; FieldList* attr_letfields_;
Expr *attr_multiline_end_; Expr* attr_multiline_end_;
Expr *attr_linebreaker_; Expr* attr_linebreaker_;
bool attr_oneline_; bool attr_oneline_;
bool attr_refcount_; bool attr_refcount_;
ExprList *attr_requires_; ExprList* attr_requires_;
bool attr_restofdata_; bool attr_restofdata_;
bool attr_restofflow_; bool attr_restofflow_;
bool attr_transient_; bool attr_transient_;
public: public:
static void init(); static void init();
static bool CompatibleTypes(Type *type1, Type *type2); static bool CompatibleTypes(Type* type1, Type* type2);
static void AddPredefinedType(const string &type_name, Type *type); static void AddPredefinedType(const string& type_name, Type* type);
static Type *LookUpByID(ID *id); static Type* LookUpByID(ID* id);
protected: protected:
typedef map<string, Type *> type_map_t; typedef map<string, Type*> type_map_t;
static type_map_t type_map_; static type_map_t type_map_;
}; };
#endif // pac_type_h #endif // pac_type_h

View file

@ -1,3 +1,5 @@
#include "pac_typedecl.h"
#include "pac_attr.h" #include "pac_attr.h"
#include "pac_context.h" #include "pac_context.h"
#include "pac_dataptr.h" #include "pac_dataptr.h"
@ -12,7 +14,6 @@
#include "pac_paramtype.h" #include "pac_paramtype.h"
#include "pac_record.h" #include "pac_record.h"
#include "pac_type.h" #include "pac_type.h"
#include "pac_typedecl.h"
#include "pac_utils.h" #include "pac_utils.h"
TypeDecl::TypeDecl(ID* id, ParamList* params, Type* type) TypeDecl::TypeDecl(ID* id, ParamList* params, Type* type)
@ -35,7 +36,7 @@ void TypeDecl::ProcessAttr(Attr* a)
type_->ProcessAttr(a); type_->ProcessAttr(a);
} }
void TypeDecl::AddParam(Param *param) void TypeDecl::AddParam(Param* param)
{ {
// Cannot work after Prepare() // Cannot work after Prepare()
ASSERT(! env_); ASSERT(! env_);
@ -65,11 +66,9 @@ void TypeDecl::Prepare()
if ( type_->attr_byteorder_expr() ) if ( type_->attr_byteorder_expr() )
{ {
DEBUG_MSG("Adding byteorder field to %s\n", DEBUG_MSG("Adding byteorder field to %s\n", id()->Name());
id()->Name()); type_->AddField(
type_->AddField(new LetField(byteorder_id->clone(), new LetField(byteorder_id->clone(), extern_type_int, type_->attr_byteorder_expr()));
extern_type_int,
type_->attr_byteorder_expr()));
} }
type_->Prepare(env_, Type::TO_BE_PARSED); type_->Prepare(env_, Type::TO_BE_PARSED);
@ -99,13 +98,11 @@ void TypeDecl::GenCode(Output* out_h, Output* out_cc)
if ( RequiresAnalyzerContext::compute(type_) ) if ( RequiresAnalyzerContext::compute(type_) )
{ {
DEBUG_MSG("%s requires analyzer context\n", DEBUG_MSG("%s requires analyzer context\n", id()->Name());
id()->Name()); Type* param_type = analyzer_context()->param_type();
Type *param_type = analyzer_context()->param_type();
env_->AddID(analyzer_context_id, TEMP_VAR, param_type); env_->AddID(analyzer_context_id, TEMP_VAR, param_type);
env_->SetEvaluated(analyzer_context_id); env_->SetEvaluated(analyzer_context_id);
env_->AddMacro(context_macro_id, env_->AddMacro(context_macro_id, new Expr(analyzer_context_id->clone()));
new Expr(analyzer_context_id->clone()));
} }
// Add parameter "byteorder" // Add parameter "byteorder"
@ -170,30 +167,25 @@ void TypeDecl::GenCode(Output* out_h, Output* out_cc)
out_h->println("};\n"); out_h->println("};\n");
} }
void TypeDecl::GenPubDecls(Output* out_h, Output *out_cc) void TypeDecl::GenPubDecls(Output* out_h, Output* out_cc)
{ {
// GenParamPubDecls(params_, out_h, env_); // GenParamPubDecls(params_, out_h, env_);
} }
void TypeDecl::GenPrivDecls(Output* out_h, Output *out_cc) void TypeDecl::GenPrivDecls(Output* out_h, Output* out_cc)
{ {
// GenParamPrivDecls(params_, out_h, env_); // GenParamPrivDecls(params_, out_h, env_);
} }
void TypeDecl::GenInitCode(Output *out_cc) void TypeDecl::GenInitCode(Output* out_cc) { }
{
}
void TypeDecl::GenCleanUpCode(Output *out_cc) void TypeDecl::GenCleanUpCode(Output* out_cc) { }
{
}
void TypeDecl::GenConstructorFunc(Output* out_h, Output* out_cc) void TypeDecl::GenConstructorFunc(Output* out_h, Output* out_cc)
{ {
string params_str = ParamDecls(params_); string params_str = ParamDecls(params_);
string proto = string proto = strfmt("%s(%s)", class_name().c_str(), params_str.c_str());
strfmt("%s(%s)", class_name().c_str(), params_str.c_str());
out_h->println("%s;", proto.c_str()); out_h->println("%s;", proto.c_str());
@ -230,31 +222,28 @@ void TypeDecl::GenDestructorFunc(Output* out_h, Output* out_cc)
string TypeDecl::ParseFuncPrototype(Env* env) string TypeDecl::ParseFuncPrototype(Env* env)
{ {
const char *func_name = 0; const char* func_name = 0;
const char *return_type = 0; const char* return_type = 0;
string params; string params;
if ( type_->incremental_input() ) if ( type_->incremental_input() )
{ {
func_name = kParseFuncWithBuffer; func_name = kParseFuncWithBuffer;
return_type = "bool"; return_type = "bool";
params = strfmt("flow_buffer_t %s", params = strfmt("flow_buffer_t %s", env->LValue(flow_buffer_id));
env->LValue(flow_buffer_id));
} }
else else
{ {
func_name = kParseFuncWithoutBuffer; func_name = kParseFuncWithoutBuffer;
return_type = "int"; return_type = "int";
params = strfmt("const_byteptr const %s, const_byteptr const %s", params = strfmt("const_byteptr const %s, const_byteptr const %s",
env->LValue(begin_of_data), env->LValue(begin_of_data), env->LValue(end_of_data));
env->LValue(end_of_data));
} }
if ( RequiresAnalyzerContext::compute(type_) ) if ( RequiresAnalyzerContext::compute(type_) )
{ {
Type *param_type = analyzer_context()->param_type(); Type* param_type = analyzer_context()->param_type();
params += strfmt(", %s %s", params += strfmt(", %s %s", param_type->DataTypeConstRefStr().c_str(),
param_type->DataTypeConstRefStr().c_str(),
env->LValue(analyzer_context_id)); env->LValue(analyzer_context_id));
} }
@ -265,11 +254,10 @@ string TypeDecl::ParseFuncPrototype(Env* env)
} }
// Returns "<return type> %s<func name>(<params>)%s". // Returns "<return type> %s<func name>(<params>)%s".
return strfmt("%s %%s%s(%s)%%s", return strfmt("%s %%s%s(%s)%%s", return_type, func_name, params.c_str());
return_type, func_name, params.c_str());
} }
void TypeDecl::GenParsingEnd(Output *out_cc, Env *env, const DataPtr &data) void TypeDecl::GenParsingEnd(Output* out_cc, Env* env, const DataPtr& data)
{ {
string ret_val_0, ret_val_1; string ret_val_0, ret_val_1;
@ -283,27 +271,23 @@ void TypeDecl::GenParsingEnd(Output *out_cc, Env *env, const DataPtr &data)
ret_val_0 = type_->DataSize(0, env, data).c_str(); ret_val_0 = type_->DataSize(0, env, data).c_str();
ret_val_1 = "@@@"; ret_val_1 = "@@@";
out_cc->println("BINPAC_ASSERT(%s + (%s) <= %s);", out_cc->println("BINPAC_ASSERT(%s + (%s) <= %s);", env->RValue(begin_of_data),
env->RValue(begin_of_data), ret_val_0.c_str(), env->RValue(end_of_data));
ret_val_0.c_str(),
env->RValue(end_of_data));
} }
if ( type_->incremental_parsing() && if ( type_->incremental_parsing() &&
( type_->tot() == Type::RECORD || type_->tot() == Type::ARRAY ) ) (type_->tot() == Type::RECORD || type_->tot() == Type::ARRAY) )
{ {
// In which case parsing may jump to label // In which case parsing may jump to label
// "need_more_data" ... // "need_more_data" ...
out_cc->println("BINPAC_ASSERT(%s);", out_cc->println("BINPAC_ASSERT(%s);", type_->parsing_complete(env).c_str());
type_->parsing_complete(env).c_str());
out_cc->println("return %s;", ret_val_0.c_str()); out_cc->println("return %s;", ret_val_0.c_str());
out_cc->println(""); out_cc->println("");
out_cc->dec_indent(); out_cc->dec_indent();
out_cc->println("%s:", kNeedMoreData); out_cc->println("%s:", kNeedMoreData);
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("BINPAC_ASSERT(!(%s));", out_cc->println("BINPAC_ASSERT(!(%s));", type_->parsing_complete(env).c_str());
type_->parsing_complete(env).c_str());
out_cc->println("return %s;", ret_val_1.c_str()); out_cc->println("return %s;", ret_val_1.c_str());
} }
else if ( type_->incremental_input() ) else if ( type_->incremental_input() )
@ -323,7 +307,7 @@ void TypeDecl::GenParseFunc(Output* out_h, Output* out_cc)
// Env within the parse function // Env within the parse function
Env p_func_env(env_, this); Env p_func_env(env_, this);
Env *env = &p_func_env; Env* env = &p_func_env;
if ( type_->incremental_input() ) if ( type_->incremental_input() )
{ {
@ -382,19 +366,17 @@ void TypeDecl::GenInitialBufferLengthFunc(Output* out_h, Output* out_cc)
if ( init_buffer_length < 0 ) // cannot be statically determined if ( init_buffer_length < 0 ) // cannot be statically determined
{ {
throw Exception(type()->attr_length_expr(), throw Exception(type()->attr_length_expr(), strfmt("cannot determine initial buffer length"
strfmt("cannot determine initial buffer length" " for type %s",
" for type %s", id_->Name())); id_->Name()));
} }
out_h->println("int %s() const { return %d; }", out_h->println("int %s() const { return %d; }", func.c_str(), init_buffer_length);
func.c_str(),
init_buffer_length);
} }
Type* TypeDecl::LookUpType(const ID *id) Type* TypeDecl::LookUpType(const ID* id)
{ {
Decl *decl = LookUpDecl(id); Decl* decl = LookUpDecl(id);
if ( ! decl ) if ( ! decl )
return 0; return 0;
switch ( decl->decl_type() ) switch ( decl->decl_type() )
@ -402,11 +384,10 @@ Type* TypeDecl::LookUpType(const ID *id)
case TYPE: case TYPE:
case CONN: case CONN:
case FLOW: case FLOW:
return static_cast<TypeDecl *>(decl)->type(); return static_cast<TypeDecl*>(decl)->type();
case ENUM: case ENUM:
return static_cast<EnumDecl *>(decl)->DataType(); return static_cast<EnumDecl*>(decl)->DataType();
default: default:
return 0; return 0;
} }
} }

View file

@ -4,44 +4,44 @@
#include "pac_decl.h" #include "pac_decl.h"
class TypeDecl : public Decl class TypeDecl : public Decl
{ {
public: public:
TypeDecl(ID *arg_id, ParamList *arg_params, Type *arg_type); TypeDecl(ID* arg_id, ParamList* arg_params, Type* arg_type);
~TypeDecl(); ~TypeDecl();
void Prepare(); void Prepare();
void GenForwardDeclaration(Output *out_h); void GenForwardDeclaration(Output* out_h);
void GenCode(Output *out_h, Output *out_cc); void GenCode(Output* out_h, Output* out_cc);
Env *env() const { return env_; } Env* env() const { return env_; }
Type *type() const { return type_; } Type* type() const { return type_; }
string class_name() const; string class_name() const;
static Type *LookUpType(const ID *id); static Type* LookUpType(const ID* id);
protected: protected:
void AddParam(Param *param); void AddParam(Param* param);
virtual void AddBaseClass(vector<string> *base_classes) const {} virtual void AddBaseClass(vector<string>* base_classes) const { }
void ProcessAttr(Attr *a); void ProcessAttr(Attr* a);
virtual void GenPubDecls(Output *out_h, Output *out_cc); virtual void GenPubDecls(Output* out_h, Output* out_cc);
virtual void GenPrivDecls(Output *out_h, Output *out_cc); virtual void GenPrivDecls(Output* out_h, Output* out_cc);
virtual void GenInitCode(Output *out_cc); virtual void GenInitCode(Output* out_cc);
virtual void GenCleanUpCode(Output *out_cc); virtual void GenCleanUpCode(Output* out_cc);
void GenConstructorFunc(Output *out_h, Output *out_cc); void GenConstructorFunc(Output* out_h, Output* out_cc);
void GenDestructorFunc(Output *out_h, Output *out_cc); void GenDestructorFunc(Output* out_h, Output* out_cc);
string ParseFuncPrototype(Env* env); string ParseFuncPrototype(Env* env);
void GenParseFunc(Output *out_h, Output *out_cc); void GenParseFunc(Output* out_h, Output* out_cc);
void GenParsingEnd(Output *out_cc, Env *env, const DataPtr &data); void GenParsingEnd(Output* out_cc, Env* env, const DataPtr& data);
void GenInitialBufferLengthFunc(Output *out_h, Output *out_cc); void GenInitialBufferLengthFunc(Output* out_h, Output* out_cc);
protected: protected:
Env *env_; Env* env_;
ParamList *params_; ParamList* params_;
Type *type_; Type* type_;
}; };
#endif // pac_typedecl_h #endif // pac_typedecl_h

View file

@ -1,17 +1,18 @@
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include "pac_utils.h" #include "pac_utils.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
char* copy_string(const char* s) char* copy_string(const char* s)
{ {
char* c = new char[strlen(s)+1]; char* c = new char[strlen(s) + 1];
strcpy(c, s); strcpy(c, s);
return c; return c;
} }
namespace { namespace
{
const char* do_fmt(const char* format, va_list ap) const char* do_fmt(const char* format, va_list ap)
{ {
@ -20,7 +21,7 @@ const char* do_fmt(const char* format, va_list ap)
return buf; return buf;
} }
} }
string strfmt(const char* format, ...) string strfmt(const char* format, ...)
{ {

View file

@ -1,6 +1,6 @@
#include "pac_varfield.h" #include "pac_varfield.h"
void PrivVarField::Prepare(Env *env) void PrivVarField::Prepare(Env* env)
{ {
Field::Prepare(env); Field::Prepare(env);
} }

View file

@ -5,47 +5,53 @@
// A private variable evaluated with parsing // A private variable evaluated with parsing
class ParseVarField : public Field class ParseVarField : public Field
{ {
public: public:
ParseVarField(int is_class_member, ID* id, Type *type) ParseVarField(int is_class_member, ID* id, Type* type)
: Field(PARSE_VAR_FIELD, : Field(PARSE_VAR_FIELD, TYPE_TO_BE_PARSED | is_class_member | NOT_PUBLIC_READABLE, id,
TYPE_TO_BE_PARSED | is_class_member | NOT_PUBLIC_READABLE, type)
id, type) {} {
void GenPubDecls(Output* out, Env* env) { /* do nothing */ } }
}; void GenPubDecls(Output* out, Env* env)
{ /* do nothing */
}
};
// A public variable // A public variable
class PubVarField : public Field class PubVarField : public Field
{ {
public: public:
PubVarField(ID* id, Type *type) PubVarField(ID* id, Type* type)
: Field(PUB_VAR_FIELD, : Field(PUB_VAR_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type)
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, {
id, type) {} }
~PubVarField() {} ~PubVarField() { }
}; };
// A private variable // A private variable
class PrivVarField : public Field class PrivVarField : public Field
{ {
public: public:
PrivVarField(ID* id, Type *type) PrivVarField(ID* id, Type* type)
: Field(PRIV_VAR_FIELD, : Field(PRIV_VAR_FIELD, TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | NOT_PUBLIC_READABLE, id,
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | NOT_PUBLIC_READABLE, type)
id, type) {} {
~PrivVarField() {} }
~PrivVarField() { }
void GenPubDecls(Output* out, Env* env) { /* do nothing */ } void GenPubDecls(Output* out, Env* env)
}; { /* do nothing */
}
};
class TempVarField : public Field class TempVarField : public Field
{ {
public: public:
TempVarField(ID* id, Type *type) TempVarField(ID* id, Type* type)
: Field(TEMP_VAR_FIELD, : Field(TEMP_VAR_FIELD, TYPE_NOT_TO_BE_PARSED | NOT_CLASS_MEMBER, id, type)
TYPE_NOT_TO_BE_PARSED | NOT_CLASS_MEMBER, {
id, type) {} }
~TempVarField() {} ~TempVarField() { }
}; };
#endif // pac_varfield_h #endif // pac_varfield_h

View file

@ -1,14 +1,13 @@
#include "pac_withinput.h" #include "pac_withinput.h"
#include "pac_dataptr.h" #include "pac_dataptr.h"
#include "pac_expr.h" #include "pac_expr.h"
#include "pac_inputbuf.h" #include "pac_inputbuf.h"
#include "pac_output.h" #include "pac_output.h"
#include "pac_type.h" #include "pac_type.h"
WithInputField::WithInputField(ID* id, Type *type, InputBuffer* input) WithInputField::WithInputField(ID* id, Type* type, InputBuffer* input)
: Field(WITHINPUT_FIELD, : Field(WITHINPUT_FIELD, TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, id, type),
TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
id, type),
input_(input) input_(input)
{ {
ASSERT(type_); ASSERT(type_);
@ -20,16 +19,14 @@ WithInputField::~WithInputField()
delete input_; delete input_;
} }
bool WithInputField::DoTraverse(DataDepVisitor *visitor) bool WithInputField::DoTraverse(DataDepVisitor* visitor)
{ {
return Field::DoTraverse(visitor) && return Field::DoTraverse(visitor) && input()->Traverse(visitor);
input()->Traverse(visitor);
} }
bool WithInputField::RequiresAnalyzerContext() const bool WithInputField::RequiresAnalyzerContext() const
{ {
return Field::RequiresAnalyzerContext() || return Field::RequiresAnalyzerContext() || (input() && input()->RequiresAnalyzerContext());
(input() && input()->RequiresAnalyzerContext());
} }
void WithInputField::Prepare(Env* env) void WithInputField::Prepare(Env* env)
@ -43,8 +40,7 @@ void WithInputField::GenEval(Output* out_cc, Env* env)
GenParseCode(out_cc, env); GenParseCode(out_cc, env);
if ( type_->attr_if_expr() ) if ( type_->attr_if_expr() )
{ {
out_cc->println("BINPAC_ASSERT(%s);", out_cc->println("BINPAC_ASSERT(%s);", env->RValue(type_->has_value_var()));
env->RValue(type_->has_value_var()));
} }
} }
@ -55,8 +51,7 @@ void WithInputField::GenParseCode(Output* out_cc, Env* env)
{ {
// A conditional field // A conditional field
env->Evaluate(out_cc, type_->has_value_var()); env->Evaluate(out_cc, type_->has_value_var());
out_cc->println("if ( %s )", out_cc->println("if ( %s )", env->RValue(type_->has_value_var()));
env->RValue(type_->has_value_var()));
out_cc->inc_indent(); out_cc->inc_indent();
out_cc->println("{"); out_cc->println("{");
} }
@ -66,9 +61,7 @@ void WithInputField::GenParseCode(Output* out_cc, Env* env)
Env field_env(env, this); Env field_env(env, this);
ASSERT(! type_->incremental_input()); ASSERT(! type_->incremental_input());
type_->GenPreParsing(out_cc, &field_env); type_->GenPreParsing(out_cc, &field_env);
type_->GenParseCode(out_cc, &field_env, type_->GenParseCode(out_cc, &field_env, input()->GenDataBeginEnd(out_cc, &field_env), 0);
input()->GenDataBeginEnd(out_cc, &field_env),
0);
if ( type_->attr_if_expr() ) if ( type_->attr_if_expr() )
{ {

View file

@ -6,12 +6,12 @@
#include "pac_field.h" #include "pac_field.h"
class WithInputField : public Field, public Evaluatable class WithInputField : public Field, public Evaluatable
{ {
public: public:
WithInputField(ID* id, Type *type, InputBuffer* input); WithInputField(ID* id, Type* type, InputBuffer* input);
virtual ~WithInputField(); virtual ~WithInputField();
InputBuffer *input() const { return input_; } InputBuffer* input() const { return input_; }
void Prepare(Env* env); void Prepare(Env* env);
@ -29,10 +29,10 @@ public:
bool RequiresAnalyzerContext() const; bool RequiresAnalyzerContext() const;
protected: protected:
bool DoTraverse(DataDepVisitor *visitor); bool DoTraverse(DataDepVisitor* visitor);
protected: protected:
InputBuffer *input_; InputBuffer* input_;
}; };
#endif // pac_withinput_h #endif // pac_withinput_h