/* * Copyright (c) 2011 Jiri Svoboda * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file Run-time data representation. */ #ifndef RDATA_T_H_ #define RDATA_T_H_ #include "intmap_t.h" /** Boolean variable. */ typedef struct { bool_t value; } rdata_bool_t; /** Character variable. * * Sysel character type should be able to store arbitrarily (or at least * very) large character sets. */ typedef struct { bigint_t value; } rdata_char_t; /** Integer variable. * * Sysel int type should be able to store arbitrarily (or at least * very) large numbers. */ typedef struct { bigint_t value; } rdata_int_t; /** String variable */ typedef struct { const char *value; } rdata_string_t; /** Reference variable */ typedef struct { struct rdata_var *vref; } rdata_ref_t; /** Delegate variable * * A delegate variable points to a static or non-static symbol. If the * symbol is non static, @c obj points to the object the symbol * belongs to. */ typedef struct { /** Object or @c NULL if deleg. points to a static function. */ struct rdata_var *obj; /** Member symbol. */ struct stree_symbol *sym; } rdata_deleg_t; /** Enumerated type value. */ typedef struct { /** Enum member declaration */ struct stree_embr *value; } rdata_enum_t; /** Array variable */ typedef struct { /** Rank */ int rank; /** Extents (@c rank entries) */ int *extent; /** * Elements (extent[0] * extent[1] * ... extent[rank - 1] entries) * stored in lexicographical order. Each element is (rdata_var_t *). */ struct rdata_var **element; } rdata_array_t; /** Object variable */ typedef struct { /** Class of this object (symbol) */ struct stree_symbol *class_sym; /** @c sn_static if this is a static object (i.e. class object) */ statns_t static_obj; /** Map field name SID to field data */ intmap_t fields; /* of (rdata_var_t *) */ } rdata_object_t; /** Resource handle * * Binding to external data. This type can be used to refer to data used * by builtin functions (such as files). */ typedef struct { /** Only understood by the right builtin function. */ void *data; } rdata_resource_t; /** Symbol reference variable * * A symbol reference points to a program symbol. */ typedef struct { /** Program symbol. */ struct stree_symbol *sym; } rdata_symbol_t; typedef enum var_class { /** Boolean */ vc_bool, /** Character */ vc_char, /** Integer */ vc_int, /** String */ vc_string, /** Reference */ vc_ref, /** Delegate */ vc_deleg, /** Enumerated type value */ vc_enum, /** Array */ vc_array, /** Object */ vc_object, /** Interpreter builtin resource */ vc_resource, /** Symbol reference */ vc_symbol } var_class_t; /** Variable. * * A piece of memory holding one of the basic types of data element. * It is addressable (via rdata_var_t *) and mutable, at least from * internal point of view of the interpreter. */ typedef struct rdata_var { var_class_t vc; union { rdata_bool_t *bool_v; rdata_char_t *char_v; rdata_int_t *int_v; rdata_string_t *string_v; rdata_ref_t *ref_v; rdata_deleg_t *deleg_v; rdata_enum_t *enum_v; rdata_array_t *array_v; rdata_object_t *object_v; rdata_resource_t *resource_v; rdata_symbol_t *symbol_v; } u; } rdata_var_t; /** Address class */ typedef enum { /** Variable address */ ac_var, /** Property address */ ac_prop } address_class_t; /** Variable address */ typedef struct { /** Targeted variable */ rdata_var_t *vref; } rdata_addr_var_t; /** Named property address */ typedef struct { /** Delegate to the property */ rdata_deleg_t *prop_d; } rdata_aprop_named_t; /** Indexed property address */ typedef struct { /** Delegate to the object (or CSI) which is being indexed. */ rdata_deleg_t *object_d; /** Arguments (indices) */ list_t args; /* of rdata_item_t */ } rdata_aprop_indexed_t; typedef enum { /* Named property address */ apc_named, /* Indexed property address */ apc_indexed } aprop_class_t; /** Property address. * * When an access or index operation is performed on a property, the getter * is run and the prefetched value is stored in @c tvalue. If the property * is a non-scalar value type (a struct), then we might want to point to * the proper @c var node inside it. @c tpos is used for this purpose. * * The assignment operator will modify @c tvalue and at the end the setter * is called to store @c tvalue back into the property. */ typedef struct { aprop_class_t apc; /** Temporary copy of property value or @c NULL when not used. */ struct rdata_value *tvalue; /** * Points to the specific var node within @c tvalue that is addressed * or @c NULL when @c tvalue is not used. */ rdata_var_t *tpos; union { rdata_aprop_named_t *named; rdata_aprop_indexed_t *indexed; } u; } rdata_addr_prop_t; /** Address item */ typedef struct rdata_address { address_class_t ac; union { rdata_addr_var_t *var_a; rdata_addr_prop_t *prop_a; } u; } rdata_address_t; /** Value item. */ typedef struct rdata_value { /** * Read-only Variable holding a copy of the data. Currently we don't * allow sharing the same @c var node between different value nodes * so that when destroying the value we can destroy the var. * * We could share this, but would need to reference-count it. */ rdata_var_t *var; } rdata_value_t; typedef enum { /** Address of a variable. */ ic_address, /** Value */ ic_value } item_class_t; /** Data item. * * Data item is the result of evaluating an expression. An address expression * yields an address item (a.k.a. L-value), a value expression yields a data * item (a.k.a. R-value). This model is used to accomodate semantics of the * assignment operator. */ typedef struct rdata_item { item_class_t ic; union { rdata_address_t *address; rdata_value_t *value; } u; } rdata_item_t; #endif