summaryrefslogtreecommitdiff
path: root/prism_compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'prism_compile.c')
-rw-r--r--prism_compile.c84
1 files changed, 73 insertions, 11 deletions
diff --git a/prism_compile.c b/prism_compile.c
index 3aeb9d0e8e..08e2c4cc85 100644
--- a/prism_compile.c
+++ b/prism_compile.c
@@ -3443,19 +3443,83 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, const pm_line_c
dtype = DEFINED_FALSE;
break;
case PM_ARRAY_NODE: {
- const pm_array_node_t *cast = (const pm_array_node_t *) node;
+ const pm_array_node_t *cast = (const pm_array_node_t *) node;
- if (!PM_NODE_FLAG_P(cast, PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT)) {
- for (size_t index = 0; index < cast->elements.size; index++) {
- pm_compile_defined_expr0(iseq, cast->elements.nodes[index], node_location, ret, popped, scope_node, true, lfinish, false);
+ if (cast->elements.size > 0 && !lfinish[1]) {
+ lfinish[1] = NEW_LABEL(location.line);
+ }
- if (!lfinish[1]) {
- lfinish[1] = NEW_LABEL(location.line);
- }
+ for (size_t index = 0; index < cast->elements.size; index++) {
+ pm_compile_defined_expr0(iseq, cast->elements.nodes[index], node_location, ret, popped, scope_node, true, lfinish, false);
+ PUSH_INSNL(ret, location, branchunless, lfinish[1]);
+ }
+
+ dtype = DEFINED_EXPR;
+ break;
+ }
+ case PM_HASH_NODE:
+ case PM_KEYWORD_HASH_NODE: {
+ const pm_node_list_t *elements;
+
+ if (PM_NODE_TYPE_P(node, PM_HASH_NODE)) {
+ elements = &((const pm_hash_node_t *) node)->elements;
+ }
+ else {
+ elements = &((const pm_keyword_hash_node_t *) node)->elements;
+ }
+
+ if (elements->size > 0 && !lfinish[1]) {
+ lfinish[1] = NEW_LABEL(location.line);
+ }
+
+ for (size_t index = 0; index < elements->size; index++) {
+ const pm_node_t *element = elements->nodes[index];
- PUSH_INSNL(ret, location, branchunless, lfinish[1]);
+ switch (PM_NODE_TYPE(element)) {
+ case PM_ASSOC_NODE: {
+ const pm_assoc_node_t *assoc = (const pm_assoc_node_t *) element;
+
+ pm_compile_defined_expr0(iseq, assoc->key, node_location, ret, popped, scope_node, true, lfinish, false);
+ PUSH_INSNL(ret, location, branchunless, lfinish[1]);
+
+ pm_compile_defined_expr0(iseq, assoc->value, node_location, ret, popped, scope_node, true, lfinish, false);
+ PUSH_INSNL(ret, location, branchunless, lfinish[1]);
+
+ break;
}
- }
+ case PM_ASSOC_SPLAT_NODE: {
+ const pm_assoc_splat_node_t *assoc_splat = (const pm_assoc_splat_node_t *) element;
+
+ pm_compile_defined_expr0(iseq, assoc_splat->value, node_location, ret, popped, scope_node, true, lfinish, false);
+ PUSH_INSNL(ret, location, branchunless, lfinish[1]);
+
+ break;
+ }
+ default:
+ rb_bug("unexpected node type in hash node: %s", pm_node_type_to_str(PM_NODE_TYPE(element)));
+ break;
+ }
+ }
+
+ dtype = DEFINED_EXPR;
+ break;
+ }
+ case PM_SPLAT_NODE: {
+ const pm_splat_node_t *cast = (const pm_splat_node_t *) node;
+ pm_compile_defined_expr0(iseq, cast->expression, node_location, ret, popped, scope_node, in_condition, lfinish, false);
+
+ if (!lfinish[1]) {
+ lfinish[1] = NEW_LABEL(location.line);
+ }
+
+ PUSH_INSNL(ret, location, branchunless, lfinish[1]);
+ dtype = DEFINED_EXPR;
+ break;
+ }
+ case PM_IMPLICIT_NODE: {
+ const pm_implicit_node_t *cast = (const pm_implicit_node_t *) node;
+ pm_compile_defined_expr0(iseq, cast->value, node_location, ret, popped, scope_node, in_condition, lfinish, explicit_receiver);
+ return;
}
case PM_AND_NODE:
case PM_BEGIN_NODE:
@@ -3467,7 +3531,6 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, const pm_line_c
case PM_DEFINED_NODE:
case PM_FLOAT_NODE:
case PM_FOR_NODE:
- case PM_HASH_NODE:
case PM_IF_NODE:
case PM_IMAGINARY_NODE:
case PM_INTEGER_NODE:
@@ -3475,7 +3538,6 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, const pm_line_c
case PM_INTERPOLATED_STRING_NODE:
case PM_INTERPOLATED_SYMBOL_NODE:
case PM_INTERPOLATED_X_STRING_NODE:
- case PM_KEYWORD_HASH_NODE:
case PM_LAMBDA_NODE:
case PM_MATCH_PREDICATE_NODE:
case PM_MATCH_REQUIRED_NODE: