(valstr): Replace member val_as.off by val_as.sym, which contains

offset and index.  This is for the new dumps; conditions can't use it,
yet.
(nstr_comp_val): Zero index.
(nstr_exec_val): Implement index.

(nstr_exec_val): Simplify coercion to WANT.
This commit is contained in:
Markus Armbruster 2004-08-20 12:21:04 +00:00
parent d1bf11a015
commit 612f2dadb8
2 changed files with 47 additions and 40 deletions

View file

@ -78,11 +78,12 @@ typedef unsigned char nsc_flags;
/* /*
* Value, possibly symbolic. * Value, possibly symbolic.
* If type is NSC_NOTYPE, it's an error value. * If type is NSC_NOTYPE, it's an error value.
* If category is NSC_OFF, the value is at offset val_as.off in the * If category is NSC_OFF, the value is in a context object at offset
* context object. * val_as.sym.off + val_as.sym.idx * S, where S is the size of the
* value.
* If category is NSC_VAL, the value is in val_as, and the type is a * If category is NSC_VAL, the value is in val_as, and the type is a
* promoted type. * promoted type.
* Some values can also be interpreted as an object type. The values * Some values can also be interpreted as an object type. The value's
* consumer chooses how to interpret it, depending on context. * consumer chooses how to interpret it, depending on context.
*/ */
struct valstr { struct valstr {
@ -90,8 +91,11 @@ struct valstr {
packed_nsc_cat val_cat; /* category of value */ packed_nsc_cat val_cat; /* category of value */
signed char val_as_type; /* value interpreted as object type */ signed char val_as_type; /* value interpreted as object type */
union { union {
ptrdiff_t off; /* cat NSC_OFF */ struct { /* cat NSC_OFF */
double dbl; /* cat NSC_VAL, types NSC_DOUBLE */ ptrdiff_t off;
int idx;
} sym;
double dbl; /* cat NSC_VAL, type NSC_DOUBLE */
char *str; /* cat NSC_VAL, type NSC_STRING */ char *str; /* cat NSC_VAL, type NSC_STRING */
long lng; /* cat NSC_VAL, type NSC_LONG */ long lng; /* cat NSC_VAL, type NSC_LONG */
} val_as; } val_as;

View file

@ -187,6 +187,8 @@ nstr_exec(struct nscstr *np, int ncond, void *ptr)
* Return a pointer to the first character after the value on success, * Return a pointer to the first character after the value on success,
* NULL on error. * NULL on error.
* TYPE is the context type, a file type. * TYPE is the context type, a file type.
* If STR names an array, VAL simply refers to the element with index
* zero.
*/ */
char * char *
nstr_comp_val(char *str, struct valstr*val, int type) nstr_comp_val(char *str, struct valstr*val, int type)
@ -232,7 +234,8 @@ nstr_comp_val(char *str, struct valstr*val, int type)
else { else {
val->val_type = cap[j].ca_type; val->val_type = cap[j].ca_type;
val->val_cat = NSC_OFF; val->val_cat = NSC_OFF;
val->val_as.off = cap[j].ca_off; val->val_as.sym.off = cap[j].ca_off;
val->val_as.sym.idx = 0;
} }
} }
} else } else
@ -391,8 +394,8 @@ nstr_coerce_val(struct valstr *val, nsc_type to, char *str)
* Use coordinate system of country CNUM. * Use coordinate system of country CNUM.
* PTR points to a context object of the type that was used to compile * PTR points to a context object of the type that was used to compile
* the value. * the value.
* If WANT is not zero, coerce the value to promoted value type WANT. * Unless WANT is NSC_NOTYPE, coerce the value to promoted value type
* VAL must be coercible. That's the case if a previous * WANT. VAL must be coercible. That's the case if a previous
* nstr_coerce_val(VAL, WANT, STR) succeeded. * nstr_coerce_val(VAL, WANT, STR) succeeded.
*/ */
void void
@ -400,6 +403,7 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want)
{ {
char *memb_ptr; char *memb_ptr;
nsc_type valtype = NSC_LONG; nsc_type valtype = NSC_LONG;
int idx;
switch (val->val_cat) { switch (val->val_cat) {
default: default:
@ -410,38 +414,39 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want)
break; break;
case NSC_OFF: case NSC_OFF:
memb_ptr = ptr; memb_ptr = ptr;
memb_ptr += val->val_as.off; memb_ptr += val->val_as.sym.off;
idx = val->val_as.sym.idx;
switch (val->val_type) { switch (val->val_type) {
case NSC_CHAR: case NSC_CHAR:
val->val_as.lng = *(signed char *)memb_ptr; val->val_as.lng = ((signed char *)memb_ptr)[idx];
break; break;
case NSC_UCHAR: case NSC_UCHAR:
val->val_as.lng = *(unsigned char *)memb_ptr; val->val_as.lng = ((unsigned char *)memb_ptr)[idx];
break; break;
case NSC_SHORT: case NSC_SHORT:
val->val_as.lng = *(short *)memb_ptr; val->val_as.lng = ((short *)memb_ptr)[idx];
break; break;
case NSC_USHORT: case NSC_USHORT:
val->val_as.lng = *(unsigned short *)memb_ptr; val->val_as.lng = ((unsigned short *)memb_ptr)[idx];
break; break;
case NSC_INT: case NSC_INT:
val->val_as.lng = *(int *)memb_ptr; val->val_as.lng = ((int *)memb_ptr)[idx];
break; break;
case NSC_LONG: case NSC_LONG:
val->val_as.lng = *(long *)memb_ptr; val->val_as.lng = ((long *)memb_ptr)[idx];
break; break;
case NSC_XCOORD: case NSC_XCOORD:
val->val_as.lng = xrel(getnatp(cnum), *(short *)memb_ptr); val->val_as.lng = xrel(getnatp(cnum), ((short *)memb_ptr)[idx]);
break; break;
case NSC_YCOORD: case NSC_YCOORD:
val->val_as.lng = yrel(getnatp(cnum), *(short *)memb_ptr); val->val_as.lng = yrel(getnatp(cnum), ((short *)memb_ptr)[idx]);
break; break;
case NSC_FLOAT: case NSC_FLOAT:
val->val_as.dbl = *(float *)memb_ptr; val->val_as.dbl = ((float *)memb_ptr)[idx];
valtype = NSC_DOUBLE; valtype = NSC_DOUBLE;
break; break;
case NSC_DOUBLE: case NSC_DOUBLE:
val->val_as.dbl = *(double *)memb_ptr; val->val_as.dbl = ((double *)memb_ptr)[idx];
valtype = NSC_DOUBLE; valtype = NSC_DOUBLE;
break; break;
case NSC_STRING: case NSC_STRING:
@ -449,10 +454,10 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want)
valtype = NSC_STRING; valtype = NSC_STRING;
break; break;
case NSC_TIME: case NSC_TIME:
val->val_as.lng = *(time_t *)memb_ptr; val->val_as.lng = ((time_t *)memb_ptr)[idx];
break; break;
case NSC_TYPEID: case NSC_TYPEID:
val->val_as.lng = *(signed char *)memb_ptr; val->val_as.lng = ((signed char *)memb_ptr)[idx];
valtype = NSC_TYPEID; valtype = NSC_TYPEID;
break; break;
default: default:
@ -461,26 +466,24 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want)
} }
} }
if (want) { if (valtype == want)
if (valtype == want) ;
; else if (want == NSC_DOUBLE) {
else if (want == NSC_DOUBLE) { if (valtype == NSC_LONG) {
if (valtype == NSC_LONG) {
valtype = want;
val->val_as.dbl = val->val_as.lng;
}
} else if (want == NSC_STRING)
CANT_HAPPEN("unimplemented WANT"); /* FIXME */
if (CANT_HAPPEN(valtype != want)) {
valtype = want; valtype = want;
switch (want) { val->val_as.dbl = val->val_as.lng;
case NSC_TYPEID: }
case NSC_LONG: val->val_as.lng = 0; break; } else if (want == NSC_STRING)
case NSC_DOUBLE: val->val_as.dbl = 0.0; break; CANT_HAPPEN("unimplemented WANT"); /* FIXME */
case NSC_STRING: val->val_as.str = ""; break; if (CANT_HAPPEN(valtype != want && want != NSC_NOTYPE)) {
default: valtype = want;
CANT_HAPPEN("bad WANT argument"); switch (want) {
} case NSC_TYPEID:
case NSC_LONG: val->val_as.lng = 0; break;
case NSC_DOUBLE: val->val_as.dbl = 0.0; break;
case NSC_STRING: val->val_as.str = ""; break;
default:
CANT_HAPPEN("bad WANT argument");
} }
} }