]> granicus.if.org Git - yasm/commitdiff
Long hairy integration of expression handling into the grammar.
authorMichael Urman <mu@tortall.net>
Thu, 5 Jul 2001 08:37:59 +0000 (08:37 -0000)
committerMichael Urman <mu@tortall.net>
Thu, 5 Jul 2001 08:37:59 +0000 (08:37 -0000)
Added printing, getvalue functionality to expr.[ch]
Changed immval to house an expr* instead of an unsigned long.

gen_instr.pl needs to be updated for ONE cases to fix pointer compares.
bison s/r conflicts still need to be handled.

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

22 files changed:
include/bytecode.h
include/expr.h
libyasm/bytecode.c
libyasm/bytecode.h
libyasm/expr.c
libyasm/expr.h
modules/arch/x86/expr.c
modules/arch/x86/x86expr.c
modules/parsers/nasm/bison.y.in
modules/parsers/nasm/nasm-bison.y
modules/parsers/nasm/token.l.in
src/arch/x86/expr.c
src/arch/x86/x86expr.c
src/bison.y.in
src/bytecode.c
src/bytecode.h
src/expr.c
src/expr.h
src/parsers/nasm/bison.y.in
src/parsers/nasm/nasm-bison.y
src/parsers/nasm/token.l.in
src/token.l.in

index d17ec0a6f4e89f23889f4cdccfc59643861151c7..ce8ee6bde377cc4d0a5743addf73cc7bf32ef21e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: bytecode.h,v 1.8 2001/06/28 21:22:01 peter Exp $
+/* $Id: bytecode.h,v 1.9 2001/07/05 08:37:59 mu Exp $
  * Bytecode utility functions header file
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -38,7 +38,7 @@ typedef struct effaddr_s {
 } effaddr;
 
 typedef struct immval_s {
-    unsigned long val;
+    struct expr_s *val;
 
     unsigned char len;         /* length of val (in bytes), 0 if none */
     unsigned char isrel;
index 18d6eee1df91d37281cf003ac00093a4f32f01f8..3ca1ec683ba8ab77a4b16c6a88f8b6c142377176 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: expr.h,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: expr.h,v 1.2 2001/07/05 08:37:59 mu Exp $
  * Expression handling header file
  *
  *  Copyright (C) 2001  Michael Urman
@@ -57,7 +57,7 @@ typedef enum {
 typedef union expritem_u {
     struct symrec_s *sym;
     struct expr_s *expr;
-    int num;
+    unsigned long num;
 } ExprItem;
 
 typedef struct expr_s {
@@ -67,6 +67,20 @@ typedef struct expr_s {
 } expr;
 
 expr *expr_new (ExprType, ExprItem, ExprOp, ExprType, ExprItem);
+/*expr *expr_new_tree (ExprItem, ExprOp, ExprItem);
+expr *expr_new_branch (ExprOp, ExprItem);
+expr *expr_new_ident (ExprType, ExprItem);*/
+#define expr_new_tree(l,o,r) \
+    expr_new (EXPR_EXPR, (ExprItem)(l), (ExprOp)(o), EXPR_EXPR, (ExprItem)(r))
+#define expr_new_branch(o,r) \
+    expr_new (EXPR_NONE, (ExprItem)0UL, (ExprOp)(o), EXPR_EXPR, (ExprItem)(r))
+#define expr_new_ident(t,r) \
+    expr_new (EXPR_NONE, (ExprItem)0UL, EXPR_IDENT, (ExprType)(t), (ExprItem)(r))
 int expr_simplify (expr *);
 
+void expr_print (expr *);
+
+/* get the value if possible.  return value is IF POSSIBLE, not the val */
+int expr_get_value (expr *, unsigned long *);
+
 #endif
index f9d92a017ccec4c23ca7ce2cc5e2ce99f6c0af14..5812dbd29dffc24f9a70cd2d8158d6b6c6fe416f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: bytecode.c,v 1.8 2001/05/30 07:41:03 peter Exp $
+/* $Id: bytecode.c,v 1.9 2001/07/05 08:37:59 mu Exp $
  * Bytecode utility functions
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -23,6 +23,7 @@
 #include "globals.h"
 #include "bytecode.h"
 #include "errwarn.h"
+#include "expr.h"
 
 static effaddr eff_static;
 static immval im_static;
@@ -70,10 +71,12 @@ effaddr *ConvertRegToEA(effaddr *ptr, unsigned long reg)
 
 effaddr *ConvertImmToEA(effaddr *ptr, immval *im_ptr, unsigned char im_len)
 {
+    int gotexprval;
     if(!ptr)
        ptr = &eff_static;
 
-    ptr->disp = im_ptr->val;
+    /* FIXME: warn when gotexprval is 0, and/or die */
+    gotexprval = expr_get_value (im_ptr->val, &ptr->disp);
     if(im_ptr->len > im_len)
        Warning(WARN_VALUE_EXCEEDS_BOUNDS, (char *)NULL, "word");
     ptr->len = im_len;
@@ -91,7 +94,8 @@ immval *ConvertIntToImm(immval *ptr, unsigned long int_val)
     if(!ptr)
        ptr = &im_static;
 
-    ptr->val = int_val;
+    /* FIXME: this will leak expr's if static is used */
+    ptr->val = expr_new_ident(EXPR_NUM, int_val);
 
     if((int_val & 0xFF) == int_val)
        ptr->len = 1;
@@ -106,6 +110,19 @@ immval *ConvertIntToImm(immval *ptr, unsigned long int_val)
     return ptr;
 }
 
+immval *ConvertExprToImm(immval *ptr, expr *expr_ptr)
+{
+    if(!ptr)
+       ptr = &im_static;
+
+    ptr->val = expr_ptr;
+
+    ptr->isrel = 0;
+    ptr->isneg = 0;
+
+    return ptr;
+}
+
 void SetEASegment(effaddr *ptr, unsigned char segment)
 {
     if(!ptr)
@@ -240,7 +257,9 @@ void DebugPrintBC(bytecode *bc)
                (unsigned int)bc->data.insn.ea.valid_sib,
                (unsigned int)bc->data.insn.ea.need_sib);
            printf("Immediate/Relative Value:\n");
-           printf(" Val=%lx\n", bc->data.insn.imm.val);
+           printf(" Val=");
+           expr_print(bc->data.insn.imm.val);
+           printf("\n");
            printf(" Len=%u, IsRel=%u, IsNeg=%u\n",
                (unsigned int)bc->data.insn.imm.len,
                (unsigned int)bc->data.insn.imm.isrel,
index d17ec0a6f4e89f23889f4cdccfc59643861151c7..ce8ee6bde377cc4d0a5743addf73cc7bf32ef21e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: bytecode.h,v 1.8 2001/06/28 21:22:01 peter Exp $
+/* $Id: bytecode.h,v 1.9 2001/07/05 08:37:59 mu Exp $
  * Bytecode utility functions header file
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -38,7 +38,7 @@ typedef struct effaddr_s {
 } effaddr;
 
 typedef struct immval_s {
-    unsigned long val;
+    struct expr_s *val;
 
     unsigned char len;         /* length of val (in bytes), 0 if none */
     unsigned char isrel;
index e62109578a7325b39e8163a4cad3fdb63497d47b..0d7f722123ae2c1deb1d5e01dfcf10c2188c2b67 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: expr.c,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: expr.c,v 1.2 2001/07/05 08:37:59 mu Exp $
  * Expression handling
  *
  *  Copyright (C) 2001  Michael Urman
@@ -189,3 +189,58 @@ int expr_simplify (expr *e)
 
     return simplified;
 }
+
+int expr_get_value (expr *e, unsigned long *retval)
+{
+    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+          && expr_simplify (e));
+
+    if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+    {
+       *retval = e->right.num;
+       return 1;
+    }
+    else
+       return 0;
+}
+
+void expr_print (expr *e)
+{
+    if (e->op != EXPR_IDENT) {
+       switch (e->ltype) {
+           case EXPR_NUM: printf ("%d", e->left.num); break;
+           case EXPR_SYM: printf ("%s", e->left.sym->name); break;
+           case EXPR_EXPR: printf ("("); expr_print (e->left.expr); printf(")");
+           case EXPR_NONE: break;
+       }
+    }
+    switch (e->op) {
+       case EXPR_ADD: printf ("+"); break;
+       case EXPR_SUB: printf ("-"); break;
+       case EXPR_MUL: printf ("*"); break;
+       case EXPR_DIV: printf ("/"); break;
+       case EXPR_MOD: printf ("%"); break;
+       case EXPR_NEG: printf ("-"); break;
+       case EXPR_NOT: printf ("~"); break;
+       case EXPR_OR: printf ("|"); break;
+       case EXPR_AND: printf ("&"); break;
+       case EXPR_XOR: printf ("^"); break;
+       case EXPR_SHL: printf ("<<"); break;
+       case EXPR_SHR: printf (">>"); break;
+       case EXPR_LOR: printf ("||"); break;
+       case EXPR_LAND: printf ("&&"); break;
+       case EXPR_LNOT: printf ("!"); break;
+       case EXPR_LT: printf ("<"); break;
+       case EXPR_GT: printf (">"); break;
+       case EXPR_LE: printf ("<="); break;
+       case EXPR_GE: printf (">="); break;
+       case EXPR_NE: printf ("!="); break;
+       case EXPR_IDENT: break;
+    }
+    switch (e->rtype) {
+       case EXPR_NUM: printf ("%d", e->right.num); break;
+       case EXPR_SYM: printf ("%s", e->right.sym->name); break;
+       case EXPR_EXPR: printf ("("); expr_print (e->right.expr); printf(")");
+       case EXPR_NONE: break;
+    }
+}
index 18d6eee1df91d37281cf003ac00093a4f32f01f8..3ca1ec683ba8ab77a4b16c6a88f8b6c142377176 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: expr.h,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: expr.h,v 1.2 2001/07/05 08:37:59 mu Exp $
  * Expression handling header file
  *
  *  Copyright (C) 2001  Michael Urman
@@ -57,7 +57,7 @@ typedef enum {
 typedef union expritem_u {
     struct symrec_s *sym;
     struct expr_s *expr;
-    int num;
+    unsigned long num;
 } ExprItem;
 
 typedef struct expr_s {
@@ -67,6 +67,20 @@ typedef struct expr_s {
 } expr;
 
 expr *expr_new (ExprType, ExprItem, ExprOp, ExprType, ExprItem);
+/*expr *expr_new_tree (ExprItem, ExprOp, ExprItem);
+expr *expr_new_branch (ExprOp, ExprItem);
+expr *expr_new_ident (ExprType, ExprItem);*/
+#define expr_new_tree(l,o,r) \
+    expr_new (EXPR_EXPR, (ExprItem)(l), (ExprOp)(o), EXPR_EXPR, (ExprItem)(r))
+#define expr_new_branch(o,r) \
+    expr_new (EXPR_NONE, (ExprItem)0UL, (ExprOp)(o), EXPR_EXPR, (ExprItem)(r))
+#define expr_new_ident(t,r) \
+    expr_new (EXPR_NONE, (ExprItem)0UL, EXPR_IDENT, (ExprType)(t), (ExprItem)(r))
 int expr_simplify (expr *);
 
+void expr_print (expr *);
+
+/* get the value if possible.  return value is IF POSSIBLE, not the val */
+int expr_get_value (expr *, unsigned long *);
+
 #endif
index e62109578a7325b39e8163a4cad3fdb63497d47b..0d7f722123ae2c1deb1d5e01dfcf10c2188c2b67 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: expr.c,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: expr.c,v 1.2 2001/07/05 08:37:59 mu Exp $
  * Expression handling
  *
  *  Copyright (C) 2001  Michael Urman
@@ -189,3 +189,58 @@ int expr_simplify (expr *e)
 
     return simplified;
 }
+
+int expr_get_value (expr *e, unsigned long *retval)
+{
+    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+          && expr_simplify (e));
+
+    if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+    {
+       *retval = e->right.num;
+       return 1;
+    }
+    else
+       return 0;
+}
+
+void expr_print (expr *e)
+{
+    if (e->op != EXPR_IDENT) {
+       switch (e->ltype) {
+           case EXPR_NUM: printf ("%d", e->left.num); break;
+           case EXPR_SYM: printf ("%s", e->left.sym->name); break;
+           case EXPR_EXPR: printf ("("); expr_print (e->left.expr); printf(")");
+           case EXPR_NONE: break;
+       }
+    }
+    switch (e->op) {
+       case EXPR_ADD: printf ("+"); break;
+       case EXPR_SUB: printf ("-"); break;
+       case EXPR_MUL: printf ("*"); break;
+       case EXPR_DIV: printf ("/"); break;
+       case EXPR_MOD: printf ("%"); break;
+       case EXPR_NEG: printf ("-"); break;
+       case EXPR_NOT: printf ("~"); break;
+       case EXPR_OR: printf ("|"); break;
+       case EXPR_AND: printf ("&"); break;
+       case EXPR_XOR: printf ("^"); break;
+       case EXPR_SHL: printf ("<<"); break;
+       case EXPR_SHR: printf (">>"); break;
+       case EXPR_LOR: printf ("||"); break;
+       case EXPR_LAND: printf ("&&"); break;
+       case EXPR_LNOT: printf ("!"); break;
+       case EXPR_LT: printf ("<"); break;
+       case EXPR_GT: printf (">"); break;
+       case EXPR_LE: printf ("<="); break;
+       case EXPR_GE: printf (">="); break;
+       case EXPR_NE: printf ("!="); break;
+       case EXPR_IDENT: break;
+    }
+    switch (e->rtype) {
+       case EXPR_NUM: printf ("%d", e->right.num); break;
+       case EXPR_SYM: printf ("%s", e->right.sym->name); break;
+       case EXPR_EXPR: printf ("("); expr_print (e->right.expr); printf(")");
+       case EXPR_NONE: break;
+    }
+}
index f653822ad7df980d357713eeb2849f1e2ee837e8..1bf3c8845180b52c7e5757f0faa924efeaf59639 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: x86expr.c,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: x86expr.c,v 1.2 2001/07/05 08:37:59 mu Exp $
  * Expression handling
  *
  *  Copyright (C) 2001  Michael Urman
@@ -189,3 +189,58 @@ int expr_simplify (expr *e)
 
     return simplified;
 }
+
+int expr_get_value (expr *e, unsigned long *retval)
+{
+    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+          && expr_simplify (e));
+
+    if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+    {
+       *retval = e->right.num;
+       return 1;
+    }
+    else
+       return 0;
+}
+
+void expr_print (expr *e)
+{
+    if (e->op != EXPR_IDENT) {
+       switch (e->ltype) {
+           case EXPR_NUM: printf ("%d", e->left.num); break;
+           case EXPR_SYM: printf ("%s", e->left.sym->name); break;
+           case EXPR_EXPR: printf ("("); expr_print (e->left.expr); printf(")");
+           case EXPR_NONE: break;
+       }
+    }
+    switch (e->op) {
+       case EXPR_ADD: printf ("+"); break;
+       case EXPR_SUB: printf ("-"); break;
+       case EXPR_MUL: printf ("*"); break;
+       case EXPR_DIV: printf ("/"); break;
+       case EXPR_MOD: printf ("%"); break;
+       case EXPR_NEG: printf ("-"); break;
+       case EXPR_NOT: printf ("~"); break;
+       case EXPR_OR: printf ("|"); break;
+       case EXPR_AND: printf ("&"); break;
+       case EXPR_XOR: printf ("^"); break;
+       case EXPR_SHL: printf ("<<"); break;
+       case EXPR_SHR: printf (">>"); break;
+       case EXPR_LOR: printf ("||"); break;
+       case EXPR_LAND: printf ("&&"); break;
+       case EXPR_LNOT: printf ("!"); break;
+       case EXPR_LT: printf ("<"); break;
+       case EXPR_GT: printf (">"); break;
+       case EXPR_LE: printf ("<="); break;
+       case EXPR_GE: printf (">="); break;
+       case EXPR_NE: printf ("!="); break;
+       case EXPR_IDENT: break;
+    }
+    switch (e->rtype) {
+       case EXPR_NUM: printf ("%d", e->right.num); break;
+       case EXPR_SYM: printf ("%s", e->right.sym->name); break;
+       case EXPR_EXPR: printf ("("); expr_print (e->right.expr); printf(")");
+       case EXPR_NONE: break;
+    }
+}
index 72b0b96d41a7e49fa47170d9ca2bbf0bf809629c..f1644f07ecd8620e2ba802002d85728520d0ffe0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: bison.y.in,v 1.15 2001/07/05 07:21:35 peter Exp $
+/* $Id: bison.y.in,v 1.16 2001/07/05 08:37:59 mu Exp $
  * Main bison parser
  *
  *  Copyright (C) 2001  Peter Johnson, Michael Urman
@@ -26,6 +26,7 @@
 #include "globals.h"
 #include "bytecode.h"
 #include "errwarn.h"
+#include "expr.h"
 
 #define YYDEBUG 1
 
@@ -46,6 +47,7 @@ extern void yyerror(char *);
     } syminfo;
     unsigned char groupdata[3];
     effaddr ea_val;
+    expr *exp;
     immval im_val;
     bytecode bc;
 } 
@@ -83,7 +85,9 @@ extern void yyerror(char *);
 %type <ea_val> mem8 mem16 mem32 mem64 mem80 mem128 mem1632
 %type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
 %type <ea_val> rm8 rm16 rm32 rm64 rm128
-%type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <exp> immexp
+%type <syminfo> immlabel
 %type <sym> label_id
 
 %left '-' '+'
@@ -271,10 +275,36 @@ rm128: XMMREG     { (void)ConvertRegToEA(&$$, $1); }
 
 /* immediate values */
 /* TODO: formula expansion */
-immexp: INTNUM { (void)ConvertIntToImm(&$$, $1); }
-;
-
-imm: immexp
+immexp: /*INTNUM       { (void)ConvertIntToImm(&$$, $1); } */
+       INTNUM          { $$ = expr_new_ident (EXPR_NUM, $1); }
+    | immlabel         { $$ = expr_new_ident (EXPR_SYM, sym_use_get ($1.name, SYM_LABEL)); }
+    /*| immexp '||' immexp     { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/
+    | immexp '|' immexp        { $$ = expr_new_tree ($1, EXPR_OR, $3); }
+    | immexp '^' immexp        { $$ = expr_new_tree ($1, EXPR_XOR, $3); }
+    /*| immexp '&&' immexp     { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/
+    | immexp '&' immexp        { $$ = expr_new_tree ($1, EXPR_AND, $3); }
+    /*| immexp '==' immexp     { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/
+    /*| immexp '>' immexp      { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+    /*| immexp '<' immexp      { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+    /*| immexp '>=' immexp     { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+    /*| immexp '<=' immexp     { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+    /*| immexp '!=' immexp     { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/
+    | immexp LEFT_OP immexp    { $$ = expr_new_tree ($1, EXPR_SHL, $3); }
+    | immexp RIGHT_OP immexp   { $$ = expr_new_tree ($1, EXPR_SHR, $3); }
+    | immexp '+' immexp        { $$ = expr_new_tree ($1, EXPR_ADD, $3); }
+    | immexp '-' immexp        { $$ = expr_new_tree ($1, EXPR_SUB, $3); }
+    | immexp '*' immexp        { $$ = expr_new_tree ($1, EXPR_MUL, $3); }
+    | immexp '/' immexp        { $$ = expr_new_tree ($1, EXPR_DIV, $3); }
+    | immexp '%' immexp        { $$ = expr_new_tree ($1, EXPR_MOD, $3); }
+    | '-' immexp       { $$ = expr_new_branch (EXPR_NEG, $2); }
+    /*| '!' immexp     { $$ = expr_new_branch (EXPR_LNOT, $2); }*/
+    | '~' immexp       { $$ = expr_new_branch (EXPR_NOT, $2); }
+    | '(' immexp ')'   { $$ = $2; }
+;
+
+immlabel: ID | SPECIAL_ID | LOCAL_ID ;
+
+imm: immexp            { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
 ;
 
 /* explicit immediates */
index 7a32a80e0256b3c355ab7f876acde671437ffa4d..6c1a66bb314ba185bb6eb6818119c70c9d47701c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: nasm-bison.y,v 1.15 2001/07/05 07:21:35 peter Exp $
+/* $Id: nasm-bison.y,v 1.16 2001/07/05 08:37:59 mu Exp $
  * Main bison parser
  *
  *  Copyright (C) 2001  Peter Johnson, Michael Urman
@@ -26,6 +26,7 @@
 #include "globals.h"
 #include "bytecode.h"
 #include "errwarn.h"
+#include "expr.h"
 
 #define YYDEBUG 1
 
@@ -46,6 +47,7 @@ extern void yyerror(char *);
     } syminfo;
     unsigned char groupdata[3];
     effaddr ea_val;
+    expr *exp;
     immval im_val;
     bytecode bc;
 } 
@@ -83,7 +85,9 @@ extern void yyerror(char *);
 %type <ea_val> mem8 mem16 mem32 mem64 mem80 mem128 mem1632
 %type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
 %type <ea_val> rm8 rm16 rm32 rm64 rm128
-%type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <exp> immexp
+%type <syminfo> immlabel
 %type <sym> label_id
 
 %left '-' '+'
@@ -271,10 +275,36 @@ rm128: XMMREG     { (void)ConvertRegToEA(&$$, $1); }
 
 /* immediate values */
 /* TODO: formula expansion */
-immexp: INTNUM { (void)ConvertIntToImm(&$$, $1); }
-;
-
-imm: immexp
+immexp: /*INTNUM       { (void)ConvertIntToImm(&$$, $1); } */
+       INTNUM          { $$ = expr_new_ident (EXPR_NUM, $1); }
+    | immlabel         { $$ = expr_new_ident (EXPR_SYM, sym_use_get ($1.name, SYM_LABEL)); }
+    /*| immexp '||' immexp     { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/
+    | immexp '|' immexp        { $$ = expr_new_tree ($1, EXPR_OR, $3); }
+    | immexp '^' immexp        { $$ = expr_new_tree ($1, EXPR_XOR, $3); }
+    /*| immexp '&&' immexp     { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/
+    | immexp '&' immexp        { $$ = expr_new_tree ($1, EXPR_AND, $3); }
+    /*| immexp '==' immexp     { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/
+    /*| immexp '>' immexp      { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+    /*| immexp '<' immexp      { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+    /*| immexp '>=' immexp     { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+    /*| immexp '<=' immexp     { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+    /*| immexp '!=' immexp     { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/
+    | immexp LEFT_OP immexp    { $$ = expr_new_tree ($1, EXPR_SHL, $3); }
+    | immexp RIGHT_OP immexp   { $$ = expr_new_tree ($1, EXPR_SHR, $3); }
+    | immexp '+' immexp        { $$ = expr_new_tree ($1, EXPR_ADD, $3); }
+    | immexp '-' immexp        { $$ = expr_new_tree ($1, EXPR_SUB, $3); }
+    | immexp '*' immexp        { $$ = expr_new_tree ($1, EXPR_MUL, $3); }
+    | immexp '/' immexp        { $$ = expr_new_tree ($1, EXPR_DIV, $3); }
+    | immexp '%' immexp        { $$ = expr_new_tree ($1, EXPR_MOD, $3); }
+    | '-' immexp       { $$ = expr_new_branch (EXPR_NEG, $2); }
+    /*| '!' immexp     { $$ = expr_new_branch (EXPR_LNOT, $2); }*/
+    | '~' immexp       { $$ = expr_new_branch (EXPR_NOT, $2); }
+    | '(' immexp ')'   { $$ = $2; }
+;
+
+immlabel: ID | SPECIAL_ID | LOCAL_ID ;
+
+imm: immexp            { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
 ;
 
 /* explicit immediates */
index 4aa92c492ac7ada085932b62eb9eefb21a65227c..2a19cdc8aedb4832ed17197a931e06e02e3f6c24 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: token.l.in,v 1.8 2001/06/29 05:11:40 peter Exp $
+/* $Id: token.l.in,v 1.9 2001/07/05 08:37:59 mu Exp $
  * Main lexer
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -34,6 +34,7 @@
 #include "symrec.h"
 #include "bytecode.h"
 #include "errwarn.h"
+#include "expr.h"
 #include "bison.h"
 
 %}
index e62109578a7325b39e8163a4cad3fdb63497d47b..0d7f722123ae2c1deb1d5e01dfcf10c2188c2b67 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: expr.c,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: expr.c,v 1.2 2001/07/05 08:37:59 mu Exp $
  * Expression handling
  *
  *  Copyright (C) 2001  Michael Urman
@@ -189,3 +189,58 @@ int expr_simplify (expr *e)
 
     return simplified;
 }
+
+int expr_get_value (expr *e, unsigned long *retval)
+{
+    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+          && expr_simplify (e));
+
+    if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+    {
+       *retval = e->right.num;
+       return 1;
+    }
+    else
+       return 0;
+}
+
+void expr_print (expr *e)
+{
+    if (e->op != EXPR_IDENT) {
+       switch (e->ltype) {
+           case EXPR_NUM: printf ("%d", e->left.num); break;
+           case EXPR_SYM: printf ("%s", e->left.sym->name); break;
+           case EXPR_EXPR: printf ("("); expr_print (e->left.expr); printf(")");
+           case EXPR_NONE: break;
+       }
+    }
+    switch (e->op) {
+       case EXPR_ADD: printf ("+"); break;
+       case EXPR_SUB: printf ("-"); break;
+       case EXPR_MUL: printf ("*"); break;
+       case EXPR_DIV: printf ("/"); break;
+       case EXPR_MOD: printf ("%"); break;
+       case EXPR_NEG: printf ("-"); break;
+       case EXPR_NOT: printf ("~"); break;
+       case EXPR_OR: printf ("|"); break;
+       case EXPR_AND: printf ("&"); break;
+       case EXPR_XOR: printf ("^"); break;
+       case EXPR_SHL: printf ("<<"); break;
+       case EXPR_SHR: printf (">>"); break;
+       case EXPR_LOR: printf ("||"); break;
+       case EXPR_LAND: printf ("&&"); break;
+       case EXPR_LNOT: printf ("!"); break;
+       case EXPR_LT: printf ("<"); break;
+       case EXPR_GT: printf (">"); break;
+       case EXPR_LE: printf ("<="); break;
+       case EXPR_GE: printf (">="); break;
+       case EXPR_NE: printf ("!="); break;
+       case EXPR_IDENT: break;
+    }
+    switch (e->rtype) {
+       case EXPR_NUM: printf ("%d", e->right.num); break;
+       case EXPR_SYM: printf ("%s", e->right.sym->name); break;
+       case EXPR_EXPR: printf ("("); expr_print (e->right.expr); printf(")");
+       case EXPR_NONE: break;
+    }
+}
index f653822ad7df980d357713eeb2849f1e2ee837e8..1bf3c8845180b52c7e5757f0faa924efeaf59639 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: x86expr.c,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: x86expr.c,v 1.2 2001/07/05 08:37:59 mu Exp $
  * Expression handling
  *
  *  Copyright (C) 2001  Michael Urman
@@ -189,3 +189,58 @@ int expr_simplify (expr *e)
 
     return simplified;
 }
+
+int expr_get_value (expr *e, unsigned long *retval)
+{
+    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+          && expr_simplify (e));
+
+    if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+    {
+       *retval = e->right.num;
+       return 1;
+    }
+    else
+       return 0;
+}
+
+void expr_print (expr *e)
+{
+    if (e->op != EXPR_IDENT) {
+       switch (e->ltype) {
+           case EXPR_NUM: printf ("%d", e->left.num); break;
+           case EXPR_SYM: printf ("%s", e->left.sym->name); break;
+           case EXPR_EXPR: printf ("("); expr_print (e->left.expr); printf(")");
+           case EXPR_NONE: break;
+       }
+    }
+    switch (e->op) {
+       case EXPR_ADD: printf ("+"); break;
+       case EXPR_SUB: printf ("-"); break;
+       case EXPR_MUL: printf ("*"); break;
+       case EXPR_DIV: printf ("/"); break;
+       case EXPR_MOD: printf ("%"); break;
+       case EXPR_NEG: printf ("-"); break;
+       case EXPR_NOT: printf ("~"); break;
+       case EXPR_OR: printf ("|"); break;
+       case EXPR_AND: printf ("&"); break;
+       case EXPR_XOR: printf ("^"); break;
+       case EXPR_SHL: printf ("<<"); break;
+       case EXPR_SHR: printf (">>"); break;
+       case EXPR_LOR: printf ("||"); break;
+       case EXPR_LAND: printf ("&&"); break;
+       case EXPR_LNOT: printf ("!"); break;
+       case EXPR_LT: printf ("<"); break;
+       case EXPR_GT: printf (">"); break;
+       case EXPR_LE: printf ("<="); break;
+       case EXPR_GE: printf (">="); break;
+       case EXPR_NE: printf ("!="); break;
+       case EXPR_IDENT: break;
+    }
+    switch (e->rtype) {
+       case EXPR_NUM: printf ("%d", e->right.num); break;
+       case EXPR_SYM: printf ("%s", e->right.sym->name); break;
+       case EXPR_EXPR: printf ("("); expr_print (e->right.expr); printf(")");
+       case EXPR_NONE: break;
+    }
+}
index 72b0b96d41a7e49fa47170d9ca2bbf0bf809629c..f1644f07ecd8620e2ba802002d85728520d0ffe0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: bison.y.in,v 1.15 2001/07/05 07:21:35 peter Exp $
+/* $Id: bison.y.in,v 1.16 2001/07/05 08:37:59 mu Exp $
  * Main bison parser
  *
  *  Copyright (C) 2001  Peter Johnson, Michael Urman
@@ -26,6 +26,7 @@
 #include "globals.h"
 #include "bytecode.h"
 #include "errwarn.h"
+#include "expr.h"
 
 #define YYDEBUG 1
 
@@ -46,6 +47,7 @@ extern void yyerror(char *);
     } syminfo;
     unsigned char groupdata[3];
     effaddr ea_val;
+    expr *exp;
     immval im_val;
     bytecode bc;
 } 
@@ -83,7 +85,9 @@ extern void yyerror(char *);
 %type <ea_val> mem8 mem16 mem32 mem64 mem80 mem128 mem1632
 %type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
 %type <ea_val> rm8 rm16 rm32 rm64 rm128
-%type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <exp> immexp
+%type <syminfo> immlabel
 %type <sym> label_id
 
 %left '-' '+'
@@ -271,10 +275,36 @@ rm128: XMMREG     { (void)ConvertRegToEA(&$$, $1); }
 
 /* immediate values */
 /* TODO: formula expansion */
-immexp: INTNUM { (void)ConvertIntToImm(&$$, $1); }
-;
-
-imm: immexp
+immexp: /*INTNUM       { (void)ConvertIntToImm(&$$, $1); } */
+       INTNUM          { $$ = expr_new_ident (EXPR_NUM, $1); }
+    | immlabel         { $$ = expr_new_ident (EXPR_SYM, sym_use_get ($1.name, SYM_LABEL)); }
+    /*| immexp '||' immexp     { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/
+    | immexp '|' immexp        { $$ = expr_new_tree ($1, EXPR_OR, $3); }
+    | immexp '^' immexp        { $$ = expr_new_tree ($1, EXPR_XOR, $3); }
+    /*| immexp '&&' immexp     { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/
+    | immexp '&' immexp        { $$ = expr_new_tree ($1, EXPR_AND, $3); }
+    /*| immexp '==' immexp     { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/
+    /*| immexp '>' immexp      { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+    /*| immexp '<' immexp      { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+    /*| immexp '>=' immexp     { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+    /*| immexp '<=' immexp     { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+    /*| immexp '!=' immexp     { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/
+    | immexp LEFT_OP immexp    { $$ = expr_new_tree ($1, EXPR_SHL, $3); }
+    | immexp RIGHT_OP immexp   { $$ = expr_new_tree ($1, EXPR_SHR, $3); }
+    | immexp '+' immexp        { $$ = expr_new_tree ($1, EXPR_ADD, $3); }
+    | immexp '-' immexp        { $$ = expr_new_tree ($1, EXPR_SUB, $3); }
+    | immexp '*' immexp        { $$ = expr_new_tree ($1, EXPR_MUL, $3); }
+    | immexp '/' immexp        { $$ = expr_new_tree ($1, EXPR_DIV, $3); }
+    | immexp '%' immexp        { $$ = expr_new_tree ($1, EXPR_MOD, $3); }
+    | '-' immexp       { $$ = expr_new_branch (EXPR_NEG, $2); }
+    /*| '!' immexp     { $$ = expr_new_branch (EXPR_LNOT, $2); }*/
+    | '~' immexp       { $$ = expr_new_branch (EXPR_NOT, $2); }
+    | '(' immexp ')'   { $$ = $2; }
+;
+
+immlabel: ID | SPECIAL_ID | LOCAL_ID ;
+
+imm: immexp            { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
 ;
 
 /* explicit immediates */
index f9d92a017ccec4c23ca7ce2cc5e2ce99f6c0af14..5812dbd29dffc24f9a70cd2d8158d6b6c6fe416f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: bytecode.c,v 1.8 2001/05/30 07:41:03 peter Exp $
+/* $Id: bytecode.c,v 1.9 2001/07/05 08:37:59 mu Exp $
  * Bytecode utility functions
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -23,6 +23,7 @@
 #include "globals.h"
 #include "bytecode.h"
 #include "errwarn.h"
+#include "expr.h"
 
 static effaddr eff_static;
 static immval im_static;
@@ -70,10 +71,12 @@ effaddr *ConvertRegToEA(effaddr *ptr, unsigned long reg)
 
 effaddr *ConvertImmToEA(effaddr *ptr, immval *im_ptr, unsigned char im_len)
 {
+    int gotexprval;
     if(!ptr)
        ptr = &eff_static;
 
-    ptr->disp = im_ptr->val;
+    /* FIXME: warn when gotexprval is 0, and/or die */
+    gotexprval = expr_get_value (im_ptr->val, &ptr->disp);
     if(im_ptr->len > im_len)
        Warning(WARN_VALUE_EXCEEDS_BOUNDS, (char *)NULL, "word");
     ptr->len = im_len;
@@ -91,7 +94,8 @@ immval *ConvertIntToImm(immval *ptr, unsigned long int_val)
     if(!ptr)
        ptr = &im_static;
 
-    ptr->val = int_val;
+    /* FIXME: this will leak expr's if static is used */
+    ptr->val = expr_new_ident(EXPR_NUM, int_val);
 
     if((int_val & 0xFF) == int_val)
        ptr->len = 1;
@@ -106,6 +110,19 @@ immval *ConvertIntToImm(immval *ptr, unsigned long int_val)
     return ptr;
 }
 
+immval *ConvertExprToImm(immval *ptr, expr *expr_ptr)
+{
+    if(!ptr)
+       ptr = &im_static;
+
+    ptr->val = expr_ptr;
+
+    ptr->isrel = 0;
+    ptr->isneg = 0;
+
+    return ptr;
+}
+
 void SetEASegment(effaddr *ptr, unsigned char segment)
 {
     if(!ptr)
@@ -240,7 +257,9 @@ void DebugPrintBC(bytecode *bc)
                (unsigned int)bc->data.insn.ea.valid_sib,
                (unsigned int)bc->data.insn.ea.need_sib);
            printf("Immediate/Relative Value:\n");
-           printf(" Val=%lx\n", bc->data.insn.imm.val);
+           printf(" Val=");
+           expr_print(bc->data.insn.imm.val);
+           printf("\n");
            printf(" Len=%u, IsRel=%u, IsNeg=%u\n",
                (unsigned int)bc->data.insn.imm.len,
                (unsigned int)bc->data.insn.imm.isrel,
index d17ec0a6f4e89f23889f4cdccfc59643861151c7..ce8ee6bde377cc4d0a5743addf73cc7bf32ef21e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: bytecode.h,v 1.8 2001/06/28 21:22:01 peter Exp $
+/* $Id: bytecode.h,v 1.9 2001/07/05 08:37:59 mu Exp $
  * Bytecode utility functions header file
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -38,7 +38,7 @@ typedef struct effaddr_s {
 } effaddr;
 
 typedef struct immval_s {
-    unsigned long val;
+    struct expr_s *val;
 
     unsigned char len;         /* length of val (in bytes), 0 if none */
     unsigned char isrel;
index e62109578a7325b39e8163a4cad3fdb63497d47b..0d7f722123ae2c1deb1d5e01dfcf10c2188c2b67 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: expr.c,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: expr.c,v 1.2 2001/07/05 08:37:59 mu Exp $
  * Expression handling
  *
  *  Copyright (C) 2001  Michael Urman
@@ -189,3 +189,58 @@ int expr_simplify (expr *e)
 
     return simplified;
 }
+
+int expr_get_value (expr *e, unsigned long *retval)
+{
+    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+          && expr_simplify (e));
+
+    if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+    {
+       *retval = e->right.num;
+       return 1;
+    }
+    else
+       return 0;
+}
+
+void expr_print (expr *e)
+{
+    if (e->op != EXPR_IDENT) {
+       switch (e->ltype) {
+           case EXPR_NUM: printf ("%d", e->left.num); break;
+           case EXPR_SYM: printf ("%s", e->left.sym->name); break;
+           case EXPR_EXPR: printf ("("); expr_print (e->left.expr); printf(")");
+           case EXPR_NONE: break;
+       }
+    }
+    switch (e->op) {
+       case EXPR_ADD: printf ("+"); break;
+       case EXPR_SUB: printf ("-"); break;
+       case EXPR_MUL: printf ("*"); break;
+       case EXPR_DIV: printf ("/"); break;
+       case EXPR_MOD: printf ("%"); break;
+       case EXPR_NEG: printf ("-"); break;
+       case EXPR_NOT: printf ("~"); break;
+       case EXPR_OR: printf ("|"); break;
+       case EXPR_AND: printf ("&"); break;
+       case EXPR_XOR: printf ("^"); break;
+       case EXPR_SHL: printf ("<<"); break;
+       case EXPR_SHR: printf (">>"); break;
+       case EXPR_LOR: printf ("||"); break;
+       case EXPR_LAND: printf ("&&"); break;
+       case EXPR_LNOT: printf ("!"); break;
+       case EXPR_LT: printf ("<"); break;
+       case EXPR_GT: printf (">"); break;
+       case EXPR_LE: printf ("<="); break;
+       case EXPR_GE: printf (">="); break;
+       case EXPR_NE: printf ("!="); break;
+       case EXPR_IDENT: break;
+    }
+    switch (e->rtype) {
+       case EXPR_NUM: printf ("%d", e->right.num); break;
+       case EXPR_SYM: printf ("%s", e->right.sym->name); break;
+       case EXPR_EXPR: printf ("("); expr_print (e->right.expr); printf(")");
+       case EXPR_NONE: break;
+    }
+}
index 18d6eee1df91d37281cf003ac00093a4f32f01f8..3ca1ec683ba8ab77a4b16c6a88f8b6c142377176 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: expr.h,v 1.1 2001/07/05 06:28:54 mu Exp $
+/* $Id: expr.h,v 1.2 2001/07/05 08:37:59 mu Exp $
  * Expression handling header file
  *
  *  Copyright (C) 2001  Michael Urman
@@ -57,7 +57,7 @@ typedef enum {
 typedef union expritem_u {
     struct symrec_s *sym;
     struct expr_s *expr;
-    int num;
+    unsigned long num;
 } ExprItem;
 
 typedef struct expr_s {
@@ -67,6 +67,20 @@ typedef struct expr_s {
 } expr;
 
 expr *expr_new (ExprType, ExprItem, ExprOp, ExprType, ExprItem);
+/*expr *expr_new_tree (ExprItem, ExprOp, ExprItem);
+expr *expr_new_branch (ExprOp, ExprItem);
+expr *expr_new_ident (ExprType, ExprItem);*/
+#define expr_new_tree(l,o,r) \
+    expr_new (EXPR_EXPR, (ExprItem)(l), (ExprOp)(o), EXPR_EXPR, (ExprItem)(r))
+#define expr_new_branch(o,r) \
+    expr_new (EXPR_NONE, (ExprItem)0UL, (ExprOp)(o), EXPR_EXPR, (ExprItem)(r))
+#define expr_new_ident(t,r) \
+    expr_new (EXPR_NONE, (ExprItem)0UL, EXPR_IDENT, (ExprType)(t), (ExprItem)(r))
 int expr_simplify (expr *);
 
+void expr_print (expr *);
+
+/* get the value if possible.  return value is IF POSSIBLE, not the val */
+int expr_get_value (expr *, unsigned long *);
+
 #endif
index 72b0b96d41a7e49fa47170d9ca2bbf0bf809629c..f1644f07ecd8620e2ba802002d85728520d0ffe0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: bison.y.in,v 1.15 2001/07/05 07:21:35 peter Exp $
+/* $Id: bison.y.in,v 1.16 2001/07/05 08:37:59 mu Exp $
  * Main bison parser
  *
  *  Copyright (C) 2001  Peter Johnson, Michael Urman
@@ -26,6 +26,7 @@
 #include "globals.h"
 #include "bytecode.h"
 #include "errwarn.h"
+#include "expr.h"
 
 #define YYDEBUG 1
 
@@ -46,6 +47,7 @@ extern void yyerror(char *);
     } syminfo;
     unsigned char groupdata[3];
     effaddr ea_val;
+    expr *exp;
     immval im_val;
     bytecode bc;
 } 
@@ -83,7 +85,9 @@ extern void yyerror(char *);
 %type <ea_val> mem8 mem16 mem32 mem64 mem80 mem128 mem1632
 %type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
 %type <ea_val> rm8 rm16 rm32 rm64 rm128
-%type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <exp> immexp
+%type <syminfo> immlabel
 %type <sym> label_id
 
 %left '-' '+'
@@ -271,10 +275,36 @@ rm128: XMMREG     { (void)ConvertRegToEA(&$$, $1); }
 
 /* immediate values */
 /* TODO: formula expansion */
-immexp: INTNUM { (void)ConvertIntToImm(&$$, $1); }
-;
-
-imm: immexp
+immexp: /*INTNUM       { (void)ConvertIntToImm(&$$, $1); } */
+       INTNUM          { $$ = expr_new_ident (EXPR_NUM, $1); }
+    | immlabel         { $$ = expr_new_ident (EXPR_SYM, sym_use_get ($1.name, SYM_LABEL)); }
+    /*| immexp '||' immexp     { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/
+    | immexp '|' immexp        { $$ = expr_new_tree ($1, EXPR_OR, $3); }
+    | immexp '^' immexp        { $$ = expr_new_tree ($1, EXPR_XOR, $3); }
+    /*| immexp '&&' immexp     { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/
+    | immexp '&' immexp        { $$ = expr_new_tree ($1, EXPR_AND, $3); }
+    /*| immexp '==' immexp     { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/
+    /*| immexp '>' immexp      { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+    /*| immexp '<' immexp      { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+    /*| immexp '>=' immexp     { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+    /*| immexp '<=' immexp     { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+    /*| immexp '!=' immexp     { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/
+    | immexp LEFT_OP immexp    { $$ = expr_new_tree ($1, EXPR_SHL, $3); }
+    | immexp RIGHT_OP immexp   { $$ = expr_new_tree ($1, EXPR_SHR, $3); }
+    | immexp '+' immexp        { $$ = expr_new_tree ($1, EXPR_ADD, $3); }
+    | immexp '-' immexp        { $$ = expr_new_tree ($1, EXPR_SUB, $3); }
+    | immexp '*' immexp        { $$ = expr_new_tree ($1, EXPR_MUL, $3); }
+    | immexp '/' immexp        { $$ = expr_new_tree ($1, EXPR_DIV, $3); }
+    | immexp '%' immexp        { $$ = expr_new_tree ($1, EXPR_MOD, $3); }
+    | '-' immexp       { $$ = expr_new_branch (EXPR_NEG, $2); }
+    /*| '!' immexp     { $$ = expr_new_branch (EXPR_LNOT, $2); }*/
+    | '~' immexp       { $$ = expr_new_branch (EXPR_NOT, $2); }
+    | '(' immexp ')'   { $$ = $2; }
+;
+
+immlabel: ID | SPECIAL_ID | LOCAL_ID ;
+
+imm: immexp            { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
 ;
 
 /* explicit immediates */
index 7a32a80e0256b3c355ab7f876acde671437ffa4d..6c1a66bb314ba185bb6eb6818119c70c9d47701c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: nasm-bison.y,v 1.15 2001/07/05 07:21:35 peter Exp $
+/* $Id: nasm-bison.y,v 1.16 2001/07/05 08:37:59 mu Exp $
  * Main bison parser
  *
  *  Copyright (C) 2001  Peter Johnson, Michael Urman
@@ -26,6 +26,7 @@
 #include "globals.h"
 #include "bytecode.h"
 #include "errwarn.h"
+#include "expr.h"
 
 #define YYDEBUG 1
 
@@ -46,6 +47,7 @@ extern void yyerror(char *);
     } syminfo;
     unsigned char groupdata[3];
     effaddr ea_val;
+    expr *exp;
     immval im_val;
     bytecode bc;
 } 
@@ -83,7 +85,9 @@ extern void yyerror(char *);
 %type <ea_val> mem8 mem16 mem32 mem64 mem80 mem128 mem1632
 %type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
 %type <ea_val> rm8 rm16 rm32 rm64 rm128
-%type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <exp> immexp
+%type <syminfo> immlabel
 %type <sym> label_id
 
 %left '-' '+'
@@ -271,10 +275,36 @@ rm128: XMMREG     { (void)ConvertRegToEA(&$$, $1); }
 
 /* immediate values */
 /* TODO: formula expansion */
-immexp: INTNUM { (void)ConvertIntToImm(&$$, $1); }
-;
-
-imm: immexp
+immexp: /*INTNUM       { (void)ConvertIntToImm(&$$, $1); } */
+       INTNUM          { $$ = expr_new_ident (EXPR_NUM, $1); }
+    | immlabel         { $$ = expr_new_ident (EXPR_SYM, sym_use_get ($1.name, SYM_LABEL)); }
+    /*| immexp '||' immexp     { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/
+    | immexp '|' immexp        { $$ = expr_new_tree ($1, EXPR_OR, $3); }
+    | immexp '^' immexp        { $$ = expr_new_tree ($1, EXPR_XOR, $3); }
+    /*| immexp '&&' immexp     { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/
+    | immexp '&' immexp        { $$ = expr_new_tree ($1, EXPR_AND, $3); }
+    /*| immexp '==' immexp     { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/
+    /*| immexp '>' immexp      { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+    /*| immexp '<' immexp      { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/
+    /*| immexp '>=' immexp     { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+    /*| immexp '<=' immexp     { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/
+    /*| immexp '!=' immexp     { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/
+    | immexp LEFT_OP immexp    { $$ = expr_new_tree ($1, EXPR_SHL, $3); }
+    | immexp RIGHT_OP immexp   { $$ = expr_new_tree ($1, EXPR_SHR, $3); }
+    | immexp '+' immexp        { $$ = expr_new_tree ($1, EXPR_ADD, $3); }
+    | immexp '-' immexp        { $$ = expr_new_tree ($1, EXPR_SUB, $3); }
+    | immexp '*' immexp        { $$ = expr_new_tree ($1, EXPR_MUL, $3); }
+    | immexp '/' immexp        { $$ = expr_new_tree ($1, EXPR_DIV, $3); }
+    | immexp '%' immexp        { $$ = expr_new_tree ($1, EXPR_MOD, $3); }
+    | '-' immexp       { $$ = expr_new_branch (EXPR_NEG, $2); }
+    /*| '!' immexp     { $$ = expr_new_branch (EXPR_LNOT, $2); }*/
+    | '~' immexp       { $$ = expr_new_branch (EXPR_NOT, $2); }
+    | '(' immexp ')'   { $$ = $2; }
+;
+
+immlabel: ID | SPECIAL_ID | LOCAL_ID ;
+
+imm: immexp            { expr_simplify ($1); ConvertExprToImm (&$$, $1); }
 ;
 
 /* explicit immediates */
index 4aa92c492ac7ada085932b62eb9eefb21a65227c..2a19cdc8aedb4832ed17197a931e06e02e3f6c24 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: token.l.in,v 1.8 2001/06/29 05:11:40 peter Exp $
+/* $Id: token.l.in,v 1.9 2001/07/05 08:37:59 mu Exp $
  * Main lexer
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -34,6 +34,7 @@
 #include "symrec.h"
 #include "bytecode.h"
 #include "errwarn.h"
+#include "expr.h"
 #include "bison.h"
 
 %}
index 4aa92c492ac7ada085932b62eb9eefb21a65227c..2a19cdc8aedb4832ed17197a931e06e02e3f6c24 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: token.l.in,v 1.8 2001/06/29 05:11:40 peter Exp $
+/* $Id: token.l.in,v 1.9 2001/07/05 08:37:59 mu Exp $
  * Main lexer
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -34,6 +34,7 @@
 #include "symrec.h"
 #include "bytecode.h"
 #include "errwarn.h"
+#include "expr.h"
 #include "bison.h"
 
 %}