int16_t corto_value_field( corto_value *val, const char* field_expr, corto_value *out) { corto_type t = corto_value_typeof(val); corto_object o = corto_value_objectof(val); void *ptr = corto_value_ptrof(val); corto_field field = {0}; ut_try(corto_field_lookup(field_expr, t, ptr, &field), NULL); if (field.index != -1) { *out = corto_value_element(o, field.type, field.index, field.ptr); } else if (!field.member && !field.is_super) { if (o == ptr) { *out = corto_value_base(field.ptr, field.type); } else { /* super member of a nested sub-struct */ *out = corto_value_pointer(field.ptr, field.type); } } else { if (field.is_super) { *out = corto_value_base(field.ptr, field.type); } else { *out = corto_value_member(o, field.member, field.ptr); } } return 0; error: return -1; }
corto_int16 corto_value_memberExpr(corto_value *val, corto_string member, corto_value *out) { corto_type t = corto_value_typeof(val); corto_object o = corto_value_objectof(val); void *ptr = corto_value_ptrof(val); corto_id tokens; strncpy(tokens, member, sizeof(corto_id)); char *cur = tokens, *prev = tokens; do { if (cur && (cur = strchr(cur + 1, '.'))) *cur = '\0'; if (!corto_instanceof(corto_interface_o, t)) { corto_seterr( "cannot get member from a non-composite value (type is '%s')", corto_fullpath(NULL, t)); goto error; } if (!strcmp(prev, "super")) { if (!(t = (corto_type)corto_interface(t)->base)) { corto_seterr("super unpexpected: interface '%s' does not have a base", corto_fullpath(NULL, t)); goto error; } else { *out = corto_value_base(ptr, t); } } else { corto_member m = corto_interface_resolveMember(t, prev); if (!m) { corto_seterr( "unresolved member '%s' in type '%s'", prev, corto_fullpath(NULL, t)); goto error; } ptr = CORTO_OFFSET(ptr, m->offset); t = m->type; *out = corto_value_member(o, m, ptr); } prev = cur + 1; } while (cur); return 0; error: return -1; }