Skip to content

Commit 75e0601

Browse files
committed
Add a yp_location_for_node function to the C API
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
1 parent f3802e0 commit 75e0601

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

include/yarp.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,23 @@ YP_EXPORTED_FUNCTION void yp_parse_serialize(const char *source, size_t size, yp
6666
// Returns a string representation of the given token type.
6767
YP_EXPORTED_FUNCTION const char * yp_token_type_to_str(yp_token_type_t token_type);
6868

69+
// This reprsents a line, column position in the parsed source code
70+
// The layouts of this struct should not change because they mirror
71+
// rb_code_position_struct in ruby/ruby which allows us to type pun
72+
typedef struct yp_code_position_struct {
73+
int lineno;
74+
int column;
75+
} yp_code_position_t;
76+
77+
// This reprsents a begin and end of anything in the AST that has a
78+
// location from the parsed source code.
79+
// The layouts of this struct should not change because they mirror
80+
// rb_code_position_struct in ruby/ruby which allows us to type pun
81+
typedef struct yp_code_location_struct {
82+
yp_code_position_t beg_pos;
83+
yp_code_position_t end_pos;
84+
} yp_code_location_t;
85+
86+
yp_code_location_t yp_location_for_node(yp_parser_t *parser, yp_node_t *node);
87+
6988
#endif

src/yarp.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12900,6 +12900,40 @@ yp_parse_serialize(const char *source, size_t size, yp_buffer_t *buffer) {
1290012900
yp_parser_free(&parser);
1290112901
}
1290212902

12903+
static yp_code_position_t
12904+
yp_code_position(yp_newline_list_t newline_list, size_t loc) {
12905+
int line = 0;
12906+
while (line < (int)newline_list.size && newline_list.offsets[line] < loc) {
12907+
line++;
12908+
}
12909+
12910+
if (line > 0) {
12911+
line--;
12912+
}
12913+
12914+
int column = (int) (loc - newline_list.offsets[line]);
12915+
12916+
yp_code_position_t position;
12917+
position.lineno = line;
12918+
position.column = column;
12919+
12920+
return position;
12921+
}
12922+
12923+
yp_code_location_t
12924+
yp_location_for_node(yp_parser_t *parser, yp_node_t *node) {
12925+
yp_newline_list_t newline_list = parser->newline_list;
12926+
12927+
yp_code_position_t start = yp_code_position(newline_list, (size_t)(node->location.start - parser->start));
12928+
yp_code_position_t end = yp_code_position(newline_list, (size_t)(node->location.end - parser->start));
12929+
12930+
yp_code_location_t location;
12931+
location.beg_pos = start;
12932+
location.end_pos = end;
12933+
12934+
return location;
12935+
}
12936+
1290312937
#undef YP_CASE_KEYWORD
1290412938
#undef YP_CASE_OPERATOR
1290512939
#undef YP_CASE_WRITABLE

0 commit comments

Comments
 (0)