diff --git a/src/glue.c b/src/glue.c index 1df8173195c7090f3ca861f7263e15f84522766b..79e106c8bd902d6fe13ac485781222d202ea9dcc 100644 --- a/src/glue.c +++ b/src/glue.c @@ -121,6 +121,20 @@ HParsedToken *h_make_uint(HArena *arena, uint64_t val) return ret; } +HParsedToken *h_make_double(HArena *arena, double val) +{ + HParsedToken *ret = h_make_(arena, TT_DOUBLE); + ret->dbl = val; + return ret; +} + +HParsedToken *h_make_float(HArena *arena, float val) +{ + HParsedToken *ret = h_make_(arena, TT_FLOAT); + ret->flt = val; + return ret; +} + // XXX -> internal HParsedToken *h_carray_index(const HCountedArray *a, size_t i) { diff --git a/src/glue.h b/src/glue.h index 1de285823b3f2ae6fd956c04c9bc81d92445719a..08e5255ab2572d5d828943cd98331081ab02fc02 100644 --- a/src/glue.h +++ b/src/glue.h @@ -198,6 +198,8 @@ HParsedToken *h_make_seqn(HArena *arena, size_t n); // Makes empty sequence of HParsedToken *h_make_bytes(HArena *arena, const uint8_t *array, size_t len); HParsedToken *h_make_sint(HArena *arena, int64_t val); HParsedToken *h_make_uint(HArena *arena, uint64_t val); +HParsedToken *h_make_double(HArena *arena, double val); +HParsedToken *h_make_float(HArena *arena, float val); // Standard short-hands to make tokens in an action. #define H_MAKE(TYP, VAL) h_make(p->arena, (HTokenType)TT_ ## TYP, VAL) @@ -206,6 +208,8 @@ HParsedToken *h_make_uint(HArena *arena, uint64_t val); #define H_MAKE_BYTES(VAL, LEN) h_make_bytes(p->arena, VAL, LEN) #define H_MAKE_SINT(VAL) h_make_sint(p->arena, VAL) #define H_MAKE_UINT(VAL) h_make_uint(p->arena, VAL) +#define H_MAKE_DOUBLE(VAL) h_make_double(p->arena, VAL) +#define H_MAKE_FLOAT(VAL) h_make_float(p->arena, VAL) // Extract (cast) type-specific value back from HParsedTokens... @@ -218,6 +222,8 @@ HParsedToken *h_make_uint(HArena *arena, uint64_t val); #define H_ASSERT_BYTES(TOK) h_assert_type(TT_BYTES, TOK) #define H_ASSERT_SINT(TOK) h_assert_type(TT_SINT, TOK) #define H_ASSERT_UINT(TOK) h_assert_type(TT_UINT, TOK) +#define H_ASSERT_DOUBLE(TOK) h_assert_type(TT_DOUBLE, TOK) +#define H_ASSERT_FLOAT(TOK) h_assert_type(TT_FLOAT, TOK) // Assert expected type and return contained value. #define H_CAST(TYP, TOK) ((TYP *) H_ASSERT(TYP, TOK)->user) @@ -225,6 +231,8 @@ HParsedToken *h_make_uint(HArena *arena, uint64_t val); #define H_CAST_BYTES(TOK) (H_ASSERT_BYTES(TOK)->bytes) #define H_CAST_SINT(TOK) (H_ASSERT_SINT(TOK)->sint) #define H_CAST_UINT(TOK) (H_ASSERT_UINT(TOK)->uint) +#define H_CAST_DOUBLE(TOK) (H_ASSERT_DOUBLE(TOK)->dbl) +#define H_CAST_FLOAT(TOK) (H_ASSERT_FLOAT(TOK)->flt) // Sequence access... @@ -247,6 +255,8 @@ HParsedToken *h_seq_index_vpath(const HParsedToken *p, size_t i, va_list va); #define H_INDEX_BYTES(SEQ, ...) H_CAST_BYTES(H_INDEX_TOKEN(SEQ, __VA_ARGS__)) #define H_INDEX_SINT(SEQ, ...) H_CAST_SINT(H_INDEX_TOKEN(SEQ, __VA_ARGS__)) #define H_INDEX_UINT(SEQ, ...) H_CAST_UINT(H_INDEX_TOKEN(SEQ, __VA_ARGS__)) +#define H_INDEX_DOUBLE(SEQ, ...) H_CAST_DOUBLE(H_INDEX_TOKEN(SEQ, __VA_ARGS__)) +#define H_INDEX_FLOAT(SEQ, ...) H_CAST_FLOAT(H_INDEX_TOKEN(SEQ, __VA_ARGS__)) #define H_INDEX_TOKEN(SEQ, ...) h_seq_index_path(H_ASSERT_SEQ(SEQ), __VA_ARGS__, -1) // Standard short-hand to access and cast elements on a sequence token. @@ -255,6 +265,8 @@ HParsedToken *h_seq_index_vpath(const HParsedToken *p, size_t i, va_list va); #define H_FIELD_BYTES(...) H_INDEX_BYTES(p->ast, __VA_ARGS__) #define H_FIELD_SINT(...) H_INDEX_SINT(p->ast, __VA_ARGS__) #define H_FIELD_UINT(...) H_INDEX_UINT(p->ast, __VA_ARGS__) +#define H_FIELD_DOUBLE(...) H_INDEX_DOUBLE(p->ast, __VA_ARGS__) +#define H_FIELD_FLOAT(...) H_INDEX_FLOAT(p->ast, __VA_ARGS__) #define H_FIELD_TOKEN(...) H_INDEX_TOKEN(p->ast, __VA_ARGS__) // Lower-level helper for h_seq_index. diff --git a/src/hammer.h b/src/hammer.h index 6cd2660d3cfd29a9b4d34e1e054d2613ca4260a2..787af0b254a969226eeda985fc75d470796bd7cc 100644 --- a/src/hammer.h +++ b/src/hammer.h @@ -56,6 +56,8 @@ typedef enum HTokenType_ { TT_BYTES = 2, TT_SINT = 4, TT_UINT = 8, + TT_DOUBLE = 12, + TT_FLOAT = 13, TT_SEQUENCE = 16, TT_RESERVED_1, // reserved for backend-specific internal use TT_ERR = 32, diff --git a/src/pprint.c b/src/pprint.c index 145bf5237ae98e7db240aa1540bf8b242801edd1..5f6e1e2c5a6d98869be764218cc2e4f191c0e669 100644 --- a/src/pprint.c +++ b/src/pprint.c @@ -63,6 +63,12 @@ void h_pprint(FILE* stream, const HParsedToken* tok, int indent, int delta) { case TT_UINT: fprintf(stream, "%" PRIu64, tok->uint); break; + case TT_DOUBLE: + fprintf(stream, "%f", tok->dbl); + break; + case TT_FLOAT: + fprintf(stream, "%f", (double)tok->flt); + break; case TT_SEQUENCE: if (tok->seq->used == 0) fprintf(stream, "[ ]"); @@ -183,6 +189,12 @@ static void unamb_sub(const HParsedToken* tok, struct result_buf *buf) { case TT_UINT: h_append_buf_formatted(buf, "u%#" PRIx64, tok->uint); break; + case TT_DOUBLE: + h_append_buf_formatted(buf, "d%a", tok->dbl); + break; + case TT_FLOAT: + h_append_buf_formatted(buf, "f%a", (double)tok->flt); + break; case TT_ERR: h_append_buf(buf, "ERR", 3); break; diff --git a/src/t_parser.c b/src/t_parser.c index 2d933ef1d3a025fd15fa8a1e247dc8ced3ba63ea..356c38f1674d6d3f90e3b0da672646455437f7a2 100644 --- a/src/t_parser.c +++ b/src/t_parser.c @@ -129,6 +129,29 @@ static void test_uint8(gconstpointer backend) { } //@MARK_END +// XXX implement h_double() and h_float(). these just test the pretty-printer... +static HParsedToken *act_double(const HParseResult *p, void *u) { + return H_MAKE_DOUBLE((double)H_FIELD_UINT(0) + (double)H_FIELD_UINT(1)/10); +} +static void test_double(gconstpointer backend) { + HParser *b = h_uint8(); + HParser *dbl = h_action(h_sequence(b, b, NULL), act_double, NULL); + uint8_t input[] = {4,2}; + + g_check_parse_match(dbl, (HParserBackend)GPOINTER_TO_INT(backend), input, 2, "d0x1.0cccccccccccdp+2"); +} + +static HParsedToken *act_float(const HParseResult *p, void *u) { + return H_MAKE_FLOAT((float)H_FIELD_UINT(0) + (float)H_FIELD_UINT(1)/10); +} +static void test_float(gconstpointer backend) { + HParser *b = h_uint8(); + HParser *flt = h_action(h_sequence(b, b, NULL), act_float, NULL); + uint8_t input[] = {4,2}; + + g_check_parse_match(flt, (HParserBackend)GPOINTER_TO_INT(backend), input, 2, "f0x1.0cccccp+2"); +} + static void test_int_range(gconstpointer backend) { const HParser *int_range_ = h_int_range(h_uint8(), 3, 10); @@ -873,10 +896,8 @@ void register_parser_tests(void) { g_test_add_data_func("/core/parser/packrat/uint16", GINT_TO_POINTER(PB_PACKRAT), test_uint16); g_test_add_data_func("/core/parser/packrat/uint8", GINT_TO_POINTER(PB_PACKRAT), test_uint8); g_test_add_data_func("/core/parser/packrat/int_range", GINT_TO_POINTER(PB_PACKRAT), test_int_range); -#if 0 - g_test_add_data_func("/core/parser/packrat/float64", GINT_TO_POINTER(PB_PACKRAT), test_float64); - g_test_add_data_func("/core/parser/packrat/float32", GINT_TO_POINTER(PB_PACKRAT), test_float32); -#endif + g_test_add_data_func("/core/parser/packrat/double", GINT_TO_POINTER(PB_PACKRAT), test_double); + g_test_add_data_func("/core/parser/packrat/float", GINT_TO_POINTER(PB_PACKRAT), test_float); g_test_add_data_func("/core/parser/packrat/whitespace", GINT_TO_POINTER(PB_PACKRAT), test_whitespace); g_test_add_data_func("/core/parser/packrat/left", GINT_TO_POINTER(PB_PACKRAT), test_left); g_test_add_data_func("/core/parser/packrat/right", GINT_TO_POINTER(PB_PACKRAT), test_right); @@ -931,10 +952,8 @@ void register_parser_tests(void) { g_test_add_data_func("/core/parser/llk/uint16", GINT_TO_POINTER(PB_LLk), test_uint16); g_test_add_data_func("/core/parser/llk/uint8", GINT_TO_POINTER(PB_LLk), test_uint8); g_test_add_data_func("/core/parser/llk/int_range", GINT_TO_POINTER(PB_LLk), test_int_range); -#if 0 - g_test_add_data_func("/core/parser/llk/float64", GINT_TO_POINTER(PB_LLk), test_float64); - g_test_add_data_func("/core/parser/llk/float32", GINT_TO_POINTER(PB_LLk), test_float32); -#endif + g_test_add_data_func("/core/parser/llk/double", GINT_TO_POINTER(PB_LLk), test_double); + g_test_add_data_func("/core/parser/llk/float", GINT_TO_POINTER(PB_LLk), test_float); g_test_add_data_func("/core/parser/llk/whitespace", GINT_TO_POINTER(PB_LLk), test_whitespace); g_test_add_data_func("/core/parser/llk/left", GINT_TO_POINTER(PB_LLk), test_left); g_test_add_data_func("/core/parser/llk/right", GINT_TO_POINTER(PB_LLk), test_right); @@ -977,11 +996,9 @@ void register_parser_tests(void) { g_test_add_data_func("/core/parser/regex/uint32", GINT_TO_POINTER(PB_REGULAR), test_uint32); g_test_add_data_func("/core/parser/regex/uint16", GINT_TO_POINTER(PB_REGULAR), test_uint16); g_test_add_data_func("/core/parser/regex/uint8", GINT_TO_POINTER(PB_REGULAR), test_uint8); -#if 0 - g_test_add_data_func("/core/parser/regex/int_range", GINT_TO_POINTER(PB_REGULAR), test_int_range); - g_test_add_data_func("/core/parser/regex/float64", GINT_TO_POINTER(PB_REGULAR), test_float64); - g_test_add_data_func("/core/parser/regex/float32", GINT_TO_POINTER(PB_REGULAR), test_float32); -#endif + //g_test_add_data_func("/core/parser/regex/int_range", GINT_TO_POINTER(PB_REGULAR), test_int_range); + g_test_add_data_func("/core/parser/regex/double", GINT_TO_POINTER(PB_REGULAR), test_double); + g_test_add_data_func("/core/parser/regex/float", GINT_TO_POINTER(PB_REGULAR), test_float); g_test_add_data_func("/core/parser/regex/whitespace", GINT_TO_POINTER(PB_REGULAR), test_whitespace); g_test_add_data_func("/core/parser/regex/left", GINT_TO_POINTER(PB_REGULAR), test_left); g_test_add_data_func("/core/parser/regex/right", GINT_TO_POINTER(PB_REGULAR), test_right); @@ -1020,10 +1037,8 @@ void register_parser_tests(void) { g_test_add_data_func("/core/parser/lalr/uint16", GINT_TO_POINTER(PB_LALR), test_uint16); g_test_add_data_func("/core/parser/lalr/uint8", GINT_TO_POINTER(PB_LALR), test_uint8); g_test_add_data_func("/core/parser/lalr/int_range", GINT_TO_POINTER(PB_LALR), test_int_range); -#if 0 - g_test_add_data_func("/core/parser/lalr/float64", GINT_TO_POINTER(PB_LALR), test_float64); - g_test_add_data_func("/core/parser/lalr/float32", GINT_TO_POINTER(PB_LALR), test_float32); -#endif + g_test_add_data_func("/core/parser/lalr/double", GINT_TO_POINTER(PB_LALR), test_double); + g_test_add_data_func("/core/parser/lalr/float", GINT_TO_POINTER(PB_LALR), test_float); g_test_add_data_func("/core/parser/lalr/whitespace", GINT_TO_POINTER(PB_LALR), test_whitespace); g_test_add_data_func("/core/parser/lalr/left", GINT_TO_POINTER(PB_LALR), test_left); g_test_add_data_func("/core/parser/lalr/right", GINT_TO_POINTER(PB_LALR), test_right); @@ -1068,10 +1083,8 @@ void register_parser_tests(void) { g_test_add_data_func("/core/parser/glr/uint16", GINT_TO_POINTER(PB_GLR), test_uint16); g_test_add_data_func("/core/parser/glr/uint8", GINT_TO_POINTER(PB_GLR), test_uint8); g_test_add_data_func("/core/parser/glr/int_range", GINT_TO_POINTER(PB_GLR), test_int_range); -#if 0 - g_test_add_data_func("/core/parser/glr/float64", GINT_TO_POINTER(PB_GLR), test_float64); - g_test_add_data_func("/core/parser/glr/float32", GINT_TO_POINTER(PB_GLR), test_float32); -#endif + g_test_add_data_func("/core/parser/glr/double", GINT_TO_POINTER(PB_GLR), test_double); + g_test_add_data_func("/core/parser/glr/float", GINT_TO_POINTER(PB_GLR), test_float); g_test_add_data_func("/core/parser/glr/whitespace", GINT_TO_POINTER(PB_GLR), test_whitespace); g_test_add_data_func("/core/parser/glr/left", GINT_TO_POINTER(PB_GLR), test_left); g_test_add_data_func("/core/parser/glr/right", GINT_TO_POINTER(PB_GLR), test_right);