Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions bin/dump
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

$:.unshift(File.expand_path("../lib", __dir__))
require "yarp"

source = File.read("test.rb")

pp YARP.load(source, YARP.dump(source, "test.rb"))
4 changes: 3 additions & 1 deletion bin/templates/lib/yarp/serialize.rb.erb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ module YARP

def load_location
start_offset, end_offset = io.read(8).unpack("LL")
Location.new(start_offset, end_offset)
start_line, start_column = io.read(8).unpack("LL")
end_line, end_column = io.read(8).unpack("LL")
Location.new(start_offset, end_offset, start_line, start_column, end_line, end_column)
end

def load_optional_location
Expand Down
66 changes: 53 additions & 13 deletions bin/templates/src/serialize.c.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,68 @@
#include "yarp/util/yp_buffer.h"
#include "yarp/util/yp_conversion.h"

static inline uint32_t
line_number(char **newline_locations, const char *start) {
uint32_t index = 0;

while (newline_locations[index] != NULL) {
if (start < newline_locations[index]) {
return index + 1;
}
index++;
}
return index == 0 ? 1 : index;
}

static inline uint32_t
column_number(yp_parser_t *parser, char **newline_locations, const char *start) {
uint32_t index = 0;

while (newline_locations[index] != NULL) {
if (start < newline_locations[index]) {
if (index == 0) {
return start - parser->start;
} else {
return start - newline_locations[index - 1];
}
}
index++;
}
return index == 0 ? 1 : index;
}

static void
serialize_token(yp_parser_t *parser, yp_token_t *token, yp_buffer_t *buffer) {
serialize_token(yp_parser_t *parser, yp_token_t *token, char **newline_locations, yp_buffer_t *buffer) {
assert(token->start);
assert(token->end);


yp_buffer_append_u8(buffer, token->type);
yp_buffer_append_u32(buffer, yp_long_to_u32(token->start - parser->start));
yp_buffer_append_u32(buffer, yp_long_to_u32(token->end - parser->start));

yp_buffer_append_u32(buffer, line_number(newline_locations, token->start));
yp_buffer_append_u32(buffer, column_number(parser, newline_locations, token->start));
yp_buffer_append_u32(buffer, line_number(newline_locations, token->end));
yp_buffer_append_u32(buffer, column_number(parser, newline_locations, token->end));
}

static void
serialize_location(yp_parser_t *parser, yp_location_t *location, yp_buffer_t *buffer) {
serialize_location(yp_parser_t *parser, yp_location_t *location, char **newline_locations, yp_buffer_t *buffer) {
assert(location->start);
assert(location->end);

yp_buffer_append_u32(buffer, yp_long_to_u32(location->start - parser->start));
yp_buffer_append_u32(buffer, yp_long_to_u32(location->end - parser->start));

yp_buffer_append_u32(buffer, line_number(newline_locations, location->start));
yp_buffer_append_u32(buffer, column_number(parser, newline_locations, location->start));
yp_buffer_append_u32(buffer, line_number(newline_locations, location->end));
yp_buffer_append_u32(buffer, column_number(parser, newline_locations, location->end));
}

void
yp_serialize_node(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer) {
yp_serialize_node(yp_parser_t *parser, yp_node_t *node, char ** newline_locations, yp_buffer_t *buffer) {
yp_buffer_append_u8(buffer, node->type);

size_t offset = buffer->length;
Expand All @@ -37,21 +78,20 @@ yp_serialize_node(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer) {
assert(node->location.start);
assert(node->location.end);

yp_buffer_append_u32(buffer, yp_long_to_u32(node->location.start - parser->start));
yp_buffer_append_u32(buffer, yp_long_to_u32(node->location.end - parser->start));
serialize_location(parser, &node->location, newline_locations, buffer);

switch (node->type) {
<%- nodes.each do |node| -%>
case <%= node.type %>: {
<%- node.params.each do |param| -%>
<%- case param -%>
<%- when NodeParam -%>
yp_serialize_node(parser, (yp_node_t *)((yp_<%= node.human %>_t *)node)-><%= param.name %>, buffer);
yp_serialize_node(parser, (yp_node_t *)((yp_<%= node.human %>_t *)node)-><%= param.name %>, newline_locations, buffer);
<%- when OptionalNodeParam -%>
if (((yp_<%= node.human %>_t *)node)-><%= param.name %> == NULL) {
yp_buffer_append_u8(buffer, 0);
} else {
yp_serialize_node(parser, (yp_node_t *)((yp_<%= node.human %>_t *)node)-><%= param.name %>, buffer);
yp_serialize_node(parser, (yp_node_t *)((yp_<%= node.human %>_t *)node)-><%= param.name %>, newline_locations, buffer);
}
<%- when StringParam -%>
uint32_t <%= param.name %>_length = yp_ulong_to_u32(yp_string_length(&((yp_<%= node.human %>_t *)node)-><%= param.name %>));
Expand All @@ -61,30 +101,30 @@ yp_serialize_node(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer) {
uint32_t <%= param.name %>_size = yp_ulong_to_u32(((yp_<%= node.human %>_t *)node)-><%= param.name %>.size);
yp_buffer_append_u32(buffer, <%= param.name %>_size);
for (uint32_t index = 0; index < <%= param.name %>_size; index++) {
yp_serialize_node(parser, (yp_node_t *) ((yp_<%= node.human %>_t *)node)-><%= param.name %>.nodes[index], buffer);
yp_serialize_node(parser, (yp_node_t *) ((yp_<%= node.human %>_t *)node)-><%= param.name %>.nodes[index], newline_locations, buffer);
}
<%- when TokenParam -%>
serialize_token(parser, &((yp_<%= node.human %>_t *)node)-><%= param.name %>, buffer);
serialize_token(parser, &((yp_<%= node.human %>_t *)node)-><%= param.name %>, newline_locations, buffer);
<%- when OptionalTokenParam -%>
if (((yp_<%= node.human %>_t *)node)-><%= param.name %>.type == YP_TOKEN_NOT_PROVIDED) {
yp_buffer_append_u8(buffer, 0);
} else {
serialize_token(parser, &((yp_<%= node.human %>_t *)node)-><%= param.name %>, buffer);
serialize_token(parser, &((yp_<%= node.human %>_t *)node)-><%= param.name %>, newline_locations, buffer);
}
<%- when TokenListParam -%>
uint32_t <%= param.name %>_size = yp_ulong_to_u32(((yp_<%= node.human %>_t *)node)-><%= param.name %>.size);
yp_buffer_append_u32(buffer, <%= param.name %>_size);
for (uint32_t index = 0; index < <%= param.name %>_size; index++) {
serialize_token(parser, &((yp_<%= node.human %>_t *)node)-><%= param.name %>.tokens[index], buffer);
serialize_token(parser, &((yp_<%= node.human %>_t *)node)-><%= param.name %>.tokens[index], newline_locations, buffer);
}
<%- when LocationParam -%>
serialize_location(parser, &((yp_<%= node.human %>_t *)node)-><%= param.name %>, buffer);
serialize_location(parser, &((yp_<%= node.human %>_t *)node)-><%= param.name %>, newline_locations, buffer);
<%- when OptionalLocationParam -%>
if (((yp_<%= node.human %>_t *)node)-><%= param.name %>.start == NULL) {
yp_buffer_append_u8(buffer, 0);
} else {
yp_buffer_append_u8(buffer, 1);
serialize_location(parser, &((yp_<%= node.human %>_t *)node)-><%= param.name %>, buffer);
serialize_location(parser, &((yp_<%= node.human %>_t *)node)-><%= param.name %>, newline_locations, buffer);
}
<%- when IntegerParam -%>
yp_buffer_append_int(buffer, ((yp_<%= node.human %>_t *)node)-><%= param.name %>);
Expand Down
4 changes: 4 additions & 0 deletions docs/serialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ After the header comes the body of the serialized string. The body consistents o
| `4` | byte offset into the serialized string where this node ends |
| `4` | byte offset into the source string where this node begins |
| `4` | byte offset into the source string where this node ends |
| `4` | line number where this node begins |
| `4` | column number where this node begins |
| `4` | line number where this node end |
| `4` | column number where this node ends |

Each node's child is then appended to the serialized string. The child node types can be determined by referencing `config.yml`. Depending on the type of child node, it could take a couple of different forms, described below:

Expand Down
Loading