summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y97
1 files changed, 89 insertions, 8 deletions
diff --git a/parse.y b/parse.y
index 49094f92ef..3f783af352 100644
--- a/parse.y
+++ b/parse.y
@@ -35,19 +35,21 @@
#define ID_SCOPE_SHIFT 3
#define ID_SCOPE_MASK 0x07
-#define ID_LOCAL 0x01
-#define ID_INSTANCE 0x02
-#define ID_GLOBAL 0x03
-#define ID_ATTRSET 0x04
-#define ID_CONST 0x05
-#define ID_CLASS 0x06
-#define ID_JUNK 0x07
-#define ID_INTERNAL ID_JUNK
+#define ID_LOCAL 0x00
+#define ID_INSTANCE 0x01
+#define ID_INSTANCE2 0x02
+#define ID_GLOBAL 0x03
+#define ID_ATTRSET 0x04
+#define ID_CONST 0x05
+#define ID_CLASS 0x06
+#define ID_JUNK 0x07
+#define ID_INTERNAL ID_JUNK
#define is_notop_id(id) ((id)>tLAST_TOKEN)
#define is_local_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL)
#define is_global_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_GLOBAL)
#define is_instance_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE)
+#define is_instance2_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE2)
#define is_attrset_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_ATTRSET)
#define is_const_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CONST)
#define is_class_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CLASS)
@@ -7245,6 +7247,9 @@ gettable_gen(struct parser_params *parser, ID id)
else if (is_instance_id(id)) {
return NEW_IVAR(id);
}
+ else if (is_instance2_id(id)) {
+ return NEW_IVAR2(id);
+ }
else if (is_const_id(id)) {
return NEW_CONST(id);
}
@@ -7298,6 +7303,9 @@ assignable_gen(struct parser_params *parser, ID id, NODE *val)
else if (is_instance_id(id)) {
return NEW_IASGN(id, val);
}
+ else if (is_instance2_id(id)) {
+ return NEW_IASGN2(id, val);
+ }
else if (is_const_id(id)) {
if (in_def || in_single)
yyerror("dynamic constant assignment");
@@ -7432,6 +7440,7 @@ node_assign_gen(struct parser_params *parser, NODE *lhs, NODE *rhs)
switch (nd_type(lhs)) {
case NODE_GASGN:
case NODE_IASGN:
+ case NODE_IASGN2:
case NODE_LASGN:
case NODE_DASGN:
case NODE_DASGN_CURR:
@@ -8319,6 +8328,8 @@ static struct symbols {
ID last_id;
st_table *sym_id;
st_table *id_str;
+ st_table *ivar2_id;
+ st_table *id_ivar2;
VALUE op_sym[tLAST_TOKEN];
} global_symbols = {tLAST_TOKEN};
@@ -8327,11 +8338,38 @@ static struct st_hash_type symhash = {
rb_str_hash,
};
+struct ivar2_key {
+ ID id;
+ VALUE klass;
+};
+
+static int
+ivar2_cmp(struct ivar2_key *key1, struct ivar2_key *key2)
+{
+ if (key1->id == key2->id && key1->klass == key2->klass) {
+ return 0;
+ }
+ return 1;
+}
+
+static int
+ivar2_hash(struct ivar2_key *key)
+{
+ return (key->id << 8) ^ (key->klass >> 2);
+}
+
+static struct st_hash_type ivar2_hash_type = {
+ ivar2_cmp,
+ ivar2_hash,
+};
+
void
Init_sym(void)
{
global_symbols.sym_id = st_init_table_with_size(&symhash, 1000);
global_symbols.id_str = st_init_numtable_with_size(1000);
+ global_symbols.ivar2_id = st_init_table_with_size(&ivar2_hash_type, 1000);
+ global_symbols.id_ivar2 = st_init_numtable_with_size(1000);
}
void
@@ -8466,6 +8504,9 @@ rb_intern2(const char *name, long len)
m++;
id |= ID_CLASS;
}
+ else if (name[1] == '_') {
+ id |= ID_INSTANCE2;
+ }
else {
id |= ID_INSTANCE;
}
@@ -8527,6 +8568,39 @@ rb_intern(const char *name)
return rb_intern2(name, strlen(name));
}
+ID
+rb_compose_ivar2(ID oid, VALUE klass)
+{
+ struct ivar2_key key, *kp;
+ ID id;
+
+ key.id = oid;
+ key.klass = klass;
+ if (st_lookup(global_symbols.ivar2_id, (st_data_t)&key, (st_data_t *)&id))
+ return id;
+
+ kp = ALLOC_N(struct ivar2_key, 1);
+ kp->id = oid; kp->klass = klass;
+ id = ID_INSTANCE2;
+ id |= ++global_symbols.last_id << ID_SCOPE_SHIFT;
+ st_add_direct(global_symbols.ivar2_id, (st_data_t)kp, (st_data_t)id);
+ st_add_direct(global_symbols.id_ivar2, (st_data_t)id, (st_data_t)kp);
+ return id;
+}
+
+ID
+rb_decompose_ivar2(ID id, VALUE *klassp)
+{
+ struct ivar2_key *kp;
+ ID oid;
+
+ if (!st_lookup(global_symbols.id_ivar2, (st_data_t)id, (st_data_t *)&kp)) {
+ return id;
+ }
+ if (klassp) *klassp = kp->klass;
+ return kp->id;
+}
+
VALUE
rb_id2str(ID id)
{
@@ -8636,6 +8710,13 @@ rb_is_instance_id(ID id)
}
int
+rb_is_instance2_id(ID id)
+{
+ if (is_instance2_id(id)) return Qtrue;
+ return Qfalse;
+}
+
+int
rb_is_local_id(ID id)
{
if (is_local_id(id)) return Qtrue;