]> granicus.if.org Git - yasm/commitdiff
Fix large parts of expression and symbol handling. Actually link in labels
authorPeter Johnson <peter@tortall.net>
Wed, 26 Sep 2001 00:57:55 +0000 (00:57 -0000)
committerPeter Johnson <peter@tortall.net>
Wed, 26 Sep 2001 00:57:55 +0000 (00:57 -0000)
properly (bug #8).  Framework added for portable floating point support (bug
#7).  Lots of functions still not finished in this commit.

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

27 files changed:
libyasm/bytecode.c
libyasm/bytecode.h
libyasm/expr.c
libyasm/expr.h
libyasm/floatnum.c [new file with mode: 0644]
libyasm/floatnum.h [new file with mode: 0644]
libyasm/symrec.c
libyasm/symrec.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/Makefile.am
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 [new file with mode: 0644]
src/floatnum.h [new file with mode: 0644]
src/parsers/nasm/bison.y.in
src/parsers/nasm/nasm-bison.y
src/parsers/nasm/token.l.in
src/symrec.c
src/symrec.h

index a8b17ed2ae810a056c9a42bc3d7a3da52a7128a8..01695afea39b38753222d7bf0df1528d64b96ee7 100644 (file)
 
 #include "globals.h"
 #include "errwarn.h"
+#include "floatnum.h"
 #include "expr.h"
 
 #include "bytecode.h"
+#include "section.h"
 
 RCSID("$IdPath$");
 
@@ -119,7 +121,7 @@ ConvertIntToImm(immval *ptr, unsigned long int_val)
        ptr = &im_static;
 
     /* FIXME: this will leak expr's if static is used */
-    ptr->val = expr_new_ident(EXPR_NUM, ExprNum(int_val));
+    ptr->val = expr_new_ident(EXPR_INT, ExprInt(int_val));
 
     if ((int_val & 0xFF) == int_val)
        ptr->len = 1;
@@ -432,6 +434,12 @@ bytecode_new_reserve(expr *numitems, unsigned long itemsize)
     return bc;
 }
 
+int
+bytecode_get_offset(section *sect, bytecode *bc, unsigned long *ret_val)
+{
+    return 0;  /* TODO */
+}
+
 void
 bytecode_print(bytecode *bc)
 {
@@ -553,15 +561,18 @@ bytecode_print(bytecode *bc)
     printf("Offset=%lx BITS=%u\n", bc->offset, bc->mode_bits);
 }
 
-void
+bytecode *
 bytecodes_append(bytecodehead *headp, bytecode *bc)
 {
     if (bc) {
-       if (bc->type != BC_EMPTY)
+       if (bc->type != BC_EMPTY) {
            STAILQ_INSERT_TAIL(headp, bc, link);
-       else
+           return bc;
+       } else {
            free(bc);
+       }
     }
+    return (bytecode *)NULL;
 }
 
 dataval *
@@ -579,7 +590,7 @@ dataval_new_expr(expr *exp)
 }
 
 dataval *
-dataval_new_float(double float_val)
+dataval_new_float(floatnum *flt)
 {
     dataval *retval = malloc(sizeof(dataval));
 
@@ -587,7 +598,7 @@ dataval_new_float(double float_val)
        Fatal(FATAL_NOMEM);
 
     retval->type = DV_FLOAT;
-    retval->data.float_val = float_val;
+    retval->data.flt = flt;
 
     return retval;
 }
@@ -622,7 +633,9 @@ dataval_print(datavalhead *head)
                printf("\n");
                break;
            case DV_FLOAT:
-               printf(" Float=%e\n", cur->data.float_val);
+               printf(" Float=");
+               floatnum_print(cur->data.flt);
+               printf("\n");
                break;
            case DV_STRING:
                printf(" String=%s\n", cur->data.str_val);
index 5ff60a8c88c1b4e78e88d2fd525c36acbf443181..01a0ac19657a5a9ba5053386fd8b5b97906d5258 100644 (file)
@@ -22,6 +22,8 @@
 #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 */
@@ -56,7 +58,7 @@ typedef struct dataval_s {
 
     union {
        struct expr_s *exp;
-       double float_val;
+       struct floatnum_s *flt;
        char *str_val;
     } data;
 } dataval;
@@ -210,6 +212,12 @@ bytecode *bytecode_new_data(datavalhead *datahead, unsigned long size);
 bytecode *bytecode_new_reserve(struct expr_s *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);
+
 void bytecode_print(bytecode *bc);
 
 /* void bytecodes_initialize(bytecodehead *headp); */
@@ -218,12 +226,13 @@ void bytecode_print(bytecode *bc);
 /* Adds bc to the list of bytecodes headp.
  * NOTE: Does not make a copy of bc; so don't pass this function
  * static or local variables, and discard the bc pointer after calling
- * this function.
+ * this function.  If bc was actually appended (it wasn't NULL or empty),
+ * then returns bc, otherwise returns NULL.
  */
-void bytecodes_append(bytecodehead *headp, bytecode *bc);
+bytecode *bytecodes_append(bytecodehead *headp, bytecode *bc);
 
 dataval *dataval_new_expr(struct expr_s *exp);
-dataval *dataval_new_float(double float_val);
+dataval *dataval_new_float(struct floatnum_s *flt);
 dataval *dataval_new_string(char *str_val);
 
 void dataval_print(datavalhead *head);
index 20da35721c9ba76b24ca9ae95b570cb7288e8e51..030b2c58190e3934504806e16e467f4bfec8b703 100644 (file)
@@ -1,7 +1,7 @@
 /* $IdPath$
  * Expression handling
  *
- *  Copyright (C) 2001  Michael Urman
+ *  Copyright (C) 2001  Michael Urman, Peter Johnson
  *
  *  This file is part of YASM.
  *
@@ -34,6 +34,7 @@
 
 #include "globals.h"
 #include "errwarn.h"
+#include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
 
@@ -56,18 +57,20 @@ expr_new(ExprType ltype,
     ptr->op = op;
     ptr->rtype = rtype;
     switch (ltype) {
-       case EXPR_NUM:
        case EXPR_SYM:
        case EXPR_EXPR:
+       case EXPR_INT:
+       case EXPR_FLOAT:
            memcpy(&ptr->left, &left, sizeof(ExprItem));
            break;
        case EXPR_NONE:
            break;
     }
     switch (rtype) {
-       case EXPR_NUM:
        case EXPR_SYM:
        case EXPR_EXPR:
+       case EXPR_INT:
+       case EXPR_FLOAT:
            memcpy(&ptr->right, &right, sizeof(ExprItem));
            break;
        case EXPR_NONE:
@@ -91,17 +94,26 @@ ExprItem
 ExprExpr(expr *x)
 {
     ExprItem e;
-    e.expr = x;
+    e.exp = x;
 
     return e;
 }
 
 ExprItem
-ExprNum(unsigned long n)
+ExprInt(unsigned long i)
 {
     ExprItem e;
 
-    e.num = n;
+    e.int_val = i;
+    return e;
+}
+
+ExprItem
+ExprFloat(floatnum *f)
+{
+    ExprItem e;
+
+    e.flt = f;
     return e;
 }
 
@@ -110,7 +122,7 @@ ExprNone(void)
 {
     ExprItem e;
 
-    e.num = 0;
+    e.int_val = 0;
     return e;
 }
 
@@ -119,121 +131,121 @@ int
 expr_simplify(expr *e)
 {
     int simplified = 0;
+    unsigned long int_val;
 
     /* try to simplify the left side */
     if (e->ltype == EXPR_EXPR) {
        /* if the left subexpr isn't an IDENT, recurse simplification */
-       if (e->left.expr->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->left.expr);
+       if (e->left.exp->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->left.exp);
 
        /* 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.expr->op == EXPR_IDENT) {
+       while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->ltype = e->left.expr->rtype;
-           memcpy(&tmp, &(e->left.expr->right), sizeof(ExprItem));
-           free(e->left.expr);
-           memcpy(&(e->left.num), &tmp, sizeof(ExprItem));
+           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));
            simplified = 1;
        }
     } else if (e->ltype == EXPR_SYM) {
-       /* if it's a symbol that has a defined value, turn it into a
-        * number */
-       if (e->left.sym->status & SYM_VALUED) {
-           e->ltype = EXPR_NUM;
+       /* try to get value of symbol */
+       if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
+           e->ltype = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->left.num = e->left.sym->value;
+           e->left.int_val = int_val;
            simplified = 1;
        }
     }
 
     /* ditto on the right */
     if (e->rtype == EXPR_EXPR) {
-       if (e->right.expr->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->right.expr);
+       if (e->right.exp->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->right.exp);
 
-       while (e->rtype == EXPR_EXPR && e->right.expr->op == EXPR_IDENT) {
+       while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->rtype = e->right.expr->rtype;
-           memcpy(&tmp, &(e->right.expr->right), sizeof(ExprItem));
-           free(e->right.expr);
-           memcpy(&(e->right.num), &tmp, sizeof(ExprItem));
+           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));
            simplified = 1;
        }
     } else if (e->rtype == EXPR_SYM) {
-       if (e->right.sym->status & SYM_VALUED) {
-           e->rtype = EXPR_NUM;
+       if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
+           e->rtype = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->right.num = e->right.sym->value;
+           e->right.int_val = int_val;
            simplified = 1;
        }
     }
 
-    if ((e->ltype == EXPR_NUM || e->ltype == EXPR_NONE)
-       && e->rtype == EXPR_NUM && e->op != EXPR_IDENT) {
+    if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
+       && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
        switch (e->op) {
            case EXPR_ADD:
-               e->right.num = e->left.num + e->right.num;
+               e->right.int_val = e->left.int_val + e->right.int_val;
                break;
            case EXPR_SUB:
-               e->right.num = e->left.num - e->right.num;
+               e->right.int_val = e->left.int_val - e->right.int_val;
                break;
            case EXPR_MUL:
-               e->right.num = e->left.num * e->right.num;
+               e->right.int_val = e->left.int_val * e->right.int_val;
                break;
            case EXPR_DIV:
-               e->right.num = e->left.num / e->right.num;
+               e->right.int_val = e->left.int_val / e->right.int_val;
                break;
            case EXPR_MOD:
-               e->right.num = e->left.num % e->right.num;
+               e->right.int_val = e->left.int_val % e->right.int_val;
                break;
            case EXPR_NEG:
-               e->right.num = -(e->right.num);
+               e->right.int_val = -(e->right.int_val);
                break;
            case EXPR_NOT:
-               e->right.num = ~(e->right.num);
+               e->right.int_val = ~(e->right.int_val);
                break;
            case EXPR_OR:
-               e->right.num = e->left.num | e->right.num;
+               e->right.int_val = e->left.int_val | e->right.int_val;
                break;
            case EXPR_AND:
-               e->right.num = e->left.num & e->right.num;
+               e->right.int_val = e->left.int_val & e->right.int_val;
                break;
            case EXPR_XOR:
-               e->right.num = e->left.num ^ e->right.num;
+               e->right.int_val = e->left.int_val ^ e->right.int_val;
                break;
            case EXPR_SHL:
-               e->right.num = e->right.num << e->left.num;
+               e->right.int_val = e->right.int_val << e->left.int_val;
                break;
            case EXPR_SHR:
-               e->right.num = e->right.num << e->left.num;
+               e->right.int_val = e->right.int_val << e->left.int_val;
                break;
            case EXPR_LOR:
-               e->right.num = e->left.num || e->right.num;
+               e->right.int_val = e->left.int_val || e->right.int_val;
                break;
            case EXPR_LAND:
-               e->right.num = e->left.num && e->right.num;
+               e->right.int_val = e->left.int_val && e->right.int_val;
                break;
            case EXPR_LNOT:
-               e->right.num = !e->right.num;
+               e->right.int_val = !e->right.int_val;
                break;
            case EXPR_EQ:
-               e->right.num = e->right.num == e->left.num;
+               e->right.int_val = e->right.int_val == e->left.int_val;
                break;
            case EXPR_LT:
-               e->right.num = e->right.num < e->left.num;
+               e->right.int_val = e->right.int_val < e->left.int_val;
                break;
            case EXPR_GT:
-               e->right.num = e->right.num > e->left.num;
+               e->right.int_val = e->right.int_val > e->left.int_val;
                break;
            case EXPR_LE:
-               e->right.num = e->right.num <= e->left.num;
+               e->right.int_val = e->right.int_val <= e->left.int_val;
                break;
            case EXPR_GE:
-               e->right.num = e->right.num >= e->left.num;
+               e->right.int_val = e->right.int_val >= e->left.int_val;
                break;
            case EXPR_NE:
-               e->right.num = e->right.num != e->left.num;
+               e->right.int_val = e->right.int_val != e->left.int_val;
                break;
            case EXPR_IDENT:
                break;
@@ -243,31 +255,31 @@ expr_simplify(expr *e)
     }
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->ltype == EXPR_NUM && ((e->left.num == 1 && e->op == EXPR_MUL)
-                                     || (e->left.num == 0 &&
+    else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->left.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->left.num == -1 &&
+                                     || (e->left.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->left.num == 0 &&
+                                     || (e->left.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_NUM && ((e->right.num == 1 && e->op == EXPR_MUL)
-                                     || (e->right.num == 1 &&
+    else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->right.int_val == 1 &&
                                          e->op == EXPR_DIV)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SUB)
-                                     || (e->right.num == -1 &&
+                                     || (e->right.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_OR)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SHL)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SHR))) {
        e->op = EXPR_IDENT;
        e->rtype = e->ltype;
@@ -281,11 +293,11 @@ expr_simplify(expr *e)
 int
 expr_get_value(expr *e, unsigned long *retval)
 {
-    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
           && expr_simplify(e)) ;
 
-    if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM) {
-       *retval = e->right.num;
+    if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
+       *retval = e->right.int_val;
        return 1;
     } else
        return 0;
@@ -296,17 +308,20 @@ expr_print(expr *e)
 {
     if (e->op != EXPR_IDENT) {
        switch (e->ltype) {
-           case EXPR_NUM:
-               printf("%lu", e->left.num);
-               break;
            case EXPR_SYM:
                printf("%s", e->left.sym->name);
                break;
            case EXPR_EXPR:
                printf("(");
-               expr_print(e->left.expr);
-
+               expr_print(e->left.exp);
                printf(")");
+               break;
+           case EXPR_INT:
+               printf("%lu", e->left.int_val);
+               break;
+           case EXPR_FLOAT:
+               floatnum_print(e->left.flt);
+               break;
            case EXPR_NONE:
                break;
        }
@@ -379,17 +394,20 @@ expr_print(expr *e)
            break;
     }
     switch (e->rtype) {
-       case EXPR_NUM:
-           printf("%lu", e->right.num);
-           break;
        case EXPR_SYM:
            printf("%s", e->right.sym->name);
            break;
        case EXPR_EXPR:
            printf("(");
-           expr_print(e->right.expr);
-
+           expr_print(e->right.exp);
            printf(")");
+           break;
+       case EXPR_INT:
+           printf("%lu", e->right.int_val);
+           break;
+       case EXPR_FLOAT:
+           floatnum_print(e->right.flt);
+           break;
        case EXPR_NONE:
            break;
     }
index 8723d8980924b99d12745ee02ddbae842fc12f75..6846fdb23067d0ddce2870898399c0c0f81f8498 100644 (file)
@@ -1,7 +1,7 @@
 /* $IdPath$
  * Expression handling header file
  *
- *  Copyright (C) 2001  Michael Urman
+ *  Copyright (C) 2001  Michael Urman, Peter Johnson
  *
  *  This file is part of YASM.
  *
@@ -49,15 +49,17 @@ typedef enum {
 
 typedef enum {
     EXPR_NONE,                 /* for left side of a NOT, NEG, etc. */
-    EXPR_NUM,
+    EXPR_SYM,
     EXPR_EXPR,
-    EXPR_SYM
+    EXPR_INT,
+    EXPR_FLOAT
 } ExprType;
 
 typedef union expritem_u {
     struct symrec_s *sym;
-    struct expr_s *expr;
-    unsigned long num;
+    struct expr_s *exp;
+    unsigned long int_val;
+    struct floatnum_s *flt;
 } ExprItem;
 
 typedef struct expr_s {
@@ -70,7 +72,8 @@ expr *expr_new(ExprType, ExprItem, ExprOp, ExprType, ExprItem);
 
 ExprItem ExprSym(struct symrec_s *);
 ExprItem ExprExpr(expr *);
-ExprItem ExprNum(unsigned long);
+ExprItem ExprInt(unsigned long);
+ExprItem ExprFloat(struct floatnum_s *);
 ExprItem ExprNone(void);
 
 #define expr_new_tree(l,o,r) \
diff --git a/libyasm/floatnum.c b/libyasm/floatnum.c
new file mode 100644 (file)
index 0000000..bef9080
--- /dev/null
@@ -0,0 +1,77 @@
+/* $IdPath$
+ * Floating point number functions.
+ *
+ *  Copyright (C) 2001  Peter Johnson
+ *
+ *  This file is part of YASM.
+ *
+ *  YASM is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  YASM is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "util.h"
+
+#include <stdio.h>
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+#endif
+
+#include "errwarn.h"
+#include "floatnum.h"
+
+RCSID("$IdPath$");
+
+floatnum *
+floatnum_new(char *str)
+{
+    floatnum *flt = malloc(sizeof(floatnum));
+    if (!flt)
+       Fatal(FATAL_NOMEM);
+    /* TODO */
+    return flt;
+}
+
+unsigned long
+floatnum_get_int(floatnum *flt)
+{
+    return 0;  /* TODO */
+}
+
+unsigned char *
+floatnum_get_single(unsigned char *ptr, floatnum *flt)
+{
+    return ptr;        /* TODO */
+}
+
+unsigned char *
+floatnum_get_double(unsigned char *ptr, floatnum *flt)
+{
+    return ptr;        /* TODO */
+}
+
+unsigned char *
+floatnum_get_extended(unsigned char *ptr, floatnum *flt)
+{
+    return ptr;        /* TODO */
+}
+
+void
+floatnum_print(floatnum *flt)
+{
+    /* TODO */
+}
diff --git a/libyasm/floatnum.h b/libyasm/floatnum.h
new file mode 100644 (file)
index 0000000..bbea975
--- /dev/null
@@ -0,0 +1,37 @@
+/* $IdPath$
+ * Floating point number functions header file.
+ *
+ *  Copyright (C) 2001  Peter Johnson
+ *
+ *  This file is part of YASM.
+ *
+ *  YASM is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  YASM is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef YASM_FLOATNUM_H
+#define YASM_FLOATNUM_H
+
+typedef struct floatnum_s {
+    unsigned char extval[10];      /* float stored in extended precision */
+} floatnum;
+
+floatnum *floatnum_new(char *str);
+unsigned long floatnum_get_int(floatnum *flt);
+unsigned char *floatnum_get_single(unsigned char *ptr, floatnum *flt);
+unsigned char *floatnum_get_double(unsigned char *ptr, floatnum *flt);
+unsigned char *floatnum_get_extended(unsigned char *ptr, floatnum *flt);
+
+void floatnum_print(floatnum *flt);
+
+#endif
index 2196638e4c5eb9e931a1508fdc56891688b8dfd4..2c7947cd498281be1116e503ea21a0d6f9503426 100644 (file)
@@ -1,7 +1,7 @@
 /* $IdPath$
  * Symbol table handling
  *
- *  Copyright (C) 2001  Michael Urman
+ *  Copyright (C) 2001  Michael Urman, Peter Johnson
  *
  *  This file is part of YASM.
  *
 
 #include "globals.h"
 #include "errwarn.h"
+#include "floatnum.h"
 #include "symrec.h"
 
+#include "bytecode.h"
+#include "section.h"
+
 RCSID("$IdPath$");
 
 /* private functions */
-static symrec *symrec_get_or_new(char *, SymType);
+static symrec *symrec_get_or_new(const char *);
+static symrec *symrec_define(const char *, SymType type);
 
 /* The symbol table: a ternary tree. */
 static ternary_tree sym_table = (ternary_tree)NULL;
 
 /* create a new symrec */
 static symrec *
-symrec_get_or_new(char *name, SymType type)
+symrec_get_or_new(const char *name)
 {
     symrec *rec, *rec2;
 
@@ -65,41 +70,128 @@ symrec_get_or_new(char *name, SymType type)
     rec->name = strdup(name);
     if (!rec->name)
        Fatal(FATAL_NOMEM);
-    rec->type = type;
-    rec->value = 0;
+    rec->type = SYM_UNKNOWN;
     rec->filename = strdup(filename);
     rec->line = line_number;
     rec->status = SYM_NOSTATUS;
+    rec->visibility = SYM_LOCAL;
 
     return rec;
 }
 
 /* call a function with each symrec.  stop early if 0 returned */
 void
-symrec_foreach(int (*func) (char *name, symrec *rec))
+symrec_foreach(int (*func) (const char *name, symrec *rec))
 {
+    /* TODO */
 }
 
 symrec *
-symrec_use(char *name, SymType type)
+symrec_use(const char *name)
 {
-    symrec *rec;
+    symrec *rec = symrec_get_or_new(name);
 
-    rec = symrec_get_or_new(name, type);
     rec->status |= SYM_USED;
     return rec;
 }
 
+static symrec *
+symrec_define(const char *name, SymType type)
+{
+    symrec *rec = symrec_get_or_new(name);
+
+    /* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */
+    if (rec->status & SYM_DEFINED) {
+       Error(_("duplicate definition of `%s'; first defined on line %d"),
+             name, rec->line);
+    } else {
+       rec->line = line_number;        /* set line number of definition */
+       rec->type = type;
+       rec->status |= SYM_DEFINED;
+    }
+    return rec;
+}
+
+symrec *
+symrec_define_constant_int(const char *name, unsigned long int_val)
+{
+    symrec *rec = symrec_define(name, SYM_CONSTANT_INT);
+    rec->value.int_val = int_val;
+    rec->status |= SYM_VALUED;
+    return rec;
+}
+
 symrec *
-symrec_define(char *name, SymType type)
+symrec_define_constant_float(const char *name, floatnum *flt)
 {
-    symrec *rec;
+    symrec *rec = symrec_define(name, SYM_CONSTANT_FLOAT);
+    rec->value.flt = flt;
+    rec->status |= SYM_VALUED;
+    return rec;
+}
 
-    rec = symrec_get_or_new(name, type);
-    if (rec->status & SYM_DECLARED)
-       Error(_("duplicate definition of `%s'; previously defined on line %d"),
+symrec *
+symrec_define_label(const char *name, section *sect, bytecode *precbc)
+{
+    symrec *rec = symrec_define(name, SYM_LABEL);
+    rec->value.label.sect = sect;
+    rec->value.label.bc = precbc;
+    return rec;
+}
+
+symrec *
+symrec_declare(const char *name, SymVisibility vis)
+{
+    symrec *rec = symrec_get_or_new(name);
+
+    /* Don't allow EXTERN and COMMON if symbol has already been DEFINED. */
+    /* Also, EXTERN and COMMON are mutually exclusive. */
+    if ((rec->status & SYM_DEFINED) ||
+       ((rec->visibility & SYM_COMMON) && (vis == SYM_EXTERN)) ||
+       ((rec->visibility & SYM_EXTERN) && (vis == SYM_COMMON))) {
+       Error(_("duplicate definition of `%s'; first defined on line %d"),
              name, rec->line);
-    rec->line = line_number;   /* set line number of definition */
-    rec->status |= SYM_DECLARED;
+    } else {
+       rec->line = line_number;        /* set line number of declaration */
+       rec->visibility |= vis;
+
+       /* If declared as COMMON or EXTERN, set as DEFINED. */
+       if ((vis == SYM_COMMON) || (vis == SYM_EXTERN))
+           rec->status |= SYM_DEFINED;
+    }
     return rec;
 }
+
+int
+symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
+                    int resolve_label)
+{
+    /* If we already know the value, just return it. */
+    if (sym->status & SYM_VALUED) {
+       switch (sym->type) {
+           case SYM_CONSTANT_INT:
+               *ret_val = sym->value.int_val;
+               break;
+           case SYM_CONSTANT_FLOAT:
+               *ret_val = floatnum_get_int(sym->value.flt);
+               break;
+           case SYM_LABEL:
+               if (!bytecode_get_offset(sym->value.label.sect,
+                                        sym->value.label.bc, ret_val))
+                   InternalError(__LINE__, __FILE__,
+                                 _("Label symbol is valued but cannot get offset"));
+           case SYM_UNKNOWN:
+               InternalError(__LINE__, __FILE__,
+                             _("Have a valued symbol but of unknown type"));
+       }
+       return 1;
+    }
+
+    /* Try to get offset of unvalued label */
+    if (resolve_label && sym->type == SYM_LABEL)
+       return bytecode_get_offset(sym->value.label.sect, sym->value.label.bc,
+                                  ret_val);
+
+    /* We can't get the value right now. */
+    return 0;
+}
index fd2e5c387ac70b178fd74e996bc3c849a258d71e..21183f4bdf8c6de433ea13a97025b26a8bc19458 100644 (file)
@@ -1,7 +1,7 @@
 /* $IdPath$
  * Symbol table handling header file
  *
- *  Copyright (C) 2001  Michael Urman
+ *  Copyright (C) 2001  Michael Urman, Peter Johnson
  *
  *  This file is part of YASM.
  *
 #ifndef YASM_SYMREC_H
 #define YASM_SYMREC_H
 
+/* DEFINED is set with EXTERN and COMMON below */
 typedef enum {
     SYM_NOSTATUS = 0,
-    SYM_USED = 1 << 0,         /* for using variables before declared */
-    SYM_DECLARED = 1 << 1,     /* once it's been declared */
+    SYM_USED = 1 << 0,         /* for using variables before definition */
+    SYM_DEFINED = 1 << 1,      /* once it's been defined in the file */
     SYM_VALUED = 1 << 2                /* once its value has been determined */
 } SymStatus;
 
+/* EXTERN and COMMON are mutually exclusive */
 typedef enum {
-    SYM_CONSTANT,              /* for EQU defined symbols */
+    SYM_LOCAL = 0,             /* default, local only */
+    SYM_GLOBAL = 1 << 0,       /* if it's declared GLOBAL */
+    SYM_COMMON = 1 << 1,       /* if it's declared COMMON */
+    SYM_EXTERN = 1 << 2                /* if it's declared EXTERN */
+} SymVisibility;
+
+typedef enum {
+    SYM_UNKNOWN,               /* for unknown type (COMMON/EXTERN) */
+    SYM_CONSTANT_INT,          /* for EQU defined symbols (integers) */
+    SYM_CONSTANT_FLOAT,                /*  (floating point) */
     SYM_LABEL                  /* for labels */
 } SymType;
 
@@ -38,13 +49,34 @@ typedef struct symrec_s {
     char *name;
     SymType type;
     SymStatus status;
+    SymVisibility visibility;
     char *filename;            /* file and line */
-    int line;                  /*  symbol was first declared or used on */
-    double value;
+    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;
 
-symrec *symrec_use(char *name, SymType type);
-symrec *symrec_define(char *name, SymType type);
-void symrec_foreach(int (*func) (char *name, symrec *rec));
+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_declare(const char *name, SymVisibility vis);
+
+/* Get the numeric 32-bit value of a symbol if possible.
+ * Return value is IF POSSIBLE, not the value.
+ * If resolve_label is true, tries to get offset of labels, otherwise it
+ * returns not possible.
+ */
+int symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
+                        int resolve_label);
+
+void symrec_foreach(int (*func) (const char *name, symrec *rec));
 
 #endif
index 20da35721c9ba76b24ca9ae95b570cb7288e8e51..030b2c58190e3934504806e16e467f4bfec8b703 100644 (file)
@@ -1,7 +1,7 @@
 /* $IdPath$
  * Expression handling
  *
- *  Copyright (C) 2001  Michael Urman
+ *  Copyright (C) 2001  Michael Urman, Peter Johnson
  *
  *  This file is part of YASM.
  *
@@ -34,6 +34,7 @@
 
 #include "globals.h"
 #include "errwarn.h"
+#include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
 
@@ -56,18 +57,20 @@ expr_new(ExprType ltype,
     ptr->op = op;
     ptr->rtype = rtype;
     switch (ltype) {
-       case EXPR_NUM:
        case EXPR_SYM:
        case EXPR_EXPR:
+       case EXPR_INT:
+       case EXPR_FLOAT:
            memcpy(&ptr->left, &left, sizeof(ExprItem));
            break;
        case EXPR_NONE:
            break;
     }
     switch (rtype) {
-       case EXPR_NUM:
        case EXPR_SYM:
        case EXPR_EXPR:
+       case EXPR_INT:
+       case EXPR_FLOAT:
            memcpy(&ptr->right, &right, sizeof(ExprItem));
            break;
        case EXPR_NONE:
@@ -91,17 +94,26 @@ ExprItem
 ExprExpr(expr *x)
 {
     ExprItem e;
-    e.expr = x;
+    e.exp = x;
 
     return e;
 }
 
 ExprItem
-ExprNum(unsigned long n)
+ExprInt(unsigned long i)
 {
     ExprItem e;
 
-    e.num = n;
+    e.int_val = i;
+    return e;
+}
+
+ExprItem
+ExprFloat(floatnum *f)
+{
+    ExprItem e;
+
+    e.flt = f;
     return e;
 }
 
@@ -110,7 +122,7 @@ ExprNone(void)
 {
     ExprItem e;
 
-    e.num = 0;
+    e.int_val = 0;
     return e;
 }
 
@@ -119,121 +131,121 @@ int
 expr_simplify(expr *e)
 {
     int simplified = 0;
+    unsigned long int_val;
 
     /* try to simplify the left side */
     if (e->ltype == EXPR_EXPR) {
        /* if the left subexpr isn't an IDENT, recurse simplification */
-       if (e->left.expr->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->left.expr);
+       if (e->left.exp->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->left.exp);
 
        /* 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.expr->op == EXPR_IDENT) {
+       while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->ltype = e->left.expr->rtype;
-           memcpy(&tmp, &(e->left.expr->right), sizeof(ExprItem));
-           free(e->left.expr);
-           memcpy(&(e->left.num), &tmp, sizeof(ExprItem));
+           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));
            simplified = 1;
        }
     } else if (e->ltype == EXPR_SYM) {
-       /* if it's a symbol that has a defined value, turn it into a
-        * number */
-       if (e->left.sym->status & SYM_VALUED) {
-           e->ltype = EXPR_NUM;
+       /* try to get value of symbol */
+       if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
+           e->ltype = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->left.num = e->left.sym->value;
+           e->left.int_val = int_val;
            simplified = 1;
        }
     }
 
     /* ditto on the right */
     if (e->rtype == EXPR_EXPR) {
-       if (e->right.expr->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->right.expr);
+       if (e->right.exp->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->right.exp);
 
-       while (e->rtype == EXPR_EXPR && e->right.expr->op == EXPR_IDENT) {
+       while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->rtype = e->right.expr->rtype;
-           memcpy(&tmp, &(e->right.expr->right), sizeof(ExprItem));
-           free(e->right.expr);
-           memcpy(&(e->right.num), &tmp, sizeof(ExprItem));
+           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));
            simplified = 1;
        }
     } else if (e->rtype == EXPR_SYM) {
-       if (e->right.sym->status & SYM_VALUED) {
-           e->rtype = EXPR_NUM;
+       if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
+           e->rtype = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->right.num = e->right.sym->value;
+           e->right.int_val = int_val;
            simplified = 1;
        }
     }
 
-    if ((e->ltype == EXPR_NUM || e->ltype == EXPR_NONE)
-       && e->rtype == EXPR_NUM && e->op != EXPR_IDENT) {
+    if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
+       && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
        switch (e->op) {
            case EXPR_ADD:
-               e->right.num = e->left.num + e->right.num;
+               e->right.int_val = e->left.int_val + e->right.int_val;
                break;
            case EXPR_SUB:
-               e->right.num = e->left.num - e->right.num;
+               e->right.int_val = e->left.int_val - e->right.int_val;
                break;
            case EXPR_MUL:
-               e->right.num = e->left.num * e->right.num;
+               e->right.int_val = e->left.int_val * e->right.int_val;
                break;
            case EXPR_DIV:
-               e->right.num = e->left.num / e->right.num;
+               e->right.int_val = e->left.int_val / e->right.int_val;
                break;
            case EXPR_MOD:
-               e->right.num = e->left.num % e->right.num;
+               e->right.int_val = e->left.int_val % e->right.int_val;
                break;
            case EXPR_NEG:
-               e->right.num = -(e->right.num);
+               e->right.int_val = -(e->right.int_val);
                break;
            case EXPR_NOT:
-               e->right.num = ~(e->right.num);
+               e->right.int_val = ~(e->right.int_val);
                break;
            case EXPR_OR:
-               e->right.num = e->left.num | e->right.num;
+               e->right.int_val = e->left.int_val | e->right.int_val;
                break;
            case EXPR_AND:
-               e->right.num = e->left.num & e->right.num;
+               e->right.int_val = e->left.int_val & e->right.int_val;
                break;
            case EXPR_XOR:
-               e->right.num = e->left.num ^ e->right.num;
+               e->right.int_val = e->left.int_val ^ e->right.int_val;
                break;
            case EXPR_SHL:
-               e->right.num = e->right.num << e->left.num;
+               e->right.int_val = e->right.int_val << e->left.int_val;
                break;
            case EXPR_SHR:
-               e->right.num = e->right.num << e->left.num;
+               e->right.int_val = e->right.int_val << e->left.int_val;
                break;
            case EXPR_LOR:
-               e->right.num = e->left.num || e->right.num;
+               e->right.int_val = e->left.int_val || e->right.int_val;
                break;
            case EXPR_LAND:
-               e->right.num = e->left.num && e->right.num;
+               e->right.int_val = e->left.int_val && e->right.int_val;
                break;
            case EXPR_LNOT:
-               e->right.num = !e->right.num;
+               e->right.int_val = !e->right.int_val;
                break;
            case EXPR_EQ:
-               e->right.num = e->right.num == e->left.num;
+               e->right.int_val = e->right.int_val == e->left.int_val;
                break;
            case EXPR_LT:
-               e->right.num = e->right.num < e->left.num;
+               e->right.int_val = e->right.int_val < e->left.int_val;
                break;
            case EXPR_GT:
-               e->right.num = e->right.num > e->left.num;
+               e->right.int_val = e->right.int_val > e->left.int_val;
                break;
            case EXPR_LE:
-               e->right.num = e->right.num <= e->left.num;
+               e->right.int_val = e->right.int_val <= e->left.int_val;
                break;
            case EXPR_GE:
-               e->right.num = e->right.num >= e->left.num;
+               e->right.int_val = e->right.int_val >= e->left.int_val;
                break;
            case EXPR_NE:
-               e->right.num = e->right.num != e->left.num;
+               e->right.int_val = e->right.int_val != e->left.int_val;
                break;
            case EXPR_IDENT:
                break;
@@ -243,31 +255,31 @@ expr_simplify(expr *e)
     }
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->ltype == EXPR_NUM && ((e->left.num == 1 && e->op == EXPR_MUL)
-                                     || (e->left.num == 0 &&
+    else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->left.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->left.num == -1 &&
+                                     || (e->left.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->left.num == 0 &&
+                                     || (e->left.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_NUM && ((e->right.num == 1 && e->op == EXPR_MUL)
-                                     || (e->right.num == 1 &&
+    else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->right.int_val == 1 &&
                                          e->op == EXPR_DIV)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SUB)
-                                     || (e->right.num == -1 &&
+                                     || (e->right.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_OR)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SHL)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SHR))) {
        e->op = EXPR_IDENT;
        e->rtype = e->ltype;
@@ -281,11 +293,11 @@ expr_simplify(expr *e)
 int
 expr_get_value(expr *e, unsigned long *retval)
 {
-    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
           && expr_simplify(e)) ;
 
-    if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM) {
-       *retval = e->right.num;
+    if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
+       *retval = e->right.int_val;
        return 1;
     } else
        return 0;
@@ -296,17 +308,20 @@ expr_print(expr *e)
 {
     if (e->op != EXPR_IDENT) {
        switch (e->ltype) {
-           case EXPR_NUM:
-               printf("%lu", e->left.num);
-               break;
            case EXPR_SYM:
                printf("%s", e->left.sym->name);
                break;
            case EXPR_EXPR:
                printf("(");
-               expr_print(e->left.expr);
-
+               expr_print(e->left.exp);
                printf(")");
+               break;
+           case EXPR_INT:
+               printf("%lu", e->left.int_val);
+               break;
+           case EXPR_FLOAT:
+               floatnum_print(e->left.flt);
+               break;
            case EXPR_NONE:
                break;
        }
@@ -379,17 +394,20 @@ expr_print(expr *e)
            break;
     }
     switch (e->rtype) {
-       case EXPR_NUM:
-           printf("%lu", e->right.num);
-           break;
        case EXPR_SYM:
            printf("%s", e->right.sym->name);
            break;
        case EXPR_EXPR:
            printf("(");
-           expr_print(e->right.expr);
-
+           expr_print(e->right.exp);
            printf(")");
+           break;
+       case EXPR_INT:
+           printf("%lu", e->right.int_val);
+           break;
+       case EXPR_FLOAT:
+           floatnum_print(e->right.flt);
+           break;
        case EXPR_NONE:
            break;
     }
index 20da35721c9ba76b24ca9ae95b570cb7288e8e51..030b2c58190e3934504806e16e467f4bfec8b703 100644 (file)
@@ -1,7 +1,7 @@
 /* $IdPath$
  * Expression handling
  *
- *  Copyright (C) 2001  Michael Urman
+ *  Copyright (C) 2001  Michael Urman, Peter Johnson
  *
  *  This file is part of YASM.
  *
@@ -34,6 +34,7 @@
 
 #include "globals.h"
 #include "errwarn.h"
+#include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
 
@@ -56,18 +57,20 @@ expr_new(ExprType ltype,
     ptr->op = op;
     ptr->rtype = rtype;
     switch (ltype) {
-       case EXPR_NUM:
        case EXPR_SYM:
        case EXPR_EXPR:
+       case EXPR_INT:
+       case EXPR_FLOAT:
            memcpy(&ptr->left, &left, sizeof(ExprItem));
            break;
        case EXPR_NONE:
            break;
     }
     switch (rtype) {
-       case EXPR_NUM:
        case EXPR_SYM:
        case EXPR_EXPR:
+       case EXPR_INT:
+       case EXPR_FLOAT:
            memcpy(&ptr->right, &right, sizeof(ExprItem));
            break;
        case EXPR_NONE:
@@ -91,17 +94,26 @@ ExprItem
 ExprExpr(expr *x)
 {
     ExprItem e;
-    e.expr = x;
+    e.exp = x;
 
     return e;
 }
 
 ExprItem
-ExprNum(unsigned long n)
+ExprInt(unsigned long i)
 {
     ExprItem e;
 
-    e.num = n;
+    e.int_val = i;
+    return e;
+}
+
+ExprItem
+ExprFloat(floatnum *f)
+{
+    ExprItem e;
+
+    e.flt = f;
     return e;
 }
 
@@ -110,7 +122,7 @@ ExprNone(void)
 {
     ExprItem e;
 
-    e.num = 0;
+    e.int_val = 0;
     return e;
 }
 
@@ -119,121 +131,121 @@ int
 expr_simplify(expr *e)
 {
     int simplified = 0;
+    unsigned long int_val;
 
     /* try to simplify the left side */
     if (e->ltype == EXPR_EXPR) {
        /* if the left subexpr isn't an IDENT, recurse simplification */
-       if (e->left.expr->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->left.expr);
+       if (e->left.exp->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->left.exp);
 
        /* 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.expr->op == EXPR_IDENT) {
+       while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->ltype = e->left.expr->rtype;
-           memcpy(&tmp, &(e->left.expr->right), sizeof(ExprItem));
-           free(e->left.expr);
-           memcpy(&(e->left.num), &tmp, sizeof(ExprItem));
+           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));
            simplified = 1;
        }
     } else if (e->ltype == EXPR_SYM) {
-       /* if it's a symbol that has a defined value, turn it into a
-        * number */
-       if (e->left.sym->status & SYM_VALUED) {
-           e->ltype = EXPR_NUM;
+       /* try to get value of symbol */
+       if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
+           e->ltype = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->left.num = e->left.sym->value;
+           e->left.int_val = int_val;
            simplified = 1;
        }
     }
 
     /* ditto on the right */
     if (e->rtype == EXPR_EXPR) {
-       if (e->right.expr->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->right.expr);
+       if (e->right.exp->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->right.exp);
 
-       while (e->rtype == EXPR_EXPR && e->right.expr->op == EXPR_IDENT) {
+       while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->rtype = e->right.expr->rtype;
-           memcpy(&tmp, &(e->right.expr->right), sizeof(ExprItem));
-           free(e->right.expr);
-           memcpy(&(e->right.num), &tmp, sizeof(ExprItem));
+           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));
            simplified = 1;
        }
     } else if (e->rtype == EXPR_SYM) {
-       if (e->right.sym->status & SYM_VALUED) {
-           e->rtype = EXPR_NUM;
+       if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
+           e->rtype = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->right.num = e->right.sym->value;
+           e->right.int_val = int_val;
            simplified = 1;
        }
     }
 
-    if ((e->ltype == EXPR_NUM || e->ltype == EXPR_NONE)
-       && e->rtype == EXPR_NUM && e->op != EXPR_IDENT) {
+    if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
+       && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
        switch (e->op) {
            case EXPR_ADD:
-               e->right.num = e->left.num + e->right.num;
+               e->right.int_val = e->left.int_val + e->right.int_val;
                break;
            case EXPR_SUB:
-               e->right.num = e->left.num - e->right.num;
+               e->right.int_val = e->left.int_val - e->right.int_val;
                break;
            case EXPR_MUL:
-               e->right.num = e->left.num * e->right.num;
+               e->right.int_val = e->left.int_val * e->right.int_val;
                break;
            case EXPR_DIV:
-               e->right.num = e->left.num / e->right.num;
+               e->right.int_val = e->left.int_val / e->right.int_val;
                break;
            case EXPR_MOD:
-               e->right.num = e->left.num % e->right.num;
+               e->right.int_val = e->left.int_val % e->right.int_val;
                break;
            case EXPR_NEG:
-               e->right.num = -(e->right.num);
+               e->right.int_val = -(e->right.int_val);
                break;
            case EXPR_NOT:
-               e->right.num = ~(e->right.num);
+               e->right.int_val = ~(e->right.int_val);
                break;
            case EXPR_OR:
-               e->right.num = e->left.num | e->right.num;
+               e->right.int_val = e->left.int_val | e->right.int_val;
                break;
            case EXPR_AND:
-               e->right.num = e->left.num & e->right.num;
+               e->right.int_val = e->left.int_val & e->right.int_val;
                break;
            case EXPR_XOR:
-               e->right.num = e->left.num ^ e->right.num;
+               e->right.int_val = e->left.int_val ^ e->right.int_val;
                break;
            case EXPR_SHL:
-               e->right.num = e->right.num << e->left.num;
+               e->right.int_val = e->right.int_val << e->left.int_val;
                break;
            case EXPR_SHR:
-               e->right.num = e->right.num << e->left.num;
+               e->right.int_val = e->right.int_val << e->left.int_val;
                break;
            case EXPR_LOR:
-               e->right.num = e->left.num || e->right.num;
+               e->right.int_val = e->left.int_val || e->right.int_val;
                break;
            case EXPR_LAND:
-               e->right.num = e->left.num && e->right.num;
+               e->right.int_val = e->left.int_val && e->right.int_val;
                break;
            case EXPR_LNOT:
-               e->right.num = !e->right.num;
+               e->right.int_val = !e->right.int_val;
                break;
            case EXPR_EQ:
-               e->right.num = e->right.num == e->left.num;
+               e->right.int_val = e->right.int_val == e->left.int_val;
                break;
            case EXPR_LT:
-               e->right.num = e->right.num < e->left.num;
+               e->right.int_val = e->right.int_val < e->left.int_val;
                break;
            case EXPR_GT:
-               e->right.num = e->right.num > e->left.num;
+               e->right.int_val = e->right.int_val > e->left.int_val;
                break;
            case EXPR_LE:
-               e->right.num = e->right.num <= e->left.num;
+               e->right.int_val = e->right.int_val <= e->left.int_val;
                break;
            case EXPR_GE:
-               e->right.num = e->right.num >= e->left.num;
+               e->right.int_val = e->right.int_val >= e->left.int_val;
                break;
            case EXPR_NE:
-               e->right.num = e->right.num != e->left.num;
+               e->right.int_val = e->right.int_val != e->left.int_val;
                break;
            case EXPR_IDENT:
                break;
@@ -243,31 +255,31 @@ expr_simplify(expr *e)
     }
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->ltype == EXPR_NUM && ((e->left.num == 1 && e->op == EXPR_MUL)
-                                     || (e->left.num == 0 &&
+    else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->left.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->left.num == -1 &&
+                                     || (e->left.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->left.num == 0 &&
+                                     || (e->left.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_NUM && ((e->right.num == 1 && e->op == EXPR_MUL)
-                                     || (e->right.num == 1 &&
+    else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->right.int_val == 1 &&
                                          e->op == EXPR_DIV)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SUB)
-                                     || (e->right.num == -1 &&
+                                     || (e->right.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_OR)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SHL)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SHR))) {
        e->op = EXPR_IDENT;
        e->rtype = e->ltype;
@@ -281,11 +293,11 @@ expr_simplify(expr *e)
 int
 expr_get_value(expr *e, unsigned long *retval)
 {
-    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
           && expr_simplify(e)) ;
 
-    if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM) {
-       *retval = e->right.num;
+    if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
+       *retval = e->right.int_val;
        return 1;
     } else
        return 0;
@@ -296,17 +308,20 @@ expr_print(expr *e)
 {
     if (e->op != EXPR_IDENT) {
        switch (e->ltype) {
-           case EXPR_NUM:
-               printf("%lu", e->left.num);
-               break;
            case EXPR_SYM:
                printf("%s", e->left.sym->name);
                break;
            case EXPR_EXPR:
                printf("(");
-               expr_print(e->left.expr);
-
+               expr_print(e->left.exp);
                printf(")");
+               break;
+           case EXPR_INT:
+               printf("%lu", e->left.int_val);
+               break;
+           case EXPR_FLOAT:
+               floatnum_print(e->left.flt);
+               break;
            case EXPR_NONE:
                break;
        }
@@ -379,17 +394,20 @@ expr_print(expr *e)
            break;
     }
     switch (e->rtype) {
-       case EXPR_NUM:
-           printf("%lu", e->right.num);
-           break;
        case EXPR_SYM:
            printf("%s", e->right.sym->name);
            break;
        case EXPR_EXPR:
            printf("(");
-           expr_print(e->right.expr);
-
+           expr_print(e->right.exp);
            printf(")");
+           break;
+       case EXPR_INT:
+           printf("%lu", e->right.int_val);
+           break;
+       case EXPR_FLOAT:
+           floatnum_print(e->right.flt);
+           break;
        case EXPR_NONE:
            break;
     }
index cb596260f8273e9b8e11cf0a911b3c21b0ea27b1..5aa68e6fafe837920870de7f6c13a11851d1fd02 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "globals.h"
 #include "errwarn.h"
+#include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
 
@@ -58,17 +59,15 @@ extern sectionhead nasm_parser_sections;
 extern section *nasm_parser_cur_section;
 extern char *nasm_parser_locallabel_base;
 
+static bytecode *nasm_parser_prev_bc = (bytecode *)NULL;
+static bytecode *nasm_parser_temp_bc;
+
 %}
 
 %union {
     unsigned long int_val;
     char *str_val;
-    double double_val;
-    symrec *sym;
-    struct {
-       char *name;
-       int line;
-    } syminfo;
+    floatnum *flt;
     unsigned char groupdata[4];
     effaddr *ea;
     expr *exp;
@@ -80,7 +79,7 @@ extern char *nasm_parser_locallabel_base;
 }
 
 %token <int_val> INTNUM
-%token <double_val> FLTNUM
+%token <flt> FLTNUM
 %token <str_val> DIRECTIVE_NAME DIRECTIVE_VAL STRING
 %token <int_val> BYTE WORD DWORD QWORD TWORD DQWORD
 %token <int_val> DECLARE_DATA
@@ -96,7 +95,7 @@ extern char *nasm_parser_locallabel_base;
 %token <int_val> REG_AL REG_CL REG_DL REG_BL REG_AH REG_CH REG_DH REG_BH
 %token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
 %token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
-%token <syminfo> ID LOCAL_ID SPECIAL_ID
+%token <str_val> ID LOCAL_ID SPECIAL_ID
 
 /* instruction tokens (dynamically generated) */
 /* @TOKENS@ */
@@ -113,8 +112,7 @@ extern char *nasm_parser_locallabel_base;
 %type <ea> rm8 rm16 rm32 rm64 rm128
 %type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
 %type <exp> expr expr_no_string
-%type <syminfo> explabel
-%type <sym> label_id
+%type <str_val> explabel label_id
 %type <tgt_val> target
 %type <data> dataval
 %type <datahead> datavals
@@ -130,7 +128,10 @@ extern char *nasm_parser_locallabel_base;
 %%
 input: /* empty */
     | input line    {
-       bytecodes_append(&nasm_parser_cur_section->bc, $2);
+       nasm_parser_temp_bc = bytecodes_append(&nasm_parser_cur_section->bc,
+                                              $2);
+       if (nasm_parser_temp_bc)
+           nasm_parser_prev_bc = nasm_parser_temp_bc;
        line_number++;
     }
 ;
@@ -171,25 +172,31 @@ dataval: expr_no_string   { $$ = dataval_new_expr($1); }
     }
 ;
 
-label: label_id            { $1->value = 0; } /* TODO: add pointer to bytecode */
-    | label_id ':'  { $1->value = 0; } /* TODO: add pointer to bytecode */
+label: label_id            {
+       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc);
+    }
+    | label_id ':'  {
+       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc);
+    }
 ;
 
 label_id: ID       {
-       $$ = symrec_define($1.name, SYM_LABEL);
-       nasm_parser_locallabel_base = strdup($1.name);
+       $$ = $1;
+       nasm_parser_locallabel_base = strdup($1);
     }
-    | SPECIAL_ID    { $$ = symrec_define($1.name, SYM_LABEL); }
-    | LOCAL_ID     { $$ = symrec_define($1.name, SYM_LABEL); }
+    | SPECIAL_ID
+    | LOCAL_ID
 ;
 
 /* directives */
 directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']'        {
-       if (strcasecmp($2, "section") == 0)
+       if (strcasecmp($2, "section") == 0) {
            nasm_parser_cur_section = sections_switch(&nasm_parser_sections,
                                                      nasm_parser_objfmt, $3);
-       else
+           nasm_parser_prev_bc = (bytecode *)NULL;
+       } else {
            printf("Directive: Name='%s' Value='%s'\n", $2, $3);
+       }
     }
     | '[' DIRECTIVE_NAME DIRECTIVE_VAL error   {
        Error(_("missing `%c'"), ']');
@@ -375,9 +382,9 @@ target: expr            { $$.val = $1; $$.op_sel = JR_NONE; }
 ;
 
 /* expression trees */
-expr_no_string: INTNUM         { $$ = expr_new_ident(EXPR_NUM, ExprNum($1)); }
+expr_no_string: INTNUM         { $$ = expr_new_ident(EXPR_INT, ExprInt($1)); }
     | explabel                 {
-       $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1.name, SYM_LABEL)));
+       $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1)));
     }
     /*| expr '||' expr         { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
     | expr '|' expr            { $$ = expr_new_tree($1, EXPR_OR, $3); }
@@ -406,7 +413,7 @@ expr_no_string: INTNUM              { $$ = expr_new_ident(EXPR_NUM, ExprNum($1)); }
 
 expr: expr_no_string
     | STRING           {
-       $$ = expr_new_ident (EXPR_NUM, ExprNum(ConvertCharConstToInt($1)));
+       $$ = expr_new_ident (EXPR_INT, ExprInt(ConvertCharConstToInt($1)));
     }
 ;
 
index cb596260f8273e9b8e11cf0a911b3c21b0ea27b1..5aa68e6fafe837920870de7f6c13a11851d1fd02 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "globals.h"
 #include "errwarn.h"
+#include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
 
@@ -58,17 +59,15 @@ extern sectionhead nasm_parser_sections;
 extern section *nasm_parser_cur_section;
 extern char *nasm_parser_locallabel_base;
 
+static bytecode *nasm_parser_prev_bc = (bytecode *)NULL;
+static bytecode *nasm_parser_temp_bc;
+
 %}
 
 %union {
     unsigned long int_val;
     char *str_val;
-    double double_val;
-    symrec *sym;
-    struct {
-       char *name;
-       int line;
-    } syminfo;
+    floatnum *flt;
     unsigned char groupdata[4];
     effaddr *ea;
     expr *exp;
@@ -80,7 +79,7 @@ extern char *nasm_parser_locallabel_base;
 }
 
 %token <int_val> INTNUM
-%token <double_val> FLTNUM
+%token <flt> FLTNUM
 %token <str_val> DIRECTIVE_NAME DIRECTIVE_VAL STRING
 %token <int_val> BYTE WORD DWORD QWORD TWORD DQWORD
 %token <int_val> DECLARE_DATA
@@ -96,7 +95,7 @@ extern char *nasm_parser_locallabel_base;
 %token <int_val> REG_AL REG_CL REG_DL REG_BL REG_AH REG_CH REG_DH REG_BH
 %token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
 %token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
-%token <syminfo> ID LOCAL_ID SPECIAL_ID
+%token <str_val> ID LOCAL_ID SPECIAL_ID
 
 /* instruction tokens (dynamically generated) */
 /* @TOKENS@ */
@@ -113,8 +112,7 @@ extern char *nasm_parser_locallabel_base;
 %type <ea> rm8 rm16 rm32 rm64 rm128
 %type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
 %type <exp> expr expr_no_string
-%type <syminfo> explabel
-%type <sym> label_id
+%type <str_val> explabel label_id
 %type <tgt_val> target
 %type <data> dataval
 %type <datahead> datavals
@@ -130,7 +128,10 @@ extern char *nasm_parser_locallabel_base;
 %%
 input: /* empty */
     | input line    {
-       bytecodes_append(&nasm_parser_cur_section->bc, $2);
+       nasm_parser_temp_bc = bytecodes_append(&nasm_parser_cur_section->bc,
+                                              $2);
+       if (nasm_parser_temp_bc)
+           nasm_parser_prev_bc = nasm_parser_temp_bc;
        line_number++;
     }
 ;
@@ -171,25 +172,31 @@ dataval: expr_no_string   { $$ = dataval_new_expr($1); }
     }
 ;
 
-label: label_id            { $1->value = 0; } /* TODO: add pointer to bytecode */
-    | label_id ':'  { $1->value = 0; } /* TODO: add pointer to bytecode */
+label: label_id            {
+       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc);
+    }
+    | label_id ':'  {
+       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc);
+    }
 ;
 
 label_id: ID       {
-       $$ = symrec_define($1.name, SYM_LABEL);
-       nasm_parser_locallabel_base = strdup($1.name);
+       $$ = $1;
+       nasm_parser_locallabel_base = strdup($1);
     }
-    | SPECIAL_ID    { $$ = symrec_define($1.name, SYM_LABEL); }
-    | LOCAL_ID     { $$ = symrec_define($1.name, SYM_LABEL); }
+    | SPECIAL_ID
+    | LOCAL_ID
 ;
 
 /* directives */
 directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']'        {
-       if (strcasecmp($2, "section") == 0)
+       if (strcasecmp($2, "section") == 0) {
            nasm_parser_cur_section = sections_switch(&nasm_parser_sections,
                                                      nasm_parser_objfmt, $3);
-       else
+           nasm_parser_prev_bc = (bytecode *)NULL;
+       } else {
            printf("Directive: Name='%s' Value='%s'\n", $2, $3);
+       }
     }
     | '[' DIRECTIVE_NAME DIRECTIVE_VAL error   {
        Error(_("missing `%c'"), ']');
@@ -375,9 +382,9 @@ target: expr            { $$.val = $1; $$.op_sel = JR_NONE; }
 ;
 
 /* expression trees */
-expr_no_string: INTNUM         { $$ = expr_new_ident(EXPR_NUM, ExprNum($1)); }
+expr_no_string: INTNUM         { $$ = expr_new_ident(EXPR_INT, ExprInt($1)); }
     | explabel                 {
-       $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1.name, SYM_LABEL)));
+       $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1)));
     }
     /*| expr '||' expr         { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
     | expr '|' expr            { $$ = expr_new_tree($1, EXPR_OR, $3); }
@@ -406,7 +413,7 @@ expr_no_string: INTNUM              { $$ = expr_new_ident(EXPR_NUM, ExprNum($1)); }
 
 expr: expr_no_string
     | STRING           {
-       $$ = expr_new_ident (EXPR_NUM, ExprNum(ConvertCharConstToInt($1)));
+       $$ = expr_new_ident (EXPR_INT, ExprInt(ConvertCharConstToInt($1)));
     }
 ;
 
index 47a6fdb7f5b6fc355bd44cf552c3dd36e90612b5..4f4b72b2df447f16fa8474b1ef8a82740f5c7842 100644 (file)
@@ -35,6 +35,7 @@
 #define _(String)      gettext(String)
 
 #include "errwarn.h"
+#include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
 
@@ -114,7 +115,7 @@ WS       [ \t\r]
 
     /* floating point value */
 {DIGIT}+\.{DIGIT}*(e[-+]?{DIGIT}+)? {
-    yylval.double_val = strtod(yytext, (char **)NULL);
+    yylval.flt = floatnum_new(yytext);
     return FLTNUM;
 }
 
@@ -295,10 +296,9 @@ gs { yylval.int_val = 5; return REG_GS; }
 
     /* special non-local ..@label and labels like ..start */
 $$|$|\.\.[a-z0-9_$#@~.?]+ {
-    yylval.syminfo.name = strdup(yytext);
-    if (!yylval.syminfo.name)
+    yylval.str_val = strdup(yytext);
+    if (!yylval.str_val)
        Fatal(FATAL_NOMEM);
-    yylval.syminfo.line = line_number;
 
     return SPECIAL_ID;
 }
@@ -307,18 +307,17 @@ $$|$|\.\.[a-z0-9_$#@~.?]+ {
 \.[a-z0-9_$#@~?][a-z0-9_$#@~.?]* {
     if (!nasm_parser_locallabel_base) {
        Warning(_("no non-local label before `%s'"), yytext);
-       yylval.syminfo.name = strdup(yytext);
-       if (!yylval.syminfo.name)
+       yylval.str_val = strdup(yytext);
+       if (!yylval.str_val)
            Fatal(FATAL_NOMEM);
     } else {
-       yylval.syminfo.name = malloc(strlen(yytext) +
-                                    strlen(nasm_parser_locallabel_base) + 1);
-       if (!yylval.syminfo.name)
+       yylval.str_val = malloc(strlen(yytext) +
+                               strlen(nasm_parser_locallabel_base) + 1);
+       if (!yylval.str_val)
            Fatal(FATAL_NOMEM);
-       strcpy(yylval.syminfo.name, nasm_parser_locallabel_base);
-       strcat(yylval.syminfo.name, yytext);
+       strcpy(yylval.str_val, nasm_parser_locallabel_base);
+       strcat(yylval.str_val, yytext);
     }
-    yylval.syminfo.line = line_number;
 
     return LOCAL_ID;
 }
@@ -328,10 +327,9 @@ $$|$|\.\.[a-z0-9_$#@~.?]+ {
 
     /* label */
 [a-z_?][a-z0-9_$#@~.?]* {
-    yylval.syminfo.name = strdup(yytext);
-    if (!yylval.syminfo.name)
+    yylval.str_val = strdup(yytext);
+    if (!yylval.str_val)
        Fatal(FATAL_NOMEM);
-    yylval.syminfo.line = line_number;
 
     return ID;
 }
index c5d0c9198fb75aa3c0851e1288c7592e004b1f33..c41f41ce16e463a4fbbaaefbaee5c077c7c05ad2 100644 (file)
@@ -39,6 +39,8 @@ libyasm_a_SOURCES = \
        parser.c                \
        parser.h                \
        optimizer.h             \
+       floatnum.c              \
+       floatnum.h              \
        ternary.c               \
        ternary.h               \
        strcasecmp.c
index 20da35721c9ba76b24ca9ae95b570cb7288e8e51..030b2c58190e3934504806e16e467f4bfec8b703 100644 (file)
@@ -1,7 +1,7 @@
 /* $IdPath$
  * Expression handling
  *
- *  Copyright (C) 2001  Michael Urman
+ *  Copyright (C) 2001  Michael Urman, Peter Johnson
  *
  *  This file is part of YASM.
  *
@@ -34,6 +34,7 @@
 
 #include "globals.h"
 #include "errwarn.h"
+#include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
 
@@ -56,18 +57,20 @@ expr_new(ExprType ltype,
     ptr->op = op;
     ptr->rtype = rtype;
     switch (ltype) {
-       case EXPR_NUM:
        case EXPR_SYM:
        case EXPR_EXPR:
+       case EXPR_INT:
+       case EXPR_FLOAT:
            memcpy(&ptr->left, &left, sizeof(ExprItem));
            break;
        case EXPR_NONE:
            break;
     }
     switch (rtype) {
-       case EXPR_NUM:
        case EXPR_SYM:
        case EXPR_EXPR:
+       case EXPR_INT:
+       case EXPR_FLOAT:
            memcpy(&ptr->right, &right, sizeof(ExprItem));
            break;
        case EXPR_NONE:
@@ -91,17 +94,26 @@ ExprItem
 ExprExpr(expr *x)
 {
     ExprItem e;
-    e.expr = x;
+    e.exp = x;
 
     return e;
 }
 
 ExprItem
-ExprNum(unsigned long n)
+ExprInt(unsigned long i)
 {
     ExprItem e;
 
-    e.num = n;
+    e.int_val = i;
+    return e;
+}
+
+ExprItem
+ExprFloat(floatnum *f)
+{
+    ExprItem e;
+
+    e.flt = f;
     return e;
 }
 
@@ -110,7 +122,7 @@ ExprNone(void)
 {
     ExprItem e;
 
-    e.num = 0;
+    e.int_val = 0;
     return e;
 }
 
@@ -119,121 +131,121 @@ int
 expr_simplify(expr *e)
 {
     int simplified = 0;
+    unsigned long int_val;
 
     /* try to simplify the left side */
     if (e->ltype == EXPR_EXPR) {
        /* if the left subexpr isn't an IDENT, recurse simplification */
-       if (e->left.expr->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->left.expr);
+       if (e->left.exp->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->left.exp);
 
        /* 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.expr->op == EXPR_IDENT) {
+       while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->ltype = e->left.expr->rtype;
-           memcpy(&tmp, &(e->left.expr->right), sizeof(ExprItem));
-           free(e->left.expr);
-           memcpy(&(e->left.num), &tmp, sizeof(ExprItem));
+           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));
            simplified = 1;
        }
     } else if (e->ltype == EXPR_SYM) {
-       /* if it's a symbol that has a defined value, turn it into a
-        * number */
-       if (e->left.sym->status & SYM_VALUED) {
-           e->ltype = EXPR_NUM;
+       /* try to get value of symbol */
+       if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
+           e->ltype = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->left.num = e->left.sym->value;
+           e->left.int_val = int_val;
            simplified = 1;
        }
     }
 
     /* ditto on the right */
     if (e->rtype == EXPR_EXPR) {
-       if (e->right.expr->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->right.expr);
+       if (e->right.exp->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->right.exp);
 
-       while (e->rtype == EXPR_EXPR && e->right.expr->op == EXPR_IDENT) {
+       while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->rtype = e->right.expr->rtype;
-           memcpy(&tmp, &(e->right.expr->right), sizeof(ExprItem));
-           free(e->right.expr);
-           memcpy(&(e->right.num), &tmp, sizeof(ExprItem));
+           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));
            simplified = 1;
        }
     } else if (e->rtype == EXPR_SYM) {
-       if (e->right.sym->status & SYM_VALUED) {
-           e->rtype = EXPR_NUM;
+       if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
+           e->rtype = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->right.num = e->right.sym->value;
+           e->right.int_val = int_val;
            simplified = 1;
        }
     }
 
-    if ((e->ltype == EXPR_NUM || e->ltype == EXPR_NONE)
-       && e->rtype == EXPR_NUM && e->op != EXPR_IDENT) {
+    if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
+       && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
        switch (e->op) {
            case EXPR_ADD:
-               e->right.num = e->left.num + e->right.num;
+               e->right.int_val = e->left.int_val + e->right.int_val;
                break;
            case EXPR_SUB:
-               e->right.num = e->left.num - e->right.num;
+               e->right.int_val = e->left.int_val - e->right.int_val;
                break;
            case EXPR_MUL:
-               e->right.num = e->left.num * e->right.num;
+               e->right.int_val = e->left.int_val * e->right.int_val;
                break;
            case EXPR_DIV:
-               e->right.num = e->left.num / e->right.num;
+               e->right.int_val = e->left.int_val / e->right.int_val;
                break;
            case EXPR_MOD:
-               e->right.num = e->left.num % e->right.num;
+               e->right.int_val = e->left.int_val % e->right.int_val;
                break;
            case EXPR_NEG:
-               e->right.num = -(e->right.num);
+               e->right.int_val = -(e->right.int_val);
                break;
            case EXPR_NOT:
-               e->right.num = ~(e->right.num);
+               e->right.int_val = ~(e->right.int_val);
                break;
            case EXPR_OR:
-               e->right.num = e->left.num | e->right.num;
+               e->right.int_val = e->left.int_val | e->right.int_val;
                break;
            case EXPR_AND:
-               e->right.num = e->left.num & e->right.num;
+               e->right.int_val = e->left.int_val & e->right.int_val;
                break;
            case EXPR_XOR:
-               e->right.num = e->left.num ^ e->right.num;
+               e->right.int_val = e->left.int_val ^ e->right.int_val;
                break;
            case EXPR_SHL:
-               e->right.num = e->right.num << e->left.num;
+               e->right.int_val = e->right.int_val << e->left.int_val;
                break;
            case EXPR_SHR:
-               e->right.num = e->right.num << e->left.num;
+               e->right.int_val = e->right.int_val << e->left.int_val;
                break;
            case EXPR_LOR:
-               e->right.num = e->left.num || e->right.num;
+               e->right.int_val = e->left.int_val || e->right.int_val;
                break;
            case EXPR_LAND:
-               e->right.num = e->left.num && e->right.num;
+               e->right.int_val = e->left.int_val && e->right.int_val;
                break;
            case EXPR_LNOT:
-               e->right.num = !e->right.num;
+               e->right.int_val = !e->right.int_val;
                break;
            case EXPR_EQ:
-               e->right.num = e->right.num == e->left.num;
+               e->right.int_val = e->right.int_val == e->left.int_val;
                break;
            case EXPR_LT:
-               e->right.num = e->right.num < e->left.num;
+               e->right.int_val = e->right.int_val < e->left.int_val;
                break;
            case EXPR_GT:
-               e->right.num = e->right.num > e->left.num;
+               e->right.int_val = e->right.int_val > e->left.int_val;
                break;
            case EXPR_LE:
-               e->right.num = e->right.num <= e->left.num;
+               e->right.int_val = e->right.int_val <= e->left.int_val;
                break;
            case EXPR_GE:
-               e->right.num = e->right.num >= e->left.num;
+               e->right.int_val = e->right.int_val >= e->left.int_val;
                break;
            case EXPR_NE:
-               e->right.num = e->right.num != e->left.num;
+               e->right.int_val = e->right.int_val != e->left.int_val;
                break;
            case EXPR_IDENT:
                break;
@@ -243,31 +255,31 @@ expr_simplify(expr *e)
     }
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->ltype == EXPR_NUM && ((e->left.num == 1 && e->op == EXPR_MUL)
-                                     || (e->left.num == 0 &&
+    else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->left.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->left.num == -1 &&
+                                     || (e->left.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->left.num == 0 &&
+                                     || (e->left.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_NUM && ((e->right.num == 1 && e->op == EXPR_MUL)
-                                     || (e->right.num == 1 &&
+    else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->right.int_val == 1 &&
                                          e->op == EXPR_DIV)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SUB)
-                                     || (e->right.num == -1 &&
+                                     || (e->right.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_OR)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SHL)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SHR))) {
        e->op = EXPR_IDENT;
        e->rtype = e->ltype;
@@ -281,11 +293,11 @@ expr_simplify(expr *e)
 int
 expr_get_value(expr *e, unsigned long *retval)
 {
-    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
           && expr_simplify(e)) ;
 
-    if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM) {
-       *retval = e->right.num;
+    if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
+       *retval = e->right.int_val;
        return 1;
     } else
        return 0;
@@ -296,17 +308,20 @@ expr_print(expr *e)
 {
     if (e->op != EXPR_IDENT) {
        switch (e->ltype) {
-           case EXPR_NUM:
-               printf("%lu", e->left.num);
-               break;
            case EXPR_SYM:
                printf("%s", e->left.sym->name);
                break;
            case EXPR_EXPR:
                printf("(");
-               expr_print(e->left.expr);
-
+               expr_print(e->left.exp);
                printf(")");
+               break;
+           case EXPR_INT:
+               printf("%lu", e->left.int_val);
+               break;
+           case EXPR_FLOAT:
+               floatnum_print(e->left.flt);
+               break;
            case EXPR_NONE:
                break;
        }
@@ -379,17 +394,20 @@ expr_print(expr *e)
            break;
     }
     switch (e->rtype) {
-       case EXPR_NUM:
-           printf("%lu", e->right.num);
-           break;
        case EXPR_SYM:
            printf("%s", e->right.sym->name);
            break;
        case EXPR_EXPR:
            printf("(");
-           expr_print(e->right.expr);
-
+           expr_print(e->right.exp);
            printf(")");
+           break;
+       case EXPR_INT:
+           printf("%lu", e->right.int_val);
+           break;
+       case EXPR_FLOAT:
+           floatnum_print(e->right.flt);
+           break;
        case EXPR_NONE:
            break;
     }
index 20da35721c9ba76b24ca9ae95b570cb7288e8e51..030b2c58190e3934504806e16e467f4bfec8b703 100644 (file)
@@ -1,7 +1,7 @@
 /* $IdPath$
  * Expression handling
  *
- *  Copyright (C) 2001  Michael Urman
+ *  Copyright (C) 2001  Michael Urman, Peter Johnson
  *
  *  This file is part of YASM.
  *
@@ -34,6 +34,7 @@
 
 #include "globals.h"
 #include "errwarn.h"
+#include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
 
@@ -56,18 +57,20 @@ expr_new(ExprType ltype,
     ptr->op = op;
     ptr->rtype = rtype;
     switch (ltype) {
-       case EXPR_NUM:
        case EXPR_SYM:
        case EXPR_EXPR:
+       case EXPR_INT:
+       case EXPR_FLOAT:
            memcpy(&ptr->left, &left, sizeof(ExprItem));
            break;
        case EXPR_NONE:
            break;
     }
     switch (rtype) {
-       case EXPR_NUM:
        case EXPR_SYM:
        case EXPR_EXPR:
+       case EXPR_INT:
+       case EXPR_FLOAT:
            memcpy(&ptr->right, &right, sizeof(ExprItem));
            break;
        case EXPR_NONE:
@@ -91,17 +94,26 @@ ExprItem
 ExprExpr(expr *x)
 {
     ExprItem e;
-    e.expr = x;
+    e.exp = x;
 
     return e;
 }
 
 ExprItem
-ExprNum(unsigned long n)
+ExprInt(unsigned long i)
 {
     ExprItem e;
 
-    e.num = n;
+    e.int_val = i;
+    return e;
+}
+
+ExprItem
+ExprFloat(floatnum *f)
+{
+    ExprItem e;
+
+    e.flt = f;
     return e;
 }
 
@@ -110,7 +122,7 @@ ExprNone(void)
 {
     ExprItem e;
 
-    e.num = 0;
+    e.int_val = 0;
     return e;
 }
 
@@ -119,121 +131,121 @@ int
 expr_simplify(expr *e)
 {
     int simplified = 0;
+    unsigned long int_val;
 
     /* try to simplify the left side */
     if (e->ltype == EXPR_EXPR) {
        /* if the left subexpr isn't an IDENT, recurse simplification */
-       if (e->left.expr->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->left.expr);
+       if (e->left.exp->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->left.exp);
 
        /* 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.expr->op == EXPR_IDENT) {
+       while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->ltype = e->left.expr->rtype;
-           memcpy(&tmp, &(e->left.expr->right), sizeof(ExprItem));
-           free(e->left.expr);
-           memcpy(&(e->left.num), &tmp, sizeof(ExprItem));
+           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));
            simplified = 1;
        }
     } else if (e->ltype == EXPR_SYM) {
-       /* if it's a symbol that has a defined value, turn it into a
-        * number */
-       if (e->left.sym->status & SYM_VALUED) {
-           e->ltype = EXPR_NUM;
+       /* try to get value of symbol */
+       if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
+           e->ltype = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->left.num = e->left.sym->value;
+           e->left.int_val = int_val;
            simplified = 1;
        }
     }
 
     /* ditto on the right */
     if (e->rtype == EXPR_EXPR) {
-       if (e->right.expr->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->right.expr);
+       if (e->right.exp->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->right.exp);
 
-       while (e->rtype == EXPR_EXPR && e->right.expr->op == EXPR_IDENT) {
+       while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->rtype = e->right.expr->rtype;
-           memcpy(&tmp, &(e->right.expr->right), sizeof(ExprItem));
-           free(e->right.expr);
-           memcpy(&(e->right.num), &tmp, sizeof(ExprItem));
+           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));
            simplified = 1;
        }
     } else if (e->rtype == EXPR_SYM) {
-       if (e->right.sym->status & SYM_VALUED) {
-           e->rtype = EXPR_NUM;
+       if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
+           e->rtype = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->right.num = e->right.sym->value;
+           e->right.int_val = int_val;
            simplified = 1;
        }
     }
 
-    if ((e->ltype == EXPR_NUM || e->ltype == EXPR_NONE)
-       && e->rtype == EXPR_NUM && e->op != EXPR_IDENT) {
+    if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
+       && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
        switch (e->op) {
            case EXPR_ADD:
-               e->right.num = e->left.num + e->right.num;
+               e->right.int_val = e->left.int_val + e->right.int_val;
                break;
            case EXPR_SUB:
-               e->right.num = e->left.num - e->right.num;
+               e->right.int_val = e->left.int_val - e->right.int_val;
                break;
            case EXPR_MUL:
-               e->right.num = e->left.num * e->right.num;
+               e->right.int_val = e->left.int_val * e->right.int_val;
                break;
            case EXPR_DIV:
-               e->right.num = e->left.num / e->right.num;
+               e->right.int_val = e->left.int_val / e->right.int_val;
                break;
            case EXPR_MOD:
-               e->right.num = e->left.num % e->right.num;
+               e->right.int_val = e->left.int_val % e->right.int_val;
                break;
            case EXPR_NEG:
-               e->right.num = -(e->right.num);
+               e->right.int_val = -(e->right.int_val);
                break;
            case EXPR_NOT:
-               e->right.num = ~(e->right.num);
+               e->right.int_val = ~(e->right.int_val);
                break;
            case EXPR_OR:
-               e->right.num = e->left.num | e->right.num;
+               e->right.int_val = e->left.int_val | e->right.int_val;
                break;
            case EXPR_AND:
-               e->right.num = e->left.num & e->right.num;
+               e->right.int_val = e->left.int_val & e->right.int_val;
                break;
            case EXPR_XOR:
-               e->right.num = e->left.num ^ e->right.num;
+               e->right.int_val = e->left.int_val ^ e->right.int_val;
                break;
            case EXPR_SHL:
-               e->right.num = e->right.num << e->left.num;
+               e->right.int_val = e->right.int_val << e->left.int_val;
                break;
            case EXPR_SHR:
-               e->right.num = e->right.num << e->left.num;
+               e->right.int_val = e->right.int_val << e->left.int_val;
                break;
            case EXPR_LOR:
-               e->right.num = e->left.num || e->right.num;
+               e->right.int_val = e->left.int_val || e->right.int_val;
                break;
            case EXPR_LAND:
-               e->right.num = e->left.num && e->right.num;
+               e->right.int_val = e->left.int_val && e->right.int_val;
                break;
            case EXPR_LNOT:
-               e->right.num = !e->right.num;
+               e->right.int_val = !e->right.int_val;
                break;
            case EXPR_EQ:
-               e->right.num = e->right.num == e->left.num;
+               e->right.int_val = e->right.int_val == e->left.int_val;
                break;
            case EXPR_LT:
-               e->right.num = e->right.num < e->left.num;
+               e->right.int_val = e->right.int_val < e->left.int_val;
                break;
            case EXPR_GT:
-               e->right.num = e->right.num > e->left.num;
+               e->right.int_val = e->right.int_val > e->left.int_val;
                break;
            case EXPR_LE:
-               e->right.num = e->right.num <= e->left.num;
+               e->right.int_val = e->right.int_val <= e->left.int_val;
                break;
            case EXPR_GE:
-               e->right.num = e->right.num >= e->left.num;
+               e->right.int_val = e->right.int_val >= e->left.int_val;
                break;
            case EXPR_NE:
-               e->right.num = e->right.num != e->left.num;
+               e->right.int_val = e->right.int_val != e->left.int_val;
                break;
            case EXPR_IDENT:
                break;
@@ -243,31 +255,31 @@ expr_simplify(expr *e)
     }
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->ltype == EXPR_NUM && ((e->left.num == 1 && e->op == EXPR_MUL)
-                                     || (e->left.num == 0 &&
+    else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->left.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->left.num == -1 &&
+                                     || (e->left.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->left.num == 0 &&
+                                     || (e->left.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_NUM && ((e->right.num == 1 && e->op == EXPR_MUL)
-                                     || (e->right.num == 1 &&
+    else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->right.int_val == 1 &&
                                          e->op == EXPR_DIV)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SUB)
-                                     || (e->right.num == -1 &&
+                                     || (e->right.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_OR)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SHL)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SHR))) {
        e->op = EXPR_IDENT;
        e->rtype = e->ltype;
@@ -281,11 +293,11 @@ expr_simplify(expr *e)
 int
 expr_get_value(expr *e, unsigned long *retval)
 {
-    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
           && expr_simplify(e)) ;
 
-    if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM) {
-       *retval = e->right.num;
+    if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
+       *retval = e->right.int_val;
        return 1;
     } else
        return 0;
@@ -296,17 +308,20 @@ expr_print(expr *e)
 {
     if (e->op != EXPR_IDENT) {
        switch (e->ltype) {
-           case EXPR_NUM:
-               printf("%lu", e->left.num);
-               break;
            case EXPR_SYM:
                printf("%s", e->left.sym->name);
                break;
            case EXPR_EXPR:
                printf("(");
-               expr_print(e->left.expr);
-
+               expr_print(e->left.exp);
                printf(")");
+               break;
+           case EXPR_INT:
+               printf("%lu", e->left.int_val);
+               break;
+           case EXPR_FLOAT:
+               floatnum_print(e->left.flt);
+               break;
            case EXPR_NONE:
                break;
        }
@@ -379,17 +394,20 @@ expr_print(expr *e)
            break;
     }
     switch (e->rtype) {
-       case EXPR_NUM:
-           printf("%lu", e->right.num);
-           break;
        case EXPR_SYM:
            printf("%s", e->right.sym->name);
            break;
        case EXPR_EXPR:
            printf("(");
-           expr_print(e->right.expr);
-
+           expr_print(e->right.exp);
            printf(")");
+           break;
+       case EXPR_INT:
+           printf("%lu", e->right.int_val);
+           break;
+       case EXPR_FLOAT:
+           floatnum_print(e->right.flt);
+           break;
        case EXPR_NONE:
            break;
     }
index a8b17ed2ae810a056c9a42bc3d7a3da52a7128a8..01695afea39b38753222d7bf0df1528d64b96ee7 100644 (file)
 
 #include "globals.h"
 #include "errwarn.h"
+#include "floatnum.h"
 #include "expr.h"
 
 #include "bytecode.h"
+#include "section.h"
 
 RCSID("$IdPath$");
 
@@ -119,7 +121,7 @@ ConvertIntToImm(immval *ptr, unsigned long int_val)
        ptr = &im_static;
 
     /* FIXME: this will leak expr's if static is used */
-    ptr->val = expr_new_ident(EXPR_NUM, ExprNum(int_val));
+    ptr->val = expr_new_ident(EXPR_INT, ExprInt(int_val));
 
     if ((int_val & 0xFF) == int_val)
        ptr->len = 1;
@@ -432,6 +434,12 @@ bytecode_new_reserve(expr *numitems, unsigned long itemsize)
     return bc;
 }
 
+int
+bytecode_get_offset(section *sect, bytecode *bc, unsigned long *ret_val)
+{
+    return 0;  /* TODO */
+}
+
 void
 bytecode_print(bytecode *bc)
 {
@@ -553,15 +561,18 @@ bytecode_print(bytecode *bc)
     printf("Offset=%lx BITS=%u\n", bc->offset, bc->mode_bits);
 }
 
-void
+bytecode *
 bytecodes_append(bytecodehead *headp, bytecode *bc)
 {
     if (bc) {
-       if (bc->type != BC_EMPTY)
+       if (bc->type != BC_EMPTY) {
            STAILQ_INSERT_TAIL(headp, bc, link);
-       else
+           return bc;
+       } else {
            free(bc);
+       }
     }
+    return (bytecode *)NULL;
 }
 
 dataval *
@@ -579,7 +590,7 @@ dataval_new_expr(expr *exp)
 }
 
 dataval *
-dataval_new_float(double float_val)
+dataval_new_float(floatnum *flt)
 {
     dataval *retval = malloc(sizeof(dataval));
 
@@ -587,7 +598,7 @@ dataval_new_float(double float_val)
        Fatal(FATAL_NOMEM);
 
     retval->type = DV_FLOAT;
-    retval->data.float_val = float_val;
+    retval->data.flt = flt;
 
     return retval;
 }
@@ -622,7 +633,9 @@ dataval_print(datavalhead *head)
                printf("\n");
                break;
            case DV_FLOAT:
-               printf(" Float=%e\n", cur->data.float_val);
+               printf(" Float=");
+               floatnum_print(cur->data.flt);
+               printf("\n");
                break;
            case DV_STRING:
                printf(" String=%s\n", cur->data.str_val);
index 5ff60a8c88c1b4e78e88d2fd525c36acbf443181..01a0ac19657a5a9ba5053386fd8b5b97906d5258 100644 (file)
@@ -22,6 +22,8 @@
 #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 */
@@ -56,7 +58,7 @@ typedef struct dataval_s {
 
     union {
        struct expr_s *exp;
-       double float_val;
+       struct floatnum_s *flt;
        char *str_val;
     } data;
 } dataval;
@@ -210,6 +212,12 @@ bytecode *bytecode_new_data(datavalhead *datahead, unsigned long size);
 bytecode *bytecode_new_reserve(struct expr_s *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);
+
 void bytecode_print(bytecode *bc);
 
 /* void bytecodes_initialize(bytecodehead *headp); */
@@ -218,12 +226,13 @@ void bytecode_print(bytecode *bc);
 /* Adds bc to the list of bytecodes headp.
  * NOTE: Does not make a copy of bc; so don't pass this function
  * static or local variables, and discard the bc pointer after calling
- * this function.
+ * this function.  If bc was actually appended (it wasn't NULL or empty),
+ * then returns bc, otherwise returns NULL.
  */
-void bytecodes_append(bytecodehead *headp, bytecode *bc);
+bytecode *bytecodes_append(bytecodehead *headp, bytecode *bc);
 
 dataval *dataval_new_expr(struct expr_s *exp);
-dataval *dataval_new_float(double float_val);
+dataval *dataval_new_float(struct floatnum_s *flt);
 dataval *dataval_new_string(char *str_val);
 
 void dataval_print(datavalhead *head);
index 20da35721c9ba76b24ca9ae95b570cb7288e8e51..030b2c58190e3934504806e16e467f4bfec8b703 100644 (file)
@@ -1,7 +1,7 @@
 /* $IdPath$
  * Expression handling
  *
- *  Copyright (C) 2001  Michael Urman
+ *  Copyright (C) 2001  Michael Urman, Peter Johnson
  *
  *  This file is part of YASM.
  *
@@ -34,6 +34,7 @@
 
 #include "globals.h"
 #include "errwarn.h"
+#include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
 
@@ -56,18 +57,20 @@ expr_new(ExprType ltype,
     ptr->op = op;
     ptr->rtype = rtype;
     switch (ltype) {
-       case EXPR_NUM:
        case EXPR_SYM:
        case EXPR_EXPR:
+       case EXPR_INT:
+       case EXPR_FLOAT:
            memcpy(&ptr->left, &left, sizeof(ExprItem));
            break;
        case EXPR_NONE:
            break;
     }
     switch (rtype) {
-       case EXPR_NUM:
        case EXPR_SYM:
        case EXPR_EXPR:
+       case EXPR_INT:
+       case EXPR_FLOAT:
            memcpy(&ptr->right, &right, sizeof(ExprItem));
            break;
        case EXPR_NONE:
@@ -91,17 +94,26 @@ ExprItem
 ExprExpr(expr *x)
 {
     ExprItem e;
-    e.expr = x;
+    e.exp = x;
 
     return e;
 }
 
 ExprItem
-ExprNum(unsigned long n)
+ExprInt(unsigned long i)
 {
     ExprItem e;
 
-    e.num = n;
+    e.int_val = i;
+    return e;
+}
+
+ExprItem
+ExprFloat(floatnum *f)
+{
+    ExprItem e;
+
+    e.flt = f;
     return e;
 }
 
@@ -110,7 +122,7 @@ ExprNone(void)
 {
     ExprItem e;
 
-    e.num = 0;
+    e.int_val = 0;
     return e;
 }
 
@@ -119,121 +131,121 @@ int
 expr_simplify(expr *e)
 {
     int simplified = 0;
+    unsigned long int_val;
 
     /* try to simplify the left side */
     if (e->ltype == EXPR_EXPR) {
        /* if the left subexpr isn't an IDENT, recurse simplification */
-       if (e->left.expr->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->left.expr);
+       if (e->left.exp->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->left.exp);
 
        /* 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.expr->op == EXPR_IDENT) {
+       while (e->ltype == EXPR_EXPR && e->left.exp->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->ltype = e->left.expr->rtype;
-           memcpy(&tmp, &(e->left.expr->right), sizeof(ExprItem));
-           free(e->left.expr);
-           memcpy(&(e->left.num), &tmp, sizeof(ExprItem));
+           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));
            simplified = 1;
        }
     } else if (e->ltype == EXPR_SYM) {
-       /* if it's a symbol that has a defined value, turn it into a
-        * number */
-       if (e->left.sym->status & SYM_VALUED) {
-           e->ltype = EXPR_NUM;
+       /* try to get value of symbol */
+       if (symrec_get_int_value(e->left.sym, &int_val, 0)) {
+           e->ltype = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->left.num = e->left.sym->value;
+           e->left.int_val = int_val;
            simplified = 1;
        }
     }
 
     /* ditto on the right */
     if (e->rtype == EXPR_EXPR) {
-       if (e->right.expr->op != EXPR_IDENT)
-           simplified |= expr_simplify(e->right.expr);
+       if (e->right.exp->op != EXPR_IDENT)
+           simplified |= expr_simplify(e->right.exp);
 
-       while (e->rtype == EXPR_EXPR && e->right.expr->op == EXPR_IDENT) {
+       while (e->rtype == EXPR_EXPR && e->right.exp->op == EXPR_IDENT) {
            ExprItem tmp;
-           e->rtype = e->right.expr->rtype;
-           memcpy(&tmp, &(e->right.expr->right), sizeof(ExprItem));
-           free(e->right.expr);
-           memcpy(&(e->right.num), &tmp, sizeof(ExprItem));
+           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));
            simplified = 1;
        }
     } else if (e->rtype == EXPR_SYM) {
-       if (e->right.sym->status & SYM_VALUED) {
-           e->rtype = EXPR_NUM;
+       if (symrec_get_int_value(e->right.sym, &int_val, 0)) {
+           e->rtype = EXPR_INT;
            /* don't try to free the symrec here. */
-           e->right.num = e->right.sym->value;
+           e->right.int_val = int_val;
            simplified = 1;
        }
     }
 
-    if ((e->ltype == EXPR_NUM || e->ltype == EXPR_NONE)
-       && e->rtype == EXPR_NUM && e->op != EXPR_IDENT) {
+    if ((e->ltype == EXPR_INT || e->ltype == EXPR_NONE)
+       && e->rtype == EXPR_INT && e->op != EXPR_IDENT) {
        switch (e->op) {
            case EXPR_ADD:
-               e->right.num = e->left.num + e->right.num;
+               e->right.int_val = e->left.int_val + e->right.int_val;
                break;
            case EXPR_SUB:
-               e->right.num = e->left.num - e->right.num;
+               e->right.int_val = e->left.int_val - e->right.int_val;
                break;
            case EXPR_MUL:
-               e->right.num = e->left.num * e->right.num;
+               e->right.int_val = e->left.int_val * e->right.int_val;
                break;
            case EXPR_DIV:
-               e->right.num = e->left.num / e->right.num;
+               e->right.int_val = e->left.int_val / e->right.int_val;
                break;
            case EXPR_MOD:
-               e->right.num = e->left.num % e->right.num;
+               e->right.int_val = e->left.int_val % e->right.int_val;
                break;
            case EXPR_NEG:
-               e->right.num = -(e->right.num);
+               e->right.int_val = -(e->right.int_val);
                break;
            case EXPR_NOT:
-               e->right.num = ~(e->right.num);
+               e->right.int_val = ~(e->right.int_val);
                break;
            case EXPR_OR:
-               e->right.num = e->left.num | e->right.num;
+               e->right.int_val = e->left.int_val | e->right.int_val;
                break;
            case EXPR_AND:
-               e->right.num = e->left.num & e->right.num;
+               e->right.int_val = e->left.int_val & e->right.int_val;
                break;
            case EXPR_XOR:
-               e->right.num = e->left.num ^ e->right.num;
+               e->right.int_val = e->left.int_val ^ e->right.int_val;
                break;
            case EXPR_SHL:
-               e->right.num = e->right.num << e->left.num;
+               e->right.int_val = e->right.int_val << e->left.int_val;
                break;
            case EXPR_SHR:
-               e->right.num = e->right.num << e->left.num;
+               e->right.int_val = e->right.int_val << e->left.int_val;
                break;
            case EXPR_LOR:
-               e->right.num = e->left.num || e->right.num;
+               e->right.int_val = e->left.int_val || e->right.int_val;
                break;
            case EXPR_LAND:
-               e->right.num = e->left.num && e->right.num;
+               e->right.int_val = e->left.int_val && e->right.int_val;
                break;
            case EXPR_LNOT:
-               e->right.num = !e->right.num;
+               e->right.int_val = !e->right.int_val;
                break;
            case EXPR_EQ:
-               e->right.num = e->right.num == e->left.num;
+               e->right.int_val = e->right.int_val == e->left.int_val;
                break;
            case EXPR_LT:
-               e->right.num = e->right.num < e->left.num;
+               e->right.int_val = e->right.int_val < e->left.int_val;
                break;
            case EXPR_GT:
-               e->right.num = e->right.num > e->left.num;
+               e->right.int_val = e->right.int_val > e->left.int_val;
                break;
            case EXPR_LE:
-               e->right.num = e->right.num <= e->left.num;
+               e->right.int_val = e->right.int_val <= e->left.int_val;
                break;
            case EXPR_GE:
-               e->right.num = e->right.num >= e->left.num;
+               e->right.int_val = e->right.int_val >= e->left.int_val;
                break;
            case EXPR_NE:
-               e->right.num = e->right.num != e->left.num;
+               e->right.int_val = e->right.int_val != e->left.int_val;
                break;
            case EXPR_IDENT:
                break;
@@ -243,31 +255,31 @@ expr_simplify(expr *e)
     }
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->ltype == EXPR_NUM && ((e->left.num == 1 && e->op == EXPR_MUL)
-                                     || (e->left.num == 0 &&
+    else if (e->ltype == EXPR_INT && ((e->left.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->left.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->left.num == -1 &&
+                                     || (e->left.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->left.num == 0 &&
+                                     || (e->left.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_NUM && ((e->right.num == 1 && e->op == EXPR_MUL)
-                                     || (e->right.num == 1 &&
+    else if (e->rtype == EXPR_INT && ((e->right.int_val == 1 && e->op == EXPR_MUL)
+                                     || (e->right.int_val == 1 &&
                                          e->op == EXPR_DIV)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_ADD)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SUB)
-                                     || (e->right.num == -1 &&
+                                     || (e->right.int_val == -1 &&
                                          e->op == EXPR_AND)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_OR)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SHL)
-                                     || (e->right.num == 0 &&
+                                     || (e->right.int_val == 0 &&
                                          e->op == EXPR_SHR))) {
        e->op = EXPR_IDENT;
        e->rtype = e->ltype;
@@ -281,11 +293,11 @@ expr_simplify(expr *e)
 int
 expr_get_value(expr *e, unsigned long *retval)
 {
-    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_NUM)
+    while (!(e->op == EXPR_IDENT && e->rtype == EXPR_INT)
           && expr_simplify(e)) ;
 
-    if (e->op == EXPR_IDENT && e->rtype == EXPR_NUM) {
-       *retval = e->right.num;
+    if (e->op == EXPR_IDENT && e->rtype == EXPR_INT) {
+       *retval = e->right.int_val;
        return 1;
     } else
        return 0;
@@ -296,17 +308,20 @@ expr_print(expr *e)
 {
     if (e->op != EXPR_IDENT) {
        switch (e->ltype) {
-           case EXPR_NUM:
-               printf("%lu", e->left.num);
-               break;
            case EXPR_SYM:
                printf("%s", e->left.sym->name);
                break;
            case EXPR_EXPR:
                printf("(");
-               expr_print(e->left.expr);
-
+               expr_print(e->left.exp);
                printf(")");
+               break;
+           case EXPR_INT:
+               printf("%lu", e->left.int_val);
+               break;
+           case EXPR_FLOAT:
+               floatnum_print(e->left.flt);
+               break;
            case EXPR_NONE:
                break;
        }
@@ -379,17 +394,20 @@ expr_print(expr *e)
            break;
     }
     switch (e->rtype) {
-       case EXPR_NUM:
-           printf("%lu", e->right.num);
-           break;
        case EXPR_SYM:
            printf("%s", e->right.sym->name);
            break;
        case EXPR_EXPR:
            printf("(");
-           expr_print(e->right.expr);
-
+           expr_print(e->right.exp);
            printf(")");
+           break;
+       case EXPR_INT:
+           printf("%lu", e->right.int_val);
+           break;
+       case EXPR_FLOAT:
+           floatnum_print(e->right.flt);
+           break;
        case EXPR_NONE:
            break;
     }
index 8723d8980924b99d12745ee02ddbae842fc12f75..6846fdb23067d0ddce2870898399c0c0f81f8498 100644 (file)
@@ -1,7 +1,7 @@
 /* $IdPath$
  * Expression handling header file
  *
- *  Copyright (C) 2001  Michael Urman
+ *  Copyright (C) 2001  Michael Urman, Peter Johnson
  *
  *  This file is part of YASM.
  *
@@ -49,15 +49,17 @@ typedef enum {
 
 typedef enum {
     EXPR_NONE,                 /* for left side of a NOT, NEG, etc. */
-    EXPR_NUM,
+    EXPR_SYM,
     EXPR_EXPR,
-    EXPR_SYM
+    EXPR_INT,
+    EXPR_FLOAT
 } ExprType;
 
 typedef union expritem_u {
     struct symrec_s *sym;
-    struct expr_s *expr;
-    unsigned long num;
+    struct expr_s *exp;
+    unsigned long int_val;
+    struct floatnum_s *flt;
 } ExprItem;
 
 typedef struct expr_s {
@@ -70,7 +72,8 @@ expr *expr_new(ExprType, ExprItem, ExprOp, ExprType, ExprItem);
 
 ExprItem ExprSym(struct symrec_s *);
 ExprItem ExprExpr(expr *);
-ExprItem ExprNum(unsigned long);
+ExprItem ExprInt(unsigned long);
+ExprItem ExprFloat(struct floatnum_s *);
 ExprItem ExprNone(void);
 
 #define expr_new_tree(l,o,r) \
diff --git a/src/floatnum.c b/src/floatnum.c
new file mode 100644 (file)
index 0000000..bef9080
--- /dev/null
@@ -0,0 +1,77 @@
+/* $IdPath$
+ * Floating point number functions.
+ *
+ *  Copyright (C) 2001  Peter Johnson
+ *
+ *  This file is part of YASM.
+ *
+ *  YASM is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  YASM is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "util.h"
+
+#include <stdio.h>
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+#endif
+
+#include "errwarn.h"
+#include "floatnum.h"
+
+RCSID("$IdPath$");
+
+floatnum *
+floatnum_new(char *str)
+{
+    floatnum *flt = malloc(sizeof(floatnum));
+    if (!flt)
+       Fatal(FATAL_NOMEM);
+    /* TODO */
+    return flt;
+}
+
+unsigned long
+floatnum_get_int(floatnum *flt)
+{
+    return 0;  /* TODO */
+}
+
+unsigned char *
+floatnum_get_single(unsigned char *ptr, floatnum *flt)
+{
+    return ptr;        /* TODO */
+}
+
+unsigned char *
+floatnum_get_double(unsigned char *ptr, floatnum *flt)
+{
+    return ptr;        /* TODO */
+}
+
+unsigned char *
+floatnum_get_extended(unsigned char *ptr, floatnum *flt)
+{
+    return ptr;        /* TODO */
+}
+
+void
+floatnum_print(floatnum *flt)
+{
+    /* TODO */
+}
diff --git a/src/floatnum.h b/src/floatnum.h
new file mode 100644 (file)
index 0000000..bbea975
--- /dev/null
@@ -0,0 +1,37 @@
+/* $IdPath$
+ * Floating point number functions header file.
+ *
+ *  Copyright (C) 2001  Peter Johnson
+ *
+ *  This file is part of YASM.
+ *
+ *  YASM is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  YASM is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef YASM_FLOATNUM_H
+#define YASM_FLOATNUM_H
+
+typedef struct floatnum_s {
+    unsigned char extval[10];      /* float stored in extended precision */
+} floatnum;
+
+floatnum *floatnum_new(char *str);
+unsigned long floatnum_get_int(floatnum *flt);
+unsigned char *floatnum_get_single(unsigned char *ptr, floatnum *flt);
+unsigned char *floatnum_get_double(unsigned char *ptr, floatnum *flt);
+unsigned char *floatnum_get_extended(unsigned char *ptr, floatnum *flt);
+
+void floatnum_print(floatnum *flt);
+
+#endif
index cb596260f8273e9b8e11cf0a911b3c21b0ea27b1..5aa68e6fafe837920870de7f6c13a11851d1fd02 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "globals.h"
 #include "errwarn.h"
+#include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
 
@@ -58,17 +59,15 @@ extern sectionhead nasm_parser_sections;
 extern section *nasm_parser_cur_section;
 extern char *nasm_parser_locallabel_base;
 
+static bytecode *nasm_parser_prev_bc = (bytecode *)NULL;
+static bytecode *nasm_parser_temp_bc;
+
 %}
 
 %union {
     unsigned long int_val;
     char *str_val;
-    double double_val;
-    symrec *sym;
-    struct {
-       char *name;
-       int line;
-    } syminfo;
+    floatnum *flt;
     unsigned char groupdata[4];
     effaddr *ea;
     expr *exp;
@@ -80,7 +79,7 @@ extern char *nasm_parser_locallabel_base;
 }
 
 %token <int_val> INTNUM
-%token <double_val> FLTNUM
+%token <flt> FLTNUM
 %token <str_val> DIRECTIVE_NAME DIRECTIVE_VAL STRING
 %token <int_val> BYTE WORD DWORD QWORD TWORD DQWORD
 %token <int_val> DECLARE_DATA
@@ -96,7 +95,7 @@ extern char *nasm_parser_locallabel_base;
 %token <int_val> REG_AL REG_CL REG_DL REG_BL REG_AH REG_CH REG_DH REG_BH
 %token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
 %token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
-%token <syminfo> ID LOCAL_ID SPECIAL_ID
+%token <str_val> ID LOCAL_ID SPECIAL_ID
 
 /* instruction tokens (dynamically generated) */
 /* @TOKENS@ */
@@ -113,8 +112,7 @@ extern char *nasm_parser_locallabel_base;
 %type <ea> rm8 rm16 rm32 rm64 rm128
 %type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
 %type <exp> expr expr_no_string
-%type <syminfo> explabel
-%type <sym> label_id
+%type <str_val> explabel label_id
 %type <tgt_val> target
 %type <data> dataval
 %type <datahead> datavals
@@ -130,7 +128,10 @@ extern char *nasm_parser_locallabel_base;
 %%
 input: /* empty */
     | input line    {
-       bytecodes_append(&nasm_parser_cur_section->bc, $2);
+       nasm_parser_temp_bc = bytecodes_append(&nasm_parser_cur_section->bc,
+                                              $2);
+       if (nasm_parser_temp_bc)
+           nasm_parser_prev_bc = nasm_parser_temp_bc;
        line_number++;
     }
 ;
@@ -171,25 +172,31 @@ dataval: expr_no_string   { $$ = dataval_new_expr($1); }
     }
 ;
 
-label: label_id            { $1->value = 0; } /* TODO: add pointer to bytecode */
-    | label_id ':'  { $1->value = 0; } /* TODO: add pointer to bytecode */
+label: label_id            {
+       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc);
+    }
+    | label_id ':'  {
+       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc);
+    }
 ;
 
 label_id: ID       {
-       $$ = symrec_define($1.name, SYM_LABEL);
-       nasm_parser_locallabel_base = strdup($1.name);
+       $$ = $1;
+       nasm_parser_locallabel_base = strdup($1);
     }
-    | SPECIAL_ID    { $$ = symrec_define($1.name, SYM_LABEL); }
-    | LOCAL_ID     { $$ = symrec_define($1.name, SYM_LABEL); }
+    | SPECIAL_ID
+    | LOCAL_ID
 ;
 
 /* directives */
 directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']'        {
-       if (strcasecmp($2, "section") == 0)
+       if (strcasecmp($2, "section") == 0) {
            nasm_parser_cur_section = sections_switch(&nasm_parser_sections,
                                                      nasm_parser_objfmt, $3);
-       else
+           nasm_parser_prev_bc = (bytecode *)NULL;
+       } else {
            printf("Directive: Name='%s' Value='%s'\n", $2, $3);
+       }
     }
     | '[' DIRECTIVE_NAME DIRECTIVE_VAL error   {
        Error(_("missing `%c'"), ']');
@@ -375,9 +382,9 @@ target: expr            { $$.val = $1; $$.op_sel = JR_NONE; }
 ;
 
 /* expression trees */
-expr_no_string: INTNUM         { $$ = expr_new_ident(EXPR_NUM, ExprNum($1)); }
+expr_no_string: INTNUM         { $$ = expr_new_ident(EXPR_INT, ExprInt($1)); }
     | explabel                 {
-       $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1.name, SYM_LABEL)));
+       $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1)));
     }
     /*| expr '||' expr         { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
     | expr '|' expr            { $$ = expr_new_tree($1, EXPR_OR, $3); }
@@ -406,7 +413,7 @@ expr_no_string: INTNUM              { $$ = expr_new_ident(EXPR_NUM, ExprNum($1)); }
 
 expr: expr_no_string
     | STRING           {
-       $$ = expr_new_ident (EXPR_NUM, ExprNum(ConvertCharConstToInt($1)));
+       $$ = expr_new_ident (EXPR_INT, ExprInt(ConvertCharConstToInt($1)));
     }
 ;
 
index cb596260f8273e9b8e11cf0a911b3c21b0ea27b1..5aa68e6fafe837920870de7f6c13a11851d1fd02 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "globals.h"
 #include "errwarn.h"
+#include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
 
@@ -58,17 +59,15 @@ extern sectionhead nasm_parser_sections;
 extern section *nasm_parser_cur_section;
 extern char *nasm_parser_locallabel_base;
 
+static bytecode *nasm_parser_prev_bc = (bytecode *)NULL;
+static bytecode *nasm_parser_temp_bc;
+
 %}
 
 %union {
     unsigned long int_val;
     char *str_val;
-    double double_val;
-    symrec *sym;
-    struct {
-       char *name;
-       int line;
-    } syminfo;
+    floatnum *flt;
     unsigned char groupdata[4];
     effaddr *ea;
     expr *exp;
@@ -80,7 +79,7 @@ extern char *nasm_parser_locallabel_base;
 }
 
 %token <int_val> INTNUM
-%token <double_val> FLTNUM
+%token <flt> FLTNUM
 %token <str_val> DIRECTIVE_NAME DIRECTIVE_VAL STRING
 %token <int_val> BYTE WORD DWORD QWORD TWORD DQWORD
 %token <int_val> DECLARE_DATA
@@ -96,7 +95,7 @@ extern char *nasm_parser_locallabel_base;
 %token <int_val> REG_AL REG_CL REG_DL REG_BL REG_AH REG_CH REG_DH REG_BH
 %token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
 %token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
-%token <syminfo> ID LOCAL_ID SPECIAL_ID
+%token <str_val> ID LOCAL_ID SPECIAL_ID
 
 /* instruction tokens (dynamically generated) */
 /* @TOKENS@ */
@@ -113,8 +112,7 @@ extern char *nasm_parser_locallabel_base;
 %type <ea> rm8 rm16 rm32 rm64 rm128
 %type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
 %type <exp> expr expr_no_string
-%type <syminfo> explabel
-%type <sym> label_id
+%type <str_val> explabel label_id
 %type <tgt_val> target
 %type <data> dataval
 %type <datahead> datavals
@@ -130,7 +128,10 @@ extern char *nasm_parser_locallabel_base;
 %%
 input: /* empty */
     | input line    {
-       bytecodes_append(&nasm_parser_cur_section->bc, $2);
+       nasm_parser_temp_bc = bytecodes_append(&nasm_parser_cur_section->bc,
+                                              $2);
+       if (nasm_parser_temp_bc)
+           nasm_parser_prev_bc = nasm_parser_temp_bc;
        line_number++;
     }
 ;
@@ -171,25 +172,31 @@ dataval: expr_no_string   { $$ = dataval_new_expr($1); }
     }
 ;
 
-label: label_id            { $1->value = 0; } /* TODO: add pointer to bytecode */
-    | label_id ':'  { $1->value = 0; } /* TODO: add pointer to bytecode */
+label: label_id            {
+       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc);
+    }
+    | label_id ':'  {
+       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc);
+    }
 ;
 
 label_id: ID       {
-       $$ = symrec_define($1.name, SYM_LABEL);
-       nasm_parser_locallabel_base = strdup($1.name);
+       $$ = $1;
+       nasm_parser_locallabel_base = strdup($1);
     }
-    | SPECIAL_ID    { $$ = symrec_define($1.name, SYM_LABEL); }
-    | LOCAL_ID     { $$ = symrec_define($1.name, SYM_LABEL); }
+    | SPECIAL_ID
+    | LOCAL_ID
 ;
 
 /* directives */
 directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']'        {
-       if (strcasecmp($2, "section") == 0)
+       if (strcasecmp($2, "section") == 0) {
            nasm_parser_cur_section = sections_switch(&nasm_parser_sections,
                                                      nasm_parser_objfmt, $3);
-       else
+           nasm_parser_prev_bc = (bytecode *)NULL;
+       } else {
            printf("Directive: Name='%s' Value='%s'\n", $2, $3);
+       }
     }
     | '[' DIRECTIVE_NAME DIRECTIVE_VAL error   {
        Error(_("missing `%c'"), ']');
@@ -375,9 +382,9 @@ target: expr            { $$.val = $1; $$.op_sel = JR_NONE; }
 ;
 
 /* expression trees */
-expr_no_string: INTNUM         { $$ = expr_new_ident(EXPR_NUM, ExprNum($1)); }
+expr_no_string: INTNUM         { $$ = expr_new_ident(EXPR_INT, ExprInt($1)); }
     | explabel                 {
-       $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1.name, SYM_LABEL)));
+       $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1)));
     }
     /*| expr '||' expr         { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
     | expr '|' expr            { $$ = expr_new_tree($1, EXPR_OR, $3); }
@@ -406,7 +413,7 @@ expr_no_string: INTNUM              { $$ = expr_new_ident(EXPR_NUM, ExprNum($1)); }
 
 expr: expr_no_string
     | STRING           {
-       $$ = expr_new_ident (EXPR_NUM, ExprNum(ConvertCharConstToInt($1)));
+       $$ = expr_new_ident (EXPR_INT, ExprInt(ConvertCharConstToInt($1)));
     }
 ;
 
index 47a6fdb7f5b6fc355bd44cf552c3dd36e90612b5..4f4b72b2df447f16fa8474b1ef8a82740f5c7842 100644 (file)
@@ -35,6 +35,7 @@
 #define _(String)      gettext(String)
 
 #include "errwarn.h"
+#include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
 
@@ -114,7 +115,7 @@ WS       [ \t\r]
 
     /* floating point value */
 {DIGIT}+\.{DIGIT}*(e[-+]?{DIGIT}+)? {
-    yylval.double_val = strtod(yytext, (char **)NULL);
+    yylval.flt = floatnum_new(yytext);
     return FLTNUM;
 }
 
@@ -295,10 +296,9 @@ gs { yylval.int_val = 5; return REG_GS; }
 
     /* special non-local ..@label and labels like ..start */
 $$|$|\.\.[a-z0-9_$#@~.?]+ {
-    yylval.syminfo.name = strdup(yytext);
-    if (!yylval.syminfo.name)
+    yylval.str_val = strdup(yytext);
+    if (!yylval.str_val)
        Fatal(FATAL_NOMEM);
-    yylval.syminfo.line = line_number;
 
     return SPECIAL_ID;
 }
@@ -307,18 +307,17 @@ $$|$|\.\.[a-z0-9_$#@~.?]+ {
 \.[a-z0-9_$#@~?][a-z0-9_$#@~.?]* {
     if (!nasm_parser_locallabel_base) {
        Warning(_("no non-local label before `%s'"), yytext);
-       yylval.syminfo.name = strdup(yytext);
-       if (!yylval.syminfo.name)
+       yylval.str_val = strdup(yytext);
+       if (!yylval.str_val)
            Fatal(FATAL_NOMEM);
     } else {
-       yylval.syminfo.name = malloc(strlen(yytext) +
-                                    strlen(nasm_parser_locallabel_base) + 1);
-       if (!yylval.syminfo.name)
+       yylval.str_val = malloc(strlen(yytext) +
+                               strlen(nasm_parser_locallabel_base) + 1);
+       if (!yylval.str_val)
            Fatal(FATAL_NOMEM);
-       strcpy(yylval.syminfo.name, nasm_parser_locallabel_base);
-       strcat(yylval.syminfo.name, yytext);
+       strcpy(yylval.str_val, nasm_parser_locallabel_base);
+       strcat(yylval.str_val, yytext);
     }
-    yylval.syminfo.line = line_number;
 
     return LOCAL_ID;
 }
@@ -328,10 +327,9 @@ $$|$|\.\.[a-z0-9_$#@~.?]+ {
 
     /* label */
 [a-z_?][a-z0-9_$#@~.?]* {
-    yylval.syminfo.name = strdup(yytext);
-    if (!yylval.syminfo.name)
+    yylval.str_val = strdup(yytext);
+    if (!yylval.str_val)
        Fatal(FATAL_NOMEM);
-    yylval.syminfo.line = line_number;
 
     return ID;
 }
index 2196638e4c5eb9e931a1508fdc56891688b8dfd4..2c7947cd498281be1116e503ea21a0d6f9503426 100644 (file)
@@ -1,7 +1,7 @@
 /* $IdPath$
  * Symbol table handling
  *
- *  Copyright (C) 2001  Michael Urman
+ *  Copyright (C) 2001  Michael Urman, Peter Johnson
  *
  *  This file is part of YASM.
  *
 
 #include "globals.h"
 #include "errwarn.h"
+#include "floatnum.h"
 #include "symrec.h"
 
+#include "bytecode.h"
+#include "section.h"
+
 RCSID("$IdPath$");
 
 /* private functions */
-static symrec *symrec_get_or_new(char *, SymType);
+static symrec *symrec_get_or_new(const char *);
+static symrec *symrec_define(const char *, SymType type);
 
 /* The symbol table: a ternary tree. */
 static ternary_tree sym_table = (ternary_tree)NULL;
 
 /* create a new symrec */
 static symrec *
-symrec_get_or_new(char *name, SymType type)
+symrec_get_or_new(const char *name)
 {
     symrec *rec, *rec2;
 
@@ -65,41 +70,128 @@ symrec_get_or_new(char *name, SymType type)
     rec->name = strdup(name);
     if (!rec->name)
        Fatal(FATAL_NOMEM);
-    rec->type = type;
-    rec->value = 0;
+    rec->type = SYM_UNKNOWN;
     rec->filename = strdup(filename);
     rec->line = line_number;
     rec->status = SYM_NOSTATUS;
+    rec->visibility = SYM_LOCAL;
 
     return rec;
 }
 
 /* call a function with each symrec.  stop early if 0 returned */
 void
-symrec_foreach(int (*func) (char *name, symrec *rec))
+symrec_foreach(int (*func) (const char *name, symrec *rec))
 {
+    /* TODO */
 }
 
 symrec *
-symrec_use(char *name, SymType type)
+symrec_use(const char *name)
 {
-    symrec *rec;
+    symrec *rec = symrec_get_or_new(name);
 
-    rec = symrec_get_or_new(name, type);
     rec->status |= SYM_USED;
     return rec;
 }
 
+static symrec *
+symrec_define(const char *name, SymType type)
+{
+    symrec *rec = symrec_get_or_new(name);
+
+    /* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */
+    if (rec->status & SYM_DEFINED) {
+       Error(_("duplicate definition of `%s'; first defined on line %d"),
+             name, rec->line);
+    } else {
+       rec->line = line_number;        /* set line number of definition */
+       rec->type = type;
+       rec->status |= SYM_DEFINED;
+    }
+    return rec;
+}
+
+symrec *
+symrec_define_constant_int(const char *name, unsigned long int_val)
+{
+    symrec *rec = symrec_define(name, SYM_CONSTANT_INT);
+    rec->value.int_val = int_val;
+    rec->status |= SYM_VALUED;
+    return rec;
+}
+
 symrec *
-symrec_define(char *name, SymType type)
+symrec_define_constant_float(const char *name, floatnum *flt)
 {
-    symrec *rec;
+    symrec *rec = symrec_define(name, SYM_CONSTANT_FLOAT);
+    rec->value.flt = flt;
+    rec->status |= SYM_VALUED;
+    return rec;
+}
 
-    rec = symrec_get_or_new(name, type);
-    if (rec->status & SYM_DECLARED)
-       Error(_("duplicate definition of `%s'; previously defined on line %d"),
+symrec *
+symrec_define_label(const char *name, section *sect, bytecode *precbc)
+{
+    symrec *rec = symrec_define(name, SYM_LABEL);
+    rec->value.label.sect = sect;
+    rec->value.label.bc = precbc;
+    return rec;
+}
+
+symrec *
+symrec_declare(const char *name, SymVisibility vis)
+{
+    symrec *rec = symrec_get_or_new(name);
+
+    /* Don't allow EXTERN and COMMON if symbol has already been DEFINED. */
+    /* Also, EXTERN and COMMON are mutually exclusive. */
+    if ((rec->status & SYM_DEFINED) ||
+       ((rec->visibility & SYM_COMMON) && (vis == SYM_EXTERN)) ||
+       ((rec->visibility & SYM_EXTERN) && (vis == SYM_COMMON))) {
+       Error(_("duplicate definition of `%s'; first defined on line %d"),
              name, rec->line);
-    rec->line = line_number;   /* set line number of definition */
-    rec->status |= SYM_DECLARED;
+    } else {
+       rec->line = line_number;        /* set line number of declaration */
+       rec->visibility |= vis;
+
+       /* If declared as COMMON or EXTERN, set as DEFINED. */
+       if ((vis == SYM_COMMON) || (vis == SYM_EXTERN))
+           rec->status |= SYM_DEFINED;
+    }
     return rec;
 }
+
+int
+symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
+                    int resolve_label)
+{
+    /* If we already know the value, just return it. */
+    if (sym->status & SYM_VALUED) {
+       switch (sym->type) {
+           case SYM_CONSTANT_INT:
+               *ret_val = sym->value.int_val;
+               break;
+           case SYM_CONSTANT_FLOAT:
+               *ret_val = floatnum_get_int(sym->value.flt);
+               break;
+           case SYM_LABEL:
+               if (!bytecode_get_offset(sym->value.label.sect,
+                                        sym->value.label.bc, ret_val))
+                   InternalError(__LINE__, __FILE__,
+                                 _("Label symbol is valued but cannot get offset"));
+           case SYM_UNKNOWN:
+               InternalError(__LINE__, __FILE__,
+                             _("Have a valued symbol but of unknown type"));
+       }
+       return 1;
+    }
+
+    /* Try to get offset of unvalued label */
+    if (resolve_label && sym->type == SYM_LABEL)
+       return bytecode_get_offset(sym->value.label.sect, sym->value.label.bc,
+                                  ret_val);
+
+    /* We can't get the value right now. */
+    return 0;
+}
index fd2e5c387ac70b178fd74e996bc3c849a258d71e..21183f4bdf8c6de433ea13a97025b26a8bc19458 100644 (file)
@@ -1,7 +1,7 @@
 /* $IdPath$
  * Symbol table handling header file
  *
- *  Copyright (C) 2001  Michael Urman
+ *  Copyright (C) 2001  Michael Urman, Peter Johnson
  *
  *  This file is part of YASM.
  *
 #ifndef YASM_SYMREC_H
 #define YASM_SYMREC_H
 
+/* DEFINED is set with EXTERN and COMMON below */
 typedef enum {
     SYM_NOSTATUS = 0,
-    SYM_USED = 1 << 0,         /* for using variables before declared */
-    SYM_DECLARED = 1 << 1,     /* once it's been declared */
+    SYM_USED = 1 << 0,         /* for using variables before definition */
+    SYM_DEFINED = 1 << 1,      /* once it's been defined in the file */
     SYM_VALUED = 1 << 2                /* once its value has been determined */
 } SymStatus;
 
+/* EXTERN and COMMON are mutually exclusive */
 typedef enum {
-    SYM_CONSTANT,              /* for EQU defined symbols */
+    SYM_LOCAL = 0,             /* default, local only */
+    SYM_GLOBAL = 1 << 0,       /* if it's declared GLOBAL */
+    SYM_COMMON = 1 << 1,       /* if it's declared COMMON */
+    SYM_EXTERN = 1 << 2                /* if it's declared EXTERN */
+} SymVisibility;
+
+typedef enum {
+    SYM_UNKNOWN,               /* for unknown type (COMMON/EXTERN) */
+    SYM_CONSTANT_INT,          /* for EQU defined symbols (integers) */
+    SYM_CONSTANT_FLOAT,                /*  (floating point) */
     SYM_LABEL                  /* for labels */
 } SymType;
 
@@ -38,13 +49,34 @@ typedef struct symrec_s {
     char *name;
     SymType type;
     SymStatus status;
+    SymVisibility visibility;
     char *filename;            /* file and line */
-    int line;                  /*  symbol was first declared or used on */
-    double value;
+    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;
 
-symrec *symrec_use(char *name, SymType type);
-symrec *symrec_define(char *name, SymType type);
-void symrec_foreach(int (*func) (char *name, symrec *rec));
+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_declare(const char *name, SymVisibility vis);
+
+/* Get the numeric 32-bit value of a symbol if possible.
+ * Return value is IF POSSIBLE, not the value.
+ * If resolve_label is true, tries to get offset of labels, otherwise it
+ * returns not possible.
+ */
+int symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
+                        int resolve_label);
+
+void symrec_foreach(int (*func) (const char *name, symrec *rec));
 
 #endif