[DGD] lwo->variable

pete at ana.sk pete at ana.sk
Mon Apr 29 14:16:26 CEST 2002


Hi ppl

If anyone is insterested, or anyone wants to looks if 
it is well done, i made me a patch to driver to allow 
direct indexing of lwo non-static variables with 
[string_expression] index, and also added 
->identifier indexing for lwo (and as side effect for 
mapping too). So lwo["var"] is same as lwo->var, it 
can be used to get or set lwo variable in same way 
as mapping or array member.
Not sure if it is absolutely correct but it is working 
well for me. Patch is in attachment.  

Pete


-------------- next part --------------
diff -urN dgd/src/array.c dgd-lwo_var_idx/src/array.c
--- dgd/src/array.c	Mon Apr 29 13:42:04 2002
+++ dgd-lwo_var_idx/src/array.c	Mon Apr 29 13:54:26 2002
@@ -2333,3 +2333,48 @@
     d_ref_imports(copy);
     return copy;
 }
+
+/*
+ * NAME:	lwobject->index()
+ * DESCRIPTION:	index a lwobject
+ */
+unsigned short lwo_index(a, s)
+register array *a;
+register string *s;
+{
+    register unsigned short i, j, nvars;
+    register control *ctrl;
+    register dvardef *v;
+    register dinherit *inh;
+    register string *str;
+    
+    if(s->len == 0)
+	error("Invalid lwobject index");
+    
+    ctrl = o_control(OBJR(d_get_elts(a)[0].oindex));
+    
+    for(nvars = 0, i = ctrl->ninherits, inh = ctrl->inherits; i > 0; i--, inh++)
+	if(inh->varoffset == nvars)
+	{
+	    ctrl = o_control(OBJR(inh->oindex));
+	    if(inh->priv)
+	    {
+		nvars += ctrl->nvardefs;
+		continue;
+	    }
+	    for(j = ctrl->nvardefs, v = d_get_vardefs(ctrl); j > 0; j--, v++)
+	    {
+		if(!(v->class & C_STATIC))
+		{
+		    str = d_get_strconst(ctrl, v->inherit, v->index);
+		    if(str->len == s->len && !memcmp(str->text, s->text, str->len))
+			return nvars + 2;
+		}
+		nvars++;
+	    }
+	}
+    
+    error("Invalid lwobject index");
+    
+    return -1;
+}
diff -urN dgd/src/array.h dgd-lwo_var_idx/src/array.h
--- dgd/src/array.h	Mon Apr 29 13:42:04 2002
+++ dgd-lwo_var_idx/src/array.h	Mon Apr 29 13:55:15 2002
@@ -52,3 +52,4 @@
 
 extern array	       *lwo_new		P((dataspace*, object*));
 extern array	       *lwo_copy	P((dataspace*, array*));
+extern unsigned short	lwo_index	P((array*, string*));
diff -urN dgd/src/comp/parser.y dgd-lwo_var_idx/src/comp/parser.y
--- dgd/src/comp/parser.y	Mon Apr 29 13:42:04 2002
+++ dgd-lwo_var_idx/src/comp/parser.y	Mon Apr 29 13:45:27 2002
@@ -33,6 +33,7 @@
 static node *uassign	P((int, node*, char*));
 static node *cast	P((node*, unsigned int));
 static node *idx	P((node*, node*));
+static node *arrow_idx	P((node*, node*));
 static node *range	P((node*, node*, node*));
 static node *bini	P((int, node*, node*, char*));
 static node *bina	P((int, node*, node*, char*));
@@ -542,6 +543,8 @@
 		{ $$ = idx($1, $3); }
 	| primary_p2_exp '[' f_opt_list_exp DOT_DOT f_opt_list_exp ']'
 		{ $$ = range($1, $3, $5); }
+	| primary_p2_exp ARROW ident
+		{ $$ = arrow_idx($1, $3); }
 	;
 
 postfix_exp
@@ -1009,11 +1012,29 @@
 	}
 	type = T_INT;
     } else {
-	if (typechecking && n1->mod != T_MAPPING && n1->mod != T_MIXED) {
+	if (typechecking && n1->mod != T_MAPPING && n1->mod != T_OBJECT && n1->mod != T_MIXED) {
 	    c_error("bad indexed type (%s)", i_typename(tnbuf, n1->mod));
 	}
 	type = T_MIXED;
     }
+    return node_bin(N_INDEX, type, n1, n2);
+}
+
+/*
+ * NAME:	arrow_idx()
+ * DESCRIPTION:	handle the -> operator (not function all)
+ */
+static node *arrow_idx(n1, n2)
+register node *n1, *n2;
+{
+    char tnbuf[17];
+    register unsigned short type;
+    
+    if (typechecking && n1->mod != T_MAPPING && n1->mod != T_OBJECT && n1->mod != T_MIXED) {
+	c_error("bad indexed type (%s)", i_typename(tnbuf, n1->mod));
+    }
+    type = T_MIXED;
+    
     return node_bin(N_INDEX, type, n1, n2);
 }
 
diff -urN dgd/src/interpret.c dgd-lwo_var_idx/src/interpret.c
--- dgd/src/interpret.c	Mon Apr 29 13:42:04 2002
+++ dgd-lwo_var_idx/src/interpret.c	Mon Apr 29 13:58:24 2002
@@ -620,6 +620,19 @@
 	i_del_value(ival);
 	break;
 
+    case T_LWOBJECT:
+	if (ival->type != T_STRING) {
+	    i_del_value(ival);
+	    error("Non-string lwobject index");
+	}
+	val = d_get_elts(aval->u.array);
+	if(DESTRUCTED(val))
+	    val = &nil_value;
+	else
+	    val = &val[lwo_index(aval->u.array, ival->u.string)];
+	i_del_value(ival);
+	break;
+
     default:
 	i_del_value(ival);
 	error("Index on bad type");
@@ -691,6 +704,19 @@
 	*f->lip++ = *ival;
 	return;
 
+    case T_LWOBJECT:
+	if (ival->type != T_STRING) {
+	    i_del_value(ival);
+	    error("Non-string lwobject index");
+	}
+	i = lwo_index(lval->u.array, ival->u.string);
+	lval->type = T_ALVALUE;
+	lval->oindex = vtype;
+	f->lip->type = T_INT;
+	(f->lip++)->u.number = i;
+	i_del_value(ival);
+	return;
+
     case T_LVALUE:
 	/*
 	 * note: the lvalue is not yet referenced
@@ -729,6 +755,20 @@
 	    arr_ref(lval->u.array = lval->u.lval->u.array);
 	    *f->lip++ = *ival;
 	    return;
+
+	case T_LWOBJECT:
+	    if (ival->type != T_STRING) {
+		i_del_value(ival);
+		error("Non-string lwobject index");
+	    }
+	    i = lwo_index(lval->u.lval->u.array, ival->u.string);
+	    lval->type = T_ALVALUE;
+	    lval->oindex = vtype;
+	    arr_ref(lval->u.array = lval->u.lval->u.array);
+	    f->lip->type = T_INT;
+	    (f->lip++)->u.number = i;
+	    i_del_value(ival);
+	    return;
 	}
 	break;
 
@@ -768,6 +808,20 @@
 	    lval->u.array = val->u.array;
 	    f->lip[-1] = *ival;
 	    return;
+
+	case T_LWOBJECT:
+	    if (ival->type != T_STRING) {
+		i_del_value(ival);
+		error("Non-string lwobject index");
+	    }
+	    i = lwo_index(val->u.array, ival->u.string);
+	    arr_ref(val->u.array);	/* has to be first */
+	    arr_del(lval->u.array);	/* has to be second */
+	    lval->oindex = vtype;
+	    lval->u.array = val->u.array;
+	    f->lip[-1].u.number = i;
+	    i_del_value(ival);
+	    return;
 	}
 	break;
 
@@ -809,6 +863,23 @@
 	    lval->u.array = val->u.array;
 	    i_del_value(&f->lip[-1]);
 	    f->lip[-1] = *ival;
+	    return;
+
+	case T_LWOBJECT:
+	    if (ival->type != T_STRING) {
+		i_del_value(ival);
+		error("Non-string lwobject index");
+	    }
+	    i = lwo_index(val->u.array, ival->u.string);
+	    arr_ref(val->u.array);	/* has to be first */
+	    arr_del(lval->u.array);	/* has to be second */
+	    lval->type = T_ALVALUE;
+	    lval->oindex = vtype;
+	    lval->u.array = val->u.array;
+	    i_del_value(&f->lip[-1]);
+	    f->lip[-1].type = T_INT;
+	    f->lip[-1].u.number = i;
+	    i_del_value(ival);
 	    return;
 	}
 	break;


More information about the DGD mailing list