/* codes.h: -*- C -*-  DESCRIPTIVE TEXT. */

/*  Copyright (c) 1996 Universal Access Inc.
    Author: E. B. Gamble Jr. (ebg@ai.mit.edu) Thu Oct 10 22:29:23 1996.  */

/* Interface declarations and definitions for byte_ops and prim_ops */

#if !defined(_BC_CODE_H_)
#define _BC_CODE_H_ 1

#include "object.h"

/* 
 * BC_BYTEOP_T (Byte Operator and byte Operand)
 *
 * Enumerate the byte_code operators.  We limit the number of byte_ops to
 * 256 (including '0' which is not a byte_op).  
 */
typedef enum
{
# define BYTEOP( operand, name, size )     BC_ ## operand ## _OP,
# include "byte_ops.h"
  BC_NUMBER_OF_BYTEOPS
# undef BYTEOP
} bc_byte_op_t;

#if BC_NUMBER_OF_BYTEOPS >= 256
#error Too many byte_ops defined
#endif

/*
 * BC_BYTEOP_LEN_T
 *
 * Byte operators have an arbitrary number of byte operands.  The
 * byte_op JUMP, for example, has two operands to encode the 'index'
 * (in the byte code vector) to jump to.  The byte_op length includes
 * the operator itself.
 */

typedef enum
{
# define BYTEOP( operand, name, size )   BC_ ## operand ## _OP_LEN = size,
# include "byte_ops.h"
  BC_IGNORE_BYTEOP_LEN
# undef BYTEOP
} bc_byte_op_len_t;

/* Get this specification correct by looking over byte_ops.h */
#define BC_MAXIMUM_BYTEOP_LEN 3

/*
 * BC_BYTE_CODE_SPEC_T
 *
 * A byte_code spec summarized byte_op and is often used for printing
 * the byte vector.
 *
 */
typedef struct bc_byte_code_spec
{
  bc_byte_op_t     operator;
  bc_byte_op_len_t length;
  bc_string_t      name;
} *bc_byte_code_spec_t;

#define BC_BYTE_CODE_SPEC_OPERATOR( spec ) ((spec)->operator)
#define BC_BYTE_CODE_SPEC_LENGTH( spec )   ((spec)->length)
#define BC_BYTE_CODE_SPEC_NAME( spec )     ((spec)->name)

/* Table with one byte code spec for each byte operator */
extern struct bc_byte_code_spec
bc_byte_code_spec_table [1 + BC_NUMBER_OF_BYTEOPS];

#define BC_BYTE_CODE_SPEC_LOOKUP( code )	\
   (& bc_byte_code_spec_table [(code)])

/* <byte_code <code-vector> <code-constants> <code-stack> ...> */

/*
 * BC_PRIM_OP_SPEC_T
 *
 *
 */
typedef struct bc_prim_op_spec
{
  bc_string_t  name;
  unsigned int min_arg_count;
  signed int   max_arg_count;	/* -1 => unlimited arguments */
  bc_byte_op_t operator;
} *bc_prim_op_spec_t;

#define BC_PRIM_OP_SPEC_NAME( prim )          ((prim)->name)
#define BC_PRIM_OP_SPEC_MIN_ARG_COUNT( prim ) ((prim)->min_arg_count)
#define BC_PRIM_OP_SPEC_MAX_ARG_COUNT( prim ) ((prim)->max_arg_count)
#define BC_PRIM_OP_SPEC_OPERATOR( prim )      ((prim)->operator)


#endif /* ! _BC_CODE_H_ */



