#ifndef PROT
#define PROT(x) ()
#endif
/*
* Define all nodes used by the interpreter.
* It is extremly important that these nodes are as small as possible,
* because they are the outstandingly most allocated data structure.
*
* Common for all nodes are:
* type: The type of the node.
* line: The line in the source. The 4 top bits store the
* basic type of the node (L_ something). Use L_MASK to mask
* out either the line number or basic type.
*/
#define L_SINGLE 0x1000
struct lnode_single {
unsigned short type;
unsigned short line;
};
#define L_NUMBER 0x2000
struct lnode_number {
unsigned short type;
unsigned short line;
int number;
};
#define L_NAME 0x3000
struct lnode_name {
unsigned short type;
unsigned short line;
char *name;
};
#define L_VARIABLE 0x4000
struct lnode_variable {
unsigned short type;
unsigned short line;
int number;
};
#define L_1 0x5000
struct lnode_1 {
unsigned short type;
unsigned short line;
struct lnode *expr;
};
#define L_2 0x6000
struct lnode_2 {
unsigned short type;
unsigned short line;
struct lnode *expr1;
struct lnode *expr2;
};
#define L_3 0x7000
struct lnode_3 {
unsigned short type;
unsigned short line;
struct lnode *expr1;
struct lnode *expr2;
struct lnode *expr3;
};
#define L_DEF 0x8000
struct lnode_def {
unsigned short type;
unsigned short line;
char *name;
struct lnode *block;
struct lnode_def *next;
unsigned char num_var; /* Number of local variables + arguments */
unsigned char num_arg; /* Number of arguments. */
unsigned short num_ref;
short is_static; /* Can not be called from outside. */
short length; /* String length of name. */
};
#define L_VAR_DEF 0x9000
struct lnode_var_def {
unsigned short type;
unsigned short line;
char *name;
struct lnode_var_def *next;
short num_var;
short num_arg; /* This /ne is hardly used, is it ? */
int is_static;
};
#define L_FUNCALL 0xa000
struct lnode_funcall {
unsigned short type;
unsigned short line;
struct lnode *expr;
char *name;
};
#define L_BLOCK 0xb000
struct lnode_block {
unsigned short type;
unsigned short line;
int num_nodes; /* Number of nodes in this block */
char *block;
};
#define L_CONSTANT 0xc000 /* Used for non-allocateable lnodes */
#define L_MASK 0xf000
#define L_MAX 0xc000 /* Highest number */
#define L_SHIFT 12 /* Number of bits to shift */
struct lnode {
unsigned short type;
unsigned short line;
struct lnode *a1, *a2, *a3; /* Statements inside this statement */
};
struct lnode_var_def *find_status PROT((char *, int));
struct lnode_number *alloc_lnode_number PROT((int, int));
struct lnode_block *alloc_lnode_block PROT((struct lnode *));
struct lnode_name *alloc_lnode_name PROT((int, char *));
struct lnode_variable *alloc_lnode_variable PROT((int, int));
struct lnode_1 *alloc_lnode_1 PROT((int, struct lnode *));
struct lnode_2 *alloc_lnode_2 PROT((int, struct lnode *, struct lnode *));
struct lnode_3 *alloc_lnode_3 PROT((int, struct lnode *, struct lnode *,
struct lnode *));
struct lnode_def *alloc_lnode_def PROT((int, char *, struct lnode *, int));
struct lnode_funcall *alloc_lnode_funcall PROT((int, char *, struct lnode *));
struct lnode_single *alloc_lnode_single PROT((int));
extern struct lnode_var_def *prog_status;
void alloc_lnode_var_def PROT((int, char *, int));
int free_prog PROT((struct lnode_def *, char *, int));
void free_sub_part PROT((struct lnode *, int)),
add_prog_ref PROT((struct lnode_def *)),
free_lnode PROT((struct lnode *, int));
extern int lnode_size[];