hammer/src/internal.h

159 lines
4.4 KiB
C
Raw Normal View History

/* Internals for Hammer.
* Copyright (C) 2012 Meredith L. Patterson, Dan "TQ" Hirsch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, version 2.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
2012-04-23 19:39:44 +01:00
#ifndef HAMMER_INTERNAL__H
#define HAMMER_INTERNAL__H
#include <glib.h>
2012-05-13 01:01:26 +01:00
#include <err.h>
2012-04-23 19:39:44 +01:00
#include "hammer.h"
2012-05-13 01:01:26 +01:00
#ifdef NDEBUG
#define assert_message(check, message) do { } while(0)
#else
#define assert_message(check, message) do { \
if (!(check)) \
2012-05-18 12:37:36 +02:00
errx(1, "Assertion failed (programmer error): %s", message); \
2012-05-13 01:01:26 +01:00
} while(0)
#endif
#define false 0
#define true 1
2012-05-26 13:01:23 +02:00
typedef struct HInputStream_ {
// This should be considered to be a really big value type.
const uint8_t *input;
size_t index;
size_t length;
char bit_offset;
char endianness;
char overrun;
2012-05-26 13:01:23 +02:00
} HInputStream;
/* The state of the parser.
*
* Members:
2012-05-26 13:13:41 +02:00
* cache - a hash table describing the state of the parse, including partial HParseResult's. It's a hash table from HParserCacheKey to HParserCacheValue.
* input_stream - the input stream at this state.
* arena - the arena that has been allocated for the parse this state is in.
2012-05-26 13:13:41 +02:00
* lr_stack - a stack of HLeftRec's, used in Warth's recursion
* recursion_heads - table of recursion heads. Keys are HParserCacheKey's with only an HInputStream (parser can be NULL), values are HRecursionHead's.
*
*/
2012-05-26 12:03:58 +02:00
struct HParseState_ {
GHashTable *cache;
2012-05-26 13:01:23 +02:00
HInputStream input_stream;
HArena * arena;
GQueue *lr_stack;
GHashTable *recursion_heads;
};
/* The (location, parser) tuple used to key the cache.
*/
2012-05-26 13:13:41 +02:00
typedef struct HParserCacheKey_ {
2012-05-26 13:01:23 +02:00
HInputStream input_pos;
const HParser *parser;
2012-05-26 13:13:41 +02:00
} HParserCacheKey;
/* A value in the cache is either of value Left or Right (this is a
* holdover from Scala, which used Either here). Left corresponds to
2012-05-26 13:13:41 +02:00
* HLeftRec, which is for left recursion; Right corresponds to
2012-05-26 13:01:23 +02:00
* HParseResult.
*/
2012-05-26 13:13:41 +02:00
typedef enum HParserCacheValueType_ {
PC_LEFT,
PC_RIGHT
2012-05-26 13:13:41 +02:00
} HParserCacheValueType;
/* A recursion head.
*
* Members:
* head_parser - the parse rule that started this recursion
2012-05-26 13:01:23 +02:00
* involved_set - A list of rules (HParser's) involved in the recursion
* eval_set -
*/
2012-05-26 13:13:41 +02:00
typedef struct HRecursionHead_ {
2012-05-26 13:01:23 +02:00
const HParser *head_parser;
GSList *involved_set;
GSList *eval_set;
2012-05-26 13:13:41 +02:00
} HRecursionHead;
/* A left recursion.
*
* Members:
* seed -
* rule -
* head -
*/
2012-05-26 13:13:41 +02:00
typedef struct HLeftRec_ {
2012-05-26 13:01:23 +02:00
HParseResult *seed;
const HParser *rule;
2012-05-26 13:13:41 +02:00
HRecursionHead *head;
} HLeftRec;
2012-05-26 13:13:41 +02:00
/* Tagged union for values in the cache: either HLeftRec's (Left) or
2012-05-26 13:01:23 +02:00
* HParseResult's (Right).
*/
2012-05-26 13:13:41 +02:00
typedef struct HParserCacheValue_t {
HParserCacheValueType value_type;
union {
2012-05-26 13:13:41 +02:00
HLeftRec *left;
2012-05-26 13:01:23 +02:00
HParseResult *right;
};
2012-05-26 13:13:41 +02:00
} HParserCacheValue;
2012-05-26 13:13:41 +02:00
typedef unsigned int *HCharset;
2012-05-26 13:13:41 +02:00
static inline HCharset new_charset() {
HCharset cs = g_new0(unsigned int, 256 / sizeof(unsigned int));
return cs;
}
2012-05-26 13:13:41 +02:00
static inline int charset_isset(HCharset cs, uint8_t pos) {
return !!(cs[pos / sizeof(*cs)] & (1 << (pos % sizeof(*cs))));
}
2012-05-26 13:13:41 +02:00
static inline void charset_set(HCharset cs, uint8_t pos, int val) {
cs[pos / sizeof(*cs)] =
val
? cs[pos / sizeof(*cs)] | (1 << (pos % sizeof(*cs)))
: cs[pos / sizeof(*cs)] & ~(1 << (pos % sizeof(*cs)));
}
// TODO(thequux): Set symbol visibility for these functions so that they aren't exported.
2012-04-23 19:39:44 +01:00
2012-05-26 13:01:23 +02:00
long long read_bits(HInputStream* state, int count, char signed_p);
HParseResult* do_parse(const HParser* parser, HParseState *state);
void put_cached(HParseState *ps, const HParser *p, HParseResult *cached);
guint djbhash(const uint8_t *buf, size_t len);
2012-05-26 13:01:23 +02:00
char* write_result_unamb(const HParsedToken* tok);
void pprint(const HParsedToken* tok, int indent, int delta);
2012-05-13 01:01:26 +01:00
2012-05-26 13:01:23 +02:00
HCountedArray *carray_new_sized(HArena * arena, size_t size);
HCountedArray *carray_new(HArena * arena);
void carray_append(HCountedArray *array, void* item);
#if 0
#include <malloc.h>
#define arena_malloc(a, s) malloc(s)
#endif
2012-04-23 19:39:44 +01:00
#endif // #ifndef HAMMER_INTERNAL__H