]> granicus.if.org Git - yasm/commitdiff
Make most data structures opaque, keeping internals truly internal and making the
authorPeter Johnson <peter@tortall.net>
Wed, 3 Oct 2001 20:42:17 +0000 (20:42 -0000)
committerPeter Johnson <peter@tortall.net>
Wed, 3 Oct 2001 20:42:17 +0000 (20:42 -0000)
overall structure much more modular.
The test files, which need access to the internals of the structures being
tested, now include the source file instead of the header file to gain access
to all internal formats and functions.

svn path=/trunk/yasm/; revision=261

36 files changed:
libyasm/bytecode.c
libyasm/bytecode.h
libyasm/expr.c
libyasm/expr.h
libyasm/floatnum.c
libyasm/floatnum.h
libyasm/section.c
libyasm/section.h
libyasm/symrec.c
libyasm/symrec.h
libyasm/tests/Makefile.am
libyasm/tests/bytecode_test.c
libyasm/tests/floatnum_test.c
modules/arch/x86/expr.c
modules/arch/x86/x86expr.c
modules/parsers/nasm/bison.y.in
modules/parsers/nasm/gen_instr.pl
modules/parsers/nasm/nasm-bison.y
src/arch/x86/expr.c
src/arch/x86/x86expr.c
src/bytecode.c
src/bytecode.h
src/expr.c
src/expr.h
src/floatnum.c
src/floatnum.h
src/parsers/nasm/bison.y.in
src/parsers/nasm/gen_instr.pl
src/parsers/nasm/nasm-bison.y
src/section.c
src/section.h
src/symrec.c
src/symrec.h
src/tests/Makefile.am
src/tests/bytecode_test.c
src/tests/floatnum_test.c

index 48d88268872af099f2c8417e226c4aa8bbd5f457..b3c9a7ea3e13745f4895657978d0701764835739 100644 (file)
 
 RCSID("$IdPath$");
 
-/* Static structures for when NULL is passed to conversion functions. */
-/*  for Convert*ToImm() */
-static immval im_static;
+struct effaddr {
+    expr *disp;                        /* address displacement */
+    unsigned char len;         /* length of disp (in bytes), 0 if none */
+
+    unsigned char segment;     /* segment override, 0 if none */
+
+    unsigned char modrm;
+    unsigned char valid_modrm; /* 1 if Mod/RM byte currently valid, 0 if not */
+    unsigned char need_modrm;  /* 1 if Mod/RM byte needed, 0 if not */
+
+    unsigned char sib;
+    unsigned char valid_sib;   /* 1 if SIB byte currently valid, 0 if not */
+    unsigned char need_sib;    /* 1 if SIB byte needed, 0 if not */
+};
+
+struct immval {
+    expr *val;
+
+    unsigned char len;         /* length of val (in bytes), 0 if none */
+    unsigned char isneg;       /* the value has been explicitly negated */
+
+    unsigned char f_len;       /* final imm length */
+    unsigned char f_sign;      /* 1 if final imm should be signed */
+};
+
+struct dataval {
+    STAILQ_ENTRY(dataval) link;
 
+    enum { DV_EMPTY, DV_EXPR, DV_FLOAT, DV_STRING } type;
+
+    union {
+       expr *expn;
+       floatnum *flt;
+       char *str_val;
+    } data;
+};
+
+struct bytecode {
+    STAILQ_ENTRY(bytecode) link;
+
+    enum { BC_EMPTY, BC_INSN, BC_JMPREL, BC_DATA, BC_RESERVE } type;
+
+    /* This union has been somewhat tweaked to get it as small as possible
+     * on the 4-byte-aligned x86 architecture (without resorting to
+     * bitfields).  In particular, insn and jmprel are the largest structures
+     * in the union, and are also the same size (after padding).  jmprel
+     * can have another unsigned char added to the end without affecting
+     * its size.
+     *
+     * Don't worry about this too much, but keep it in mind when changing
+     * this structure.  We care about the size of bytecode in particular
+     * because it accounts for the majority of the memory usage in the
+     * assembler when assembling a large file.
+     */
+    union {
+       struct {
+           effaddr *ea;        /* effective address */
+
+           immval imm;         /* immediate or relative value */
+
+           unsigned char opcode[3];    /* opcode */
+           unsigned char opcode_len;
+
+           unsigned char addrsize;     /* 0 indicates no override */
+           unsigned char opersize;     /* 0 indicates no override */
+           unsigned char lockrep_pre;  /* 0 indicates no prefix */
+
+           /* HACK, but a space-saving one: shift opcodes have an immediate
+            * form and a ,1 form (with no immediate).  In the parser, we
+            * set this and opcode_len=1, but store the ,1 version in the
+            * second byte of the opcode array.  We then choose between the
+            * two versions once we know the actual value of imm (because we
+            * don't know it in the parser module).
+            *
+            * A override to force the imm version should just leave this at
+            * 0.  Then later code won't know the ,1 version even exists.
+            * TODO: Figure out how this affects CPU flags processing.
+            *
+            * Call SetInsnShiftFlag() to set this flag to 1.
+            */
+           unsigned char shift_op;
+       } insn;
+       struct {
+           expr *target;               /* target location */
+
+           struct {
+               unsigned char opcode[3];
+               unsigned char opcode_len;   /* 0 = no opc for this version */
+           } shortop, nearop;
+
+           /* which opcode are we using? */
+           /* The *FORCED forms are specified in the source as such */
+           jmprel_opcode_sel op_sel;
+
+           unsigned char addrsize;     /* 0 indicates no override */
+           unsigned char opersize;     /* 0 indicates no override */
+           unsigned char lockrep_pre;  /* 0 indicates no prefix */
+       } jmprel;
+       struct {
+           /* non-converted data (linked list) */
+           datavalhead datahead;
+
+           /* final (converted) size of each element (in bytes) */
+           unsigned char size;
+       } data;
+       struct {
+           expr *numitems;             /* number of items to reserve */
+           unsigned char itemsize;     /* size of each item (in bytes) */
+       } reserve;
+    } data;
+
+    unsigned long len;         /* total length of entire bytecode */
+
+    /* where it came from */
+    char *filename;
+    unsigned int lineno;
+
+    /* other assembler state info */
+    unsigned long offset;
+    unsigned char mode_bits;
+};
+
+/* Static structures for when NULL is passed to conversion functions. */
 /*  for Convert*ToBytes() */
 unsigned char bytes_static[16];
 
@@ -106,37 +225,34 @@ effaddr_new_imm(immval *im_ptr, unsigned char im_len)
 }
 
 immval *
-ConvertIntToImm(immval *ptr, unsigned long int_val)
+immval_new_int(unsigned long int_val)
 {
-    if (!ptr)
-       ptr = &im_static;
+    immval *im = xmalloc(sizeof(immval));
 
-    /* FIXME: this will leak expr's if static is used */
-    ptr->val = expr_new_ident(EXPR_INT, ExprInt(int_val));
+    im->val = expr_new_ident(ExprInt(int_val));
 
     if ((int_val & 0xFF) == int_val)
-       ptr->len = 1;
+       im->len = 1;
     else if ((int_val & 0xFFFF) == int_val)
-       ptr->len = 2;
+       im->len = 2;
     else
-       ptr->len = 4;
+       im->len = 4;
 
-    ptr->isneg = 0;
+    im->isneg = 0;
 
-    return ptr;
+    return im;
 }
 
 immval *
-ConvertExprToImm(immval *ptr, expr *expr_ptr)
+immval_new_expr(expr *expr_ptr)
 {
-    if (!ptr)
-       ptr = &im_static;
+    immval *im = xmalloc(sizeof(immval));
 
-    ptr->val = expr_ptr;
+    im->val = expr_ptr;
 
-    ptr->isneg = 0;
+    im->isneg = 0;
 
-    return ptr;
+    return im;
 }
 
 void
@@ -145,7 +261,7 @@ SetEASegment(effaddr *ptr, unsigned char segment)
     if (!ptr)
        return;
 
-    if (ptr->segment != 0)
+    if (segment != 0 && ptr->segment != 0)
        Warning(_("multiple segment overrides, using leftmost"));
 
     ptr->segment = segment;
@@ -164,6 +280,19 @@ SetEALen(effaddr *ptr, unsigned char len)
     ptr->len = len;
 }
 
+effaddr *
+GetInsnEA(bytecode *bc)
+{
+    if (!bc)
+       return NULL;
+
+    if (bc->type != BC_INSN)
+       InternalError(__LINE__, __FILE__,
+                     _("Trying to get EA of non-instruction"));
+
+    return bc->data.insn.ea;
+}
+
 void
 SetInsnOperSizeOverride(bytecode *bc, unsigned char opersize)
 {
@@ -250,7 +379,8 @@ SetOpcodeSel(jmprel_opcode_sel *old_sel, jmprel_opcode_sel new_sel)
     if (!old_sel)
        return;
 
-    if ((*old_sel == JR_SHORT_FORCED) || (*old_sel == JR_NEAR_FORCED))
+    if (new_sel != JR_NONE && ((*old_sel == JR_SHORT_FORCED) ||
+                              (*old_sel == JR_NEAR_FORCED)))
        Warning(_("multiple SHORT or NEAR specifiers, using leftmost"));
     *old_sel = new_sel;
 }
@@ -596,6 +726,16 @@ dataval_new_string(char *str_val)
     return retval;
 }
 
+dataval *
+datavals_append(datavalhead *headp, dataval *dv)
+{
+    if (dv) {
+       STAILQ_INSERT_TAIL(headp, dv, link);
+       return dv;
+    }
+    return (dataval *)NULL;
+}
+
 void
 dataval_print(datavalhead *head)
 {
index 05d39de35d657159c33621276b1b93dfb10ed5f6..c2c2a63a289808fe5f276f493b8877a66d9e434d 100644 (file)
 #ifndef YASM_BYTECODE_H
 #define YASM_BYTECODE_H
 
-struct section_s;
-
-typedef struct effaddr_s {
-    struct expr_s *disp;       /* address displacement */
-    unsigned char len;         /* length of disp (in bytes), 0 if none */
-
-    unsigned char segment;     /* segment override, 0 if none */
-
-    unsigned char modrm;
-    unsigned char valid_modrm; /* 1 if Mod/RM byte currently valid, 0 if not */
-    unsigned char need_modrm;  /* 1 if Mod/RM byte needed, 0 if not */
-
-    unsigned char sib;
-    unsigned char valid_sib;   /* 1 if SIB byte currently valid, 0 if not */
-    unsigned char need_sib;    /* 1 if SIB byte needed, 0 if not */
-} effaddr;
-
-typedef struct immval_s {
-    struct expr_s *val;
-
-    unsigned char len;         /* length of val (in bytes), 0 if none */
-    unsigned char isneg;       /* the value has been explicitly negated */
-
-    unsigned char f_len;       /* final imm length */
-    unsigned char f_sign;      /* 1 if final imm should be signed */
-} immval;
+#ifndef YASM_SECTION
+#define YASM_SECTION
+typedef struct section section;
+#endif
 
-typedef STAILQ_HEAD(datavalhead_s, dataval_s) datavalhead;
+#ifndef YASM_EXPR
+#define YASM_EXPR
+typedef struct expr expr;
+#endif
 
-typedef struct dataval_s {
-    STAILQ_ENTRY(dataval_s) link;
+#ifndef YASM_FLOATNUM
+#define YASM_FLOATNUM
+typedef struct floatnum floatnum;
+#endif
 
-    enum { DV_EMPTY, DV_EXPR, DV_FLOAT, DV_STRING } type;
+typedef struct effaddr effaddr;
+typedef struct immval immval;
+typedef STAILQ_HEAD(datavalhead, dataval) datavalhead;
+typedef struct dataval dataval;
+typedef STAILQ_HEAD(bytecodehead, bytecode) bytecodehead;
 
-    union {
-       struct expr_s *expn;
-       struct floatnum_s *flt;
-       char *str_val;
-    } data;
-} dataval;
+#ifndef YASM_BYTECODE
+#define YASM_BYTECODE
+typedef struct bytecode bytecode;
+#endif
 
-typedef enum jmprel_opcode_sel_e {
+typedef enum {
     JR_NONE,
     JR_SHORT,
     JR_NEAR,
@@ -72,108 +57,23 @@ typedef enum jmprel_opcode_sel_e {
 } jmprel_opcode_sel;
 
 typedef struct targetval_s {
-    struct expr_s *val;
+    expr *val;
 
     jmprel_opcode_sel op_sel;
 } targetval;
 
-typedef STAILQ_HEAD(bytecodehead_s, bytecode_s) bytecodehead;
-
-typedef struct bytecode_s {
-    STAILQ_ENTRY(bytecode_s) link;
-
-    enum { BC_EMPTY, BC_INSN, BC_JMPREL, BC_DATA, BC_RESERVE } type;
-
-    /* This union has been somewhat tweaked to get it as small as possible
-     * on the 4-byte-aligned x86 architecture (without resorting to
-     * bitfields).  In particular, insn and jmprel are the largest structures
-     * in the union, and are also the same size (after padding).  jmprel
-     * can have another unsigned char added to the end without affecting
-     * its size.
-     *
-     * Don't worry about this too much, but keep it in mind when changing
-     * this structure.  We care about the size of bytecode in particular
-     * because it accounts for the majority of the memory usage in the
-     * assembler when assembling a large file.
-     */
-    union {
-       struct {
-           effaddr *ea;        /* effective address */
-
-           immval imm;         /* immediate or relative value */
-
-           unsigned char opcode[3];    /* opcode */
-           unsigned char opcode_len;
-
-           unsigned char addrsize;     /* 0 indicates no override */
-           unsigned char opersize;     /* 0 indicates no override */
-           unsigned char lockrep_pre;  /* 0 indicates no prefix */
-
-           /* HACK, but a space-saving one: shift opcodes have an immediate
-            * form and a ,1 form (with no immediate).  In the parser, we
-            * set this and opcode_len=1, but store the ,1 version in the
-            * second byte of the opcode array.  We then choose between the
-            * two versions once we know the actual value of imm (because we
-            * don't know it in the parser module).
-            *
-            * A override to force the imm version should just leave this at
-            * 0.  Then later code won't know the ,1 version even exists.
-            * TODO: Figure out how this affects CPU flags processing.
-            *
-            * Call SetInsnShiftFlag() to set this flag to 1.
-            */
-           unsigned char shift_op;
-       } insn;
-       struct {
-           struct expr_s *target;      /* target location */
-
-           struct {
-               unsigned char opcode[3];
-               unsigned char opcode_len;   /* 0 = no opc for this version */
-           } shortop, nearop;
-
-           /* which opcode are we using? */
-           /* The *FORCED forms are specified in the source as such */
-           jmprel_opcode_sel op_sel;
-
-           unsigned char addrsize;     /* 0 indicates no override */
-           unsigned char opersize;     /* 0 indicates no override */
-           unsigned char lockrep_pre;  /* 0 indicates no prefix */
-       } jmprel;
-       struct {
-           /* non-converted data (linked list) */
-           datavalhead datahead;
-
-           /* final (converted) size of each element (in bytes) */
-           unsigned char size;
-       } data;
-       struct {
-           struct expr_s *numitems;    /* number of items to reserve */
-           unsigned char itemsize;     /* size of each item (in bytes) */
-       } reserve;
-    } data;
-
-    unsigned long len;         /* total length of entire bytecode */
-
-    /* where it came from */
-    char *filename;
-    unsigned int lineno;
-
-    /* other assembler state info */
-    unsigned long offset;
-    unsigned char mode_bits;
-} bytecode;
-
 effaddr *effaddr_new_reg(unsigned long reg);
 effaddr *effaddr_new_imm(immval *im_ptr, unsigned char im_len);
-effaddr *effaddr_new_expr(struct expr_s *expr_ptr);
+effaddr *effaddr_new_expr(expr *expr_ptr);
 
-immval *ConvertIntToImm(immval *ptr, unsigned long int_val);
-immval *ConvertExprToImm(immval *ptr, struct expr_s *expr_ptr);
+immval *immval_new_int(unsigned long int_val);
+immval *immval_new_expr(expr *expr_ptr);
 
 void SetEASegment(effaddr *ptr, unsigned char segment);
 void SetEALen(effaddr *ptr, unsigned char len);
 
+effaddr *GetInsnEA(bytecode *bc);
+
 void SetInsnOperSizeOverride(bytecode *bc, unsigned char opersize);
 void SetInsnAddrSizeOverride(bytecode *bc, unsigned char addrsize);
 void SetInsnLockRepPrefix(bytecode *bc, unsigned char prefix);
@@ -209,14 +109,12 @@ bytecode *bytecode_new_jmprel(targetval     *target,
 
 bytecode *bytecode_new_data(datavalhead *datahead, unsigned long size);
 
-bytecode *bytecode_new_reserve(struct expr_s *numitems,
-                              unsigned long  itemsize);
+bytecode *bytecode_new_reserve(expr *numitems, unsigned long itemsize);
 
 /* Gets the offset of the bytecode specified by bc if possible.
  * Return value is IF POSSIBLE, not the value.
  */
-int bytecode_get_offset(struct section_s *sect, bytecode *bc,
-                       unsigned long *ret_val);
+int bytecode_get_offset(section *sect, bytecode *bc, unsigned long *ret_val);
 
 void bytecode_print(bytecode *bc);
 
@@ -231,10 +129,21 @@ void bytecode_print(bytecode *bc);
  */
 bytecode *bytecodes_append(bytecodehead *headp, bytecode *bc);
 
-dataval *dataval_new_expr(struct expr_s *expn);
-dataval *dataval_new_float(struct floatnum_s *flt);
+dataval *dataval_new_expr(expr *expn);
+dataval *dataval_new_float(floatnum *flt);
 dataval *dataval_new_string(char *str_val);
 
+/* void datavals_initialize(datavalhead *headp); */
+#define        datavals_initialize(headp)      STAILQ_INIT(headp)
+
+/* Adds dv to the list of datavals headp.
+ * NOTE: Does not make a copy of dv; so don't pass this function
+ * static or local variables, and discard the dv pointer after calling
+ * this function.  If dv was actually appended (it wasn't NULL), then
+ * returns dv, otherwise returns NULL.
+ */
+dataval *datavals_append(datavalhead *headp, dataval *dv);
+
 void dataval_print(datavalhead *head);
 
 #endif
index 94740c00c2bce8af8c758aa68733ff4220163995..dc56962b745296a2b329efdfe46780bedfb04789 100644 (file)
 # include <string.h>
 #endif
 
+#include <libintl.h>
+#define _(String)      gettext(String)
+#ifdef gettext_noop
+#define N_(String)     gettext_noop(String)
+#else
+#define N_(String)     (String)
+#endif
+
 #include "globals.h"
 #include "errwarn.h"
 #include "floatnum.h"
 
 RCSID("$IdPath$");
 
+typedef enum {
+    EXPR_NONE,                 /* for left side of a NOT, NEG, etc. */
+    EXPR_SYM,
+    EXPR_EXPR,
+    EXPR_INT,
+    EXPR_FLOAT
+} ExprType;
+
+struct ExprItem {
+    ExprType type;
+    union {
+       symrec *sym;
+       expr *expn;
+       unsigned long int_val;
+       floatnum *flt;
+    } data;
+};
+
+struct expr {
+    ExprItem left, right;
+    ExprOp op;
+};
+
 /* allocate a new expression node, with children as defined.
  * If it's a unary operator, put the element on the right */
 expr *
-expr_new(ExprType ltype,
-        ExprItem left,
-        ExprOp   op,
-        ExprType rtype,
-        ExprItem right)
+expr_new(ExprItem *left, ExprOp op, ExprItem *right)
 {
     expr *ptr;
     ptr = xmalloc(sizeof(expr));
 
-    ptr->ltype = ltype;
+    ptr->left.type = EXPR_NONE;
     ptr->op = op;
-    ptr->rtype = rtype;
-    switch (ltype) {
-       case EXPR_SYM:
-       case EXPR_EXPR:
-       case EXPR_INT:
-       case EXPR_FLOAT:
-           memcpy(&ptr->left, &left, sizeof(ExprItem));
-           break;
-       case EXPR_NONE:
-           break;
+    ptr->right.type = EXPR_NONE;
+    if (left) {
+       memcpy(&ptr->left, left, sizeof(ExprItem));
+       free(left);
     }
-    switch (rtype) {
-       case EXPR_SYM:
-       case EXPR_EXPR:
-       case EXPR_INT:
-       case EXPR_FLOAT:
-           memcpy(&ptr->right, &right, sizeof(ExprItem));
-           break;
-       case EXPR_NONE:
-           Fatal(FATAL_UNKNOWN);       /* TODO: better error? */
-           break;
+    if (right) {
+       memcpy(&ptr->right, right, sizeof(ExprItem));
+       free(right);
+    } else {
+       InternalError(__LINE__, __FILE__,
+                     _("Right side of expression must exist"));
     }
     return ptr;
 }
 
 /* helpers */
-ExprItem
-ExprSym(struct symrec_s *s)
+ExprItem *
+ExprSym(symrec *s)
 {
-    ExprItem e;
-
-    e.sym = s;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_SYM;
+    e->data.sym = s;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprExpr(expr *x)
 {
-    ExprItem e;
-    e.exp = x;
-
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_EXPR;
+    e->data.expn = x;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprInt(unsigned long i)
 {
-    ExprItem e;
-
-    e.int_val = i;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_INT;
+    e->data.int_val = i;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprFloat(floatnum *f)
 {
-    ExprItem e;
-
-    e.flt = f;
-    return e;
-}
-
-ExprItem
-ExprNone(void)
-{
-    ExprItem e;
-
-    e.int_val = 0;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_FLOAT;
+    e->data.flt = f;
     return e;
 }
 
@@ -133,118 +141,118 @@ expr_simplify(expr *e)
     unsigned long int_val;
 
     /* try to simplify the left side */
-    if (e->ltype == EXPR_EXPR) {
+    if (e->left.type == EXPR_EXPR) {
        /* if the left subexpr isn't an IDENT, recurse simplification */
-       if (e->left.exp->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->left.exp);
+       if (e->left.data.expn->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->left.data.expn);
 
        /* if the left subexpr is just an IDENT (or string thereof),
         * pull it up into the current node */
-       while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
+       while (e->left.type == EXPR_EXPR && e->left.data.expn->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->ltype = e->left.exp->rtype;
-           memcpy(&tmp, &(e->left.exp->right), sizeof(ExprItem));
-           free(e->left.exp);
-           memcpy(&(e->left.int_val), &tmp, sizeof(ExprItem));
+           e->left.type = e->left.data.expn->right.type;
+           memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
+           free(e->left.data.expn);
+           memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->ltype == EXPR_SYM) {
+    } else if (e->left.type == EXPR_SYM) {
        /* try to get value of symbol */
-       if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
-           e->ltype = EXPR_INT;
+       if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
+           e->left.type = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->left.int_val = int_val;
+           e->left.data.int_val = int_val;
            simplified = 1;
        }
     }
 
     /* ditto on the right */
-    if (e->rtype == EXPR_EXPR) {
-       if (e->right.exp->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->right.exp);
+    if (e->right.type == EXPR_EXPR) {
+       if (e->right.data.expn->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->right.data.expn);
 
-       while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
+       while (e->right.type == EXPR_EXPR && e->right.data.expn->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->rtype = e->right.exp->rtype;
-           memcpy(&tmp, &(e->right.exp->right), sizeof(ExprItem));
-           free(e->right.exp);
-           memcpy(&(e->right.int_val), &tmp, sizeof(ExprItem));
+           e->right.type = e->right.data.expn->right.type;
+           memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
+           free(e->right.data.expn);
+           memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->rtype == EXPR_SYM) {
-       if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
-           e->rtype = EXPR_INT;
+    } else if (e->right.type == EXPR_SYM) {
+       if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
+           e->right.type = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->right.int_val = int_val;
+           e->right.data.int_val = int_val;
            simplified = 1;
        }
     }
 
-    if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
-       && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
+    if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE)
+       && e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
        switch (e->op) {
            case EXPR_ADD:
-               e->right.int_val = e->left.int_val + e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val + e->right.data.int_val;
                break;
            case EXPR_SUB:
-               e->right.int_val = e->left.int_val - e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val - e->right.data.int_val;
                break;
            case EXPR_MUL:
-               e->right.int_val = e->left.int_val * e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val * e->right.data.int_val;
                break;
            case EXPR_DIV:
-               e->right.int_val = e->left.int_val / e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val / e->right.data.int_val;
                break;
            case EXPR_MOD:
-               e->right.int_val = e->left.int_val % e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val % e->right.data.int_val;
                break;
            case EXPR_NEG:
-               e->right.int_val = -(e->right.int_val);
+               e->right.data.int_val = -(e->right.data.int_val);
                break;
            case EXPR_NOT:
-               e->right.int_val = ~(e->right.int_val);
+               e->right.data.int_val = ~(e->right.data.int_val);
                break;
            case EXPR_OR:
-               e->right.int_val = e->left.int_val | e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val | e->right.data.int_val;
                break;
            case EXPR_AND:
-               e->right.int_val = e->left.int_val & e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val & e->right.data.int_val;
                break;
            case EXPR_XOR:
-               e->right.int_val = e->left.int_val ^ e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val ^ e->right.data.int_val;
                break;
            case EXPR_SHL:
-               e->right.int_val = e->right.int_val << e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
                break;
            case EXPR_SHR:
-               e->right.int_val = e->right.int_val << e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
                break;
            case EXPR_LOR:
-               e->right.int_val = e->left.int_val || e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val || e->right.data.int_val;
                break;
            case EXPR_LAND:
-               e->right.int_val = e->left.int_val && e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val && e->right.data.int_val;
                break;
            case EXPR_LNOT:
-               e->right.int_val = !e->right.int_val;
+               e->right.data.int_val = !e->right.data.int_val;
                break;
            case EXPR_EQ:
-               e->right.int_val = e->right.int_val == e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val == e->left.data.int_val;
                break;
            case EXPR_LT:
-               e->right.int_val = e->right.int_val < e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val < e->left.data.int_val;
                break;
            case EXPR_GT:
-               e->right.int_val = e->right.int_val > e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val > e->left.data.int_val;
                break;
            case EXPR_LE:
-               e->right.int_val = e->right.int_val <= e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val <= e->left.data.int_val;
                break;
            case EXPR_GE:
-               e->right.int_val = e->right.int_val >= e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val >= e->left.data.int_val;
                break;
            case EXPR_NE:
-               e->right.int_val = e->right.int_val != e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val != e->left.data.int_val;
                break;
            case EXPR_IDENT:
                break;
@@ -254,34 +262,34 @@ expr_simplify(expr *e)
     }
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
-                                     || (e->left.int_val == 0 &&
+    else if (e->left.type == EXPR_INT && ((e->left.data.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->left.data.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->left.int_val == -1 &&
+                                     || (e->left.data.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->left.int_val == 0 &&
+                                     || (e->left.data.int_val == 0 &&
                                          e->op == EXPR_OR))) {
        e->op = EXPR_IDENT;
        simplified = 1;
     }
     /* and the corresponding x+|-0, x*&/1 */
-    else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
-                                     || (e->right.int_val == 1 &&
+    else if (e->right.type == EXPR_INT && ((e->right.data.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->right.data.int_val == 1 &&
                                          e->op == EXPR_DIV)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SUB)
-                                     || (e->right.int_val == -1 &&
+                                     || (e->right.data.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_OR)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SHL)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SHR))) {
        e->op = EXPR_IDENT;
-       e->rtype = e->ltype;
+       e->right.type = e->left.type;
        memcpy(&e->right, &e->left, sizeof(ExprItem));
        simplified = 1;
     }
@@ -292,11 +300,11 @@ expr_simplify(expr *e)
 int
 expr_get_value(expr *e, unsigned long *retval)
 {
-    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
+    while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
           && expr_simplify(e)) ;
 
-    if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
-       *retval = e->right.int_val;
+    if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
+       *retval = e->right.data.int_val;
        return 1;
     } else
        return 0;
@@ -306,20 +314,20 @@ void
 expr_print(expr *e)
 {
     if (e->op != EXPR_IDENT) {
-       switch (e->ltype) {
+       switch (e->left.type) {
            case EXPR_SYM:
-               printf("%s", e->left.sym->name);
+               printf("%s", symrec_get_name(e->left.data.sym));
                break;
            case EXPR_EXPR:
                printf("(");
-               expr_print(e->left.exp);
+               expr_print(e->left.data.expn);
                printf(")");
                break;
            case EXPR_INT:
-               printf("%lu", e->left.int_val);
+               printf("%lu", e->left.data.int_val);
                break;
            case EXPR_FLOAT:
-               floatnum_print(e->left.flt);
+               floatnum_print(e->left.data.flt);
                break;
            case EXPR_NONE:
                break;
@@ -392,20 +400,20 @@ expr_print(expr *e)
        case EXPR_IDENT:
            break;
     }
-    switch (e->rtype) {
+    switch (e->right.type) {
        case EXPR_SYM:
-           printf("%s", e->right.sym->name);
+           printf("%s", symrec_get_name(e->right.data.sym));
            break;
        case EXPR_EXPR:
            printf("(");
-           expr_print(e->right.exp);
+           expr_print(e->right.data.expn);
            printf(")");
            break;
        case EXPR_INT:
-           printf("%lu", e->right.int_val);
+           printf("%lu", e->right.data.int_val);
            break;
        case EXPR_FLOAT:
-           floatnum_print(e->right.flt);
+           floatnum_print(e->right.data.flt);
            break;
        case EXPR_NONE:
            break;
index 6846fdb23067d0ddce2870898399c0c0f81f8498..25a0bb48f92f234643a3f4a775b6b10ce8483cf2 100644 (file)
 #ifndef YASM_EXPR_H
 #define YASM_EXPR_H
 
+#ifndef YASM_SYMREC
+#define YASM_SYMREC
+typedef struct symrec symrec;
+#endif
+
+#ifndef YASM_FLOATNUM
+#define YASM_FLOATNUM
+typedef struct floatnum floatnum;
+#endif
+
 typedef enum {
     EXPR_ADD,
     EXPR_SUB,
@@ -47,41 +57,26 @@ typedef enum {
     EXPR_IDENT                 /* if right is IDENT, then the entire expr is just a num */
 } ExprOp;
 
-typedef enum {
-    EXPR_NONE,                 /* for left side of a NOT, NEG, etc. */
-    EXPR_SYM,
-    EXPR_EXPR,
-    EXPR_INT,
-    EXPR_FLOAT
-} ExprType;
-
-typedef union expritem_u {
-    struct symrec_s *sym;
-    struct expr_s *exp;
-    unsigned long int_val;
-    struct floatnum_s *flt;
-} ExprItem;
+typedef struct ExprItem ExprItem;
 
-typedef struct expr_s {
-    ExprType ltype, rtype;
-    ExprItem left, right;
-    ExprOp op;
-} expr;
+#ifndef YASM_EXPR
+#define YASM_EXPR
+typedef struct expr expr;
+#endif
 
-expr *expr_new(ExprType, ExprItem, ExprOp, ExprType, ExprItem);
+expr *expr_new(ExprItem *, ExprOp, ExprItem *);
 
-ExprItem ExprSym(struct symrec_s *);
-ExprItem ExprExpr(expr *);
-ExprItem ExprInt(unsigned long);
-ExprItem ExprFloat(struct floatnum_s *);
-ExprItem ExprNone(void);
+ExprItem *ExprSym(symrec *);
+ExprItem *ExprExpr(expr *);
+ExprItem *ExprInt(unsigned long);
+ExprItem *ExprFloat(floatnum *);
 
 #define expr_new_tree(l,o,r) \
-    expr_new (EXPR_EXPR, ExprExpr(l), (o), EXPR_EXPR, ExprExpr(r))
+    expr_new (ExprExpr(l), (o), ExprExpr(r))
 #define expr_new_branch(o,r) \
-    expr_new (EXPR_NONE, ExprNone(), (o), EXPR_EXPR, ExprExpr(r))
-#define expr_new_ident(t,r) \
-    expr_new (EXPR_NONE, ExprNone(), EXPR_IDENT, (ExprType)(t), (r))
+    expr_new ((ExprItem *)NULL, (o), ExprExpr(r))
+#define expr_new_ident(r) \
+    expr_new ((ExprItem *)NULL, EXPR_IDENT, (r))
 
 int expr_simplify(expr *);
 void expr_print(expr *);
index 5979fe1fc2c81706d381b6ddb8b94aa66899da60..b658ee983e1f74991b5d8fb0b7a7a140f2aff74c 100644 (file)
 
 RCSID("$IdPath$");
 
+/* 97-bit internal floating point format:
+ * xxxxxxxs eeeeeeee eeeeeeee m.....................................m
+ * Sign          exponent     mantissa (80 bits)
+ *                            79                                    0
+ *
+ * Only L.O. bit of Sign byte is significant.  The rest is garbage.
+ * Exponent is bias 32767.
+ * Mantissa does NOT have an implied one bit (it's explicit).
+ */
+struct floatnum {
+    unsigned int *mantissa;    /* Allocated to 64 bits */
+    unsigned short exponent;
+    unsigned char sign;
+    unsigned char flags;
+};
+
 /* constants describing parameters of internal floating point format */
 #define MANT_BITS      80
 #define MANT_BYTES     10
index 554d4aae9cf2728baf8e259eaabe4b5113aea8e7..612922497468264c37d61426e37f69f9aff908c8 100644 (file)
 #ifndef YASM_FLOATNUM_H
 #define YASM_FLOATNUM_H
 
-/* 97-bit internal floating point format:
- * xxxxxxxs eeeeeeee eeeeeeee m.....................................m
- * Sign          exponent     mantissa (80 bits)
- *                            79                                    0
- *
- * Only L.O. bit of Sign byte is significant.  The rest is garbage.
- * Exponent is bias 32767.
- * Mantissa does NOT have an implied one bit (it's explicit).
- */
-typedef struct floatnum_s {
-    unsigned int *mantissa;    /* Allocated to 64 bits */
-    unsigned short exponent;
-    unsigned char sign;
-    unsigned char flags;
-} floatnum;
+#ifndef YASM_FLOATNUM
+#define YASM_FLOATNUM
+typedef struct floatnum floatnum;
+#endif
 
 floatnum *floatnum_new(const char *str);
 void floatnum_delete(floatnum *flt);
index 7670e8b264027053eef5a00d3aaecf0b461793e6..e655a5c2ec518ccdf2fda24f27ddc07f11313468 100644 (file)
 
 RCSID("$IdPath$");
 
+struct section {
+    STAILQ_ENTRY(section) link;
+
+    enum { SECTION_GENERAL, SECTION_ABSOLUTE } type;
+
+    char *name;                        /* strdup()'ed name (given by user) */
+
+    union {
+       /* SECTION_GENERAL data */
+       /* SECTION_ABSOLUTE data */
+       unsigned long start;
+    } data;
+
+    bytecodehead bc;           /* the bytecodes for the section's contents */
+};
+
 section *
 sections_initialize(sectionhead *headp, objfmt *of)
 {
@@ -107,3 +123,9 @@ sections_switch(sectionhead *headp, objfmt *of, const char *name)
 
     return s;
 }
+
+bytecodehead *
+section_get_bytecodes(section *sect)
+{
+    return &sect->bc;
+}
index 71dd50b277152e229b3ded79544cb90e10f0498e..ff881721cacf0b115cc488415ea0658672bccecf 100644 (file)
 
 struct objfmt_s;
 
-typedef STAILQ_HEAD(sectionhead_s, section_s) sectionhead;
+typedef STAILQ_HEAD(sectionhead, section) sectionhead;
 
-typedef struct section_s {
-    STAILQ_ENTRY(section_s) link;
-
-    enum { SECTION_GENERAL, SECTION_ABSOLUTE } type;
-
-    char *name;                        /* strdup()'ed name (given by user) */
-
-    union {
-       /* SECTION_GENERAL data */
-       /* SECTION_ABSOLUTE data */
-       unsigned long start;
-    } data;
-
-    bytecodehead bc;           /* the bytecodes for the section's contents */
-} section;
+#ifndef YASM_SECTION
+#define YASM_SECTION
+typedef struct section section;
+#endif
 
 section *sections_initialize(sectionhead *headp, struct objfmt_s *of);
 
 section *sections_switch(sectionhead *headp, struct objfmt_s *of,
                         const char *name);
 
+bytecodehead *section_get_bytecodes(section *sect);
 #endif
index cd3704e2c048235b4a7e82a73e1903d2e4a84314..df2c2733948d8d2a3dca6c7a9efe78cf00273bbd 100644 (file)
 
 RCSID("$IdPath$");
 
+struct symrec {
+    char *name;
+    SymType type;
+    SymStatus status;
+    SymVisibility visibility;
+    char *filename;            /* file and line */
+    unsigned long line;                /*  symbol was first declared or used on */
+    union {
+       unsigned long int_val;  /* integer constant */
+       floatnum *flt;          /* floating point constant */
+       struct label_s {        /* bytecode immediately preceding a label */
+           section *sect;
+           bytecode *bc;
+       } label;
+    } value;
+};
+
 /* private functions */
 static symrec *symrec_get_or_new(const char *);
 static symrec *symrec_define(const char *, SymType type);
@@ -192,3 +209,9 @@ symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
     /* We can't get the value right now. */
     return 0;
 }
+
+const char *
+symrec_get_name(const symrec *sym)
+{
+    return sym->name;
+}
index 21183f4bdf8c6de433ea13a97025b26a8bc19458..88bc608e0870f5355867da7cc310fe490f4a870a 100644 (file)
 #ifndef YASM_SYMREC_H
 #define YASM_SYMREC_H
 
+#ifndef YASM_FLOATNUM
+#define YASM_FLOATNUM
+typedef struct floatnum floatnum;
+#endif
+
+#ifndef YASM_SECTION
+#define YASM_SECTION
+typedef struct section section;
+#endif
+
+#ifndef YASM_BYTECODE
+#define YASM_BYTECODE
+typedef struct bytecode bytecode;
+#endif
+
 /* DEFINED is set with EXTERN and COMMON below */
 typedef enum {
     SYM_NOSTATUS = 0,
@@ -45,28 +60,15 @@ typedef enum {
     SYM_LABEL                  /* for labels */
 } SymType;
 
-typedef struct symrec_s {
-    char *name;
-    SymType type;
-    SymStatus status;
-    SymVisibility visibility;
-    char *filename;            /* file and line */
-    unsigned long line;                /*  symbol was first declared or used on */
-    union {
-       unsigned long int_val;  /* integer constant */
-       struct floatnum_s *flt; /* floating point constant */
-       struct label_s {        /* bytecode immediately preceding a label */
-           struct section_s *sect;
-           struct bytecode_s *bc;
-       } label;
-    } value;
-} symrec;
+#ifndef YASM_SYMREC
+#define YASM_SYMREC
+typedef struct symrec symrec;
+#endif
 
 symrec *symrec_use(const char *name);
 symrec *symrec_define_constant_int(const char *name, unsigned long int_val);
-symrec *symrec_define_constant_float(const char *name, struct floatnum_s *flt);
-symrec *symrec_define_label(const char *name, struct section_s *sect,
-                           struct bytecode_s *precbc);
+symrec *symrec_define_constant_float(const char *name, floatnum *flt);
+symrec *symrec_define_label(const char *name, section *sect, bytecode *precbc);
 symrec *symrec_declare(const char *name, SymVisibility vis);
 
 /* Get the numeric 32-bit value of a symbol if possible.
@@ -77,6 +79,8 @@ symrec *symrec_declare(const char *name, SymVisibility vis);
 int symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
                         int resolve_label);
 
+const char *symrec_get_name(const symrec *sym);
+
 void symrec_foreach(int (*func) (const char *name, symrec *rec));
 
 #endif
index a5430acbf871caf51d99603cb6e48e1318b7d118..169cae5cec26ed48bb3db827032ca0476fb5bc3c 100644 (file)
@@ -21,7 +21,8 @@ bytecode_test_SOURCES = \
 floatnum_test_SOURCES = \
        floatnum_test.c
 
-INCLUDES= -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/check
+INCLUDES= -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/check \
+       -I$(top_builddir)/intl
 LDADD = \
        $(top_builddir)/check/libcheck.a                        \
        $(top_builddir)/src/parsers/nasm/libparser.a            \
index c9898c0b31630d77f5c4444b6800464f332de8d1..77eadc6ad9c9302dc427994a5b85c06439aee684 100644 (file)
@@ -28,9 +28,7 @@
 
 #include "check.h"
 
-#include "util.h"
-
-#include "bytecode.h"
+#include "bytecode.c"
 
 START_TEST(test_effaddr_new_reg)
 {
index b3c5c31a83a900699991641cecf1f581a473047a..d768e3c7adf1a8235cf213d4cc6a03514da679a7 100644 (file)
@@ -31,9 +31,7 @@
 
 #include "check.h"
 
-#include "bitvect.h"
-
-#include "floatnum.h"
+#include "floatnum.c"
 
 /* constants describing parameters of internal floating point format.
  *  (these should match those in src/floatnum.c !)
index 94740c00c2bce8af8c758aa68733ff4220163995..dc56962b745296a2b329efdfe46780bedfb04789 100644 (file)
 # include <string.h>
 #endif
 
+#include <libintl.h>
+#define _(String)      gettext(String)
+#ifdef gettext_noop
+#define N_(String)     gettext_noop(String)
+#else
+#define N_(String)     (String)
+#endif
+
 #include "globals.h"
 #include "errwarn.h"
 #include "floatnum.h"
 
 RCSID("$IdPath$");
 
+typedef enum {
+    EXPR_NONE,                 /* for left side of a NOT, NEG, etc. */
+    EXPR_SYM,
+    EXPR_EXPR,
+    EXPR_INT,
+    EXPR_FLOAT
+} ExprType;
+
+struct ExprItem {
+    ExprType type;
+    union {
+       symrec *sym;
+       expr *expn;
+       unsigned long int_val;
+       floatnum *flt;
+    } data;
+};
+
+struct expr {
+    ExprItem left, right;
+    ExprOp op;
+};
+
 /* allocate a new expression node, with children as defined.
  * If it's a unary operator, put the element on the right */
 expr *
-expr_new(ExprType ltype,
-        ExprItem left,
-        ExprOp   op,
-        ExprType rtype,
-        ExprItem right)
+expr_new(ExprItem *left, ExprOp op, ExprItem *right)
 {
     expr *ptr;
     ptr = xmalloc(sizeof(expr));
 
-    ptr->ltype = ltype;
+    ptr->left.type = EXPR_NONE;
     ptr->op = op;
-    ptr->rtype = rtype;
-    switch (ltype) {
-       case EXPR_SYM:
-       case EXPR_EXPR:
-       case EXPR_INT:
-       case EXPR_FLOAT:
-           memcpy(&ptr->left, &left, sizeof(ExprItem));
-           break;
-       case EXPR_NONE:
-           break;
+    ptr->right.type = EXPR_NONE;
+    if (left) {
+       memcpy(&ptr->left, left, sizeof(ExprItem));
+       free(left);
     }
-    switch (rtype) {
-       case EXPR_SYM:
-       case EXPR_EXPR:
-       case EXPR_INT:
-       case EXPR_FLOAT:
-           memcpy(&ptr->right, &right, sizeof(ExprItem));
-           break;
-       case EXPR_NONE:
-           Fatal(FATAL_UNKNOWN);       /* TODO: better error? */
-           break;
+    if (right) {
+       memcpy(&ptr->right, right, sizeof(ExprItem));
+       free(right);
+    } else {
+       InternalError(__LINE__, __FILE__,
+                     _("Right side of expression must exist"));
     }
     return ptr;
 }
 
 /* helpers */
-ExprItem
-ExprSym(struct symrec_s *s)
+ExprItem *
+ExprSym(symrec *s)
 {
-    ExprItem e;
-
-    e.sym = s;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_SYM;
+    e->data.sym = s;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprExpr(expr *x)
 {
-    ExprItem e;
-    e.exp = x;
-
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_EXPR;
+    e->data.expn = x;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprInt(unsigned long i)
 {
-    ExprItem e;
-
-    e.int_val = i;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_INT;
+    e->data.int_val = i;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprFloat(floatnum *f)
 {
-    ExprItem e;
-
-    e.flt = f;
-    return e;
-}
-
-ExprItem
-ExprNone(void)
-{
-    ExprItem e;
-
-    e.int_val = 0;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_FLOAT;
+    e->data.flt = f;
     return e;
 }
 
@@ -133,118 +141,118 @@ expr_simplify(expr *e)
     unsigned long int_val;
 
     /* try to simplify the left side */
-    if (e->ltype == EXPR_EXPR) {
+    if (e->left.type == EXPR_EXPR) {
        /* if the left subexpr isn't an IDENT, recurse simplification */
-       if (e->left.exp->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->left.exp);
+       if (e->left.data.expn->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->left.data.expn);
 
        /* if the left subexpr is just an IDENT (or string thereof),
         * pull it up into the current node */
-       while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
+       while (e->left.type == EXPR_EXPR && e->left.data.expn->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->ltype = e->left.exp->rtype;
-           memcpy(&tmp, &(e->left.exp->right), sizeof(ExprItem));
-           free(e->left.exp);
-           memcpy(&(e->left.int_val), &tmp, sizeof(ExprItem));
+           e->left.type = e->left.data.expn->right.type;
+           memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
+           free(e->left.data.expn);
+           memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->ltype == EXPR_SYM) {
+    } else if (e->left.type == EXPR_SYM) {
        /* try to get value of symbol */
-       if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
-           e->ltype = EXPR_INT;
+       if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
+           e->left.type = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->left.int_val = int_val;
+           e->left.data.int_val = int_val;
            simplified = 1;
        }
     }
 
     /* ditto on the right */
-    if (e->rtype == EXPR_EXPR) {
-       if (e->right.exp->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->right.exp);
+    if (e->right.type == EXPR_EXPR) {
+       if (e->right.data.expn->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->right.data.expn);
 
-       while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
+       while (e->right.type == EXPR_EXPR && e->right.data.expn->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->rtype = e->right.exp->rtype;
-           memcpy(&tmp, &(e->right.exp->right), sizeof(ExprItem));
-           free(e->right.exp);
-           memcpy(&(e->right.int_val), &tmp, sizeof(ExprItem));
+           e->right.type = e->right.data.expn->right.type;
+           memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
+           free(e->right.data.expn);
+           memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->rtype == EXPR_SYM) {
-       if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
-           e->rtype = EXPR_INT;
+    } else if (e->right.type == EXPR_SYM) {
+       if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
+           e->right.type = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->right.int_val = int_val;
+           e->right.data.int_val = int_val;
            simplified = 1;
        }
     }
 
-    if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
-       && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
+    if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE)
+       && e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
        switch (e->op) {
            case EXPR_ADD:
-               e->right.int_val = e->left.int_val + e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val + e->right.data.int_val;
                break;
            case EXPR_SUB:
-               e->right.int_val = e->left.int_val - e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val - e->right.data.int_val;
                break;
            case EXPR_MUL:
-               e->right.int_val = e->left.int_val * e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val * e->right.data.int_val;
                break;
            case EXPR_DIV:
-               e->right.int_val = e->left.int_val / e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val / e->right.data.int_val;
                break;
            case EXPR_MOD:
-               e->right.int_val = e->left.int_val % e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val % e->right.data.int_val;
                break;
            case EXPR_NEG:
-               e->right.int_val = -(e->right.int_val);
+               e->right.data.int_val = -(e->right.data.int_val);
                break;
            case EXPR_NOT:
-               e->right.int_val = ~(e->right.int_val);
+               e->right.data.int_val = ~(e->right.data.int_val);
                break;
            case EXPR_OR:
-               e->right.int_val = e->left.int_val | e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val | e->right.data.int_val;
                break;
            case EXPR_AND:
-               e->right.int_val = e->left.int_val & e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val & e->right.data.int_val;
                break;
            case EXPR_XOR:
-               e->right.int_val = e->left.int_val ^ e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val ^ e->right.data.int_val;
                break;
            case EXPR_SHL:
-               e->right.int_val = e->right.int_val << e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
                break;
            case EXPR_SHR:
-               e->right.int_val = e->right.int_val << e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
                break;
            case EXPR_LOR:
-               e->right.int_val = e->left.int_val || e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val || e->right.data.int_val;
                break;
            case EXPR_LAND:
-               e->right.int_val = e->left.int_val && e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val && e->right.data.int_val;
                break;
            case EXPR_LNOT:
-               e->right.int_val = !e->right.int_val;
+               e->right.data.int_val = !e->right.data.int_val;
                break;
            case EXPR_EQ:
-               e->right.int_val = e->right.int_val == e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val == e->left.data.int_val;
                break;
            case EXPR_LT:
-               e->right.int_val = e->right.int_val < e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val < e->left.data.int_val;
                break;
            case EXPR_GT:
-               e->right.int_val = e->right.int_val > e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val > e->left.data.int_val;
                break;
            case EXPR_LE:
-               e->right.int_val = e->right.int_val <= e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val <= e->left.data.int_val;
                break;
            case EXPR_GE:
-               e->right.int_val = e->right.int_val >= e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val >= e->left.data.int_val;
                break;
            case EXPR_NE:
-               e->right.int_val = e->right.int_val != e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val != e->left.data.int_val;
                break;
            case EXPR_IDENT:
                break;
@@ -254,34 +262,34 @@ expr_simplify(expr *e)
     }
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
-                                     || (e->left.int_val == 0 &&
+    else if (e->left.type == EXPR_INT && ((e->left.data.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->left.data.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->left.int_val == -1 &&
+                                     || (e->left.data.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->left.int_val == 0 &&
+                                     || (e->left.data.int_val == 0 &&
                                          e->op == EXPR_OR))) {
        e->op = EXPR_IDENT;
        simplified = 1;
     }
     /* and the corresponding x+|-0, x*&/1 */
-    else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
-                                     || (e->right.int_val == 1 &&
+    else if (e->right.type == EXPR_INT && ((e->right.data.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->right.data.int_val == 1 &&
                                          e->op == EXPR_DIV)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SUB)
-                                     || (e->right.int_val == -1 &&
+                                     || (e->right.data.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_OR)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SHL)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SHR))) {
        e->op = EXPR_IDENT;
-       e->rtype = e->ltype;
+       e->right.type = e->left.type;
        memcpy(&e->right, &e->left, sizeof(ExprItem));
        simplified = 1;
     }
@@ -292,11 +300,11 @@ expr_simplify(expr *e)
 int
 expr_get_value(expr *e, unsigned long *retval)
 {
-    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
+    while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
           && expr_simplify(e)) ;
 
-    if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
-       *retval = e->right.int_val;
+    if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
+       *retval = e->right.data.int_val;
        return 1;
     } else
        return 0;
@@ -306,20 +314,20 @@ void
 expr_print(expr *e)
 {
     if (e->op != EXPR_IDENT) {
-       switch (e->ltype) {
+       switch (e->left.type) {
            case EXPR_SYM:
-               printf("%s", e->left.sym->name);
+               printf("%s", symrec_get_name(e->left.data.sym));
                break;
            case EXPR_EXPR:
                printf("(");
-               expr_print(e->left.exp);
+               expr_print(e->left.data.expn);
                printf(")");
                break;
            case EXPR_INT:
-               printf("%lu", e->left.int_val);
+               printf("%lu", e->left.data.int_val);
                break;
            case EXPR_FLOAT:
-               floatnum_print(e->left.flt);
+               floatnum_print(e->left.data.flt);
                break;
            case EXPR_NONE:
                break;
@@ -392,20 +400,20 @@ expr_print(expr *e)
        case EXPR_IDENT:
            break;
     }
-    switch (e->rtype) {
+    switch (e->right.type) {
        case EXPR_SYM:
-           printf("%s", e->right.sym->name);
+           printf("%s", symrec_get_name(e->right.data.sym));
            break;
        case EXPR_EXPR:
            printf("(");
-           expr_print(e->right.exp);
+           expr_print(e->right.data.expn);
            printf(")");
            break;
        case EXPR_INT:
-           printf("%lu", e->right.int_val);
+           printf("%lu", e->right.data.int_val);
            break;
        case EXPR_FLOAT:
-           floatnum_print(e->right.flt);
+           floatnum_print(e->right.data.flt);
            break;
        case EXPR_NONE:
            break;
index 94740c00c2bce8af8c758aa68733ff4220163995..dc56962b745296a2b329efdfe46780bedfb04789 100644 (file)
 # include <string.h>
 #endif
 
+#include <libintl.h>
+#define _(String)      gettext(String)
+#ifdef gettext_noop
+#define N_(String)     gettext_noop(String)
+#else
+#define N_(String)     (String)
+#endif
+
 #include "globals.h"
 #include "errwarn.h"
 #include "floatnum.h"
 
 RCSID("$IdPath$");
 
+typedef enum {
+    EXPR_NONE,                 /* for left side of a NOT, NEG, etc. */
+    EXPR_SYM,
+    EXPR_EXPR,
+    EXPR_INT,
+    EXPR_FLOAT
+} ExprType;
+
+struct ExprItem {
+    ExprType type;
+    union {
+       symrec *sym;
+       expr *expn;
+       unsigned long int_val;
+       floatnum *flt;
+    } data;
+};
+
+struct expr {
+    ExprItem left, right;
+    ExprOp op;
+};
+
 /* allocate a new expression node, with children as defined.
  * If it's a unary operator, put the element on the right */
 expr *
-expr_new(ExprType ltype,
-        ExprItem left,
-        ExprOp   op,
-        ExprType rtype,
-        ExprItem right)
+expr_new(ExprItem *left, ExprOp op, ExprItem *right)
 {
     expr *ptr;
     ptr = xmalloc(sizeof(expr));
 
-    ptr->ltype = ltype;
+    ptr->left.type = EXPR_NONE;
     ptr->op = op;
-    ptr->rtype = rtype;
-    switch (ltype) {
-       case EXPR_SYM:
-       case EXPR_EXPR:
-       case EXPR_INT:
-       case EXPR_FLOAT:
-           memcpy(&ptr->left, &left, sizeof(ExprItem));
-           break;
-       case EXPR_NONE:
-           break;
+    ptr->right.type = EXPR_NONE;
+    if (left) {
+       memcpy(&ptr->left, left, sizeof(ExprItem));
+       free(left);
     }
-    switch (rtype) {
-       case EXPR_SYM:
-       case EXPR_EXPR:
-       case EXPR_INT:
-       case EXPR_FLOAT:
-           memcpy(&ptr->right, &right, sizeof(ExprItem));
-           break;
-       case EXPR_NONE:
-           Fatal(FATAL_UNKNOWN);       /* TODO: better error? */
-           break;
+    if (right) {
+       memcpy(&ptr->right, right, sizeof(ExprItem));
+       free(right);
+    } else {
+       InternalError(__LINE__, __FILE__,
+                     _("Right side of expression must exist"));
     }
     return ptr;
 }
 
 /* helpers */
-ExprItem
-ExprSym(struct symrec_s *s)
+ExprItem *
+ExprSym(symrec *s)
 {
-    ExprItem e;
-
-    e.sym = s;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_SYM;
+    e->data.sym = s;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprExpr(expr *x)
 {
-    ExprItem e;
-    e.exp = x;
-
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_EXPR;
+    e->data.expn = x;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprInt(unsigned long i)
 {
-    ExprItem e;
-
-    e.int_val = i;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_INT;
+    e->data.int_val = i;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprFloat(floatnum *f)
 {
-    ExprItem e;
-
-    e.flt = f;
-    return e;
-}
-
-ExprItem
-ExprNone(void)
-{
-    ExprItem e;
-
-    e.int_val = 0;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_FLOAT;
+    e->data.flt = f;
     return e;
 }
 
@@ -133,118 +141,118 @@ expr_simplify(expr *e)
     unsigned long int_val;
 
     /* try to simplify the left side */
-    if (e->ltype == EXPR_EXPR) {
+    if (e->left.type == EXPR_EXPR) {
        /* if the left subexpr isn't an IDENT, recurse simplification */
-       if (e->left.exp->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->left.exp);
+       if (e->left.data.expn->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->left.data.expn);
 
        /* if the left subexpr is just an IDENT (or string thereof),
         * pull it up into the current node */
-       while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
+       while (e->left.type == EXPR_EXPR && e->left.data.expn->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->ltype = e->left.exp->rtype;
-           memcpy(&tmp, &(e->left.exp->right), sizeof(ExprItem));
-           free(e->left.exp);
-           memcpy(&(e->left.int_val), &tmp, sizeof(ExprItem));
+           e->left.type = e->left.data.expn->right.type;
+           memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
+           free(e->left.data.expn);
+           memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->ltype == EXPR_SYM) {
+    } else if (e->left.type == EXPR_SYM) {
        /* try to get value of symbol */
-       if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
-           e->ltype = EXPR_INT;
+       if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
+           e->left.type = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->left.int_val = int_val;
+           e->left.data.int_val = int_val;
            simplified = 1;
        }
     }
 
     /* ditto on the right */
-    if (e->rtype == EXPR_EXPR) {
-       if (e->right.exp->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->right.exp);
+    if (e->right.type == EXPR_EXPR) {
+       if (e->right.data.expn->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->right.data.expn);
 
-       while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
+       while (e->right.type == EXPR_EXPR && e->right.data.expn->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->rtype = e->right.exp->rtype;
-           memcpy(&tmp, &(e->right.exp->right), sizeof(ExprItem));
-           free(e->right.exp);
-           memcpy(&(e->right.int_val), &tmp, sizeof(ExprItem));
+           e->right.type = e->right.data.expn->right.type;
+           memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
+           free(e->right.data.expn);
+           memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->rtype == EXPR_SYM) {
-       if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
-           e->rtype = EXPR_INT;
+    } else if (e->right.type == EXPR_SYM) {
+       if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
+           e->right.type = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->right.int_val = int_val;
+           e->right.data.int_val = int_val;
            simplified = 1;
        }
     }
 
-    if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
-       && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
+    if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE)
+       && e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
        switch (e->op) {
            case EXPR_ADD:
-               e->right.int_val = e->left.int_val + e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val + e->right.data.int_val;
                break;
            case EXPR_SUB:
-               e->right.int_val = e->left.int_val - e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val - e->right.data.int_val;
                break;
            case EXPR_MUL:
-               e->right.int_val = e->left.int_val * e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val * e->right.data.int_val;
                break;
            case EXPR_DIV:
-               e->right.int_val = e->left.int_val / e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val / e->right.data.int_val;
                break;
            case EXPR_MOD:
-               e->right.int_val = e->left.int_val % e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val % e->right.data.int_val;
                break;
            case EXPR_NEG:
-               e->right.int_val = -(e->right.int_val);
+               e->right.data.int_val = -(e->right.data.int_val);
                break;
            case EXPR_NOT:
-               e->right.int_val = ~(e->right.int_val);
+               e->right.data.int_val = ~(e->right.data.int_val);
                break;
            case EXPR_OR:
-               e->right.int_val = e->left.int_val | e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val | e->right.data.int_val;
                break;
            case EXPR_AND:
-               e->right.int_val = e->left.int_val & e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val & e->right.data.int_val;
                break;
            case EXPR_XOR:
-               e->right.int_val = e->left.int_val ^ e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val ^ e->right.data.int_val;
                break;
            case EXPR_SHL:
-               e->right.int_val = e->right.int_val << e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
                break;
            case EXPR_SHR:
-               e->right.int_val = e->right.int_val << e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
                break;
            case EXPR_LOR:
-               e->right.int_val = e->left.int_val || e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val || e->right.data.int_val;
                break;
            case EXPR_LAND:
-               e->right.int_val = e->left.int_val && e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val && e->right.data.int_val;
                break;
            case EXPR_LNOT:
-               e->right.int_val = !e->right.int_val;
+               e->right.data.int_val = !e->right.data.int_val;
                break;
            case EXPR_EQ:
-               e->right.int_val = e->right.int_val == e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val == e->left.data.int_val;
                break;
            case EXPR_LT:
-               e->right.int_val = e->right.int_val < e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val < e->left.data.int_val;
                break;
            case EXPR_GT:
-               e->right.int_val = e->right.int_val > e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val > e->left.data.int_val;
                break;
            case EXPR_LE:
-               e->right.int_val = e->right.int_val <= e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val <= e->left.data.int_val;
                break;
            case EXPR_GE:
-               e->right.int_val = e->right.int_val >= e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val >= e->left.data.int_val;
                break;
            case EXPR_NE:
-               e->right.int_val = e->right.int_val != e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val != e->left.data.int_val;
                break;
            case EXPR_IDENT:
                break;
@@ -254,34 +262,34 @@ expr_simplify(expr *e)
     }
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
-                                     || (e->left.int_val == 0 &&
+    else if (e->left.type == EXPR_INT && ((e->left.data.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->left.data.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->left.int_val == -1 &&
+                                     || (e->left.data.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->left.int_val == 0 &&
+                                     || (e->left.data.int_val == 0 &&
                                          e->op == EXPR_OR))) {
        e->op = EXPR_IDENT;
        simplified = 1;
     }
     /* and the corresponding x+|-0, x*&/1 */
-    else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
-                                     || (e->right.int_val == 1 &&
+    else if (e->right.type == EXPR_INT && ((e->right.data.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->right.data.int_val == 1 &&
                                          e->op == EXPR_DIV)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SUB)
-                                     || (e->right.int_val == -1 &&
+                                     || (e->right.data.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_OR)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SHL)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SHR))) {
        e->op = EXPR_IDENT;
-       e->rtype = e->ltype;
+       e->right.type = e->left.type;
        memcpy(&e->right, &e->left, sizeof(ExprItem));
        simplified = 1;
     }
@@ -292,11 +300,11 @@ expr_simplify(expr *e)
 int
 expr_get_value(expr *e, unsigned long *retval)
 {
-    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
+    while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
           && expr_simplify(e)) ;
 
-    if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
-       *retval = e->right.int_val;
+    if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
+       *retval = e->right.data.int_val;
        return 1;
     } else
        return 0;
@@ -306,20 +314,20 @@ void
 expr_print(expr *e)
 {
     if (e->op != EXPR_IDENT) {
-       switch (e->ltype) {
+       switch (e->left.type) {
            case EXPR_SYM:
-               printf("%s", e->left.sym->name);
+               printf("%s", symrec_get_name(e->left.data.sym));
                break;
            case EXPR_EXPR:
                printf("(");
-               expr_print(e->left.exp);
+               expr_print(e->left.data.expn);
                printf(")");
                break;
            case EXPR_INT:
-               printf("%lu", e->left.int_val);
+               printf("%lu", e->left.data.int_val);
                break;
            case EXPR_FLOAT:
-               floatnum_print(e->left.flt);
+               floatnum_print(e->left.data.flt);
                break;
            case EXPR_NONE:
                break;
@@ -392,20 +400,20 @@ expr_print(expr *e)
        case EXPR_IDENT:
            break;
     }
-    switch (e->rtype) {
+    switch (e->right.type) {
        case EXPR_SYM:
-           printf("%s", e->right.sym->name);
+           printf("%s", symrec_get_name(e->right.data.sym));
            break;
        case EXPR_EXPR:
            printf("(");
-           expr_print(e->right.exp);
+           expr_print(e->right.data.expn);
            printf(")");
            break;
        case EXPR_INT:
-           printf("%lu", e->right.int_val);
+           printf("%lu", e->right.data.int_val);
            break;
        case EXPR_FLOAT:
-           floatnum_print(e->right.flt);
+           floatnum_print(e->right.data.flt);
            break;
        case EXPR_NONE:
            break;
index 34129f71c6e00007bf2d3f8086e6fa824a87f76b..c69c2e66ed7f236fe23eab7bfbc3062f0fbf8529 100644 (file)
@@ -71,7 +71,7 @@ static bytecode *nasm_parser_temp_bc;
     unsigned char groupdata[4];
     effaddr *ea;
     expr *exp;
-    immval im_val;
+    immval *im_val;
     targetval tgt_val;
     datavalhead datahead;
     dataval *data;
@@ -128,7 +128,7 @@ static bytecode *nasm_parser_temp_bc;
 %%
 input: /* empty */
     | input line    {
-       nasm_parser_temp_bc = bytecodes_append(&nasm_parser_cur_section->bc,
+       nasm_parser_temp_bc = bytecodes_append(section_get_bytecodes(nasm_parser_cur_section),
                                               $2);
        if (nasm_parser_temp_bc)
            nasm_parser_prev_bc = nasm_parser_temp_bc;
@@ -154,13 +154,11 @@ exp: instr
 ;
 
 datavals: dataval          {
-       STAILQ_INIT(&$$);
-       if ($1)
-           STAILQ_INSERT_TAIL(&$$, $1, link);
+       datavals_initialize(&$$);
+       datavals_append(&$$, $1);
     }
     | datavals ',' dataval  {
-       if ($3)
-           STAILQ_INSERT_TAIL(&$1, $3, link);
+       datavals_append(&$1, $3);
        $$ = $1;
     }
 ;
@@ -259,7 +257,7 @@ segreg:  REG_ES
 memexp: expr   { expr_simplify ($1); $$ = effaddr_new_expr($1); }
 ;
 
-memaddr: memexp                    { $$ = $1; $$->segment = 0; }
+memaddr: memexp                    { $$ = $1; SetEASegment($$, 0); }
     | REG_CS ':' memaddr    { $$ = $3; SetEASegment($$, 0x2E); }
     | REG_SS ':' memaddr    { $$ = $3; SetEASegment($$, 0x36); }
     | REG_DS ':' memaddr    { $$ = $3; SetEASegment($$, 0x3E); }
@@ -355,7 +353,7 @@ rm128: XMMREG       { $$ = effaddr_new_reg($1); }
 ;
 
 /* immediate values */
-imm: expr   { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
+imm: expr   { expr_simplify($1); $$ = immval_new_expr($1); }
 ;
 
 /* explicit immediates */
@@ -378,16 +376,14 @@ imm32: imm
 ;
 
 /* jump targets */
-target: expr       { $$.val = $1; $$.op_sel = JR_NONE; }
+target: expr       { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); }
     | SHORT target  { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); }
     | NEAR target   { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); }
 ;
 
 /* expression trees */
-expr_no_string: INTNUM         { $$ = expr_new_ident(EXPR_INT, ExprInt($1)); }
-    | explabel                 {
-       $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1)));
-    }
+expr_no_string: INTNUM         { $$ = expr_new_ident(ExprInt($1)); }
+    | explabel                 { $$ = expr_new_ident(ExprSym(symrec_use($1))); }
     /*| expr '||' expr         { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
     | expr '|' expr            { $$ = expr_new_tree($1, EXPR_OR, $3); }
     | expr '^' expr            { $$ = expr_new_tree($1, EXPR_XOR, $3); }
@@ -415,7 +411,7 @@ expr_no_string: INTNUM              { $$ = expr_new_ident(EXPR_INT, ExprInt($1)); }
 
 expr: expr_no_string
     | STRING           {
-       $$ = expr_new_ident (EXPR_INT, ExprInt(ConvertCharConstToInt($1)));
+       $$ = expr_new_ident(ExprInt(ConvertCharConstToInt($1)));
     }
 ;
 
@@ -427,12 +423,12 @@ explabel: ID
 instr: instrbase
     | OPERSIZE instr   { $$ = $2; SetInsnOperSizeOverride($$, $1); }
     | ADDRSIZE instr   { $$ = $2; SetInsnAddrSizeOverride($$, $1); }
-    | REG_CS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x2E); }
-    | REG_SS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x36); }
-    | REG_DS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x3E); }
-    | REG_ES instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x26); }
-    | REG_FS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x64); }
-    | REG_GS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x65); }
+    | REG_CS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x2E); }
+    | REG_SS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x36); }
+    | REG_DS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x3E); }
+    | REG_ES instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x26); }
+    | REG_FS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x64); }
+    | REG_GS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x65); }
     | LOCK instr       { $$ = $2; SetInsnLockRepPrefix($$, 0xF0); }
     | REPNZ instr      { $$ = $2; SetInsnLockRepPrefix($$, 0xF2); }
     | REP instr                { $$ = $2; SetInsnLockRepPrefix($$, 0xF3); }
index 5b933de43987262ae58eef974840db85110ae86a..adaa58dbe18c6d10eeb8844fc1217dd26600a5b4 100755 (executable)
@@ -618,7 +618,7 @@ sub output_yacc ($@)
                        #$args[-1] =~ s/(\$\d+[ri]?)(?!\.)/\&$1/; # Just the first!
                        $args[-1] =~ s/(\$\d+)r/effaddr_new_reg($1)/;
                        $args[-1] =~ s[(\$\d+)i,\s*(\d+)]
-                           ["effaddr_new_imm(\&$1, ".($2/8)."), 0"]e;
+                           ["effaddr_new_imm($1, ".($2/8)."), 0"]e;
                        $args[-1] .= ',';
 
                        die $args[-1] if $args[-1] =~ m/\d+[ri]/;
@@ -629,11 +629,10 @@ sub output_yacc ($@)
                        $args[-1] =~ s/nil/(immval *)NULL, 0/;
                        # don't match $0.\d in the following rules.
                        $args[-1] =~ s/\$(\d+)(?!\.)/"\$".($1*2+$to).($2||'')/eg;
-                       $args[-1] =~ s/(\$\d+)(?!\.)/\&$1/; # Just the first!
                        $args[-1] =~ s[^([0-9A-Fa-f]+),]
-                           [ConvertIntToImm((immval *)NULL, 0x$1),];
+                           [immval_new_int(0x$1),];
                        $args[-1] =~ s[^\$0.(\d+),]
-                           [ConvertIntToImm((immval *)NULL, \$1\[$1\]),];
+                           [immval_new_int(\$1\[$1\]),];
 
                        # divide the second, and only the second, by 8 bits/byte
                        $args[-1] =~ s#(,\s*)(\d+)(s)?#$1 . ($2/8)#eg;
index 34129f71c6e00007bf2d3f8086e6fa824a87f76b..c69c2e66ed7f236fe23eab7bfbc3062f0fbf8529 100644 (file)
@@ -71,7 +71,7 @@ static bytecode *nasm_parser_temp_bc;
     unsigned char groupdata[4];
     effaddr *ea;
     expr *exp;
-    immval im_val;
+    immval *im_val;
     targetval tgt_val;
     datavalhead datahead;
     dataval *data;
@@ -128,7 +128,7 @@ static bytecode *nasm_parser_temp_bc;
 %%
 input: /* empty */
     | input line    {
-       nasm_parser_temp_bc = bytecodes_append(&nasm_parser_cur_section->bc,
+       nasm_parser_temp_bc = bytecodes_append(section_get_bytecodes(nasm_parser_cur_section),
                                               $2);
        if (nasm_parser_temp_bc)
            nasm_parser_prev_bc = nasm_parser_temp_bc;
@@ -154,13 +154,11 @@ exp: instr
 ;
 
 datavals: dataval          {
-       STAILQ_INIT(&$$);
-       if ($1)
-           STAILQ_INSERT_TAIL(&$$, $1, link);
+       datavals_initialize(&$$);
+       datavals_append(&$$, $1);
     }
     | datavals ',' dataval  {
-       if ($3)
-           STAILQ_INSERT_TAIL(&$1, $3, link);
+       datavals_append(&$1, $3);
        $$ = $1;
     }
 ;
@@ -259,7 +257,7 @@ segreg:  REG_ES
 memexp: expr   { expr_simplify ($1); $$ = effaddr_new_expr($1); }
 ;
 
-memaddr: memexp                    { $$ = $1; $$->segment = 0; }
+memaddr: memexp                    { $$ = $1; SetEASegment($$, 0); }
     | REG_CS ':' memaddr    { $$ = $3; SetEASegment($$, 0x2E); }
     | REG_SS ':' memaddr    { $$ = $3; SetEASegment($$, 0x36); }
     | REG_DS ':' memaddr    { $$ = $3; SetEASegment($$, 0x3E); }
@@ -355,7 +353,7 @@ rm128: XMMREG       { $$ = effaddr_new_reg($1); }
 ;
 
 /* immediate values */
-imm: expr   { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
+imm: expr   { expr_simplify($1); $$ = immval_new_expr($1); }
 ;
 
 /* explicit immediates */
@@ -378,16 +376,14 @@ imm32: imm
 ;
 
 /* jump targets */
-target: expr       { $$.val = $1; $$.op_sel = JR_NONE; }
+target: expr       { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); }
     | SHORT target  { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); }
     | NEAR target   { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); }
 ;
 
 /* expression trees */
-expr_no_string: INTNUM         { $$ = expr_new_ident(EXPR_INT, ExprInt($1)); }
-    | explabel                 {
-       $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1)));
-    }
+expr_no_string: INTNUM         { $$ = expr_new_ident(ExprInt($1)); }
+    | explabel                 { $$ = expr_new_ident(ExprSym(symrec_use($1))); }
     /*| expr '||' expr         { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
     | expr '|' expr            { $$ = expr_new_tree($1, EXPR_OR, $3); }
     | expr '^' expr            { $$ = expr_new_tree($1, EXPR_XOR, $3); }
@@ -415,7 +411,7 @@ expr_no_string: INTNUM              { $$ = expr_new_ident(EXPR_INT, ExprInt($1)); }
 
 expr: expr_no_string
     | STRING           {
-       $$ = expr_new_ident (EXPR_INT, ExprInt(ConvertCharConstToInt($1)));
+       $$ = expr_new_ident(ExprInt(ConvertCharConstToInt($1)));
     }
 ;
 
@@ -427,12 +423,12 @@ explabel: ID
 instr: instrbase
     | OPERSIZE instr   { $$ = $2; SetInsnOperSizeOverride($$, $1); }
     | ADDRSIZE instr   { $$ = $2; SetInsnAddrSizeOverride($$, $1); }
-    | REG_CS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x2E); }
-    | REG_SS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x36); }
-    | REG_DS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x3E); }
-    | REG_ES instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x26); }
-    | REG_FS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x64); }
-    | REG_GS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x65); }
+    | REG_CS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x2E); }
+    | REG_SS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x36); }
+    | REG_DS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x3E); }
+    | REG_ES instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x26); }
+    | REG_FS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x64); }
+    | REG_GS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x65); }
     | LOCK instr       { $$ = $2; SetInsnLockRepPrefix($$, 0xF0); }
     | REPNZ instr      { $$ = $2; SetInsnLockRepPrefix($$, 0xF2); }
     | REP instr                { $$ = $2; SetInsnLockRepPrefix($$, 0xF3); }
index 94740c00c2bce8af8c758aa68733ff4220163995..dc56962b745296a2b329efdfe46780bedfb04789 100644 (file)
 # include <string.h>
 #endif
 
+#include <libintl.h>
+#define _(String)      gettext(String)
+#ifdef gettext_noop
+#define N_(String)     gettext_noop(String)
+#else
+#define N_(String)     (String)
+#endif
+
 #include "globals.h"
 #include "errwarn.h"
 #include "floatnum.h"
 
 RCSID("$IdPath$");
 
+typedef enum {
+    EXPR_NONE,                 /* for left side of a NOT, NEG, etc. */
+    EXPR_SYM,
+    EXPR_EXPR,
+    EXPR_INT,
+    EXPR_FLOAT
+} ExprType;
+
+struct ExprItem {
+    ExprType type;
+    union {
+       symrec *sym;
+       expr *expn;
+       unsigned long int_val;
+       floatnum *flt;
+    } data;
+};
+
+struct expr {
+    ExprItem left, right;
+    ExprOp op;
+};
+
 /* allocate a new expression node, with children as defined.
  * If it's a unary operator, put the element on the right */
 expr *
-expr_new(ExprType ltype,
-        ExprItem left,
-        ExprOp   op,
-        ExprType rtype,
-        ExprItem right)
+expr_new(ExprItem *left, ExprOp op, ExprItem *right)
 {
     expr *ptr;
     ptr = xmalloc(sizeof(expr));
 
-    ptr->ltype = ltype;
+    ptr->left.type = EXPR_NONE;
     ptr->op = op;
-    ptr->rtype = rtype;
-    switch (ltype) {
-       case EXPR_SYM:
-       case EXPR_EXPR:
-       case EXPR_INT:
-       case EXPR_FLOAT:
-           memcpy(&ptr->left, &left, sizeof(ExprItem));
-           break;
-       case EXPR_NONE:
-           break;
+    ptr->right.type = EXPR_NONE;
+    if (left) {
+       memcpy(&ptr->left, left, sizeof(ExprItem));
+       free(left);
     }
-    switch (rtype) {
-       case EXPR_SYM:
-       case EXPR_EXPR:
-       case EXPR_INT:
-       case EXPR_FLOAT:
-           memcpy(&ptr->right, &right, sizeof(ExprItem));
-           break;
-       case EXPR_NONE:
-           Fatal(FATAL_UNKNOWN);       /* TODO: better error? */
-           break;
+    if (right) {
+       memcpy(&ptr->right, right, sizeof(ExprItem));
+       free(right);
+    } else {
+       InternalError(__LINE__, __FILE__,
+                     _("Right side of expression must exist"));
     }
     return ptr;
 }
 
 /* helpers */
-ExprItem
-ExprSym(struct symrec_s *s)
+ExprItem *
+ExprSym(symrec *s)
 {
-    ExprItem e;
-
-    e.sym = s;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_SYM;
+    e->data.sym = s;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprExpr(expr *x)
 {
-    ExprItem e;
-    e.exp = x;
-
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_EXPR;
+    e->data.expn = x;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprInt(unsigned long i)
 {
-    ExprItem e;
-
-    e.int_val = i;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_INT;
+    e->data.int_val = i;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprFloat(floatnum *f)
 {
-    ExprItem e;
-
-    e.flt = f;
-    return e;
-}
-
-ExprItem
-ExprNone(void)
-{
-    ExprItem e;
-
-    e.int_val = 0;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_FLOAT;
+    e->data.flt = f;
     return e;
 }
 
@@ -133,118 +141,118 @@ expr_simplify(expr *e)
     unsigned long int_val;
 
     /* try to simplify the left side */
-    if (e->ltype == EXPR_EXPR) {
+    if (e->left.type == EXPR_EXPR) {
        /* if the left subexpr isn't an IDENT, recurse simplification */
-       if (e->left.exp->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->left.exp);
+       if (e->left.data.expn->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->left.data.expn);
 
        /* if the left subexpr is just an IDENT (or string thereof),
         * pull it up into the current node */
-       while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
+       while (e->left.type == EXPR_EXPR && e->left.data.expn->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->ltype = e->left.exp->rtype;
-           memcpy(&tmp, &(e->left.exp->right), sizeof(ExprItem));
-           free(e->left.exp);
-           memcpy(&(e->left.int_val), &tmp, sizeof(ExprItem));
+           e->left.type = e->left.data.expn->right.type;
+           memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
+           free(e->left.data.expn);
+           memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->ltype == EXPR_SYM) {
+    } else if (e->left.type == EXPR_SYM) {
        /* try to get value of symbol */
-       if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
-           e->ltype = EXPR_INT;
+       if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
+           e->left.type = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->left.int_val = int_val;
+           e->left.data.int_val = int_val;
            simplified = 1;
        }
     }
 
     /* ditto on the right */
-    if (e->rtype == EXPR_EXPR) {
-       if (e->right.exp->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->right.exp);
+    if (e->right.type == EXPR_EXPR) {
+       if (e->right.data.expn->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->right.data.expn);
 
-       while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
+       while (e->right.type == EXPR_EXPR && e->right.data.expn->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->rtype = e->right.exp->rtype;
-           memcpy(&tmp, &(e->right.exp->right), sizeof(ExprItem));
-           free(e->right.exp);
-           memcpy(&(e->right.int_val), &tmp, sizeof(ExprItem));
+           e->right.type = e->right.data.expn->right.type;
+           memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
+           free(e->right.data.expn);
+           memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->rtype == EXPR_SYM) {
-       if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
-           e->rtype = EXPR_INT;
+    } else if (e->right.type == EXPR_SYM) {
+       if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
+           e->right.type = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->right.int_val = int_val;
+           e->right.data.int_val = int_val;
            simplified = 1;
        }
     }
 
-    if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
-       && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
+    if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE)
+       && e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
        switch (e->op) {
            case EXPR_ADD:
-               e->right.int_val = e->left.int_val + e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val + e->right.data.int_val;
                break;
            case EXPR_SUB:
-               e->right.int_val = e->left.int_val - e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val - e->right.data.int_val;
                break;
            case EXPR_MUL:
-               e->right.int_val = e->left.int_val * e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val * e->right.data.int_val;
                break;
            case EXPR_DIV:
-               e->right.int_val = e->left.int_val / e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val / e->right.data.int_val;
                break;
            case EXPR_MOD:
-               e->right.int_val = e->left.int_val % e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val % e->right.data.int_val;
                break;
            case EXPR_NEG:
-               e->right.int_val = -(e->right.int_val);
+               e->right.data.int_val = -(e->right.data.int_val);
                break;
            case EXPR_NOT:
-               e->right.int_val = ~(e->right.int_val);
+               e->right.data.int_val = ~(e->right.data.int_val);
                break;
            case EXPR_OR:
-               e->right.int_val = e->left.int_val | e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val | e->right.data.int_val;
                break;
            case EXPR_AND:
-               e->right.int_val = e->left.int_val & e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val & e->right.data.int_val;
                break;
            case EXPR_XOR:
-               e->right.int_val = e->left.int_val ^ e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val ^ e->right.data.int_val;
                break;
            case EXPR_SHL:
-               e->right.int_val = e->right.int_val << e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
                break;
            case EXPR_SHR:
-               e->right.int_val = e->right.int_val << e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
                break;
            case EXPR_LOR:
-               e->right.int_val = e->left.int_val || e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val || e->right.data.int_val;
                break;
            case EXPR_LAND:
-               e->right.int_val = e->left.int_val && e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val && e->right.data.int_val;
                break;
            case EXPR_LNOT:
-               e->right.int_val = !e->right.int_val;
+               e->right.data.int_val = !e->right.data.int_val;
                break;
            case EXPR_EQ:
-               e->right.int_val = e->right.int_val == e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val == e->left.data.int_val;
                break;
            case EXPR_LT:
-               e->right.int_val = e->right.int_val < e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val < e->left.data.int_val;
                break;
            case EXPR_GT:
-               e->right.int_val = e->right.int_val > e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val > e->left.data.int_val;
                break;
            case EXPR_LE:
-               e->right.int_val = e->right.int_val <= e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val <= e->left.data.int_val;
                break;
            case EXPR_GE:
-               e->right.int_val = e->right.int_val >= e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val >= e->left.data.int_val;
                break;
            case EXPR_NE:
-               e->right.int_val = e->right.int_val != e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val != e->left.data.int_val;
                break;
            case EXPR_IDENT:
                break;
@@ -254,34 +262,34 @@ expr_simplify(expr *e)
     }
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
-                                     || (e->left.int_val == 0 &&
+    else if (e->left.type == EXPR_INT && ((e->left.data.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->left.data.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->left.int_val == -1 &&
+                                     || (e->left.data.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->left.int_val == 0 &&
+                                     || (e->left.data.int_val == 0 &&
                                          e->op == EXPR_OR))) {
        e->op = EXPR_IDENT;
        simplified = 1;
     }
     /* and the corresponding x+|-0, x*&/1 */
-    else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
-                                     || (e->right.int_val == 1 &&
+    else if (e->right.type == EXPR_INT && ((e->right.data.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->right.data.int_val == 1 &&
                                          e->op == EXPR_DIV)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SUB)
-                                     || (e->right.int_val == -1 &&
+                                     || (e->right.data.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_OR)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SHL)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SHR))) {
        e->op = EXPR_IDENT;
-       e->rtype = e->ltype;
+       e->right.type = e->left.type;
        memcpy(&e->right, &e->left, sizeof(ExprItem));
        simplified = 1;
     }
@@ -292,11 +300,11 @@ expr_simplify(expr *e)
 int
 expr_get_value(expr *e, unsigned long *retval)
 {
-    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
+    while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
           && expr_simplify(e)) ;
 
-    if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
-       *retval = e->right.int_val;
+    if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
+       *retval = e->right.data.int_val;
        return 1;
     } else
        return 0;
@@ -306,20 +314,20 @@ void
 expr_print(expr *e)
 {
     if (e->op != EXPR_IDENT) {
-       switch (e->ltype) {
+       switch (e->left.type) {
            case EXPR_SYM:
-               printf("%s", e->left.sym->name);
+               printf("%s", symrec_get_name(e->left.data.sym));
                break;
            case EXPR_EXPR:
                printf("(");
-               expr_print(e->left.exp);
+               expr_print(e->left.data.expn);
                printf(")");
                break;
            case EXPR_INT:
-               printf("%lu", e->left.int_val);
+               printf("%lu", e->left.data.int_val);
                break;
            case EXPR_FLOAT:
-               floatnum_print(e->left.flt);
+               floatnum_print(e->left.data.flt);
                break;
            case EXPR_NONE:
                break;
@@ -392,20 +400,20 @@ expr_print(expr *e)
        case EXPR_IDENT:
            break;
     }
-    switch (e->rtype) {
+    switch (e->right.type) {
        case EXPR_SYM:
-           printf("%s", e->right.sym->name);
+           printf("%s", symrec_get_name(e->right.data.sym));
            break;
        case EXPR_EXPR:
            printf("(");
-           expr_print(e->right.exp);
+           expr_print(e->right.data.expn);
            printf(")");
            break;
        case EXPR_INT:
-           printf("%lu", e->right.int_val);
+           printf("%lu", e->right.data.int_val);
            break;
        case EXPR_FLOAT:
-           floatnum_print(e->right.flt);
+           floatnum_print(e->right.data.flt);
            break;
        case EXPR_NONE:
            break;
index 94740c00c2bce8af8c758aa68733ff4220163995..dc56962b745296a2b329efdfe46780bedfb04789 100644 (file)
 # include <string.h>
 #endif
 
+#include <libintl.h>
+#define _(String)      gettext(String)
+#ifdef gettext_noop
+#define N_(String)     gettext_noop(String)
+#else
+#define N_(String)     (String)
+#endif
+
 #include "globals.h"
 #include "errwarn.h"
 #include "floatnum.h"
 
 RCSID("$IdPath$");
 
+typedef enum {
+    EXPR_NONE,                 /* for left side of a NOT, NEG, etc. */
+    EXPR_SYM,
+    EXPR_EXPR,
+    EXPR_INT,
+    EXPR_FLOAT
+} ExprType;
+
+struct ExprItem {
+    ExprType type;
+    union {
+       symrec *sym;
+       expr *expn;
+       unsigned long int_val;
+       floatnum *flt;
+    } data;
+};
+
+struct expr {
+    ExprItem left, right;
+    ExprOp op;
+};
+
 /* allocate a new expression node, with children as defined.
  * If it's a unary operator, put the element on the right */
 expr *
-expr_new(ExprType ltype,
-        ExprItem left,
-        ExprOp   op,
-        ExprType rtype,
-        ExprItem right)
+expr_new(ExprItem *left, ExprOp op, ExprItem *right)
 {
     expr *ptr;
     ptr = xmalloc(sizeof(expr));
 
-    ptr->ltype = ltype;
+    ptr->left.type = EXPR_NONE;
     ptr->op = op;
-    ptr->rtype = rtype;
-    switch (ltype) {
-       case EXPR_SYM:
-       case EXPR_EXPR:
-       case EXPR_INT:
-       case EXPR_FLOAT:
-           memcpy(&ptr->left, &left, sizeof(ExprItem));
-           break;
-       case EXPR_NONE:
-           break;
+    ptr->right.type = EXPR_NONE;
+    if (left) {
+       memcpy(&ptr->left, left, sizeof(ExprItem));
+       free(left);
     }
-    switch (rtype) {
-       case EXPR_SYM:
-       case EXPR_EXPR:
-       case EXPR_INT:
-       case EXPR_FLOAT:
-           memcpy(&ptr->right, &right, sizeof(ExprItem));
-           break;
-       case EXPR_NONE:
-           Fatal(FATAL_UNKNOWN);       /* TODO: better error? */
-           break;
+    if (right) {
+       memcpy(&ptr->right, right, sizeof(ExprItem));
+       free(right);
+    } else {
+       InternalError(__LINE__, __FILE__,
+                     _("Right side of expression must exist"));
     }
     return ptr;
 }
 
 /* helpers */
-ExprItem
-ExprSym(struct symrec_s *s)
+ExprItem *
+ExprSym(symrec *s)
 {
-    ExprItem e;
-
-    e.sym = s;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_SYM;
+    e->data.sym = s;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprExpr(expr *x)
 {
-    ExprItem e;
-    e.exp = x;
-
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_EXPR;
+    e->data.expn = x;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprInt(unsigned long i)
 {
-    ExprItem e;
-
-    e.int_val = i;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_INT;
+    e->data.int_val = i;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprFloat(floatnum *f)
 {
-    ExprItem e;
-
-    e.flt = f;
-    return e;
-}
-
-ExprItem
-ExprNone(void)
-{
-    ExprItem e;
-
-    e.int_val = 0;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_FLOAT;
+    e->data.flt = f;
     return e;
 }
 
@@ -133,118 +141,118 @@ expr_simplify(expr *e)
     unsigned long int_val;
 
     /* try to simplify the left side */
-    if (e->ltype == EXPR_EXPR) {
+    if (e->left.type == EXPR_EXPR) {
        /* if the left subexpr isn't an IDENT, recurse simplification */
-       if (e->left.exp->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->left.exp);
+       if (e->left.data.expn->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->left.data.expn);
 
        /* if the left subexpr is just an IDENT (or string thereof),
         * pull it up into the current node */
-       while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
+       while (e->left.type == EXPR_EXPR && e->left.data.expn->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->ltype = e->left.exp->rtype;
-           memcpy(&tmp, &(e->left.exp->right), sizeof(ExprItem));
-           free(e->left.exp);
-           memcpy(&(e->left.int_val), &tmp, sizeof(ExprItem));
+           e->left.type = e->left.data.expn->right.type;
+           memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
+           free(e->left.data.expn);
+           memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->ltype == EXPR_SYM) {
+    } else if (e->left.type == EXPR_SYM) {
        /* try to get value of symbol */
-       if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
-           e->ltype = EXPR_INT;
+       if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
+           e->left.type = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->left.int_val = int_val;
+           e->left.data.int_val = int_val;
            simplified = 1;
        }
     }
 
     /* ditto on the right */
-    if (e->rtype == EXPR_EXPR) {
-       if (e->right.exp->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->right.exp);
+    if (e->right.type == EXPR_EXPR) {
+       if (e->right.data.expn->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->right.data.expn);
 
-       while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
+       while (e->right.type == EXPR_EXPR && e->right.data.expn->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->rtype = e->right.exp->rtype;
-           memcpy(&tmp, &(e->right.exp->right), sizeof(ExprItem));
-           free(e->right.exp);
-           memcpy(&(e->right.int_val), &tmp, sizeof(ExprItem));
+           e->right.type = e->right.data.expn->right.type;
+           memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
+           free(e->right.data.expn);
+           memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->rtype == EXPR_SYM) {
-       if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
-           e->rtype = EXPR_INT;
+    } else if (e->right.type == EXPR_SYM) {
+       if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
+           e->right.type = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->right.int_val = int_val;
+           e->right.data.int_val = int_val;
            simplified = 1;
        }
     }
 
-    if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
-       && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
+    if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE)
+       && e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
        switch (e->op) {
            case EXPR_ADD:
-               e->right.int_val = e->left.int_val + e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val + e->right.data.int_val;
                break;
            case EXPR_SUB:
-               e->right.int_val = e->left.int_val - e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val - e->right.data.int_val;
                break;
            case EXPR_MUL:
-               e->right.int_val = e->left.int_val * e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val * e->right.data.int_val;
                break;
            case EXPR_DIV:
-               e->right.int_val = e->left.int_val / e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val / e->right.data.int_val;
                break;
            case EXPR_MOD:
-               e->right.int_val = e->left.int_val % e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val % e->right.data.int_val;
                break;
            case EXPR_NEG:
-               e->right.int_val = -(e->right.int_val);
+               e->right.data.int_val = -(e->right.data.int_val);
                break;
            case EXPR_NOT:
-               e->right.int_val = ~(e->right.int_val);
+               e->right.data.int_val = ~(e->right.data.int_val);
                break;
            case EXPR_OR:
-               e->right.int_val = e->left.int_val | e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val | e->right.data.int_val;
                break;
            case EXPR_AND:
-               e->right.int_val = e->left.int_val & e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val & e->right.data.int_val;
                break;
            case EXPR_XOR:
-               e->right.int_val = e->left.int_val ^ e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val ^ e->right.data.int_val;
                break;
            case EXPR_SHL:
-               e->right.int_val = e->right.int_val << e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
                break;
            case EXPR_SHR:
-               e->right.int_val = e->right.int_val << e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
                break;
            case EXPR_LOR:
-               e->right.int_val = e->left.int_val || e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val || e->right.data.int_val;
                break;
            case EXPR_LAND:
-               e->right.int_val = e->left.int_val && e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val && e->right.data.int_val;
                break;
            case EXPR_LNOT:
-               e->right.int_val = !e->right.int_val;
+               e->right.data.int_val = !e->right.data.int_val;
                break;
            case EXPR_EQ:
-               e->right.int_val = e->right.int_val == e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val == e->left.data.int_val;
                break;
            case EXPR_LT:
-               e->right.int_val = e->right.int_val < e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val < e->left.data.int_val;
                break;
            case EXPR_GT:
-               e->right.int_val = e->right.int_val > e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val > e->left.data.int_val;
                break;
            case EXPR_LE:
-               e->right.int_val = e->right.int_val <= e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val <= e->left.data.int_val;
                break;
            case EXPR_GE:
-               e->right.int_val = e->right.int_val >= e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val >= e->left.data.int_val;
                break;
            case EXPR_NE:
-               e->right.int_val = e->right.int_val != e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val != e->left.data.int_val;
                break;
            case EXPR_IDENT:
                break;
@@ -254,34 +262,34 @@ expr_simplify(expr *e)
     }
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
-                                     || (e->left.int_val == 0 &&
+    else if (e->left.type == EXPR_INT && ((e->left.data.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->left.data.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->left.int_val == -1 &&
+                                     || (e->left.data.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->left.int_val == 0 &&
+                                     || (e->left.data.int_val == 0 &&
                                          e->op == EXPR_OR))) {
        e->op = EXPR_IDENT;
        simplified = 1;
     }
     /* and the corresponding x+|-0, x*&/1 */
-    else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
-                                     || (e->right.int_val == 1 &&
+    else if (e->right.type == EXPR_INT && ((e->right.data.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->right.data.int_val == 1 &&
                                          e->op == EXPR_DIV)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SUB)
-                                     || (e->right.int_val == -1 &&
+                                     || (e->right.data.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_OR)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SHL)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SHR))) {
        e->op = EXPR_IDENT;
-       e->rtype = e->ltype;
+       e->right.type = e->left.type;
        memcpy(&e->right, &e->left, sizeof(ExprItem));
        simplified = 1;
     }
@@ -292,11 +300,11 @@ expr_simplify(expr *e)
 int
 expr_get_value(expr *e, unsigned long *retval)
 {
-    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
+    while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
           && expr_simplify(e)) ;
 
-    if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
-       *retval = e->right.int_val;
+    if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
+       *retval = e->right.data.int_val;
        return 1;
     } else
        return 0;
@@ -306,20 +314,20 @@ void
 expr_print(expr *e)
 {
     if (e->op != EXPR_IDENT) {
-       switch (e->ltype) {
+       switch (e->left.type) {
            case EXPR_SYM:
-               printf("%s", e->left.sym->name);
+               printf("%s", symrec_get_name(e->left.data.sym));
                break;
            case EXPR_EXPR:
                printf("(");
-               expr_print(e->left.exp);
+               expr_print(e->left.data.expn);
                printf(")");
                break;
            case EXPR_INT:
-               printf("%lu", e->left.int_val);
+               printf("%lu", e->left.data.int_val);
                break;
            case EXPR_FLOAT:
-               floatnum_print(e->left.flt);
+               floatnum_print(e->left.data.flt);
                break;
            case EXPR_NONE:
                break;
@@ -392,20 +400,20 @@ expr_print(expr *e)
        case EXPR_IDENT:
            break;
     }
-    switch (e->rtype) {
+    switch (e->right.type) {
        case EXPR_SYM:
-           printf("%s", e->right.sym->name);
+           printf("%s", symrec_get_name(e->right.data.sym));
            break;
        case EXPR_EXPR:
            printf("(");
-           expr_print(e->right.exp);
+           expr_print(e->right.data.expn);
            printf(")");
            break;
        case EXPR_INT:
-           printf("%lu", e->right.int_val);
+           printf("%lu", e->right.data.int_val);
            break;
        case EXPR_FLOAT:
-           floatnum_print(e->right.flt);
+           floatnum_print(e->right.data.flt);
            break;
        case EXPR_NONE:
            break;
index 48d88268872af099f2c8417e226c4aa8bbd5f457..b3c9a7ea3e13745f4895657978d0701764835739 100644 (file)
 
 RCSID("$IdPath$");
 
-/* Static structures for when NULL is passed to conversion functions. */
-/*  for Convert*ToImm() */
-static immval im_static;
+struct effaddr {
+    expr *disp;                        /* address displacement */
+    unsigned char len;         /* length of disp (in bytes), 0 if none */
+
+    unsigned char segment;     /* segment override, 0 if none */
+
+    unsigned char modrm;
+    unsigned char valid_modrm; /* 1 if Mod/RM byte currently valid, 0 if not */
+    unsigned char need_modrm;  /* 1 if Mod/RM byte needed, 0 if not */
+
+    unsigned char sib;
+    unsigned char valid_sib;   /* 1 if SIB byte currently valid, 0 if not */
+    unsigned char need_sib;    /* 1 if SIB byte needed, 0 if not */
+};
+
+struct immval {
+    expr *val;
+
+    unsigned char len;         /* length of val (in bytes), 0 if none */
+    unsigned char isneg;       /* the value has been explicitly negated */
+
+    unsigned char f_len;       /* final imm length */
+    unsigned char f_sign;      /* 1 if final imm should be signed */
+};
+
+struct dataval {
+    STAILQ_ENTRY(dataval) link;
 
+    enum { DV_EMPTY, DV_EXPR, DV_FLOAT, DV_STRING } type;
+
+    union {
+       expr *expn;
+       floatnum *flt;
+       char *str_val;
+    } data;
+};
+
+struct bytecode {
+    STAILQ_ENTRY(bytecode) link;
+
+    enum { BC_EMPTY, BC_INSN, BC_JMPREL, BC_DATA, BC_RESERVE } type;
+
+    /* This union has been somewhat tweaked to get it as small as possible
+     * on the 4-byte-aligned x86 architecture (without resorting to
+     * bitfields).  In particular, insn and jmprel are the largest structures
+     * in the union, and are also the same size (after padding).  jmprel
+     * can have another unsigned char added to the end without affecting
+     * its size.
+     *
+     * Don't worry about this too much, but keep it in mind when changing
+     * this structure.  We care about the size of bytecode in particular
+     * because it accounts for the majority of the memory usage in the
+     * assembler when assembling a large file.
+     */
+    union {
+       struct {
+           effaddr *ea;        /* effective address */
+
+           immval imm;         /* immediate or relative value */
+
+           unsigned char opcode[3];    /* opcode */
+           unsigned char opcode_len;
+
+           unsigned char addrsize;     /* 0 indicates no override */
+           unsigned char opersize;     /* 0 indicates no override */
+           unsigned char lockrep_pre;  /* 0 indicates no prefix */
+
+           /* HACK, but a space-saving one: shift opcodes have an immediate
+            * form and a ,1 form (with no immediate).  In the parser, we
+            * set this and opcode_len=1, but store the ,1 version in the
+            * second byte of the opcode array.  We then choose between the
+            * two versions once we know the actual value of imm (because we
+            * don't know it in the parser module).
+            *
+            * A override to force the imm version should just leave this at
+            * 0.  Then later code won't know the ,1 version even exists.
+            * TODO: Figure out how this affects CPU flags processing.
+            *
+            * Call SetInsnShiftFlag() to set this flag to 1.
+            */
+           unsigned char shift_op;
+       } insn;
+       struct {
+           expr *target;               /* target location */
+
+           struct {
+               unsigned char opcode[3];
+               unsigned char opcode_len;   /* 0 = no opc for this version */
+           } shortop, nearop;
+
+           /* which opcode are we using? */
+           /* The *FORCED forms are specified in the source as such */
+           jmprel_opcode_sel op_sel;
+
+           unsigned char addrsize;     /* 0 indicates no override */
+           unsigned char opersize;     /* 0 indicates no override */
+           unsigned char lockrep_pre;  /* 0 indicates no prefix */
+       } jmprel;
+       struct {
+           /* non-converted data (linked list) */
+           datavalhead datahead;
+
+           /* final (converted) size of each element (in bytes) */
+           unsigned char size;
+       } data;
+       struct {
+           expr *numitems;             /* number of items to reserve */
+           unsigned char itemsize;     /* size of each item (in bytes) */
+       } reserve;
+    } data;
+
+    unsigned long len;         /* total length of entire bytecode */
+
+    /* where it came from */
+    char *filename;
+    unsigned int lineno;
+
+    /* other assembler state info */
+    unsigned long offset;
+    unsigned char mode_bits;
+};
+
+/* Static structures for when NULL is passed to conversion functions. */
 /*  for Convert*ToBytes() */
 unsigned char bytes_static[16];
 
@@ -106,37 +225,34 @@ effaddr_new_imm(immval *im_ptr, unsigned char im_len)
 }
 
 immval *
-ConvertIntToImm(immval *ptr, unsigned long int_val)
+immval_new_int(unsigned long int_val)
 {
-    if (!ptr)
-       ptr = &im_static;
+    immval *im = xmalloc(sizeof(immval));
 
-    /* FIXME: this will leak expr's if static is used */
-    ptr->val = expr_new_ident(EXPR_INT, ExprInt(int_val));
+    im->val = expr_new_ident(ExprInt(int_val));
 
     if ((int_val & 0xFF) == int_val)
-       ptr->len = 1;
+       im->len = 1;
     else if ((int_val & 0xFFFF) == int_val)
-       ptr->len = 2;
+       im->len = 2;
     else
-       ptr->len = 4;
+       im->len = 4;
 
-    ptr->isneg = 0;
+    im->isneg = 0;
 
-    return ptr;
+    return im;
 }
 
 immval *
-ConvertExprToImm(immval *ptr, expr *expr_ptr)
+immval_new_expr(expr *expr_ptr)
 {
-    if (!ptr)
-       ptr = &im_static;
+    immval *im = xmalloc(sizeof(immval));
 
-    ptr->val = expr_ptr;
+    im->val = expr_ptr;
 
-    ptr->isneg = 0;
+    im->isneg = 0;
 
-    return ptr;
+    return im;
 }
 
 void
@@ -145,7 +261,7 @@ SetEASegment(effaddr *ptr, unsigned char segment)
     if (!ptr)
        return;
 
-    if (ptr->segment != 0)
+    if (segment != 0 && ptr->segment != 0)
        Warning(_("multiple segment overrides, using leftmost"));
 
     ptr->segment = segment;
@@ -164,6 +280,19 @@ SetEALen(effaddr *ptr, unsigned char len)
     ptr->len = len;
 }
 
+effaddr *
+GetInsnEA(bytecode *bc)
+{
+    if (!bc)
+       return NULL;
+
+    if (bc->type != BC_INSN)
+       InternalError(__LINE__, __FILE__,
+                     _("Trying to get EA of non-instruction"));
+
+    return bc->data.insn.ea;
+}
+
 void
 SetInsnOperSizeOverride(bytecode *bc, unsigned char opersize)
 {
@@ -250,7 +379,8 @@ SetOpcodeSel(jmprel_opcode_sel *old_sel, jmprel_opcode_sel new_sel)
     if (!old_sel)
        return;
 
-    if ((*old_sel == JR_SHORT_FORCED) || (*old_sel == JR_NEAR_FORCED))
+    if (new_sel != JR_NONE && ((*old_sel == JR_SHORT_FORCED) ||
+                              (*old_sel == JR_NEAR_FORCED)))
        Warning(_("multiple SHORT or NEAR specifiers, using leftmost"));
     *old_sel = new_sel;
 }
@@ -596,6 +726,16 @@ dataval_new_string(char *str_val)
     return retval;
 }
 
+dataval *
+datavals_append(datavalhead *headp, dataval *dv)
+{
+    if (dv) {
+       STAILQ_INSERT_TAIL(headp, dv, link);
+       return dv;
+    }
+    return (dataval *)NULL;
+}
+
 void
 dataval_print(datavalhead *head)
 {
index 05d39de35d657159c33621276b1b93dfb10ed5f6..c2c2a63a289808fe5f276f493b8877a66d9e434d 100644 (file)
 #ifndef YASM_BYTECODE_H
 #define YASM_BYTECODE_H
 
-struct section_s;
-
-typedef struct effaddr_s {
-    struct expr_s *disp;       /* address displacement */
-    unsigned char len;         /* length of disp (in bytes), 0 if none */
-
-    unsigned char segment;     /* segment override, 0 if none */
-
-    unsigned char modrm;
-    unsigned char valid_modrm; /* 1 if Mod/RM byte currently valid, 0 if not */
-    unsigned char need_modrm;  /* 1 if Mod/RM byte needed, 0 if not */
-
-    unsigned char sib;
-    unsigned char valid_sib;   /* 1 if SIB byte currently valid, 0 if not */
-    unsigned char need_sib;    /* 1 if SIB byte needed, 0 if not */
-} effaddr;
-
-typedef struct immval_s {
-    struct expr_s *val;
-
-    unsigned char len;         /* length of val (in bytes), 0 if none */
-    unsigned char isneg;       /* the value has been explicitly negated */
-
-    unsigned char f_len;       /* final imm length */
-    unsigned char f_sign;      /* 1 if final imm should be signed */
-} immval;
+#ifndef YASM_SECTION
+#define YASM_SECTION
+typedef struct section section;
+#endif
 
-typedef STAILQ_HEAD(datavalhead_s, dataval_s) datavalhead;
+#ifndef YASM_EXPR
+#define YASM_EXPR
+typedef struct expr expr;
+#endif
 
-typedef struct dataval_s {
-    STAILQ_ENTRY(dataval_s) link;
+#ifndef YASM_FLOATNUM
+#define YASM_FLOATNUM
+typedef struct floatnum floatnum;
+#endif
 
-    enum { DV_EMPTY, DV_EXPR, DV_FLOAT, DV_STRING } type;
+typedef struct effaddr effaddr;
+typedef struct immval immval;
+typedef STAILQ_HEAD(datavalhead, dataval) datavalhead;
+typedef struct dataval dataval;
+typedef STAILQ_HEAD(bytecodehead, bytecode) bytecodehead;
 
-    union {
-       struct expr_s *expn;
-       struct floatnum_s *flt;
-       char *str_val;
-    } data;
-} dataval;
+#ifndef YASM_BYTECODE
+#define YASM_BYTECODE
+typedef struct bytecode bytecode;
+#endif
 
-typedef enum jmprel_opcode_sel_e {
+typedef enum {
     JR_NONE,
     JR_SHORT,
     JR_NEAR,
@@ -72,108 +57,23 @@ typedef enum jmprel_opcode_sel_e {
 } jmprel_opcode_sel;
 
 typedef struct targetval_s {
-    struct expr_s *val;
+    expr *val;
 
     jmprel_opcode_sel op_sel;
 } targetval;
 
-typedef STAILQ_HEAD(bytecodehead_s, bytecode_s) bytecodehead;
-
-typedef struct bytecode_s {
-    STAILQ_ENTRY(bytecode_s) link;
-
-    enum { BC_EMPTY, BC_INSN, BC_JMPREL, BC_DATA, BC_RESERVE } type;
-
-    /* This union has been somewhat tweaked to get it as small as possible
-     * on the 4-byte-aligned x86 architecture (without resorting to
-     * bitfields).  In particular, insn and jmprel are the largest structures
-     * in the union, and are also the same size (after padding).  jmprel
-     * can have another unsigned char added to the end without affecting
-     * its size.
-     *
-     * Don't worry about this too much, but keep it in mind when changing
-     * this structure.  We care about the size of bytecode in particular
-     * because it accounts for the majority of the memory usage in the
-     * assembler when assembling a large file.
-     */
-    union {
-       struct {
-           effaddr *ea;        /* effective address */
-
-           immval imm;         /* immediate or relative value */
-
-           unsigned char opcode[3];    /* opcode */
-           unsigned char opcode_len;
-
-           unsigned char addrsize;     /* 0 indicates no override */
-           unsigned char opersize;     /* 0 indicates no override */
-           unsigned char lockrep_pre;  /* 0 indicates no prefix */
-
-           /* HACK, but a space-saving one: shift opcodes have an immediate
-            * form and a ,1 form (with no immediate).  In the parser, we
-            * set this and opcode_len=1, but store the ,1 version in the
-            * second byte of the opcode array.  We then choose between the
-            * two versions once we know the actual value of imm (because we
-            * don't know it in the parser module).
-            *
-            * A override to force the imm version should just leave this at
-            * 0.  Then later code won't know the ,1 version even exists.
-            * TODO: Figure out how this affects CPU flags processing.
-            *
-            * Call SetInsnShiftFlag() to set this flag to 1.
-            */
-           unsigned char shift_op;
-       } insn;
-       struct {
-           struct expr_s *target;      /* target location */
-
-           struct {
-               unsigned char opcode[3];
-               unsigned char opcode_len;   /* 0 = no opc for this version */
-           } shortop, nearop;
-
-           /* which opcode are we using? */
-           /* The *FORCED forms are specified in the source as such */
-           jmprel_opcode_sel op_sel;
-
-           unsigned char addrsize;     /* 0 indicates no override */
-           unsigned char opersize;     /* 0 indicates no override */
-           unsigned char lockrep_pre;  /* 0 indicates no prefix */
-       } jmprel;
-       struct {
-           /* non-converted data (linked list) */
-           datavalhead datahead;
-
-           /* final (converted) size of each element (in bytes) */
-           unsigned char size;
-       } data;
-       struct {
-           struct expr_s *numitems;    /* number of items to reserve */
-           unsigned char itemsize;     /* size of each item (in bytes) */
-       } reserve;
-    } data;
-
-    unsigned long len;         /* total length of entire bytecode */
-
-    /* where it came from */
-    char *filename;
-    unsigned int lineno;
-
-    /* other assembler state info */
-    unsigned long offset;
-    unsigned char mode_bits;
-} bytecode;
-
 effaddr *effaddr_new_reg(unsigned long reg);
 effaddr *effaddr_new_imm(immval *im_ptr, unsigned char im_len);
-effaddr *effaddr_new_expr(struct expr_s *expr_ptr);
+effaddr *effaddr_new_expr(expr *expr_ptr);
 
-immval *ConvertIntToImm(immval *ptr, unsigned long int_val);
-immval *ConvertExprToImm(immval *ptr, struct expr_s *expr_ptr);
+immval *immval_new_int(unsigned long int_val);
+immval *immval_new_expr(expr *expr_ptr);
 
 void SetEASegment(effaddr *ptr, unsigned char segment);
 void SetEALen(effaddr *ptr, unsigned char len);
 
+effaddr *GetInsnEA(bytecode *bc);
+
 void SetInsnOperSizeOverride(bytecode *bc, unsigned char opersize);
 void SetInsnAddrSizeOverride(bytecode *bc, unsigned char addrsize);
 void SetInsnLockRepPrefix(bytecode *bc, unsigned char prefix);
@@ -209,14 +109,12 @@ bytecode *bytecode_new_jmprel(targetval     *target,
 
 bytecode *bytecode_new_data(datavalhead *datahead, unsigned long size);
 
-bytecode *bytecode_new_reserve(struct expr_s *numitems,
-                              unsigned long  itemsize);
+bytecode *bytecode_new_reserve(expr *numitems, unsigned long itemsize);
 
 /* Gets the offset of the bytecode specified by bc if possible.
  * Return value is IF POSSIBLE, not the value.
  */
-int bytecode_get_offset(struct section_s *sect, bytecode *bc,
-                       unsigned long *ret_val);
+int bytecode_get_offset(section *sect, bytecode *bc, unsigned long *ret_val);
 
 void bytecode_print(bytecode *bc);
 
@@ -231,10 +129,21 @@ void bytecode_print(bytecode *bc);
  */
 bytecode *bytecodes_append(bytecodehead *headp, bytecode *bc);
 
-dataval *dataval_new_expr(struct expr_s *expn);
-dataval *dataval_new_float(struct floatnum_s *flt);
+dataval *dataval_new_expr(expr *expn);
+dataval *dataval_new_float(floatnum *flt);
 dataval *dataval_new_string(char *str_val);
 
+/* void datavals_initialize(datavalhead *headp); */
+#define        datavals_initialize(headp)      STAILQ_INIT(headp)
+
+/* Adds dv to the list of datavals headp.
+ * NOTE: Does not make a copy of dv; so don't pass this function
+ * static or local variables, and discard the dv pointer after calling
+ * this function.  If dv was actually appended (it wasn't NULL), then
+ * returns dv, otherwise returns NULL.
+ */
+dataval *datavals_append(datavalhead *headp, dataval *dv);
+
 void dataval_print(datavalhead *head);
 
 #endif
index 94740c00c2bce8af8c758aa68733ff4220163995..dc56962b745296a2b329efdfe46780bedfb04789 100644 (file)
 # include <string.h>
 #endif
 
+#include <libintl.h>
+#define _(String)      gettext(String)
+#ifdef gettext_noop
+#define N_(String)     gettext_noop(String)
+#else
+#define N_(String)     (String)
+#endif
+
 #include "globals.h"
 #include "errwarn.h"
 #include "floatnum.h"
 
 RCSID("$IdPath$");
 
+typedef enum {
+    EXPR_NONE,                 /* for left side of a NOT, NEG, etc. */
+    EXPR_SYM,
+    EXPR_EXPR,
+    EXPR_INT,
+    EXPR_FLOAT
+} ExprType;
+
+struct ExprItem {
+    ExprType type;
+    union {
+       symrec *sym;
+       expr *expn;
+       unsigned long int_val;
+       floatnum *flt;
+    } data;
+};
+
+struct expr {
+    ExprItem left, right;
+    ExprOp op;
+};
+
 /* allocate a new expression node, with children as defined.
  * If it's a unary operator, put the element on the right */
 expr *
-expr_new(ExprType ltype,
-        ExprItem left,
-        ExprOp   op,
-        ExprType rtype,
-        ExprItem right)
+expr_new(ExprItem *left, ExprOp op, ExprItem *right)
 {
     expr *ptr;
     ptr = xmalloc(sizeof(expr));
 
-    ptr->ltype = ltype;
+    ptr->left.type = EXPR_NONE;
     ptr->op = op;
-    ptr->rtype = rtype;
-    switch (ltype) {
-       case EXPR_SYM:
-       case EXPR_EXPR:
-       case EXPR_INT:
-       case EXPR_FLOAT:
-           memcpy(&ptr->left, &left, sizeof(ExprItem));
-           break;
-       case EXPR_NONE:
-           break;
+    ptr->right.type = EXPR_NONE;
+    if (left) {
+       memcpy(&ptr->left, left, sizeof(ExprItem));
+       free(left);
     }
-    switch (rtype) {
-       case EXPR_SYM:
-       case EXPR_EXPR:
-       case EXPR_INT:
-       case EXPR_FLOAT:
-           memcpy(&ptr->right, &right, sizeof(ExprItem));
-           break;
-       case EXPR_NONE:
-           Fatal(FATAL_UNKNOWN);       /* TODO: better error? */
-           break;
+    if (right) {
+       memcpy(&ptr->right, right, sizeof(ExprItem));
+       free(right);
+    } else {
+       InternalError(__LINE__, __FILE__,
+                     _("Right side of expression must exist"));
     }
     return ptr;
 }
 
 /* helpers */
-ExprItem
-ExprSym(struct symrec_s *s)
+ExprItem *
+ExprSym(symrec *s)
 {
-    ExprItem e;
-
-    e.sym = s;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_SYM;
+    e->data.sym = s;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprExpr(expr *x)
 {
-    ExprItem e;
-    e.exp = x;
-
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_EXPR;
+    e->data.expn = x;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprInt(unsigned long i)
 {
-    ExprItem e;
-
-    e.int_val = i;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_INT;
+    e->data.int_val = i;
     return e;
 }
 
-ExprItem
+ExprItem *
 ExprFloat(floatnum *f)
 {
-    ExprItem e;
-
-    e.flt = f;
-    return e;
-}
-
-ExprItem
-ExprNone(void)
-{
-    ExprItem e;
-
-    e.int_val = 0;
+    ExprItem *e = xmalloc(sizeof(ExprItem));
+    e->type = EXPR_FLOAT;
+    e->data.flt = f;
     return e;
 }
 
@@ -133,118 +141,118 @@ expr_simplify(expr *e)
     unsigned long int_val;
 
     /* try to simplify the left side */
-    if (e->ltype == EXPR_EXPR) {
+    if (e->left.type == EXPR_EXPR) {
        /* if the left subexpr isn't an IDENT, recurse simplification */
-       if (e->left.exp->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->left.exp);
+       if (e->left.data.expn->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->left.data.expn);
 
        /* if the left subexpr is just an IDENT (or string thereof),
         * pull it up into the current node */
-       while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
+       while (e->left.type == EXPR_EXPR && e->left.data.expn->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->ltype = e->left.exp->rtype;
-           memcpy(&tmp, &(e->left.exp->right), sizeof(ExprItem));
-           free(e->left.exp);
-           memcpy(&(e->left.int_val), &tmp, sizeof(ExprItem));
+           e->left.type = e->left.data.expn->right.type;
+           memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
+           free(e->left.data.expn);
+           memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->ltype == EXPR_SYM) {
+    } else if (e->left.type == EXPR_SYM) {
        /* try to get value of symbol */
-       if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
-           e->ltype = EXPR_INT;
+       if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
+           e->left.type = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->left.int_val = int_val;
+           e->left.data.int_val = int_val;
            simplified = 1;
        }
     }
 
     /* ditto on the right */
-    if (e->rtype == EXPR_EXPR) {
-       if (e->right.exp->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->right.exp);
+    if (e->right.type == EXPR_EXPR) {
+       if (e->right.data.expn->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->right.data.expn);
 
-       while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
+       while (e->right.type == EXPR_EXPR && e->right.data.expn->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->rtype = e->right.exp->rtype;
-           memcpy(&tmp, &(e->right.exp->right), sizeof(ExprItem));
-           free(e->right.exp);
-           memcpy(&(e->right.int_val), &tmp, sizeof(ExprItem));
+           e->right.type = e->right.data.expn->right.type;
+           memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
+           free(e->right.data.expn);
+           memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->rtype == EXPR_SYM) {
-       if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
-           e->rtype = EXPR_INT;
+    } else if (e->right.type == EXPR_SYM) {
+       if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
+           e->right.type = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->right.int_val = int_val;
+           e->right.data.int_val = int_val;
            simplified = 1;
        }
     }
 
-    if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
-       && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
+    if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE)
+       && e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
        switch (e->op) {
            case EXPR_ADD:
-               e->right.int_val = e->left.int_val + e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val + e->right.data.int_val;
                break;
            case EXPR_SUB:
-               e->right.int_val = e->left.int_val - e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val - e->right.data.int_val;
                break;
            case EXPR_MUL:
-               e->right.int_val = e->left.int_val * e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val * e->right.data.int_val;
                break;
            case EXPR_DIV:
-               e->right.int_val = e->left.int_val / e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val / e->right.data.int_val;
                break;
            case EXPR_MOD:
-               e->right.int_val = e->left.int_val % e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val % e->right.data.int_val;
                break;
            case EXPR_NEG:
-               e->right.int_val = -(e->right.int_val);
+               e->right.data.int_val = -(e->right.data.int_val);
                break;
            case EXPR_NOT:
-               e->right.int_val = ~(e->right.int_val);
+               e->right.data.int_val = ~(e->right.data.int_val);
                break;
            case EXPR_OR:
-               e->right.int_val = e->left.int_val | e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val | e->right.data.int_val;
                break;
            case EXPR_AND:
-               e->right.int_val = e->left.int_val & e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val & e->right.data.int_val;
                break;
            case EXPR_XOR:
-               e->right.int_val = e->left.int_val ^ e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val ^ e->right.data.int_val;
                break;
            case EXPR_SHL:
-               e->right.int_val = e->right.int_val << e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
                break;
            case EXPR_SHR:
-               e->right.int_val = e->right.int_val << e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val << e->left.data.int_val;
                break;
            case EXPR_LOR:
-               e->right.int_val = e->left.int_val || e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val || e->right.data.int_val;
                break;
            case EXPR_LAND:
-               e->right.int_val = e->left.int_val && e->right.int_val;
+               e->right.data.int_val = e->left.data.int_val && e->right.data.int_val;
                break;
            case EXPR_LNOT:
-               e->right.int_val = !e->right.int_val;
+               e->right.data.int_val = !e->right.data.int_val;
                break;
            case EXPR_EQ:
-               e->right.int_val = e->right.int_val == e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val == e->left.data.int_val;
                break;
            case EXPR_LT:
-               e->right.int_val = e->right.int_val < e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val < e->left.data.int_val;
                break;
            case EXPR_GT:
-               e->right.int_val = e->right.int_val > e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val > e->left.data.int_val;
                break;
            case EXPR_LE:
-               e->right.int_val = e->right.int_val <= e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val <= e->left.data.int_val;
                break;
            case EXPR_GE:
-               e->right.int_val = e->right.int_val >= e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val >= e->left.data.int_val;
                break;
            case EXPR_NE:
-               e->right.int_val = e->right.int_val != e->left.int_val;
+               e->right.data.int_val = e->right.data.int_val != e->left.data.int_val;
                break;
            case EXPR_IDENT:
                break;
@@ -254,34 +262,34 @@ expr_simplify(expr *e)
     }
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
-                                     || (e->left.int_val == 0 &&
+    else if (e->left.type == EXPR_INT && ((e->left.data.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->left.data.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->left.int_val == -1 &&
+                                     || (e->left.data.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->left.int_val == 0 &&
+                                     || (e->left.data.int_val == 0 &&
                                          e->op == EXPR_OR))) {
        e->op = EXPR_IDENT;
        simplified = 1;
     }
     /* and the corresponding x+|-0, x*&/1 */
-    else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
-                                     || (e->right.int_val == 1 &&
+    else if (e->right.type == EXPR_INT && ((e->right.data.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->right.data.int_val == 1 &&
                                          e->op == EXPR_DIV)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SUB)
-                                     || (e->right.int_val == -1 &&
+                                     || (e->right.data.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_OR)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SHL)
-                                     || (e->right.int_val == 0 &&
+                                     || (e->right.data.int_val == 0 &&
                                          e->op == EXPR_SHR))) {
        e->op = EXPR_IDENT;
-       e->rtype = e->ltype;
+       e->right.type = e->left.type;
        memcpy(&e->right, &e->left, sizeof(ExprItem));
        simplified = 1;
     }
@@ -292,11 +300,11 @@ expr_simplify(expr *e)
 int
 expr_get_value(expr *e, unsigned long *retval)
 {
-    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
+    while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
           && expr_simplify(e)) ;
 
-    if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
-       *retval = e->right.int_val;
+    if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
+       *retval = e->right.data.int_val;
        return 1;
     } else
        return 0;
@@ -306,20 +314,20 @@ void
 expr_print(expr *e)
 {
     if (e->op != EXPR_IDENT) {
-       switch (e->ltype) {
+       switch (e->left.type) {
            case EXPR_SYM:
-               printf("%s", e->left.sym->name);
+               printf("%s", symrec_get_name(e->left.data.sym));
                break;
            case EXPR_EXPR:
                printf("(");
-               expr_print(e->left.exp);
+               expr_print(e->left.data.expn);
                printf(")");
                break;
            case EXPR_INT:
-               printf("%lu", e->left.int_val);
+               printf("%lu", e->left.data.int_val);
                break;
            case EXPR_FLOAT:
-               floatnum_print(e->left.flt);
+               floatnum_print(e->left.data.flt);
                break;
            case EXPR_NONE:
                break;
@@ -392,20 +400,20 @@ expr_print(expr *e)
        case EXPR_IDENT:
            break;
     }
-    switch (e->rtype) {
+    switch (e->right.type) {
        case EXPR_SYM:
-           printf("%s", e->right.sym->name);
+           printf("%s", symrec_get_name(e->right.data.sym));
            break;
        case EXPR_EXPR:
            printf("(");
-           expr_print(e->right.exp);
+           expr_print(e->right.data.expn);
            printf(")");
            break;
        case EXPR_INT:
-           printf("%lu", e->right.int_val);
+           printf("%lu", e->right.data.int_val);
            break;
        case EXPR_FLOAT:
-           floatnum_print(e->right.flt);
+           floatnum_print(e->right.data.flt);
            break;
        case EXPR_NONE:
            break;
index 6846fdb23067d0ddce2870898399c0c0f81f8498..25a0bb48f92f234643a3f4a775b6b10ce8483cf2 100644 (file)
 #ifndef YASM_EXPR_H
 #define YASM_EXPR_H
 
+#ifndef YASM_SYMREC
+#define YASM_SYMREC
+typedef struct symrec symrec;
+#endif
+
+#ifndef YASM_FLOATNUM
+#define YASM_FLOATNUM
+typedef struct floatnum floatnum;
+#endif
+
 typedef enum {
     EXPR_ADD,
     EXPR_SUB,
@@ -47,41 +57,26 @@ typedef enum {
     EXPR_IDENT                 /* if right is IDENT, then the entire expr is just a num */
 } ExprOp;
 
-typedef enum {
-    EXPR_NONE,                 /* for left side of a NOT, NEG, etc. */
-    EXPR_SYM,
-    EXPR_EXPR,
-    EXPR_INT,
-    EXPR_FLOAT
-} ExprType;
-
-typedef union expritem_u {
-    struct symrec_s *sym;
-    struct expr_s *exp;
-    unsigned long int_val;
-    struct floatnum_s *flt;
-} ExprItem;
+typedef struct ExprItem ExprItem;
 
-typedef struct expr_s {
-    ExprType ltype, rtype;
-    ExprItem left, right;
-    ExprOp op;
-} expr;
+#ifndef YASM_EXPR
+#define YASM_EXPR
+typedef struct expr expr;
+#endif
 
-expr *expr_new(ExprType, ExprItem, ExprOp, ExprType, ExprItem);
+expr *expr_new(ExprItem *, ExprOp, ExprItem *);
 
-ExprItem ExprSym(struct symrec_s *);
-ExprItem ExprExpr(expr *);
-ExprItem ExprInt(unsigned long);
-ExprItem ExprFloat(struct floatnum_s *);
-ExprItem ExprNone(void);
+ExprItem *ExprSym(symrec *);
+ExprItem *ExprExpr(expr *);
+ExprItem *ExprInt(unsigned long);
+ExprItem *ExprFloat(floatnum *);
 
 #define expr_new_tree(l,o,r) \
-    expr_new (EXPR_EXPR, ExprExpr(l), (o), EXPR_EXPR, ExprExpr(r))
+    expr_new (ExprExpr(l), (o), ExprExpr(r))
 #define expr_new_branch(o,r) \
-    expr_new (EXPR_NONE, ExprNone(), (o), EXPR_EXPR, ExprExpr(r))
-#define expr_new_ident(t,r) \
-    expr_new (EXPR_NONE, ExprNone(), EXPR_IDENT, (ExprType)(t), (r))
+    expr_new ((ExprItem *)NULL, (o), ExprExpr(r))
+#define expr_new_ident(r) \
+    expr_new ((ExprItem *)NULL, EXPR_IDENT, (r))
 
 int expr_simplify(expr *);
 void expr_print(expr *);
index 5979fe1fc2c81706d381b6ddb8b94aa66899da60..b658ee983e1f74991b5d8fb0b7a7a140f2aff74c 100644 (file)
 
 RCSID("$IdPath$");
 
+/* 97-bit internal floating point format:
+ * xxxxxxxs eeeeeeee eeeeeeee m.....................................m
+ * Sign          exponent     mantissa (80 bits)
+ *                            79                                    0
+ *
+ * Only L.O. bit of Sign byte is significant.  The rest is garbage.
+ * Exponent is bias 32767.
+ * Mantissa does NOT have an implied one bit (it's explicit).
+ */
+struct floatnum {
+    unsigned int *mantissa;    /* Allocated to 64 bits */
+    unsigned short exponent;
+    unsigned char sign;
+    unsigned char flags;
+};
+
 /* constants describing parameters of internal floating point format */
 #define MANT_BITS      80
 #define MANT_BYTES     10
index 554d4aae9cf2728baf8e259eaabe4b5113aea8e7..612922497468264c37d61426e37f69f9aff908c8 100644 (file)
 #ifndef YASM_FLOATNUM_H
 #define YASM_FLOATNUM_H
 
-/* 97-bit internal floating point format:
- * xxxxxxxs eeeeeeee eeeeeeee m.....................................m
- * Sign          exponent     mantissa (80 bits)
- *                            79                                    0
- *
- * Only L.O. bit of Sign byte is significant.  The rest is garbage.
- * Exponent is bias 32767.
- * Mantissa does NOT have an implied one bit (it's explicit).
- */
-typedef struct floatnum_s {
-    unsigned int *mantissa;    /* Allocated to 64 bits */
-    unsigned short exponent;
-    unsigned char sign;
-    unsigned char flags;
-} floatnum;
+#ifndef YASM_FLOATNUM
+#define YASM_FLOATNUM
+typedef struct floatnum floatnum;
+#endif
 
 floatnum *floatnum_new(const char *str);
 void floatnum_delete(floatnum *flt);
index 34129f71c6e00007bf2d3f8086e6fa824a87f76b..c69c2e66ed7f236fe23eab7bfbc3062f0fbf8529 100644 (file)
@@ -71,7 +71,7 @@ static bytecode *nasm_parser_temp_bc;
     unsigned char groupdata[4];
     effaddr *ea;
     expr *exp;
-    immval im_val;
+    immval *im_val;
     targetval tgt_val;
     datavalhead datahead;
     dataval *data;
@@ -128,7 +128,7 @@ static bytecode *nasm_parser_temp_bc;
 %%
 input: /* empty */
     | input line    {
-       nasm_parser_temp_bc = bytecodes_append(&nasm_parser_cur_section->bc,
+       nasm_parser_temp_bc = bytecodes_append(section_get_bytecodes(nasm_parser_cur_section),
                                               $2);
        if (nasm_parser_temp_bc)
            nasm_parser_prev_bc = nasm_parser_temp_bc;
@@ -154,13 +154,11 @@ exp: instr
 ;
 
 datavals: dataval          {
-       STAILQ_INIT(&$$);
-       if ($1)
-           STAILQ_INSERT_TAIL(&$$, $1, link);
+       datavals_initialize(&$$);
+       datavals_append(&$$, $1);
     }
     | datavals ',' dataval  {
-       if ($3)
-           STAILQ_INSERT_TAIL(&$1, $3, link);
+       datavals_append(&$1, $3);
        $$ = $1;
     }
 ;
@@ -259,7 +257,7 @@ segreg:  REG_ES
 memexp: expr   { expr_simplify ($1); $$ = effaddr_new_expr($1); }
 ;
 
-memaddr: memexp                    { $$ = $1; $$->segment = 0; }
+memaddr: memexp                    { $$ = $1; SetEASegment($$, 0); }
     | REG_CS ':' memaddr    { $$ = $3; SetEASegment($$, 0x2E); }
     | REG_SS ':' memaddr    { $$ = $3; SetEASegment($$, 0x36); }
     | REG_DS ':' memaddr    { $$ = $3; SetEASegment($$, 0x3E); }
@@ -355,7 +353,7 @@ rm128: XMMREG       { $$ = effaddr_new_reg($1); }
 ;
 
 /* immediate values */
-imm: expr   { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
+imm: expr   { expr_simplify($1); $$ = immval_new_expr($1); }
 ;
 
 /* explicit immediates */
@@ -378,16 +376,14 @@ imm32: imm
 ;
 
 /* jump targets */
-target: expr       { $$.val = $1; $$.op_sel = JR_NONE; }
+target: expr       { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); }
     | SHORT target  { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); }
     | NEAR target   { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); }
 ;
 
 /* expression trees */
-expr_no_string: INTNUM         { $$ = expr_new_ident(EXPR_INT, ExprInt($1)); }
-    | explabel                 {
-       $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1)));
-    }
+expr_no_string: INTNUM         { $$ = expr_new_ident(ExprInt($1)); }
+    | explabel                 { $$ = expr_new_ident(ExprSym(symrec_use($1))); }
     /*| expr '||' expr         { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
     | expr '|' expr            { $$ = expr_new_tree($1, EXPR_OR, $3); }
     | expr '^' expr            { $$ = expr_new_tree($1, EXPR_XOR, $3); }
@@ -415,7 +411,7 @@ expr_no_string: INTNUM              { $$ = expr_new_ident(EXPR_INT, ExprInt($1)); }
 
 expr: expr_no_string
     | STRING           {
-       $$ = expr_new_ident (EXPR_INT, ExprInt(ConvertCharConstToInt($1)));
+       $$ = expr_new_ident(ExprInt(ConvertCharConstToInt($1)));
     }
 ;
 
@@ -427,12 +423,12 @@ explabel: ID
 instr: instrbase
     | OPERSIZE instr   { $$ = $2; SetInsnOperSizeOverride($$, $1); }
     | ADDRSIZE instr   { $$ = $2; SetInsnAddrSizeOverride($$, $1); }
-    | REG_CS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x2E); }
-    | REG_SS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x36); }
-    | REG_DS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x3E); }
-    | REG_ES instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x26); }
-    | REG_FS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x64); }
-    | REG_GS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x65); }
+    | REG_CS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x2E); }
+    | REG_SS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x36); }
+    | REG_DS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x3E); }
+    | REG_ES instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x26); }
+    | REG_FS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x64); }
+    | REG_GS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x65); }
     | LOCK instr       { $$ = $2; SetInsnLockRepPrefix($$, 0xF0); }
     | REPNZ instr      { $$ = $2; SetInsnLockRepPrefix($$, 0xF2); }
     | REP instr                { $$ = $2; SetInsnLockRepPrefix($$, 0xF3); }
index 5b933de43987262ae58eef974840db85110ae86a..adaa58dbe18c6d10eeb8844fc1217dd26600a5b4 100755 (executable)
@@ -618,7 +618,7 @@ sub output_yacc ($@)
                        #$args[-1] =~ s/(\$\d+[ri]?)(?!\.)/\&$1/; # Just the first!
                        $args[-1] =~ s/(\$\d+)r/effaddr_new_reg($1)/;
                        $args[-1] =~ s[(\$\d+)i,\s*(\d+)]
-                           ["effaddr_new_imm(\&$1, ".($2/8)."), 0"]e;
+                           ["effaddr_new_imm($1, ".($2/8)."), 0"]e;
                        $args[-1] .= ',';
 
                        die $args[-1] if $args[-1] =~ m/\d+[ri]/;
@@ -629,11 +629,10 @@ sub output_yacc ($@)
                        $args[-1] =~ s/nil/(immval *)NULL, 0/;
                        # don't match $0.\d in the following rules.
                        $args[-1] =~ s/\$(\d+)(?!\.)/"\$".($1*2+$to).($2||'')/eg;
-                       $args[-1] =~ s/(\$\d+)(?!\.)/\&$1/; # Just the first!
                        $args[-1] =~ s[^([0-9A-Fa-f]+),]
-                           [ConvertIntToImm((immval *)NULL, 0x$1),];
+                           [immval_new_int(0x$1),];
                        $args[-1] =~ s[^\$0.(\d+),]
-                           [ConvertIntToImm((immval *)NULL, \$1\[$1\]),];
+                           [immval_new_int(\$1\[$1\]),];
 
                        # divide the second, and only the second, by 8 bits/byte
                        $args[-1] =~ s#(,\s*)(\d+)(s)?#$1 . ($2/8)#eg;
index 34129f71c6e00007bf2d3f8086e6fa824a87f76b..c69c2e66ed7f236fe23eab7bfbc3062f0fbf8529 100644 (file)
@@ -71,7 +71,7 @@ static bytecode *nasm_parser_temp_bc;
     unsigned char groupdata[4];
     effaddr *ea;
     expr *exp;
-    immval im_val;
+    immval *im_val;
     targetval tgt_val;
     datavalhead datahead;
     dataval *data;
@@ -128,7 +128,7 @@ static bytecode *nasm_parser_temp_bc;
 %%
 input: /* empty */
     | input line    {
-       nasm_parser_temp_bc = bytecodes_append(&nasm_parser_cur_section->bc,
+       nasm_parser_temp_bc = bytecodes_append(section_get_bytecodes(nasm_parser_cur_section),
                                               $2);
        if (nasm_parser_temp_bc)
            nasm_parser_prev_bc = nasm_parser_temp_bc;
@@ -154,13 +154,11 @@ exp: instr
 ;
 
 datavals: dataval          {
-       STAILQ_INIT(&$$);
-       if ($1)
-           STAILQ_INSERT_TAIL(&$$, $1, link);
+       datavals_initialize(&$$);
+       datavals_append(&$$, $1);
     }
     | datavals ',' dataval  {
-       if ($3)
-           STAILQ_INSERT_TAIL(&$1, $3, link);
+       datavals_append(&$1, $3);
        $$ = $1;
     }
 ;
@@ -259,7 +257,7 @@ segreg:  REG_ES
 memexp: expr   { expr_simplify ($1); $$ = effaddr_new_expr($1); }
 ;
 
-memaddr: memexp                    { $$ = $1; $$->segment = 0; }
+memaddr: memexp                    { $$ = $1; SetEASegment($$, 0); }
     | REG_CS ':' memaddr    { $$ = $3; SetEASegment($$, 0x2E); }
     | REG_SS ':' memaddr    { $$ = $3; SetEASegment($$, 0x36); }
     | REG_DS ':' memaddr    { $$ = $3; SetEASegment($$, 0x3E); }
@@ -355,7 +353,7 @@ rm128: XMMREG       { $$ = effaddr_new_reg($1); }
 ;
 
 /* immediate values */
-imm: expr   { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
+imm: expr   { expr_simplify($1); $$ = immval_new_expr($1); }
 ;
 
 /* explicit immediates */
@@ -378,16 +376,14 @@ imm32: imm
 ;
 
 /* jump targets */
-target: expr       { $$.val = $1; $$.op_sel = JR_NONE; }
+target: expr       { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); }
     | SHORT target  { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); }
     | NEAR target   { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); }
 ;
 
 /* expression trees */
-expr_no_string: INTNUM         { $$ = expr_new_ident(EXPR_INT, ExprInt($1)); }
-    | explabel                 {
-       $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1)));
-    }
+expr_no_string: INTNUM         { $$ = expr_new_ident(ExprInt($1)); }
+    | explabel                 { $$ = expr_new_ident(ExprSym(symrec_use($1))); }
     /*| expr '||' expr         { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
     | expr '|' expr            { $$ = expr_new_tree($1, EXPR_OR, $3); }
     | expr '^' expr            { $$ = expr_new_tree($1, EXPR_XOR, $3); }
@@ -415,7 +411,7 @@ expr_no_string: INTNUM              { $$ = expr_new_ident(EXPR_INT, ExprInt($1)); }
 
 expr: expr_no_string
     | STRING           {
-       $$ = expr_new_ident (EXPR_INT, ExprInt(ConvertCharConstToInt($1)));
+       $$ = expr_new_ident(ExprInt(ConvertCharConstToInt($1)));
     }
 ;
 
@@ -427,12 +423,12 @@ explabel: ID
 instr: instrbase
     | OPERSIZE instr   { $$ = $2; SetInsnOperSizeOverride($$, $1); }
     | ADDRSIZE instr   { $$ = $2; SetInsnAddrSizeOverride($$, $1); }
-    | REG_CS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x2E); }
-    | REG_SS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x36); }
-    | REG_DS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x3E); }
-    | REG_ES instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x26); }
-    | REG_FS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x64); }
-    | REG_GS instr     { $$ = $2; SetEASegment($$->data.insn.ea, 0x65); }
+    | REG_CS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x2E); }
+    | REG_SS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x36); }
+    | REG_DS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x3E); }
+    | REG_ES instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x26); }
+    | REG_FS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x64); }
+    | REG_GS instr     { $$ = $2; SetEASegment(GetInsnEA($$), 0x65); }
     | LOCK instr       { $$ = $2; SetInsnLockRepPrefix($$, 0xF0); }
     | REPNZ instr      { $$ = $2; SetInsnLockRepPrefix($$, 0xF2); }
     | REP instr                { $$ = $2; SetInsnLockRepPrefix($$, 0xF3); }
index 7670e8b264027053eef5a00d3aaecf0b461793e6..e655a5c2ec518ccdf2fda24f27ddc07f11313468 100644 (file)
 
 RCSID("$IdPath$");
 
+struct section {
+    STAILQ_ENTRY(section) link;
+
+    enum { SECTION_GENERAL, SECTION_ABSOLUTE } type;
+
+    char *name;                        /* strdup()'ed name (given by user) */
+
+    union {
+       /* SECTION_GENERAL data */
+       /* SECTION_ABSOLUTE data */
+       unsigned long start;
+    } data;
+
+    bytecodehead bc;           /* the bytecodes for the section's contents */
+};
+
 section *
 sections_initialize(sectionhead *headp, objfmt *of)
 {
@@ -107,3 +123,9 @@ sections_switch(sectionhead *headp, objfmt *of, const char *name)
 
     return s;
 }
+
+bytecodehead *
+section_get_bytecodes(section *sect)
+{
+    return &sect->bc;
+}
index 71dd50b277152e229b3ded79544cb90e10f0498e..ff881721cacf0b115cc488415ea0658672bccecf 100644 (file)
 
 struct objfmt_s;
 
-typedef STAILQ_HEAD(sectionhead_s, section_s) sectionhead;
+typedef STAILQ_HEAD(sectionhead, section) sectionhead;
 
-typedef struct section_s {
-    STAILQ_ENTRY(section_s) link;
-
-    enum { SECTION_GENERAL, SECTION_ABSOLUTE } type;
-
-    char *name;                        /* strdup()'ed name (given by user) */
-
-    union {
-       /* SECTION_GENERAL data */
-       /* SECTION_ABSOLUTE data */
-       unsigned long start;
-    } data;
-
-    bytecodehead bc;           /* the bytecodes for the section's contents */
-} section;
+#ifndef YASM_SECTION
+#define YASM_SECTION
+typedef struct section section;
+#endif
 
 section *sections_initialize(sectionhead *headp, struct objfmt_s *of);
 
 section *sections_switch(sectionhead *headp, struct objfmt_s *of,
                         const char *name);
 
+bytecodehead *section_get_bytecodes(section *sect);
 #endif
index cd3704e2c048235b4a7e82a73e1903d2e4a84314..df2c2733948d8d2a3dca6c7a9efe78cf00273bbd 100644 (file)
 
 RCSID("$IdPath$");
 
+struct symrec {
+    char *name;
+    SymType type;
+    SymStatus status;
+    SymVisibility visibility;
+    char *filename;            /* file and line */
+    unsigned long line;                /*  symbol was first declared or used on */
+    union {
+       unsigned long int_val;  /* integer constant */
+       floatnum *flt;          /* floating point constant */
+       struct label_s {        /* bytecode immediately preceding a label */
+           section *sect;
+           bytecode *bc;
+       } label;
+    } value;
+};
+
 /* private functions */
 static symrec *symrec_get_or_new(const char *);
 static symrec *symrec_define(const char *, SymType type);
@@ -192,3 +209,9 @@ symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
     /* We can't get the value right now. */
     return 0;
 }
+
+const char *
+symrec_get_name(const symrec *sym)
+{
+    return sym->name;
+}
index 21183f4bdf8c6de433ea13a97025b26a8bc19458..88bc608e0870f5355867da7cc310fe490f4a870a 100644 (file)
 #ifndef YASM_SYMREC_H
 #define YASM_SYMREC_H
 
+#ifndef YASM_FLOATNUM
+#define YASM_FLOATNUM
+typedef struct floatnum floatnum;
+#endif
+
+#ifndef YASM_SECTION
+#define YASM_SECTION
+typedef struct section section;
+#endif
+
+#ifndef YASM_BYTECODE
+#define YASM_BYTECODE
+typedef struct bytecode bytecode;
+#endif
+
 /* DEFINED is set with EXTERN and COMMON below */
 typedef enum {
     SYM_NOSTATUS = 0,
@@ -45,28 +60,15 @@ typedef enum {
     SYM_LABEL                  /* for labels */
 } SymType;
 
-typedef struct symrec_s {
-    char *name;
-    SymType type;
-    SymStatus status;
-    SymVisibility visibility;
-    char *filename;            /* file and line */
-    unsigned long line;                /*  symbol was first declared or used on */
-    union {
-       unsigned long int_val;  /* integer constant */
-       struct floatnum_s *flt; /* floating point constant */
-       struct label_s {        /* bytecode immediately preceding a label */
-           struct section_s *sect;
-           struct bytecode_s *bc;
-       } label;
-    } value;
-} symrec;
+#ifndef YASM_SYMREC
+#define YASM_SYMREC
+typedef struct symrec symrec;
+#endif
 
 symrec *symrec_use(const char *name);
 symrec *symrec_define_constant_int(const char *name, unsigned long int_val);
-symrec *symrec_define_constant_float(const char *name, struct floatnum_s *flt);
-symrec *symrec_define_label(const char *name, struct section_s *sect,
-                           struct bytecode_s *precbc);
+symrec *symrec_define_constant_float(const char *name, floatnum *flt);
+symrec *symrec_define_label(const char *name, section *sect, bytecode *precbc);
 symrec *symrec_declare(const char *name, SymVisibility vis);
 
 /* Get the numeric 32-bit value of a symbol if possible.
@@ -77,6 +79,8 @@ symrec *symrec_declare(const char *name, SymVisibility vis);
 int symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
                         int resolve_label);
 
+const char *symrec_get_name(const symrec *sym);
+
 void symrec_foreach(int (*func) (const char *name, symrec *rec));
 
 #endif
index a5430acbf871caf51d99603cb6e48e1318b7d118..169cae5cec26ed48bb3db827032ca0476fb5bc3c 100644 (file)
@@ -21,7 +21,8 @@ bytecode_test_SOURCES = \
 floatnum_test_SOURCES = \
        floatnum_test.c
 
-INCLUDES= -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/check
+INCLUDES= -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/check \
+       -I$(top_builddir)/intl
 LDADD = \
        $(top_builddir)/check/libcheck.a                        \
        $(top_builddir)/src/parsers/nasm/libparser.a            \
index c9898c0b31630d77f5c4444b6800464f332de8d1..77eadc6ad9c9302dc427994a5b85c06439aee684 100644 (file)
@@ -28,9 +28,7 @@
 
 #include "check.h"
 
-#include "util.h"
-
-#include "bytecode.h"
+#include "bytecode.c"
 
 START_TEST(test_effaddr_new_reg)
 {
index b3c5c31a83a900699991641cecf1f581a473047a..d768e3c7adf1a8235cf213d4cc6a03514da679a7 100644 (file)
@@ -31,9 +31,7 @@
 
 #include "check.h"
 
-#include "bitvect.h"
-
-#include "floatnum.h"
+#include "floatnum.c"
 
 /* constants describing parameters of internal floating point format.
  *  (these should match those in src/floatnum.c !)