#ifndef __NLL_VALUE_H_INCLUDED__
#define __NLL_VALUE_H_INCLUDED__

typedef enum {
  VALUE_TYPE_UNDEFINED = 0,
  VALUE_TYPE_NULL,
  VALUE_TYPE_VALUE,
  VALUE_TYPE_VECTOR,
  VALUE_TYPE_INTEGER,
  VALUE_TYPE_STRING,
#ifdef NLL_FLOATING_POINT
  VALUE_TYPE_FLOAT,
#endif
  VALUE_TYPE_ARRAY,
  VALUE_TYPE_AREA,
  VALUE_TYPE_POINTER,
  VALUE_TYPE_FUNCTION,
  VALUE_TYPE_LABEL,

  VALUE_TYPE_NUM
} value_type_t;

struct value {
  struct value *next;
  value_type_t type;
  int refcount;
  int procid;
  unsigned int flags;
#define VALUE_FLAG_CONST  (1 <<  0)
#define VALUE_FLAG_RDONLY (1 <<  1)
#define VALUE_FLAG_STATIC (1 <<  2)
  union {
    value_t value;
    integer_t integer;
    string_t string;
#ifdef NLL_FLOATING_POINT
    double floating;
#endif
    struct {
      array_t a;
      int offset;
    } array;
    area_t area;
    struct {
      value_t point;
      int offset;
    } pointer;
    function_t function;
    label_t label;
  } val;
};

int value_check(void);
int value_alloc(value_t *valuep);
int value_free(value_t value);
int value_init(void);
int value_done(void);
int value_clear(value_t value);
int value_typecode(value_t value);
const char *value_typename_string(value_type_t type);
const char *value_typename(value_t value);
int value_is_true(value_t value);
value_t value_entity(value_t value);
int value_insert_value(value_t *valuep);
int value_extend_value(value_t *valuep);
int value_shrink_value(value_t *valuep);
int value_match_values(value_t *valuep, int num);
int value_cmp_value(value_t value0, value_t value1);
int value_cmp_values(value_t value0, value_t value1);
int value_copy_value(value_t dvalue, value_t svalue);
int value_copy_values(value_t *dvaluep, value_t svalue);
int value_copy_values_novector(value_t *dvaluep, value_t svalue);
value_type_t value_get_type(value_t value);
unsigned int value_get_flags(value_t value);
int value_set_flags(value_t value, unsigned int flags);
int value_reset_flags(value_t value, unsigned int flags);
int value_size(value_t value);
int value_is_same(value_t value0, value_t value1);
int value_chain_to_vector(value_t *valuep);
int value_vector_to_chain(value_t *valuep);
int value_value_to_vector(value_t value);
int value_vector_to_value(value_t value);
int value_set_next(value_t value, value_t _value);
int value_set_null(value_t value);
int value_get_value(value_t value, value_t *valuep);
int value_set_value(value_t value, value_t _value);
int value_set_values(value_t value, value_t _value);
int value_get_vector(value_t value, value_t *valuep);
int value_set_vector(value_t value, value_t _value);
int value_get_integer(value_t value, integer_t *integerp);
int value_set_integer(value_t value, integer_t integer);
int value_get_string(value_t value, char **stringp, int *lengthp);
int value_set_string(value_t value, const char *string, int length);
#ifdef NLL_FLOATING_POINT
int value_get_float(value_t value, double *floatingp);
int value_set_float(value_t value, double floating);
#endif
int value_get_array(value_t value, array_t *arrayp, int *offsetp);
int value_set_array(value_t value, array_t array, int offset);
int value_get_area(value_t value, area_t *areap);
int value_set_area(value_t value, area_t area);
int value_get_pointer(value_t value, value_t *pointp, int *offsetp);
int value_set_pointer(value_t value, value_t point, int offset);
int value_get_function(value_t value, function_t *functionp);
int value_set_function(value_t value, function_t function);
int value_get_label(value_t value, label_t *labelp);
int value_set_label(value_t value, label_t label);
int value_get_integer_float(value_t value, integer_t *integerp);
#ifdef NLL_FLOATING_POINT
int value_get_float_integer(value_t value, double *floatingp);
#endif
int value_output_value(FILE *fp, value_t value);
int value_output_values(FILE *fp, value_t value, const char *separator);
int value_dump_value(FILE *fp, value_t value);
int value_dump(FILE *fp, value_t value);

#endif
