Skip to content

Commit

Permalink
Constant on block parameter node
Browse files Browse the repository at this point in the history
  • Loading branch information
kddnewton committed Sep 6, 2023
1 parent 8f8f353 commit 2cd9a67
Show file tree
Hide file tree
Showing 35 changed files with 142 additions and 76 deletions.
2 changes: 2 additions & 0 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,8 @@ nodes:
^^^^^^^^^^^^^^
- name: BlockParameterNode
fields:
- name: name
type: constant?
- name: name_loc
type: location?
- name: operator_loc
Expand Down
13 changes: 13 additions & 0 deletions rust/yarp/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ enum NodeFieldType {
#[serde(rename = "constant")]
Constant,

#[serde(rename = "constant?")]
OptionalConstant,

#[serde(rename = "constant[]")]
ConstantList,

Expand Down Expand Up @@ -228,6 +231,16 @@ fn write_node(file: &mut File, node: &Node) -> Result<(), Box<dyn std::error::Er
writeln!(file, " ConstantId::new(self.parser, unsafe {{ (*self.pointer).{} }})", field.name)?;
writeln!(file, " }}")?;
},
NodeFieldType::OptionalConstant => {
writeln!(file, " pub fn {}(&self) -> Option<ConstantId<'pr>> {{", field.name)?;
writeln!(file, " let id = unsafe {{ (*self.pointer).{} }};", field.name)?;
writeln!(file, " if id == 0 {{")?;
writeln!(file, " None")?;
writeln!(file, " }} else {{")?;
writeln!(file, " Some(ConstantId::new(self.parser, id))")?;
writeln!(file, " }}")?;
writeln!(file, " }}")?;
},
NodeFieldType::ConstantList => {
writeln!(file, " pub fn {}(&self) -> ConstantList<'pr> {{", field.name)?;
writeln!(file, " let pointer: *mut yp_constant_id_list_t = unsafe {{ &mut (*self.pointer).{} }};", field.name)?;
Expand Down
8 changes: 8 additions & 0 deletions src/yarp.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,13 @@ yp_parser_constant_id_token(yp_parser_t *parser, const yp_token_t *token) {
return yp_parser_constant_id_location(parser, token->start, token->end);
}

// Retrieve the constant pool id for the given token. If the token is not
// provided, then return 0.
static inline yp_constant_id_t
yp_parser_optional_constant_id_token(yp_parser_t *parser, const yp_token_t *token) {
return token->type == YP_TOKEN_NOT_PROVIDED ? 0 : yp_parser_constant_id_token(parser, token);
}

// Mark any range nodes in this subtree as flipflops.
static void
yp_flip_flop(yp_node_t *node) {
Expand Down Expand Up @@ -1134,6 +1141,7 @@ yp_block_parameter_node_create(yp_parser_t *parser, const yp_token_t *name, cons
.end = (name->type == YP_TOKEN_NOT_PROVIDED ? operator->end : name->end)
},
},
.name = yp_parser_optional_constant_id_token(parser, name),
.name_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(name),
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator)
};
Expand Down
2 changes: 2 additions & 0 deletions templates/ext/yarp/api_node.c.erb
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ yp_ast_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding) {
argv[<%= index %>] = yp_string_new(&cast-><%= field.name %>, encoding);
<%- when YARP::ConstantField -%>
argv[<%= index %>] = rb_id2sym(constants[cast-><%= field.name %> - 1]);
<%- when YARP::OptionalConstantField -%>
argv[<%= index %>] = cast-><%= field.name %> == 0 ? Qnil : rb_id2sym(constants[cast-><%= field.name %> - 1]);
<%- when YARP::ConstantListField -%>
argv[<%= index %>] = rb_ary_new_capa(cast-><%= field.name %>.size);
for (size_t index = 0; index < cast-><%= field.name %>.size; index++) {
Expand Down
2 changes: 1 addition & 1 deletion templates/include/yarp/ast.h.erb
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ typedef struct yp_<%= node.human %> {
<%= case field
when YARP::NodeField, YARP::OptionalNodeField then "struct #{field.c_type} *#{field.name}"
when YARP::NodeListField then "struct yp_node_list #{field.name}"
when YARP::ConstantField then "yp_constant_id_t #{field.name}"
when YARP::ConstantField, YARP::OptionalConstantField then "yp_constant_id_t #{field.name}"
when YARP::ConstantListField then "yp_constant_id_list_t #{field.name}"
when YARP::StringField then "yp_string_t #{field.name}"
when YARP::LocationField, YARP::OptionalLocationField then "yp_location_t #{field.name}"
Expand Down
10 changes: 10 additions & 0 deletions templates/java/org/yarp/Loader.java.erb
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,15 @@ public class Loader {
return constantPool.get(buffer, loadVarInt());
}

private byte[] loadOptionalConstant() {
if (buffer.get(buffer.position()) != 0) {
return loadConstant();
} else {
buffer.position(buffer.position() + 1); // continue after the 0 byte
return null;
}
}

private byte[][] loadConstants() {
int length = loadVarInt();
if (length == 0) {
Expand Down Expand Up @@ -264,6 +273,7 @@ public class Loader {
when YARP::StringField then "loadString()"
when YARP::NodeListField then "loadNodes()"
when YARP::ConstantField then "loadConstant()"
when YARP::OptionalConstantField then "loadOptionalConstant()"
when YARP::ConstantListField then "loadConstants()"
when YARP::LocationField then "loadLocation()"
when YARP::OptionalLocationField then "loadOptionalLocation()"
Expand Down
2 changes: 1 addition & 1 deletion templates/lib/yarp/node.rb.erb
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ module YARP
inspector << "<%= pointer %><%= field.name %>:\n"
inspector << <%= field.name %>.inspect(inspector.child_inspector("<%= preadd %>")).delete_prefix(inspector.prefix)
end
<%- when YARP::ConstantField, YARP::StringField, YARP::UInt32Field -%>
<%- when YARP::ConstantField, YARP::OptionalConstantField, YARP::StringField, YARP::UInt32Field -%>
inspector << "<%= pointer %><%= field.name %>: #{<%= field.name %>.inspect}\n"
<%- when YARP::FlagsField -%>
<%- flag = flags.find { |flag| flag.name == field.kind }.tap { |flag| raise unless flag } -%>
Expand Down
17 changes: 13 additions & 4 deletions templates/lib/yarp/serialize.rb.erb
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,7 @@ module YARP
load_location if io.getbyte != 0
end

def load_constant
index = load_varint - 1
def load_constant(index)
constant = constant_pool[index]

unless constant
Expand All @@ -169,6 +168,15 @@ module YARP
constant
end

def load_required_constant
load_constant(load_varint - 1)
end

def load_optional_constant
index = load_varint
load_constant(index - 1) if index != 0
end

def load_node
type = io.getbyte
location = load_location
Expand All @@ -185,8 +193,9 @@ module YARP
when YARP::OptionalNodeField then "load_optional_node"
when YARP::StringField then "load_string"
when YARP::NodeListField then "Array.new(load_varint) { load_node }"
when YARP::ConstantField then "load_constant"
when YARP::ConstantListField then "Array.new(load_varint) { load_constant }"
when YARP::ConstantField then "load_required_constant"
when YARP::OptionalConstantField then "load_optional_constant"
when YARP::ConstantListField then "Array.new(load_varint) { load_required_constant }"
when YARP::LocationField then "load_location"
when YARP::OptionalLocationField then "load_optional_location"
when YARP::UInt32Field, YARP::FlagsField then "load_varint"
Expand Down
6 changes: 3 additions & 3 deletions templates/src/node.c.erb
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ yp_node_destroy(yp_parser_t *parser, yp_node_t *node) {
<%- nodes.each do |node| -%>
#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>"
case <%= node.type %>: {
<%- if node.fields.any? { |field| ![YARP::LocationField, YARP::OptionalLocationField, YARP::UInt32Field, YARP::FlagsField, YARP::ConstantField].include?(field.class) } -%>
<%- if node.fields.any? { |field| ![YARP::LocationField, YARP::OptionalLocationField, YARP::UInt32Field, YARP::FlagsField, YARP::ConstantField, YARP::OptionalConstantField].include?(field.class) } -%>
yp_<%= node.human %>_t *cast = (yp_<%= node.human %>_t *) node;
<%- end -%>
<%- node.fields.each do |field| -%>
<%- case field -%>
<%- when YARP::LocationField, YARP::OptionalLocationField, YARP::UInt32Field, YARP::FlagsField, YARP::ConstantField -%>
<%- when YARP::LocationField, YARP::OptionalLocationField, YARP::UInt32Field, YARP::FlagsField, YARP::ConstantField, YARP::OptionalConstantField -%>
<%- when YARP::NodeField -%>
yp_node_destroy(parser, (yp_node_t *)cast-><%= field.name %>);
<%- when YARP::OptionalNodeField -%>
Expand Down Expand Up @@ -104,7 +104,7 @@ yp_node_memsize_node(yp_node_t *node, yp_memsize_t *memsize) {
memsize->memsize += sizeof(*cast);
<%- node.fields.each do |field| -%>
<%- case field -%>
<%- when YARP::ConstantField, YARP::UInt32Field, YARP::FlagsField, YARP::LocationField, YARP::OptionalLocationField -%>
<%- when YARP::ConstantField, YARP::OptionalConstantField, YARP::UInt32Field, YARP::FlagsField, YARP::LocationField, YARP::OptionalLocationField -%>
<%- when YARP::NodeField -%>
yp_node_memsize_node((yp_node_t *)cast-><%= field.name %>, memsize);
<%- when YARP::OptionalNodeField -%>
Expand Down
8 changes: 8 additions & 0 deletions templates/src/prettyprint.c.erb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) {
char <%= field.name %>_buffer[12];
snprintf(<%= field.name %>_buffer, sizeof(<%= field.name %>_buffer), "%u", ((yp_<%= node.human %>_t *)node)-><%= field.name %>);
yp_buffer_append_str(buffer, <%= field.name %>_buffer, strlen(<%= field.name %>_buffer));
<%- when YARP::OptionalConstantField -%>
if (((yp_<%= node.human %>_t *)node)-><%= field.name %> == 0) {
yp_buffer_append_str(buffer, "nil", 3);
} else {
char <%= field.name %>_buffer[12];
snprintf(<%= field.name %>_buffer, sizeof(<%= field.name %>_buffer), "%u", ((yp_<%= node.human %>_t *)node)-><%= field.name %>);
yp_buffer_append_str(buffer, <%= field.name %>_buffer, strlen(<%= field.name %>_buffer));
}
<%- when YARP::ConstantListField -%>
yp_buffer_append_str(buffer, "[", 1);
for (uint32_t index = 0; index < ((yp_<%= node.human %>_t *)node)-><%= field.name %>.size; index++) {
Expand Down
2 changes: 1 addition & 1 deletion templates/src/serialize.c.erb
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ yp_serialize_node(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer) {
for (uint32_t index = 0; index < <%= field.name %>_size; index++) {
yp_serialize_node(parser, (yp_node_t *) ((yp_<%= node.human %>_t *)node)-><%= field.name %>.nodes[index], buffer);
}
<%- when YARP::ConstantField -%>
<%- when YARP::ConstantField, YARP::OptionalConstantField -%>
yp_buffer_append_u32(buffer, yp_sizet_to_u32(((yp_<%= node.human %>_t *)node)-><%= field.name %>));
<%- when YARP::ConstantListField -%>
uint32_t <%= field.name %>_size = yp_sizet_to_u32(((yp_<%= node.human %>_t *)node)-><%= field.name %>.size);
Expand Down
16 changes: 15 additions & 1 deletion templates/template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ def java_type
end
end

# This represents a field on a node that is the ID of a string interned
# through the parser's constant pool and can be optionally null.
class OptionalConstantField < Field
def rbs_class
"Symbol?"
end

def java_type
"byte[]"
end
end

# This represents a field on a node that is a list of IDs that are associated
# with strings interned through the parser's constant pool.
class ConstantListField < Field
Expand Down Expand Up @@ -195,6 +207,7 @@ def field_type_for(name)
when "node[]" then NodeListField
when "string" then StringField
when "constant" then ConstantField
when "constant?" then OptionalConstantField
when "constant[]" then ConstantListField
when "location" then LocationField
when "location?" then OptionalLocationField
Expand Down Expand Up @@ -275,7 +288,8 @@ def template(name, write_to: nil)
HEADING

heading = if File.extname(filepath.gsub(".erb", "")) == ".rb"
heading =
if File.extname(filepath.gsub(".erb", "")) == ".rb"
ruby_heading
else
non_ruby_heading
Expand Down
6 changes: 3 additions & 3 deletions test/yarp/errors_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@ def test_method_parameters_after_block
nil,
[],
nil,
BlockParameterNode(Location(), Location())
BlockParameterNode(:block, Location(), Location())
),
nil,
[:block, :a],
Expand All @@ -664,7 +664,7 @@ def test_method_with_arguments_after_anonymous_block
expected = DefNode(
Location(),
nil,
ParametersNode([], [], [RequiredParameterNode(:a)], nil, [], nil, BlockParameterNode(nil, Location())),
ParametersNode([], [], [RequiredParameterNode(:a)], nil, [], nil, BlockParameterNode(nil, nil, Location())),
nil,
[:&, :a],
Location(),
Expand Down Expand Up @@ -1087,7 +1087,7 @@ def test_duplicated_parameter_names
expected = DefNode(
Location(),
nil,
ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], [], nil, [], nil, BlockParameterNode(Location(), Location())),
ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], [], nil, [], nil, BlockParameterNode(:a, Location(), Location())),
nil,
[:a, :b],
Location(),
Expand Down
4 changes: 2 additions & 2 deletions test/yarp/snapshots/methods.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions test/yarp/snapshots/procs.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion test/yarp/snapshots/seattlerb/args_kw_block.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion test/yarp/snapshots/seattlerb/block_arg__bare.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion test/yarp/snapshots/seattlerb/block_arg_opt_arg_block.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion test/yarp/snapshots/seattlerb/block_args_opt3.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion test/yarp/snapshots/seattlerb/difficult3_3.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion test/yarp/snapshots/seattlerb/iter_args_10_2.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion test/yarp/snapshots/seattlerb/iter_args_11_2.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion test/yarp/snapshots/seattlerb/iter_args_5.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 2cd9a67

Please sign in to comment.