Skip to content

Commit

Permalink
Merge pull request #1228 from ruby/flags
Browse files Browse the repository at this point in the history
Refactor flags
  • Loading branch information
kddnewton authored Aug 11, 2023
2 parents 47cb0ab + 38aa9cc commit 8e764d1
Show file tree
Hide file tree
Showing 12 changed files with 147 additions and 95 deletions.
18 changes: 12 additions & 6 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,8 @@ nodes:
type: node?
kind: BlockNode
- name: flags
type: uint32
type: flags
kind: CallNodeFlags
- name: name
type: string
comment: |
Expand Down Expand Up @@ -1323,7 +1324,8 @@ nodes:
- name: closing_loc
type: location
- name: flags
type: uint32
type: flags
kind: RegularExpressionFlags
newline: parts
comment: |
Represents a regular expression literal that contains interpolation.
Expand Down Expand Up @@ -1746,7 +1748,8 @@ nodes:
- name: operator_loc
type: location
- name: flags
type: uint32
type: flags
kind: RangeNodeFlags
comment: |
Represents the use of the `..` or `...` operators.
Expand Down Expand Up @@ -1781,7 +1784,8 @@ nodes:
- name: unescaped
type: string
- name: flags
type: uint32
type: flags
kind: RegularExpressionFlags
comment: |
Represents a regular expression literal with no interpolation.
Expand Down Expand Up @@ -2072,7 +2076,8 @@ nodes:
type: node?
kind: StatementsNode
- name: flags
type: uint32
type: flags
kind: LoopFlags
newline: predicate
comment: |
Represents the use of the `until` keyword, either in the block form or the modifier form.
Expand Down Expand Up @@ -2106,7 +2111,8 @@ nodes:
type: node?
kind: StatementsNode
- name: flags
type: uint32
type: flags
kind: LoopFlags
newline: predicate
comment: |
Represents the use of the `while` keyword, either in the block form or the modifier form.
Expand Down
46 changes: 22 additions & 24 deletions src/yarp.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ yp_flip_flop(yp_node_t *node) {
}
case YP_NODE_RANGE_NODE: {
yp_range_node_t *cast = (yp_range_node_t *) node;
cast->flags |= YP_RANGE_NODE_FLAGS_FLIP_FLOP;
cast->base.flags |= YP_RANGE_NODE_FLAGS_FLIP_FLOP;
break;
}
default:
Expand Down Expand Up @@ -530,9 +530,9 @@ yp_arguments_validate(yp_parser_t *parser, yp_arguments_t *arguments) {
/******************************************************************************/

// Parse out the options for a regular expression.
static inline uint32_t
static inline yp_node_flags_t
yp_regular_expression_flags_create(const yp_token_t *closing) {
uint32_t flags = 0;
yp_node_flags_t flags = 0;

if (closing->type == YP_TOKEN_REGEXP_END) {
for (const char *flag = closing->start + 1; flag < closing->end; flag++) {
Expand Down Expand Up @@ -1123,8 +1123,7 @@ yp_call_node_create(yp_parser_t *parser) {
.opening_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
.arguments = NULL,
.closing_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
.block = NULL,
.flags = 0
.block = NULL
};

return node;
Expand Down Expand Up @@ -1200,7 +1199,7 @@ yp_call_node_call_create(yp_parser_t *parser, yp_node_t *receiver, yp_token_t *o
node->block = arguments->block;

if (operator->type == YP_TOKEN_AMPERSAND_DOT) {
node->flags |= YP_CALL_NODE_FLAGS_SAFE_NAVIGATION;
node->base.flags |= YP_CALL_NODE_FLAGS_SAFE_NAVIGATION;
}

yp_string_shared_init(&node->name, message->start, message->end);
Expand Down Expand Up @@ -1276,7 +1275,7 @@ yp_call_node_shorthand_create(yp_parser_t *parser, yp_node_t *receiver, yp_token
node->block = arguments->block;

if (operator->type == YP_TOKEN_AMPERSAND_DOT) {
node->flags |= YP_CALL_NODE_FLAGS_SAFE_NAVIGATION;
node->base.flags |= YP_CALL_NODE_FLAGS_SAFE_NAVIGATION;
}

yp_string_constant_init(&node->name, "call", 4);
Expand Down Expand Up @@ -1317,7 +1316,7 @@ yp_call_node_variable_call_create(yp_parser_t *parser, yp_token_t *message) {
// without a receiver that could also have been a local variable read).
static inline bool
yp_call_node_variable_call_p(yp_call_node_t *node) {
return node->flags & YP_CALL_NODE_FLAGS_VARIABLE_CALL;
return node->base.flags & YP_CALL_NODE_FLAGS_VARIABLE_CALL;
}

// Allocate and initialize a new CallOperatorAndWriteNode node.
Expand Down Expand Up @@ -2657,7 +2656,6 @@ yp_interpolated_regular_expression_node_create(yp_parser_t *parser, const yp_tok
},
.opening_loc = YP_LOCATION_TOKEN_VALUE(opening),
.closing_loc = YP_LOCATION_TOKEN_VALUE(opening),
.flags = 0,
.parts = YP_EMPTY_NODE_LIST
};

Expand All @@ -2674,7 +2672,7 @@ static inline void
yp_interpolated_regular_expression_node_closing_set(yp_interpolated_regular_expression_node_t *node, const yp_token_t *closing) {
node->closing_loc = YP_LOCATION_TOKEN_VALUE(closing);
node->base.location.end = closing->end;
node->flags = yp_regular_expression_flags_create(closing);
node->base.flags |= yp_regular_expression_flags_create(closing);
}

// Allocate and initialize a new InterpolatedStringNode node.
Expand Down Expand Up @@ -3458,14 +3456,13 @@ yp_range_node_create(yp_parser_t *parser, yp_node_t *left, const yp_token_t *ope
},
.left = left,
.right = right,
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator),
.flags = 0,
.operator_loc = YP_LOCATION_TOKEN_VALUE(operator)
};

switch (operator->type) {
case YP_TOKEN_DOT_DOT_DOT:
case YP_TOKEN_UDOT_DOT_DOT:
node->flags |= YP_RANGE_NODE_FLAGS_EXCLUDE_END;
node->base.flags |= YP_RANGE_NODE_FLAGS_EXCLUDE_END;
break;
default:
break;
Expand All @@ -3492,6 +3489,7 @@ yp_regular_expression_node_create(yp_parser_t *parser, const yp_token_t *opening
*node = (yp_regular_expression_node_t) {
{
.type = YP_NODE_REGULAR_EXPRESSION_NODE,
.flags = yp_regular_expression_flags_create(closing),
.location = {
.start = opening->start,
.end = closing->end
Expand All @@ -3500,7 +3498,7 @@ yp_regular_expression_node_create(yp_parser_t *parser, const yp_token_t *opening
.opening_loc = YP_LOCATION_TOKEN_VALUE(opening),
.content_loc = YP_LOCATION_TOKEN_VALUE(content),
.closing_loc = YP_LOCATION_TOKEN_VALUE(closing),
.flags = yp_regular_expression_flags_create(closing)
.unescaped = YP_EMPTY_STRING
};

return node;
Expand Down Expand Up @@ -3813,7 +3811,7 @@ yp_statements_node_body_append(yp_statements_node_t *node, yp_node_t *statement)
node->base.location.end = statement->location.end;

// Every statement gets marked as a place where a newline can occur.
statement->flags = YP_NODE_FLAG_NEWLINE;
statement->flags |= YP_NODE_FLAG_NEWLINE;
}

// Allocate a new StringConcatNode node.
Expand Down Expand Up @@ -4125,7 +4123,7 @@ yp_unless_node_end_keyword_loc_set(yp_unless_node_t *node, const yp_token_t *end

// Allocate a new UntilNode node.
static yp_until_node_t *
yp_until_node_create(yp_parser_t *parser, const yp_token_t *keyword, yp_node_t *predicate, yp_statements_node_t *statements, uint32_t flags) {
yp_until_node_create(yp_parser_t *parser, const yp_token_t *keyword, yp_node_t *predicate, yp_statements_node_t *statements, yp_node_flags_t flags) {
yp_until_node_t *node = YP_ALLOC_NODE(parser, yp_until_node_t);
bool has_statements = (statements != NULL) && (statements->body.size != 0);

Expand All @@ -4146,15 +4144,15 @@ yp_until_node_create(yp_parser_t *parser, const yp_token_t *keyword, yp_node_t *
*node = (yp_until_node_t) {
{
.type = YP_NODE_UNTIL_NODE,
.flags = flags,
.location = {
.start = start,
.end = end,
},
},
.keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword),
.predicate = predicate,
.statements = statements,
.flags = flags
.statements = statements
};

return node;
Expand Down Expand Up @@ -4200,7 +4198,7 @@ yp_when_node_statements_set(yp_when_node_t *node, yp_statements_node_t *statemen

// Allocate a new WhileNode node.
static yp_while_node_t *
yp_while_node_create(yp_parser_t *parser, const yp_token_t *keyword, yp_node_t *predicate, yp_statements_node_t *statements, uint32_t flags) {
yp_while_node_create(yp_parser_t *parser, const yp_token_t *keyword, yp_node_t *predicate, yp_statements_node_t *statements, yp_node_flags_t flags) {
yp_while_node_t *node = YP_ALLOC_NODE(parser, yp_while_node_t);

const char *start = NULL;
Expand All @@ -4221,15 +4219,15 @@ yp_while_node_create(yp_parser_t *parser, const yp_token_t *keyword, yp_node_t *
*node = (yp_while_node_t) {
{
.type = YP_NODE_WHILE_NODE,
.flags = flags,
.location = {
.start = start,
.end = end,
},
},
.keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword),
.predicate = predicate,
.statements = statements,
.flags = flags
.statements = statements
};

return node;
Expand Down Expand Up @@ -9433,7 +9431,7 @@ parse_alias_argument(yp_parser_t *parser, bool first) {
// Parse an identifier into either a local variable read or a call.
static yp_node_t *
parse_variable_call(yp_parser_t *parser) {
uint32_t flags = 0;
yp_node_flags_t flags = 0;

if (!match_type_p(parser, YP_TOKEN_PARENTHESIS_LEFT) && (parser->previous.end[-1] != '!') && (parser->previous.end[-1] != '?')) {
int depth;
Expand All @@ -9445,7 +9443,7 @@ parse_variable_call(yp_parser_t *parser) {
}

yp_call_node_t *node = yp_call_node_variable_call_create(parser, &parser->previous);
node->flags = flags;
node->base.flags |= flags;

return (yp_node_t *) node;
}
Expand Down Expand Up @@ -10599,7 +10597,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
if (parse_arguments_list(parser, &arguments, true)) {
// Since we found arguments, we need to turn off the
// variable call bit in the flags.
call->flags &= (uint32_t) ~YP_CALL_NODE_FLAGS_VARIABLE_CALL;
call->base.flags &= (yp_node_flags_t) ~YP_CALL_NODE_FLAGS_VARIABLE_CALL;

call->opening_loc = arguments.opening_loc;
call->arguments = arguments.arguments;
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 @@ -171,6 +171,8 @@ yp_ast_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding) {
argv[<%= index %>] = cast-><%= param.name %>.start == NULL ? Qnil : yp_location_new(parser, cast-><%= param.name %>.start, cast-><%= param.name %>.end, source);
<%- when UInt32Param -%>
argv[<%= index %>] = ULONG2NUM(cast-><%= param.name %>);
<%- when FlagsParam -%>
argv[<%= index %>] = ULONG2NUM(node->flags >> <%= COMMON_FLAGS %>);
<%- else -%>
<%- raise -%>
<%- end -%>
Expand Down
9 changes: 5 additions & 4 deletions templates/include/yarp/ast.h.erb
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ enum yp_node_type {
typedef uint16_t yp_node_type_t;
typedef uint16_t yp_node_flags_t;

// We store the flags enum in every node in the tree
static const uint16_t YP_NODE_FLAG_NEWLINE = 0x1;
// We store the flags enum in every node in the tree. Some flags are common to
// all nodes (the ones listed below). Others are specific to certain node types.
static const yp_node_flags_t YP_NODE_FLAG_NEWLINE = 0x1;

// For easy access, we define some macros to check node type
#define YP_NODE_TYPE(node) ((enum yp_node_type)node->type)
Expand All @@ -81,7 +82,7 @@ typedef struct yp_node {
// <%= node.name %>
typedef struct yp_<%= node.human %> {
yp_node_t base;
<%- node.params.each do |param| -%>
<%- node.params.grep_v(FlagsParam).each do |param| -%>
<%= case param
in NodeParam | OptionalNodeParam then "struct #{param.c_type} *#{param.name}"
in NodeListParam then "struct yp_node_list #{param.name}"
Expand All @@ -100,7 +101,7 @@ typedef struct yp_<%= node.human %> {

// <%= flag.name %>
typedef enum {
<%- flag.values.each_with_index do |value, index| -%>
<%- flag.values.each.with_index(COMMON_FLAGS) do |value, index| -%>
YP_<%= flag.human.upcase %>_<%= value.name %> = 1 << <%= index %>,
<%- end -%>
} yp_<%= flag.human %>_t;
Expand Down
8 changes: 8 additions & 0 deletions templates/java/org/yarp/Loader.java.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.yarp;

import java.lang.Short;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -207,6 +208,12 @@ public class Loader {
return x;
}

private short loadFlags() {
int flags = loadVarInt();
assert flags >= 0 && flags <= Short.MAX_VALUE;
return (short) flags;
}

private Nodes.Node loadNode() {
int type = buffer.get() & 0xFF;
int startOffset = loadVarInt();
Expand All @@ -229,6 +236,7 @@ public class Loader {
when LocationParam then "loadLocation()"
when OptionalLocationParam then "loadOptionalLocation()"
when UInt32Param then "loadVarInt()"
when FlagsParam then "loadFlags()"
else raise
end
}
Expand Down
Loading

0 comments on commit 8e764d1

Please sign in to comment.