summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJemma Issroff <jemmaissroff@gmail.com>2023-08-08 12:48:49 -0400
committergit <svn-admin@ruby-lang.org>2023-08-24 19:06:00 +0000
commitd81634d3ef21b5b8072934a1e00f431e42cbce8a (patch)
tree8fe5eb8acebb56cfca72a64c41c75faf8cbe18f1
parent75c9c2c4314bbce4a27c761e592d7db509039d79 (diff)
[ruby/yarp] Add a ScopeNode and a way to create scope nodes from existing nodes
This commit creates a scope node, and exposes a method to get ScopeNodes from other existing nodes. It still has TODOs around creating ScopeNodes for other types of nodes, which will be done in future commits. https://github.com/ruby/yarp/commit/3b9ac5764d
-rw-r--r--yarp/config.yml14
-rw-r--r--yarp/yarp.c56
-rw-r--r--yarp/yarp.h3
3 files changed, 73 insertions, 0 deletions
diff --git a/yarp/config.yml b/yarp/config.yml
index e4987013bb..bf41d486d4 100644
--- a/yarp/config.yml
+++ b/yarp/config.yml
@@ -1686,6 +1686,20 @@ nodes:
return 1
^^^^^^^^
+ - name: ScopeNode
+ child_nodes:
+ - name: parameters
+ type: node?
+ kind: ParametersNode
+ - name: statements
+ type: node?
+ kind: StatementsNode
+ - name: locals
+ type: constant[]
+ comment: |
+ Used only to retrieve the scope, not an
+ actual semantically meaningful node
+
- name: SelfNode
comment: |
Represents the `self` keyword.
diff --git a/yarp/yarp.c b/yarp/yarp.c
index f944f7f5ac..5e63a92f2a 100644
--- a/yarp/yarp.c
+++ b/yarp/yarp.c
@@ -1016,6 +1016,62 @@ yp_block_argument_node_create(yp_parser_t *parser, const yp_token_t *operator, y
return node;
}
+static void
+YP_ATTRIBUTE_UNUSED yp_scope_node_create(yp_parameters_node_t *parameters, yp_statements_node_t *statements, yp_constant_id_list_t locals, const char *start, const char *end, yp_scope_node_t *dest)
+{
+ *dest = (yp_scope_node_t) {
+ {
+ .type = YP_NODE_SCOPE_NODE,
+ .location = { .start = start, .end = end },
+ },
+ .parameters = parameters,
+ .statements = statements,
+ .locals = locals,
+ };
+ return;
+}
+
+// TODO: Implement this for all other nodes which can have a scope
+void
+yp_get_scope_node(yp_node_t *node, yp_scope_node_t *dest) {
+ yp_parameters_node_t *parameters = NULL;
+ yp_statements_node_t *statements;
+ yp_constant_id_list_t locals;
+ const char *start = node->location.start;
+ const char *end = node->location.end;
+
+ switch (node->type) {
+ case YP_NODE_DEF_NODE: {
+ yp_def_node_t *def_node = (yp_def_node_t *) node;
+ parameters = def_node->parameters;
+ statements = (yp_statements_node_t *)def_node->body;
+ locals = def_node->locals;
+ break;
+ }
+
+ case YP_NODE_CLASS_NODE: {
+ yp_class_node_t *class_node = (yp_class_node_t *) node;
+ statements = (yp_statements_node_t *)class_node->body;
+ locals = class_node->locals;
+ break;
+ }
+
+ case YP_NODE_SINGLETON_CLASS_NODE: {
+ yp_singleton_class_node_t *singleton_class_node = (yp_singleton_class_node_t *) node;
+ statements = (yp_statements_node_t *)singleton_class_node->body;
+ locals = singleton_class_node->locals;
+ break;
+ }
+
+ default:
+ assert(false && "unreachable");
+ return;
+ }
+
+ yp_scope_node_create(parameters, statements, locals, start, end, dest);
+ return;
+}
+
// Allocate and initialize a new BlockNode node.
static yp_block_node_t *
yp_block_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *opening, yp_block_parameters_node_t *parameters, yp_node_t *body, const yp_token_t *closing) {
diff --git a/yarp/yarp.h b/yarp/yarp.h
index 787029fcc3..8e723f414c 100644
--- a/yarp/yarp.h
+++ b/yarp/yarp.h
@@ -30,6 +30,9 @@ void yp_serialize_content(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buf
void yp_print_node(yp_parser_t *parser, yp_node_t *node);
+// Generate a scope node for a DefNode and ClassNode
+void yp_get_scope_node(yp_node_t *node, yp_scope_node_t *dest);
+
// The YARP version and the serialization format.
YP_EXPORTED_FUNCTION const char * yp_version(void);