sima/autoconf/
sima/hosts/i386/
sima/mudlib/
sima/mudlib/kernel/
sima/mudlib/obj/
sima/mudlib/sys/
sima/synhash/mips/
/* Copright 1997 Joern Rennecke */

#ifndef COMPILER_H
#define COMPILER_H

#ifndef COMPILER_GLOBAL
#define COMPILER_GLOBAL extern
#endif

#define MAX_NODE_BLOCKS 1024
#define BLOCK_BITS 10
#define N_FUNBLOCKS 64
#define BLOCK_MASK ((1 << BLOCK_BITS) - 1)
#define BYTES_PER_NODE_BLOCK (sizeof (char *[1 << BLOCK_BITS]))
#define INIT_VARBLOCK_SIZE 256

#define ALLOC_ANODE(type) alloc_nnode(\
	(sizeof(type)+sizeof(struct binode)-1) / sizeof(struct binode)\
)

#define ALLOC_NNODE(num) \
	(alloc_nnode(sizeof(struct binode) + ((num)-2)*sizeof(union node)))

#define N_UNARY		 0
#define N_BINOP		 1
#define N_LV_UNARY	 2
#define N_LV_UNARY_CST	 3
#define N_LV_BINOP	 4
#define N_LOP		 5
#define N_LLOP		 6
#define N_SEQUENCE	 7
#define N_MULTICONST	 8
#define N_MULTIVAL	 9
#define N_EFUN		10
#define N_LFUN		11
#define N_LOCAL		12
#define N_LOCAL_INIT	13
#define N_IF		14
#define N_FOR		15
#define N_DO		16
#define N_CASE_LABEL	17
#define N_RETURN	18
#define N_VOLATILE	19 /* no drop through */
#define N_IS_VOLATILE(n) ( !((n).i & 3) && (n).p->ntype - N_RETURN <= 1U )

#define CASE_DEFAULT	0
#define CASE_STRING	1
#define CASE_NUMBER	2
#define CASE_RANGE	3

/* leaf node types; 4-aligned reserved for pointers */
#define LN_GLOBAL	 1
#define LN_PARAM	 2
#define LN_LOCAL	 3
#define LN_PICK		 5
#define LN_PUT		 6
#define LN_INT		 7
#define LN_LFUN_CLOSURE	 9
#define LN_SHARED	10
#define LN_UNSHARED	11
#define LN_CONST	13
#define LN_NIL		14

union node {
    struct binode *p;
    p_int i;
    struct {
#ifdef WORDS_BIGENDIAN
#if SIZEOF_P_INT > 4
	char dummy[SIZEOF_P_INT-4];
#endif
	union { uint16 u; int16 s; } n;
	uint16 type;
#else
	uint16 type;
	union { uint16 u; int16 s; } n;
#endif
    } leaf;
    struct {
	short code;
	short narg;
    } efun;
    struct {
	uint16 lfun;
	short narg;
    } lfun;
    svalue sv;
    struct ident *id;
} TRANSPARENT_UNION;

struct binode {
    uint8 ntype, opr;
    uint16 line;
    union node node[2];
};

struct expression {
    union node node;
    uint16 length;
    uint8 vtype;
};

struct statement {
    union node node;
    uint32 length;
};

struct function {
    int32 type, modifier;
    unsigned new_def: 1;
    unsigned inherited: 1;
    unsigned undeclared: 1;
    unsigned: 29;
    uint8 num_arg, num_local;
    uint16 ix;
    union { struct ident *id; svalue sv; } name;
    struct statement block;
    p_int cshared_threshold;
};

struct type_list {
    struct type_list *next;
    int type;
};

/* global variables come in a number of flavours:
   - there are ordinary global variables, which are allocated in
     in the variable vector of the object, at an index that consists
     of the sum of the basic index choosen at compile time the variable
     is declared, and an offset that is determined by the position
     of the variable's program in the inherit tree of the object's program.
   - There are variables that are inherited 'virtual' from a base object's
     ordinary global variables.  They are inherited only once even when
     the variable's program is inherited several times by the object's
     program.  The offset is found in fp_virtual.
   - There are shared variables, which are allocated in the program itself.
     If they are private, they are not actually allocated unless they are
     used.
   - When a shared variable is inherited, it only needs allocation when
     it is used.  For the interpreter, such a inherited shared variable
     looks like a newly defined shared variable, except that it contains
     an lvalue that references the savlue allocated in the defining
     program.
   - a single variable can be declared as virtual, in which case a complex
     mechanism is invoked that basically means the variable can be any
     of the above.  */

struct var_decl {
    int32 type, modifier;
    union { struct ident *id; } name;
    struct inherit_decl *inherited_from;
    struct var_decl *next_inherited;
    int ix;
};

#define FUNCTION(ix) (funblocks[(ix) >> BLOCK_BITS][(ix) & BLOCK_MASK])
COMPILER_GLOBAL struct function **funblocks[N_FUNBLOCKS];
#define GVARIABLE(ix) varblock[(ix)]
COMPILER_GLOBAL struct var_decl **varblock;
COMPILER_GLOBAL p_int varblock_size;
COMPILER_GLOBAL p_int function_ix, n_fun_def, n_fun_redef, variable_ix;
COMPILER_GLOBAL p_int n_globals, total_pcode;
COMPILER_GLOBAL struct binode *free_tmpnodes;
COMPILER_GLOBAL int num_shared, max_shared;
COMPILER_GLOBAL union svalue *shared;
COMPILER_GLOBAL p_int n_shared_var, cshared_threshold;
COMPILER_GLOBAL int n_param, local_preallocated, stack_use;
COMPILER_GLOBAL int n_undefined_lfuns;

extern char error_nargs[];
extern char ce_error_nargs[];
extern int32 efun_arg_types[];

extern int yyparse(void);
extern struct binode *alloc_node(void);
extern int constant_node(svalue, union node *);
extern void *alloc_nnode(size_t);
#define alloc_mnode() alloc_nnode(sizeof(struct binode)-sizeof(struct binode *))
extern void *alloc_tmpnode(void);
extern void free_tmpnode(void *);
extern int comp_type(svalue);
extern void constant_expression(); /* YYSTYPE is not declared in lang.c */
extern void multiconst_multival(struct statement *);
extern svalue multiconst_array(struct statement *);
extern svalue multiconst_mapping(struct statement *);
extern void efun_call(int, struct statement, struct expression *);
extern void lfun_call(int, struct statement, struct expression *);
extern void member_call(struct expression, svalue,
  struct statement, struct expression *);
extern svalue immediate_efun_call(int, int);
extern void bad_type(int narg, int opr);
extern struct ident *verify_declared_lfun(struct ident *);
extern mp_int store_function(struct function *f);
extern struct function *declare_lfun(int,int, struct ident*, struct type_list*);
extern void declare_global_var(int, int, struct ident*, svalue);
extern uint8 *stack_adjust(uint8 *, int);

#endif /* COMPILER_H */