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