/* * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ /* $Id$ */ /* EXPRESSION DESCRIPTOR */ /* What we want to define is the struct expr, but since it contains a union of various goodies, we define them first; so be patient. */ /* classes of value */ #define Const 1 #define Name 2 #define Label 3 struct value { int vl_class; /* Const, Name or Label */ arith vl_value; /* constant value or offset */ union { struct idf *vl_idf; /* external name */ label vl_lbl; /* compiler-generated label */ } vl_data; }; struct string { char *sg_value; /* row of bytes repr. the constant */ int sg_len; /* length of the row */ }; struct oper { struct type *op_type; /* resulting type of the operation */ struct expr *op_left; int op_oper; /* the symbol of the operator */ struct expr *op_right; }; /* The following constants indicate the class of the expression: */ #define Value 0 /* it is a value known at load time */ #define String 1 /* it is a string constant */ #define Float 2 /* it is a floating point constant */ #define Oper 3 /* it is a run-time expression */ #define Type 4 /* only its type is relevant */ struct expr { char *ex_file; /* the file it (probably) comes from */ unsigned int ex_line; /* the line it (probably) comes from */ struct type *ex_type; short ex_lvalue; short ex_flags; int ex_class; int ex_depth; union { struct value ex_value; struct string ex_string; flt_arith ex_fl_arith; struct oper ex_oper; } ex_object; }; /* some abbreviated selections */ #define EX_VALUE ex_object.ex_value #define VL_CLASS EX_VALUE.vl_class #define VL_VALUE EX_VALUE.vl_value #define VL_IDF EX_VALUE.vl_data.vl_idf #define VL_LBL EX_VALUE.vl_data.vl_lbl #define SG_VALUE ex_object.ex_string.sg_value #define SG_LEN ex_object.ex_string.sg_len #define FL_ARITH ex_object.ex_fl_arith #define OP_TYPE ex_object.ex_oper.op_type #define OP_LEFT ex_object.ex_oper.op_left #define OP_OPER ex_object.ex_oper.op_oper #define OP_RIGHT ex_object.ex_oper.op_right /* some bits for the ex_flag field, to keep track of various interesting properties of an expression. */ #define EX_SIZEOF 0x001 /* contains sizeof operator */ #define EX_CAST 0x002 /* contains cast */ #define EX_LOGICAL 0x004 /* contains logical operator */ #define EX_COMMA 0x008 /* contains expression comma */ #define EX_PARENS 0x010 /* the top level is parenthesized */ #define EX_SIDEEFFECTS 0x020 /* expression has side effects */ #define EX_READONLY 0x040 /* read only variabele */ #define EX_VOLATILE 0x080 /* volatile variabele */ #define EX_ILVALUE 0x100 /* an illegal lvalue e.g. f().x */ #define EX_ERROR 0x200 /* the expression is wrong */ #define EX_PTRDIFF 0x400 /* subtracting 2 pointers in expr. */ #define NILEXPR ((struct expr *)0) /* some useful tests */ #define ISNAME(e) ((e)->ex_class == Value && (e)->VL_CLASS == Name) #define ISCOMMA(e) ((e)->ex_class == Oper && (e)->OP_OPER == INITCOMMA) extern struct expr *intexpr(), *new_oper(); /* ALLOCDEF "expr" 20 */