Skip to content

Commit 7c9cf63

Browse files
committed
Get general prettyprint structure working
1 parent fddcf71 commit 7c9cf63

File tree

6 files changed

+249
-158
lines changed

6 files changed

+249
-158
lines changed

ext/prism/extension.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,27 @@ parse_serialize_file_metadata(VALUE self, VALUE filepath, VALUE metadata) {
554554
return result;
555555
}
556556

557+
static VALUE
558+
rb_prism_debug_inspect_node(VALUE self, VALUE source) {
559+
pm_string_t input;
560+
input_load_string(&input, source);
561+
562+
pm_parser_t parser;
563+
pm_parser_init(&parser, pm_string_source(&input), pm_string_length(&input), NULL);
564+
565+
pm_node_t *node = pm_parse(&parser);
566+
pm_buffer_t buffer = { 0 };
567+
568+
pm_prettyprint(&parser, node, &buffer);
569+
VALUE string = rb_str_new(pm_buffer_value(&buffer), pm_buffer_length(&buffer));
570+
571+
pm_buffer_free(&buffer);
572+
pm_node_destroy(&parser, node);
573+
pm_parser_free(&parser);
574+
575+
return string;
576+
}
577+
557578
/******************************************************************************/
558579
/* Initialization of the extension */
559580
/******************************************************************************/
@@ -607,6 +628,8 @@ Init_prism(void) {
607628
rb_define_singleton_method(rb_cPrismDebug, "profile_file", profile_file, 1);
608629
rb_define_singleton_method(rb_cPrismDebug, "parse_serialize_file_metadata", parse_serialize_file_metadata, 2);
609630

631+
rb_define_singleton_method(rb_cPrismDebug, "inspect_node", rb_prism_debug_inspect_node, 1);
632+
610633
// Next, initialize the other APIs.
611634
Init_prism_api_node();
612635
Init_prism_pack();

include/prism/util/pm_buffer.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
// block of memory. It is used to store the serialized representation of a
1414
// prism tree.
1515
typedef struct {
16-
char *value;
1716
size_t length;
1817
size_t capacity;
18+
char *value;
1919
} pm_buffer_t;
2020

2121
// Return the size of the pm_buffer_t struct.
@@ -37,16 +37,19 @@ PRISM_EXPORTED_FUNCTION size_t pm_buffer_length(pm_buffer_t *buffer);
3737
void pm_buffer_append_zeroes(pm_buffer_t *buffer, size_t length);
3838

3939
// Append a string to the buffer.
40-
void pm_buffer_append_str(pm_buffer_t *buffer, const char *value, size_t length);
40+
void pm_buffer_append_string(pm_buffer_t *buffer, const char *value, size_t length);
4141

4242
// Append a list of bytes to the buffer.
4343
void pm_buffer_append_bytes(pm_buffer_t *buffer, const uint8_t *value, size_t length);
4444

4545
// Append a single byte to the buffer.
46-
void pm_buffer_append_u8(pm_buffer_t *buffer, uint8_t value);
46+
void pm_buffer_append_byte(pm_buffer_t *buffer, uint8_t value);
4747

4848
// Append a 32-bit unsigned integer to the buffer.
49-
void pm_buffer_append_u32(pm_buffer_t *buffer, uint32_t value);
49+
void pm_buffer_append_varint(pm_buffer_t *buffer, uint32_t value);
50+
51+
// Append one buffer onto another.
52+
void pm_buffer_concat(pm_buffer_t *destination, const pm_buffer_t *source);
5053

5154
// Free the memory associated with the buffer.
5255
PRISM_EXPORTED_FUNCTION void pm_buffer_free(pm_buffer_t *buffer);

src/prism.c

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6343,24 +6343,24 @@ escape_byte(uint8_t value, const uint8_t flags) {
63436343
static inline void
63446344
escape_write_unicode(pm_parser_t *parser, pm_buffer_t *buffer, const uint8_t *start, const uint8_t *end, uint32_t value) {
63456345
if (value <= 0x7F) { // 0xxxxxxx
6346-
pm_buffer_append_u8(buffer, (uint8_t) value);
6346+
pm_buffer_append_byte(buffer, (uint8_t) value);
63476347
} else if (value <= 0x7FF) { // 110xxxxx 10xxxxxx
6348-
pm_buffer_append_u8(buffer, (uint8_t) (0xC0 | (value >> 6)));
6349-
pm_buffer_append_u8(buffer, (uint8_t) (0x80 | (value & 0x3F)));
6348+
pm_buffer_append_byte(buffer, (uint8_t) (0xC0 | (value >> 6)));
6349+
pm_buffer_append_byte(buffer, (uint8_t) (0x80 | (value & 0x3F)));
63506350
} else if (value <= 0xFFFF) { // 1110xxxx 10xxxxxx 10xxxxxx
6351-
pm_buffer_append_u8(buffer, (uint8_t) (0xE0 | (value >> 12)));
6352-
pm_buffer_append_u8(buffer, (uint8_t) (0x80 | ((value >> 6) & 0x3F)));
6353-
pm_buffer_append_u8(buffer, (uint8_t) (0x80 | (value & 0x3F)));
6351+
pm_buffer_append_byte(buffer, (uint8_t) (0xE0 | (value >> 12)));
6352+
pm_buffer_append_byte(buffer, (uint8_t) (0x80 | ((value >> 6) & 0x3F)));
6353+
pm_buffer_append_byte(buffer, (uint8_t) (0x80 | (value & 0x3F)));
63546354
} else if (value <= 0x10FFFF) { // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6355-
pm_buffer_append_u8(buffer, (uint8_t) (0xF0 | (value >> 18)));
6356-
pm_buffer_append_u8(buffer, (uint8_t) (0x80 | ((value >> 12) & 0x3F)));
6357-
pm_buffer_append_u8(buffer, (uint8_t) (0x80 | ((value >> 6) & 0x3F)));
6358-
pm_buffer_append_u8(buffer, (uint8_t) (0x80 | (value & 0x3F)));
6355+
pm_buffer_append_byte(buffer, (uint8_t) (0xF0 | (value >> 18)));
6356+
pm_buffer_append_byte(buffer, (uint8_t) (0x80 | ((value >> 12) & 0x3F)));
6357+
pm_buffer_append_byte(buffer, (uint8_t) (0x80 | ((value >> 6) & 0x3F)));
6358+
pm_buffer_append_byte(buffer, (uint8_t) (0x80 | (value & 0x3F)));
63596359
} else {
63606360
pm_parser_err(parser, start, end, PM_ERR_ESCAPE_INVALID_UNICODE);
6361-
pm_buffer_append_u8(buffer, 0xEF);
6362-
pm_buffer_append_u8(buffer, 0xBF);
6363-
pm_buffer_append_u8(buffer, 0xBD);
6361+
pm_buffer_append_byte(buffer, 0xEF);
6362+
pm_buffer_append_byte(buffer, 0xBF);
6363+
pm_buffer_append_byte(buffer, 0xBD);
63646364
}
63656365
}
63666366

@@ -6386,18 +6386,18 @@ escape_write_byte(pm_buffer_t *buffer, uint8_t flags, uint8_t byte) {
63866386
uint8_t byte2 = (uint8_t) (byte & 0xF);
63876387

63886388
if (byte1 >= 0xA) {
6389-
pm_buffer_append_u8(buffer, (uint8_t) ((byte1 - 0xA) + 'A'));
6389+
pm_buffer_append_byte(buffer, (uint8_t) ((byte1 - 0xA) + 'A'));
63906390
} else {
6391-
pm_buffer_append_u8(buffer, (uint8_t) (byte1 + '0'));
6391+
pm_buffer_append_byte(buffer, (uint8_t) (byte1 + '0'));
63926392
}
63936393

63946394
if (byte2 >= 0xA) {
6395-
pm_buffer_append_u8(buffer, (uint8_t) (byte2 - 0xA + 'A'));
6395+
pm_buffer_append_byte(buffer, (uint8_t) (byte2 - 0xA + 'A'));
63966396
} else {
6397-
pm_buffer_append_u8(buffer, (uint8_t) (byte2 + '0'));
6397+
pm_buffer_append_byte(buffer, (uint8_t) (byte2 + '0'));
63986398
}
63996399
} else {
6400-
pm_buffer_append_u8(buffer, byte);
6400+
pm_buffer_append_byte(buffer, byte);
64016401
}
64026402
}
64036403

@@ -6407,57 +6407,57 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags) {
64076407
switch (peek(parser)) {
64086408
case '\\': {
64096409
parser->current.end++;
6410-
pm_buffer_append_u8(buffer, '\\');
6410+
pm_buffer_append_byte(buffer, '\\');
64116411
return;
64126412
}
64136413
case '\'': {
64146414
parser->current.end++;
6415-
pm_buffer_append_u8(buffer, '\'');
6415+
pm_buffer_append_byte(buffer, '\'');
64166416
return;
64176417
}
64186418
case 'a': {
64196419
parser->current.end++;
6420-
pm_buffer_append_u8(buffer, '\a');
6420+
pm_buffer_append_byte(buffer, '\a');
64216421
return;
64226422
}
64236423
case 'b': {
64246424
parser->current.end++;
6425-
pm_buffer_append_u8(buffer, '\b');
6425+
pm_buffer_append_byte(buffer, '\b');
64266426
return;
64276427
}
64286428
case 'e': {
64296429
parser->current.end++;
6430-
pm_buffer_append_u8(buffer, '\033');
6430+
pm_buffer_append_byte(buffer, '\033');
64316431
return;
64326432
}
64336433
case 'f': {
64346434
parser->current.end++;
6435-
pm_buffer_append_u8(buffer, '\f');
6435+
pm_buffer_append_byte(buffer, '\f');
64366436
return;
64376437
}
64386438
case 'n': {
64396439
parser->current.end++;
6440-
pm_buffer_append_u8(buffer, '\n');
6440+
pm_buffer_append_byte(buffer, '\n');
64416441
return;
64426442
}
64436443
case 'r': {
64446444
parser->current.end++;
6445-
pm_buffer_append_u8(buffer, '\r');
6445+
pm_buffer_append_byte(buffer, '\r');
64466446
return;
64476447
}
64486448
case 's': {
64496449
parser->current.end++;
6450-
pm_buffer_append_u8(buffer, ' ');
6450+
pm_buffer_append_byte(buffer, ' ');
64516451
return;
64526452
}
64536453
case 't': {
64546454
parser->current.end++;
6455-
pm_buffer_append_u8(buffer, '\t');
6455+
pm_buffer_append_byte(buffer, '\t');
64566456
return;
64576457
}
64586458
case 'v': {
64596459
parser->current.end++;
6460-
pm_buffer_append_u8(buffer, '\v');
6460+
pm_buffer_append_byte(buffer, '\v');
64616461
return;
64626462
}
64636463
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': {
@@ -6474,7 +6474,7 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags) {
64746474
}
64756475
}
64766476

6477-
pm_buffer_append_u8(buffer, value);
6477+
pm_buffer_append_byte(buffer, value);
64786478
return;
64796479
}
64806480
case 'x': {
@@ -6496,7 +6496,7 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags) {
64966496
if (flags & PM_ESCAPE_FLAG_REGEXP) {
64976497
pm_buffer_append_bytes(buffer, start, (size_t) (parser->current.end - start));
64986498
} else {
6499-
pm_buffer_append_u8(buffer, value);
6499+
pm_buffer_append_byte(buffer, value);
65006500
}
65016501
} else {
65026502
pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_HEXADECIMAL);
@@ -6690,14 +6690,14 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags) {
66906690
case '\r': {
66916691
if (peek_offset(parser, 1) == '\n') {
66926692
parser->current.end += 2;
6693-
pm_buffer_append_u8(buffer, '\n');
6693+
pm_buffer_append_byte(buffer, '\n');
66946694
return;
66956695
}
66966696
}
66976697
/* fallthrough */
66986698
default: {
66996699
if (parser->current.end < parser->end) {
6700-
pm_buffer_append_u8(buffer, *parser->current.end++);
6700+
pm_buffer_append_byte(buffer, *parser->current.end++);
67016701
}
67026702
return;
67036703
}
@@ -6951,7 +6951,7 @@ typedef struct {
69516951
// Push the given byte into the token buffer.
69526952
static inline void
69536953
pm_token_buffer_push(pm_token_buffer_t *token_buffer, uint8_t byte) {
6954-
pm_buffer_append_u8(&token_buffer->buffer, byte);
6954+
pm_buffer_append_byte(&token_buffer->buffer, byte);
69556955
}
69566956

69576957
// When we're about to return from lexing the current token and we know for sure
@@ -15592,14 +15592,14 @@ pm_parse(pm_parser_t *parser) {
1559215592

1559315593
PRISM_EXPORTED_FUNCTION void
1559415594
pm_serialize(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
15595-
pm_buffer_append_str(buffer, "PRISM", 5);
15596-
pm_buffer_append_u8(buffer, PRISM_VERSION_MAJOR);
15597-
pm_buffer_append_u8(buffer, PRISM_VERSION_MINOR);
15598-
pm_buffer_append_u8(buffer, PRISM_VERSION_PATCH);
15599-
pm_buffer_append_u8(buffer, PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS ? 1 : 0);
15595+
pm_buffer_append_string(buffer, "PRISM", 5);
15596+
pm_buffer_append_byte(buffer, PRISM_VERSION_MAJOR);
15597+
pm_buffer_append_byte(buffer, PRISM_VERSION_MINOR);
15598+
pm_buffer_append_byte(buffer, PRISM_VERSION_PATCH);
15599+
pm_buffer_append_byte(buffer, PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS ? 1 : 0);
1560015600

1560115601
pm_serialize_content(parser, node, buffer);
15602-
pm_buffer_append_str(buffer, "\0", 1);
15602+
pm_buffer_append_string(buffer, "\0", 1);
1560315603
}
1560415604

1560515605
// Parse and serialize the AST represented by the given source to the given

src/util/pm_buffer.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,13 @@ pm_buffer_append_length(pm_buffer_t *buffer, size_t length) {
4040
size_t next_length = buffer->length + length;
4141

4242
if (next_length > buffer->capacity) {
43-
do {
43+
if (buffer->capacity == 0) {
44+
buffer->capacity = 1;
45+
}
46+
47+
while (next_length > buffer->capacity) {
4448
buffer->capacity *= 2;
45-
} while (next_length > buffer->capacity);
49+
}
4650

4751
buffer->value = realloc(buffer->value, buffer->capacity);
4852
}
@@ -53,20 +57,22 @@ pm_buffer_append_length(pm_buffer_t *buffer, size_t length) {
5357
// Append a generic pointer to memory to the buffer.
5458
static inline void
5559
pm_buffer_append(pm_buffer_t *buffer, const void *source, size_t length) {
60+
size_t cursor = buffer->length;
5661
pm_buffer_append_length(buffer, length);
57-
memcpy(buffer->value + (buffer->length - length), source, length);
62+
memcpy(buffer->value + cursor, source, length);
5863
}
5964

6065
// Append the given amount of space as zeroes to the buffer.
6166
void
6267
pm_buffer_append_zeroes(pm_buffer_t *buffer, size_t length) {
68+
size_t cursor = buffer->length;
6369
pm_buffer_append_length(buffer, length);
64-
memset(buffer->value + (buffer->length - length), 0, length);
70+
memset(buffer->value + cursor, 0, length);
6571
}
6672

6773
// Append a string to the buffer.
6874
void
69-
pm_buffer_append_str(pm_buffer_t *buffer, const char *value, size_t length) {
75+
pm_buffer_append_string(pm_buffer_t *buffer, const char *value, size_t length) {
7076
pm_buffer_append(buffer, value, length);
7177
}
7278

@@ -78,27 +84,35 @@ pm_buffer_append_bytes(pm_buffer_t *buffer, const uint8_t *value, size_t length)
7884

7985
// Append a single byte to the buffer.
8086
void
81-
pm_buffer_append_u8(pm_buffer_t *buffer, uint8_t value) {
87+
pm_buffer_append_byte(pm_buffer_t *buffer, uint8_t value) {
8288
const void *source = &value;
8389
pm_buffer_append(buffer, source, sizeof(uint8_t));
8490
}
8591

86-
// Append a 32-bit unsigned integer to the buffer.
92+
// Append a 32-bit unsigned integer to the buffer as a variable-length integer.
8793
void
88-
pm_buffer_append_u32(pm_buffer_t *buffer, uint32_t value) {
94+
pm_buffer_append_varint(pm_buffer_t *buffer, uint32_t value) {
8995
if (value < 128) {
90-
pm_buffer_append_u8(buffer, (uint8_t) value);
96+
pm_buffer_append_byte(buffer, (uint8_t) value);
9197
} else {
9298
uint32_t n = value;
9399
while (n >= 128) {
94-
pm_buffer_append_u8(buffer, (uint8_t) (n | 128));
100+
pm_buffer_append_byte(buffer, (uint8_t) (n | 128));
95101
n >>= 7;
96102
}
97-
pm_buffer_append_u8(buffer, (uint8_t) n);
103+
pm_buffer_append_byte(buffer, (uint8_t) n);
104+
}
105+
}
106+
107+
// Concatenate one buffer onto another.
108+
void
109+
pm_buffer_concat(pm_buffer_t *destination, const pm_buffer_t *source) {
110+
if (source->length > 0) {
111+
pm_buffer_append(destination, source->value, source->length);
98112
}
99113
}
100114

101-
// Free the memory associated with the buffer.
115+
// Free the internal memory associated with the buffer.
102116
void
103117
pm_buffer_free(pm_buffer_t *buffer) {
104118
free(buffer->value);

0 commit comments

Comments
 (0)