static csi_status_t
_init_dictionaries (csi_t *ctx)
{
    csi_status_t status;
    csi_stack_t *stack;
    csi_object_t obj;
    csi_dictionary_t *dict, *opcodes;
    const csi_operator_def_t *odef;
    const csi_integer_constant_def_t *idef;
    const csi_real_constant_def_t *rdef;
    unsigned n;

    stack = &ctx->dstack;

    status = _csi_stack_init (ctx, stack, 4);
    if (_csi_unlikely (status))
	return status;

    /* systemdict */
    status = csi_dictionary_new (ctx, &obj);
    if (_csi_unlikely (status))
	return status;

    status = _csi_stack_push (ctx, stack, &obj);
    if (_csi_unlikely (status))
	return status;

    dict = obj.datum.dictionary;

    status = csi_dictionary_new (ctx, &obj);
    if (_csi_unlikely (status))
	return status;

    opcodes = obj.datum.dictionary;

    n = 0;
    csi_integer_new (&obj, n);
    status = csi_dictionary_put (ctx, opcodes, 0, &obj);
    if (_csi_unlikely (status))
	return status;
    ctx->opcode[n++] = NULL;

    /* fill systemdict with operators */
    for (odef = _csi_operators (); odef->name != NULL; odef++) {
	status = _add_operator (ctx, dict, odef);
	if (_csi_unlikely (status))
	    return status;

	if (! csi_dictionary_has (opcodes, (csi_name_t) odef->op)) {
	    csi_integer_new (&obj, n);
	    status = csi_dictionary_put (ctx,
		                         opcodes, (csi_name_t) odef->op, &obj);
	    if (_csi_unlikely (status))
		return status;

	    assert (n < sizeof (ctx->opcode) / sizeof (ctx->opcode[0]));
	    ctx->opcode[n++] = odef->op;
	}
    }
    csi_dictionary_free (ctx, opcodes);

    /* add constants */
    for (idef = _csi_integer_constants (); idef->name != NULL; idef++) {
	status = _add_integer_constant (ctx, dict, idef);
	if (_csi_unlikely (status))
	    return status;
    }
    for (rdef = _csi_real_constants (); rdef->name != NULL; rdef++) {
	status = _add_real_constant (ctx, dict, rdef);
	if (_csi_unlikely (status))
	    return status;
    }

    /* and seal */
    //dict.type &= ~CSI_OBJECT_ATTR_WRITABLE;


    /* globaldict */
    status = csi_dictionary_new (ctx, &obj);
    if (_csi_unlikely (status))
	return status;
    status = _csi_stack_push (ctx, stack, &obj);
    if (_csi_unlikely (status))
	return status;

    /* userdict */
    status = csi_dictionary_new (ctx, &obj);
    if (_csi_unlikely (status))
	return status;
    status = _csi_stack_push (ctx, stack, &obj);
    if (_csi_unlikely (status))
	return status;

    return CSI_STATUS_SUCCESS;
}
static csi_status_t
_init_dictionaries (csi_t *ctx)
{
    csi_status_t status;
    csi_stack_t *stack;
    csi_object_t obj;
    csi_dictionary_t *dict;
    const csi_operator_def_t *odef;
    const csi_integer_constant_def_t *idef;
    const csi_real_constant_def_t *rdef;

    stack = &ctx->dstack;

    status = _csi_stack_init (ctx, stack, 4);
    if (_csi_unlikely (status))
	return status;

    /* systemdict */
    status = csi_dictionary_new (ctx, &obj);
    if (_csi_unlikely (status))
	return status;

    status = _csi_stack_push (ctx, stack, &obj);
    if (_csi_unlikely (status))
	return status;

    dict = obj.datum.dictionary;

    /* fill systemdict with operators */
    for (odef = _csi_operators (); odef->name != NULL; odef++) {
	status = _add_operator (ctx, dict, odef);
	if (_csi_unlikely (status))
	    return status;
    }

    /* add constants */
    for (idef = _csi_integer_constants (); idef->name != NULL; idef++) {
	status = _add_integer_constant (ctx, dict, idef);
	if (_csi_unlikely (status))
	    return status;
    }
    for (rdef = _csi_real_constants (); rdef->name != NULL; rdef++) {
	status = _add_real_constant (ctx, dict, rdef);
	if (_csi_unlikely (status))
	    return status;
    }

    /* and seal */
    //dict.type &= ~CSI_OBJECT_ATTR_WRITABLE;


    /* globaldict */
    status = csi_dictionary_new (ctx, &obj);
    if (_csi_unlikely (status))
	return status;
    status = _csi_stack_push (ctx, stack, &obj);
    if (_csi_unlikely (status))
	return status;

    /* userdict */
    status = csi_dictionary_new (ctx, &obj);
    if (_csi_unlikely (status))
	return status;
    status = _csi_stack_push (ctx, stack, &obj);
    if (_csi_unlikely (status))
	return status;

    return CSI_STATUS_SUCCESS;
}