NAME ^

src/key.c - Base vtable calling functions

DESCRIPTION ^

The base vtable calling functions.

Functions ^

*/

#include "parrot/parrot.h" #include "parrot/key.h"

/* HEADERIZER HFILE: include/parrot/key.h */

/*

FUNCDOC: key_new Returns a new Key PMC.

*/

PARROT_API PARROT_CANNOT_RETURN_NULL PARROT_WARN_UNUSED_RESULT PMC * key_new(PARROT_INTERP) { PMC * const key = pmc_new(interp, enum_class_Key);

    return key;
}

/*

FUNCDOC: key_new_integer Returns a new integer Key PMC with value value.

*/

PARROT_API PARROT_CANNOT_RETURN_NULL PARROT_WARN_UNUSED_RESULT PMC * key_new_integer(PARROT_INTERP, INTVAL value) { PMC * const key = pmc_new(interp, enum_class_Key);

    PObj_get_FLAGS(key) |= KEY_integer_FLAG;
    PMC_int_val(key) = value;

    return key;
}

/*

FUNCDOC: key_new_number Returns a new number Key PMC with value value.

*/

PARROT_API PARROT_CANNOT_RETURN_NULL PARROT_WARN_UNUSED_RESULT PMC * key_new_number(PARROT_INTERP, FLOATVAL value) { PMC * const key = pmc_new(interp, enum_class_Key);

    PObj_get_FLAGS(key) |= KEY_number_FLAG;
    PMC_num_val(key) = value;

    return key;
}

/*

FUNCDOC: key_new_string Returns a new string Key PMC with value value.

*/

PARROT_API PARROT_CANNOT_RETURN_NULL PARROT_WARN_UNUSED_RESULT PMC * key_new_string(PARROT_INTERP, NOTNULL(STRING *value)) { PMC * const key = pmc_new(interp, enum_class_Key);

    PObj_get_FLAGS(key) |= KEY_string_FLAG;
    PMC_str_val(key) = value;

    return key;
}

/*

FUNCDOC: key_new_cstring Returns a new string Key PMC with value value converted to a STRING.

*/

PARROT_API PARROT_CANNOT_RETURN_NULL PARROT_WARN_UNUSED_RESULT PMC * key_new_cstring(PARROT_INTERP, NULLOK(const char *value)) { return key_new_string(interp, string_from_cstring(interp, value, 0)); }

/*

FUNCDOC: key_new_pmc Returns a new PMC Key PMC with value value.

*/

PARROT_API PARROT_CANNOT_RETURN_NULL PARROT_WARN_UNUSED_RESULT PMC * key_new_pmc(PARROT_INTERP, NOTNULL(PMC *value)) { PMC * const key = pmc_new(interp, enum_class_Key);

    PObj_get_FLAGS(key) |= KEY_pmc_FLAG;
    real_exception(interp, NULL, 1, "this is broken - see slice.pmc");
    PMC_pmc_val(key) = value;

    return key;
}

/*

FUNCDOC: key_set_integer Set the integer value in key.

*/

PARROT_API void key_set_integer(SHIM_INTERP, NOTNULL(PMC *key), INTVAL value) { PObj_get_FLAGS(key) &= ~KEY_type_FLAGS; PObj_get_FLAGS(key) |= KEY_integer_FLAG; PMC_int_val(key) = value;

    return;
}

/*

FUNCDOC: key_set_register Set the register value in key.

*/

PARROT_API void key_set_register(SHIM_INTERP, NOTNULL(PMC *key), INTVAL value, INTVAL flag) { PObj_get_FLAGS(key) &= ~KEY_type_FLAGS; PObj_get_FLAGS(key) |= KEY_register_FLAG | flag; PMC_int_val(key) = value;

    return;
}

/*

FUNCDOC: key_set_number Set the number value in key.

*/

PARROT_API void key_set_number(SHIM_INTERP, NOTNULL(PMC *key), FLOATVAL value) { PObj_get_FLAGS(key) &= ~KEY_type_FLAGS; PObj_get_FLAGS(key) |= KEY_number_FLAG; PMC_num_val(key) = value;

    return;
}

/*

FUNCDOC: key_set_string Set the string value in key.

*/

PARROT_API void key_set_string(SHIM_INTERP, NOTNULL(PMC *key), NOTNULL(STRING *value)) { PObj_get_FLAGS(key) &= ~KEY_type_FLAGS; PObj_get_FLAGS(key) |= KEY_string_FLAG; PMC_str_val(key) = value;

    return;
}

/*

FUNCDOC: key_set_pmc Set the PMC value in key.

*/

PARROT_API void key_set_pmc(PARROT_INTERP, NOTNULL(PMC *key), NOTNULL(PMC *value)) { PObj_get_FLAGS(key) &= ~KEY_type_FLAGS; PObj_get_FLAGS(key) |= KEY_pmc_FLAG; /* * XXX leo * what for is this indirection? */ real_exception(interp, NULL, 1, "this is broken - see slice.pmc"); PMC_pmc_val(key) = value;

    return;
}

/*

FUNCDOC: key_type Returns the type of key.

*/

PARROT_API PARROT_WARN_UNUSED_RESULT INTVAL key_type(SHIM_INTERP, NOTNULL(const PMC *key)) { return (PObj_get_FLAGS(key) & KEY_type_FLAGS) & ~KEY_register_FLAG; }

PARROT_API PARROT_WARN_UNUSED_RESULT INTVAL key_integer(PARROT_INTERP, NOTNULL(PMC *key)) { switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) { case KEY_hash_iterator_FLAGS: case KEY_integer_FLAG: return PMC_int_val(key); case KEY_integer_FLAG | KEY_register_FLAG: return REG_INT(interp, PMC_int_val(key)); case KEY_pmc_FLAG | KEY_register_FLAG: { PMC * const reg = REG_PMC(interp, PMC_int_val(key)); return VTABLE_get_integer(interp, reg); } case KEY_string_FLAG: return string_to_int(interp, PMC_str_val(key)); case KEY_string_FLAG | KEY_register_FLAG: { STRING * const s_reg = REG_STR(interp, PMC_int_val(key)); return string_to_int(interp, s_reg); } default: /* TODO check for slice_FLAGs */ return VTABLE_get_integer(interp, key); } }

PARROT_API PARROT_WARN_UNUSED_RESULT FLOATVAL key_number(PARROT_INTERP, NOTNULL(PMC *key)) { switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) { case KEY_number_FLAG: return PMC_num_val(key); case KEY_number_FLAG | KEY_register_FLAG: return REG_NUM(interp, PMC_int_val(key)); case KEY_pmc_FLAG: return VTABLE_get_number(interp, key); /* PMC_pmc_val(key)); */ case KEY_pmc_FLAG | KEY_register_FLAG: { PMC * const reg = REG_PMC(interp, PMC_int_val(key)); return VTABLE_get_number(interp, reg); } default: real_exception(interp, NULL, INVALID_OPERATION, "Key not a number!\n"); return (FLOATVAL)0; } }

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL STRING * key_string(PARROT_INTERP, NOTNULL(PMC *key)) { switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) { case KEY_string_FLAG: return PMC_str_val(key); case KEY_string_FLAG | KEY_register_FLAG: return REG_STR(interp, PMC_int_val(key)); /* PMC_pmc_val(key)); */ case KEY_pmc_FLAG | KEY_register_FLAG: { PMC * const reg = REG_PMC(interp, PMC_int_val(key)); return VTABLE_get_string(interp, reg); } case KEY_integer_FLAG: return string_from_int(interp, PMC_int_val(key)); case KEY_integer_FLAG | KEY_register_FLAG: return string_from_int(interp, REG_INT(interp, PMC_int_val(key))); default: case KEY_pmc_FLAG: return VTABLE_get_string(interp, key); } }

/*

FUNCDOC: key_pmc These functions return the integer/number/string/PMC values of key if possible. Otherwise they throws an exceptions.

*/

PARROT_API PARROT_CANNOT_RETURN_NULL PARROT_WARN_UNUSED_RESULT PMC * key_pmc(PARROT_INTERP, NOTNULL(PMC *key)) { switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) { case KEY_pmc_FLAG | KEY_register_FLAG: return REG_PMC(interp, PMC_int_val(key)); default: return key; /* PMC_pmc_val(key); */ } }

/*

FUNCDOC: key_next Returns the next key if key is in a sequence of linked keys.

*/

PARROT_API PARROT_CAN_RETURN_NULL PARROT_WARN_UNUSED_RESULT PMC * key_next(SHIM_INTERP, NOTNULL(PMC *key)) { return key->pmc_ext ? (PMC *)PMC_data(key) : NULL; }

/*

FUNCDOC: key_append Appends key2 to key1.

Note that if key1 is not the last key in a sequence linked keys then the last key will be found and key2 appended to that.

Returns key1.

*/

PARROT_API PARROT_CANNOT_RETURN_NULL PARROT_IGNORABLE_RESULT PMC * key_append(SHIM_INTERP, NOTNULL(PMC *key1), NOTNULL(PMC *key2)) { PMC *tail = key1;

    while (PMC_data(tail)) {
        tail = (PMC *)PMC_data(tail);
    }

    PMC_data(tail) = key2;

    return key1;
}

/*

FUNCDOC: key_mark Marks key as live.

*/

PARROT_API void key_mark(PARROT_INTERP, NOTNULL(PMC *key)) { const UINTVAL flags = PObj_get_FLAGS(key) & KEY_type_FLAGS;

    if (flags == KEY_string_FLAG)
        pobject_lives(interp, (PObj *)PMC_str_val(key));
    /*
     * KEY_hash_iterator_FLAGS denote a hash key iteration, PMC_data() is
     * the bucket_index and not the next key component
     */
    if (flags == KEY_hash_iterator_FLAGS)
        return;

    /* if iteration hasn't started, above flag isn't set yet */
    if (PMC_data(key) && PMC_data(key) != (void *)INITBucketIndex)
        pobject_lives(interp, (PObj *)PMC_data(key));

}

PARROT_API PARROT_CANNOT_RETURN_NULL PARROT_WARN_UNUSED_RESULT STRING * key_set_to_string(PARROT_INTERP, NULLOK(PMC *key)) { STRING * const semicolon = string_from_cstring(interp, " ; ", 3); STRING * const quote = string_from_cstring(interp, "'", 1); STRING *value = string_from_cstring(interp, "[ ", 2);

    for (; key; key = (PMC *)PMC_data(key)) {
        switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
            case KEY_integer_FLAG:
                value = string_append(interp, value, string_from_int(interp, PMC_int_val(key)));
                break;
            case KEY_string_FLAG:
                value = string_append(interp, value, quote);
                value = string_append(interp, value, PMC_str_val(key));
                value = string_append(interp, value, quote);
                break;
            case KEY_pmc_FLAG:
                value = string_append(interp, value, VTABLE_get_string(interp, key));
                break;
            case KEY_integer_FLAG | KEY_register_FLAG:
                value = string_append(interp, value, string_from_int(interp, REG_INT(interp, PMC_int_val(key))));
                break;
            case KEY_string_FLAG | KEY_register_FLAG:
                value = string_append(interp, value, quote);
                value = string_append(interp, value, REG_STR(interp, PMC_int_val(key)));
                value = string_append(interp, value, quote);
                break;
            case KEY_pmc_FLAG | KEY_register_FLAG:
                {
                PMC * const reg = REG_PMC(interp, PMC_int_val(key));
                value = string_append(interp, value, VTABLE_get_string(interp, reg));
                }
                break;
            default:
                value = string_append(interp, value, string_from_literal(interp, "Key type unknown"));
                break;
        }

        if (PMC_data(key))
            value = string_append(interp, value, semicolon);
    }
    value = string_append(interp, value, string_from_cstring(interp, " ]", 2));
    return value;
}

/*

SEE ALSO ^

include/parrot/key.h.

HISTORY ^

Initial version by Jeff G. on 2001.12.05.

*/

/* * Local variables: * c-file-style: "parrot" * End: * vim: expandtab shiftwidth=4: */


parrot