/*
* 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