git @ Cat's Eye Technologies Kosheri / master src / value.h
master

Tree @master (Download .tar.gz)

value.h @masterraw · history · blame

/*
 * value.h
 * Values.
 */

#ifndef __VALUE_H_
#define __VALUE_H_

#include "localtypes.h"

/*
 * Types of values.
 */
#define	VALUE_STRUCTURED 8
enum value_type {
	VALUE_NULL	= 0,
	VALUE_INTEGER	= 1,
	VALUE_BOOLEAN	= 2,
	VALUE_PROCESS	= 3,
	VALUE_LABEL	= 4,

	VALUE_SYMBOL	= (VALUE_STRUCTURED | 1),
	VALUE_TUPLE	= (VALUE_STRUCTURED | 2)
};

#ifdef DEBUG
extern const char *type_name_table[];
#endif

typedef void * clabel;

struct process;

/*
 * Simple values.
 * These exist directly on the stack, and are not garbage-collected.
 */
struct value {
	enum value_type		 type;		/* VALUE_ */
	union {
		int			 integer;
		int			 boolean;
		struct process		*process;
		clabel			 label;
		struct structured_value	*structured;
	} value;
};

extern struct value VNULL;
extern struct value VFALSE;
extern struct value VTRUE;

extern struct value tag_ar;
extern struct value tag_dict;
extern struct value tag_list;
extern struct value tag_vm;

/*
 * Describe how two values compare.
 */
enum comparison {
	CMP_EQ,
	CMP_LT,
	CMP_GT,
	CMP_INCOMPARABLE
};

/* Prototypes */

/*
 * 'struct value *' parameters may NEVER be NULL.
 *
 * Only functions whose names end in _new allocate a struct value.
 */

/*
 * General functions.
 */
void		 value_copy(struct value *, const struct value *);

int		 value_is_null(const struct value *);
int		 value_is_integer(const struct value *);
int		 value_is_tuple(const struct value *);

int		 value_equal(const struct value *, const struct value *);
enum comparison	 value_compare(const struct value *, const struct value *);

		 /* public interface to garbage collector */
void		 value_gc(struct value *);

/*
 * Unstructured values.
 */

void		 value_integer_set(struct value *, int);
void		 value_boolean_set(struct value *, int);
void		 value_process_set(struct value *, struct process *);
void		 value_label_set(struct value *, clabel);

int		 value_get_integer(const struct value *);
int		 value_get_boolean(const struct value *);
clabel		 value_get_label(const struct value *);
struct process	*value_get_process(const struct value *);

/*
 * Structured values.
 */

/*
 * Retrieve an integer code that uniquely identifies this value.
 * Intended for debug output only.
 * Precondition: value is a structured value.
 */
PTR_INT		 value_get_unique_id(const struct value *);

/*
 * Symbols.
 */

/*
 * Allocate a new symbol value, with the given character string
 * (with the given length) as its token, and set the given value to it.
 * Returns true upon success, false if memory could not be allocated.
 * Precondition: value is not null, and the token is not null.
 */
int              value_symbol_new(struct value *, const char *, unsigned int);

/*
 * Allocate a new symbol value with the given length and set the
 * given value to it.  Return a pointer to the start of the character
 * data for the symbol, for later population by the caller.
 * Returns null if memory could not be allocated.
 * Precondition: value is not null, and the token is not null.
 */
char		*value_symbol_new_buffer(struct value *, unsigned int);
const char	*value_symbol_get_token(const struct value *);
unsigned int	 value_symbol_get_length(const struct value *);

/*
 * Tuples.
 */

int		 value_tuple_new(struct value *, struct value *, unsigned int);
struct value	*value_tuple_get_tag(const struct value *);
unsigned int	 value_tuple_get_size(const struct value *);
struct value	*value_tuple_fetch(const struct value *, unsigned int);
void		 value_tuple_store(struct value *, unsigned int, const struct value *);
int		 value_tuple_fetch_integer(const struct value *, unsigned int);
void		 value_tuple_store_integer(struct value *, unsigned int, int);
clabel		 value_tuple_fetch_label(const struct value *, unsigned int);

/*
 * Dictionaries.
 * Dictionaries are represented by a linked list of "layers", where
 * each layer is a tuple of the given size plus some header slots.
 */

int		 value_dict_new(struct value *, unsigned int);
struct value	*value_dict_fetch(const struct value *, const struct value *);
void		 value_dict_store(struct value *, struct value *, struct value *);
unsigned int	 value_dict_get_length(const struct value *);
unsigned int	 value_dict_get_layer_size(const struct value *);

/*
 * Dictionary iterators.
 */

int              value_dict_new_iter(struct value *, struct value *);
struct value    *value_dict_iter_get_current_key(struct value *);
void             value_dict_iter_advance(struct value *);

/*
 * Activation records.
 * Activation records are represented by tuple with 4 header entries.
 * The remainder of the entries are local variables stored in the AR.
 */

#define AR_CALLER	0	/* ar: the ar that called us */
#define AR_ENCLOSING	1	/* ar: the ar lexically outside us */
#define AR_PC		2	/* integer: code pos when resumed */
#define AR_TOP		3	/* integer: current top of stack (init. 4) */

#define AR_HEADER_SIZE	4

int		 value_ar_new(struct value *, unsigned int, struct value *, struct value *, unsigned int);
struct value	*value_ar_pop(struct value *);
void		 value_ar_push(struct value *, struct value *);
void		 value_ar_xfer(struct value *, struct value *, int);

/*
 * Virtual machines.
 * A virtual machine is represented by a tuple with 4 entries:
 * - the first is an integer offset: the program counter
 * - the second is a tuple representing the current activation record
 * - the third is a boolean: is this code direct-threaded or not?
 * - the fourth is a tuple containing the code as VM instructions
 */

#define VM_PC		0
#define VM_AR		1
#define VM_IS_DIRECT	2
#define VM_CODE		3

#define VM_SIZE		4

int		 value_vm_new(struct value *, struct value *);
void		 value_vm_reset(struct value *);

#endif /* !__VALUE_H_ */