Skip to content

Commit

Permalink
[ruby/yarp] Add a yp_location_for_node function to the C API
Browse files Browse the repository at this point in the history
yp_location_for_node takes a parser and a node and returns the
location in a way that can be punned into ruby/ruby types

ruby/prism@75e06016a7
  • Loading branch information
jemmaissroff authored and matzbot committed Jul 7, 2023
1 parent 31f83a6 commit 9e3a5cc
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
34 changes: 34 additions & 0 deletions yarp/yarp.c
Expand Up @@ -12900,6 +12900,40 @@ yp_parse_serialize(const char *source, size_t size, yp_buffer_t *buffer) {
yp_parser_free(&parser);
}

static yp_code_position_t
yp_code_position(yp_newline_list_t newline_list, size_t loc) {
int line = 0;
while (line < (int)newline_list.size && newline_list.offsets[line] < loc) {
line++;
}

if (line > 0) {
line--;
}

int column = (int) (loc - newline_list.offsets[line]);

yp_code_position_t position;
position.lineno = line;
position.column = column;

return position;
}

yp_code_location_t
yp_location_for_node(yp_parser_t *parser, yp_node_t *node) {
yp_newline_list_t newline_list = parser->newline_list;

yp_code_position_t start = yp_code_position(newline_list, (size_t)(node->location.start - parser->start));
yp_code_position_t end = yp_code_position(newline_list, (size_t)(node->location.end - parser->start));

yp_code_location_t location;
location.beg_pos = start;
location.end_pos = end;

return location;
}

#undef YP_CASE_KEYWORD
#undef YP_CASE_OPERATOR
#undef YP_CASE_WRITABLE
19 changes: 19 additions & 0 deletions yarp/yarp.h
Expand Up @@ -66,4 +66,23 @@ YP_EXPORTED_FUNCTION void yp_parse_serialize(const char *source, size_t size, yp
// Returns a string representation of the given token type.
YP_EXPORTED_FUNCTION const char * yp_token_type_to_str(yp_token_type_t token_type);

// This reprsents a line, column position in the parsed source code
// The layouts of this struct should not change because they mirror
// rb_code_position_struct in ruby/ruby which allows us to type pun
typedef struct yp_code_position_struct {
int lineno;
int column;
} yp_code_position_t;

// This reprsents a begin and end of anything in the AST that has a
// location from the parsed source code.
// The layouts of this struct should not change because they mirror
// rb_code_position_struct in ruby/ruby which allows us to type pun
typedef struct yp_code_location_struct {
yp_code_position_t beg_pos;
yp_code_position_t end_pos;
} yp_code_location_t;

yp_code_location_t yp_location_for_node(yp_parser_t *parser, yp_node_t *node);

#endif

0 comments on commit 9e3a5cc

Please sign in to comment.