]> granicus.if.org Git - yasm/commitdiff
Added handling of labels including:
authorMichael Urman <mu@tortall.net>
Wed, 13 Jun 2001 05:43:59 +0000 (05:43 -0000)
committerMichael Urman <mu@tortall.net>
Wed, 13 Jun 2001 05:43:59 +0000 (05:43 -0000)
  better symbol table functions
  calling them from yacc rather than lex
  a new warning for .label before normal_label
  locallabel_base now a symrec* instead of a strdup'd string.

Still needs some more error checking (to not allow multiple copies of
the same label, etc.)

Also includes move to y_strdup for bison.y.in (ANSI compatibility)

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

22 files changed:
include/errwarn.h
include/globals.h
include/symrec.h
libyasm/errwarn.c
libyasm/errwarn.h
libyasm/linemgr.h
libyasm/symrec.c
libyasm/symrec.h
modules/parsers/nasm/bison.y.in
modules/parsers/nasm/nasm-bison.y
modules/parsers/nasm/token.l.in
src/bison.y.in
src/errwarn.c
src/errwarn.h
src/globals.h
src/linemgr.h
src/parsers/nasm/bison.y.in
src/parsers/nasm/nasm-bison.y
src/parsers/nasm/token.l.in
src/symrec.c
src/symrec.h
src/token.l.in

index d46703a0000e363eb0c771847069df886070784a..bad9abbd5dac96842d6761ada29b7e8369a6d661 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: errwarn.h,v 1.4 2001/05/30 07:38:42 peter Exp $
+/* $Id: errwarn.h,v 1.5 2001/06/13 05:43:59 mu Exp $
  * Error and warning reporting and related functions header file.
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -49,7 +49,8 @@ typedef enum {
     WARN_UNREC_CHAR,
     WARN_VALUE_EXCEEDS_BOUNDS,
     WARN_MULT_SEG_OVERRIDE,
-    WARN_MULT_LOCKREP_PREFIX
+    WARN_MULT_LOCKREP_PREFIX,
+    WARN_NO_BASE_LABEL
 } warn_num;
 
 void Warning(warn_num, char *, ...);
index 8aee77cf943d6dc08e228d9ce765250a3483f3e0..8e183374ab50d6573883935423adef1bfc67427a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: globals.h,v 1.1 2001/05/15 05:28:06 peter Exp $
+/* $Id: globals.h,v 1.2 2001/06/13 05:43:59 mu Exp $
  * Globals header file
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -24,5 +24,6 @@
 
 extern unsigned int line_number;
 extern unsigned int mode_bits;
+extern struct symrec_s *locallabel_base;
 
 #endif
index 0ad25246c2bad00aff33be45805493e7c60007a2..525c4bd5824c57c2dd043cabad7160fac214d618 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: symrec.h,v 1.2 2001/05/18 21:40:54 peter Exp $
+/* $Id: symrec.h,v 1.3 2001/06/13 05:43:59 mu Exp $
  * Symbol table handling header file
  *
- *  Copyright (C) 2001  Peter Johnson
+ *  Copyright (C) 2001  Michael Urman
  *
  *  This file is part of YASM.
  *
 #ifndef _SYMREC_H_
 #define _SYMREC_H_
 
+typedef enum {
+    SYM_NOSTATUS = 0,
+    SYM_USED    = 1 << 0,  /* for using variables before declared */
+    SYM_DECLARED = 1 << 1,  /* once it's been declared */
+    SYM_VALUED  = 1 << 2   /* once its value has been determined */
+} SymStatus;
+
+typedef enum {
+    SYM_CONSTANT,          /* for EQU defined symbols */
+    SYM_LABEL,             /* for labels */
+    SYM_DATA               /* for variables */
+} SymType;
+
 typedef struct symrec_s {
     char *name;
-    int type;
-    union {
-       double var;
-       double (*fnctptr)(void);
-    } value;
-    struct symrec_s *next;
+    SymType type;
+    SymStatus status;
+    int line;
+    double value;
 } symrec;
 
-extern symrec *sym_table;
+typedef struct symtab_s {
+    symrec rec;
+    struct symtab_s *next;
+} symtab;
+
+extern symtab *sym_table;
+
+/*symrec *putsym(char *, SymType);*/
+/*symrec *getsym(char *);*/
 
-symrec *putsym(char *, int);
-symrec *getsym(char *);
+symrec *sym_use_get (char *, SymType);
+symrec *sym_def_get (char *, SymType);
+void sym_foreach (int(*)(symrec *));
 
 #endif
index fb7b71d2d5b465cc01b777508326076f0c303941..2c4983eeba4710d820203026f4bd0520d8b9f88c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: errwarn.c,v 1.5 2001/05/30 07:38:42 peter Exp $
+/* $Id: errwarn.c,v 1.6 2001/06/13 05:43:59 mu Exp $
  * Error and warning reporting and related functions.
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -51,7 +51,8 @@ static char *warn_msgs[] = {
     "ignoring unrecognized character '%s'",
     "%s value exceeds bounds",
     "multiple segment overrides, using leftmost",
-    "multiple LOCK or REP prefixes, using leftmost"
+    "multiple LOCK or REP prefixes, using leftmost",
+    "no non-local label before '%s'"
 };
 
 /* hate to define these as static buffers; better solution would be to use
index d46703a0000e363eb0c771847069df886070784a..bad9abbd5dac96842d6761ada29b7e8369a6d661 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: errwarn.h,v 1.4 2001/05/30 07:38:42 peter Exp $
+/* $Id: errwarn.h,v 1.5 2001/06/13 05:43:59 mu Exp $
  * Error and warning reporting and related functions header file.
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -49,7 +49,8 @@ typedef enum {
     WARN_UNREC_CHAR,
     WARN_VALUE_EXCEEDS_BOUNDS,
     WARN_MULT_SEG_OVERRIDE,
-    WARN_MULT_LOCKREP_PREFIX
+    WARN_MULT_LOCKREP_PREFIX,
+    WARN_NO_BASE_LABEL
 } warn_num;
 
 void Warning(warn_num, char *, ...);
index ba42d1099711dec0ff7b729f3fe0b63ba0652ba1..81208ecb967227db95705e57b0f2c8949baa6abd 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: linemgr.h,v 1.1 2001/05/15 05:28:06 peter Exp $
+/* $Id: linemgr.h,v 1.2 2001/06/13 05:43:59 mu Exp $
  * Globals header file
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -24,5 +24,6 @@
 
 extern unsigned int line_number;
 extern unsigned int mode_bits;
+extern struct symrec_s *locallabel_base;
 
 #endif
index aff2e6eac49d44ad0fb38e27f6a2d27df4085b70..12a7ba462cfdac4e72befd5a265a8f1e69d66d05 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: symrec.c,v 1.1 2001/05/15 05:24:04 peter Exp $
+/* $Id: symrec.c,v 1.2 2001/06/13 05:43:59 mu Exp $
  * Symbol table handling
  *
- *  Copyright (C) 2001  Peter Johnson
+ *  Copyright (C) 2001  Michael Urman
  *
  *  This file is part of YASM.
  *
 #include <stdlib.h>
 #include <string.h>
 #include "symrec.h"
+#include "globals.h"
+#include "errwarn.h"
 
-/* The symbol table: a chain of `symrec'. */
-symrec *sym_table = (symrec *)NULL;
+/* private functions */
+static symtab *symtab_get (char *);
+static symtab *symtab_new (char *, SymType);
+static symtab *symtab_get_or_new (char *, SymType);
+static void symtab_insert (symtab *);
 
+/* The symbol table: a chain of `symtab'. */
+symtab *sym_table = (symtab *)NULL;
+
+/* insert a symtab into the global sym_table */
+void symtab_insert (symtab *tab)
+{
+    tab->next = (symtab *)sym_table;
+    sym_table = tab;
+}
+
+/* find a symtab in the global sym_table */
+symtab *symtab_get (char *name)
+{
+    symtab *tab;
+    for (tab = sym_table; tab != NULL; tab = tab->next)
+    {
+       if (strcmp (tab->rec.name, name) == 0)
+       {
+           return tab;
+       }
+    }
+    return NULL;
+}
+
+/* call a function with each symrec.  stop early if 0 returned */
+void sym_foreach (int(*mapfunc)(symrec *))
+{
+    symtab *tab;
+    for (tab = sym_table; tab != NULL; tab = tab->next)
+    {
+       if (mapfunc(&(tab->rec)) == 0)
+       {
+           return;
+       }
+    }
+}
+
+/* create a new symtab */
+symtab *symtab_new (char *name, SymType type)
+{
+    symtab *tab;
+    tab = malloc(sizeof(symtab));
+    if (tab == NULL) return NULL;
+    tab->rec.name = malloc(strlen(name)+1);
+    if (tab->rec.name == NULL)
+    {
+       free (tab);
+       return NULL;
+    }
+    strcpy(tab->rec.name, name);
+    tab->rec.type = type;
+    tab->rec.value = 0;
+    tab->rec.line = line_number;
+    tab->rec.status = SYM_NOSTATUS;
+    symtab_insert (tab);
+    return tab;
+}
+
+symtab *symtab_get_or_new (char *name, SymType type)
+{
+    symtab *tab;
+    tab = symtab_get (name);
+    if (tab == NULL)
+    {
+       tab = symtab_new (name, type);
+       if (tab == NULL)
+       {
+           Fatal (FATAL_NOMEM);
+       }
+    }
+    return tab;
+}
+
+symrec *sym_use_get (char *name, SymType type)
+{
+    symtab *tab;
+    tab = symtab_get_or_new (name, type);
+    tab->rec.status |= SYM_USED;
+    return &(tab->rec);
+}
+
+symrec *sym_def_get (char *name, SymType type)
+{
+    symtab *tab;
+    tab = symtab_get_or_new (name, type);
+    tab->rec.status |= SYM_DECLARED;
+    return &(tab->rec);
+}
+
+#if 0
 symrec *putsym(char *sym_name, int sym_type)
 {
     symrec *ptr;
@@ -47,4 +142,4 @@ symrec *getsym(char *sym_name)
            return ptr;
     return 0;
 }
-
+#endif /* 0 */
index 0ad25246c2bad00aff33be45805493e7c60007a2..525c4bd5824c57c2dd043cabad7160fac214d618 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: symrec.h,v 1.2 2001/05/18 21:40:54 peter Exp $
+/* $Id: symrec.h,v 1.3 2001/06/13 05:43:59 mu Exp $
  * Symbol table handling header file
  *
- *  Copyright (C) 2001  Peter Johnson
+ *  Copyright (C) 2001  Michael Urman
  *
  *  This file is part of YASM.
  *
 #ifndef _SYMREC_H_
 #define _SYMREC_H_
 
+typedef enum {
+    SYM_NOSTATUS = 0,
+    SYM_USED    = 1 << 0,  /* for using variables before declared */
+    SYM_DECLARED = 1 << 1,  /* once it's been declared */
+    SYM_VALUED  = 1 << 2   /* once its value has been determined */
+} SymStatus;
+
+typedef enum {
+    SYM_CONSTANT,          /* for EQU defined symbols */
+    SYM_LABEL,             /* for labels */
+    SYM_DATA               /* for variables */
+} SymType;
+
 typedef struct symrec_s {
     char *name;
-    int type;
-    union {
-       double var;
-       double (*fnctptr)(void);
-    } value;
-    struct symrec_s *next;
+    SymType type;
+    SymStatus status;
+    int line;
+    double value;
 } symrec;
 
-extern symrec *sym_table;
+typedef struct symtab_s {
+    symrec rec;
+    struct symtab_s *next;
+} symtab;
+
+extern symtab *sym_table;
+
+/*symrec *putsym(char *, SymType);*/
+/*symrec *getsym(char *);*/
 
-symrec *putsym(char *, int);
-symrec *getsym(char *);
+symrec *sym_use_get (char *, SymType);
+symrec *sym_def_get (char *, SymType);
+void sym_foreach (int(*)(symrec *));
 
 #endif
index 6820f05df72dfd48111b0d57f280df3b14df429e..bb0b71bb82b43f75b5082bd8222768c64ab6aa12 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: bison.y.in,v 1.9 2001/05/30 07:41:27 peter Exp $
+/* $Id: bison.y.in,v 1.10 2001/06/13 05:43:59 mu Exp $
  * Main bison parser
  *
- *  Copyright (C) 2001  Peter Johnson
+ *  Copyright (C) 2001  Peter Johnson, Michael Urman
  *
  *  This file is part of YASM.
  *
@@ -40,6 +40,10 @@ extern void yyerror(char *);
     char *str_val;
     double double_val;
     symrec *sym;
+    struct {
+       char *name;
+       int line;
+    } syminfo;
     effaddr ea_val;
     immval im_val;
     bytecode bc;
@@ -63,14 +67,14 @@ extern void yyerror(char *);
 %token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
 %token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
 %token START_SECTION_OFFSET ENTRY_POINT
-%token <symID
+%token <syminfo> ID LOCAL_ID SPECIAL_ID
 
 /* instruction tokens (dynamically generated) */
 /* @TOKENS@ */
 
 /* @TYPES@ */
 
-%type <bc> line exp instr instrbase
+%type <bc> line exp instr instrbase label
 
 %type <int_val> fpureg reg32 reg16 reg8 segreg
 %type <ea_val> mem memaddr memexp
@@ -79,6 +83,7 @@ extern void yyerror(char *);
 %type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
 %type <ea_val> rm8 rm16 rm32 rm64 rm128
 %type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <sym> label_id
 
 %left '-' '+'
 %left '*' '/'
@@ -90,6 +95,8 @@ input: /* empty */
 
 line: '\n'     { $$.len = 0; }
     | exp '\n' { DebugPrintBC(&$1); $$ = $1; }
+    | label exp '\n' { DebugPrintBC(&$2); $$ = $2; }
+    | label '\n'
     | directive '\n' { }
     | error '\n' { Error(ERR_INVALID_LINE, (char *)NULL); yyerrok; }
 ;
@@ -97,6 +104,15 @@ line: '\n'  { $$.len = 0; }
 exp: instr
 ;
 
+label: label_id { $1->value = 0; } /* TODO: calculate offset */
+    | label_id ':' { $1->value = 0; } /* TODO: calculate offset */
+;
+
+label_id: ID { $$ = locallabel_base = sym_def_get ($1.name, SYM_LABEL); }
+    | SPECIAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
+    | LOCAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
+;
+
 /* directives */
 directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']' {
        printf("Directive: Name='%s' Value='%s'\n", $2, $3);
index 1c9cd278488fafb29910bfe9c401b14bcdbfeb78..ef594f2a28c1e2f426da93bd9b570d88f426b716 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: nasm-bison.y,v 1.9 2001/05/30 07:41:27 peter Exp $
+/* $Id: nasm-bison.y,v 1.10 2001/06/13 05:43:59 mu Exp $
  * Main bison parser
  *
- *  Copyright (C) 2001  Peter Johnson
+ *  Copyright (C) 2001  Peter Johnson, Michael Urman
  *
  *  This file is part of YASM.
  *
@@ -40,6 +40,10 @@ extern void yyerror(char *);
     char *str_val;
     double double_val;
     symrec *sym;
+    struct {
+       char *name;
+       int line;
+    } syminfo;
     effaddr ea_val;
     immval im_val;
     bytecode bc;
@@ -63,14 +67,14 @@ extern void yyerror(char *);
 %token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
 %token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
 %token START_SECTION_OFFSET ENTRY_POINT
-%token <symID
+%token <syminfo> ID LOCAL_ID SPECIAL_ID
 
 /* instruction tokens (dynamically generated) */
 /* @TOKENS@ */
 
 /* @TYPES@ */
 
-%type <bc> line exp instr instrbase
+%type <bc> line exp instr instrbase label
 
 %type <int_val> fpureg reg32 reg16 reg8 segreg
 %type <ea_val> mem memaddr memexp
@@ -79,6 +83,7 @@ extern void yyerror(char *);
 %type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
 %type <ea_val> rm8 rm16 rm32 rm64 rm128
 %type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <sym> label_id
 
 %left '-' '+'
 %left '*' '/'
@@ -90,6 +95,8 @@ input: /* empty */
 
 line: '\n'     { $$.len = 0; }
     | exp '\n' { DebugPrintBC(&$1); $$ = $1; }
+    | label exp '\n' { DebugPrintBC(&$2); $$ = $2; }
+    | label '\n'
     | directive '\n' { }
     | error '\n' { Error(ERR_INVALID_LINE, (char *)NULL); yyerrok; }
 ;
@@ -97,6 +104,15 @@ line: '\n'  { $$.len = 0; }
 exp: instr
 ;
 
+label: label_id { $1->value = 0; } /* TODO: calculate offset */
+    | label_id ':' { $1->value = 0; } /* TODO: calculate offset */
+;
+
+label_id: ID { $$ = locallabel_base = sym_def_get ($1.name, SYM_LABEL); }
+    | SPECIAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
+    | LOCAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
+;
+
 /* directives */
 directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']' {
        printf("Directive: Name='%s' Value='%s'\n", $2, $3);
index 2ceff815c268cb3f7156892df613e1fca70358d8..7aa6cc96e6ba1c8d4987b8095253405803829b43 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: token.l.in,v 1.5 2001/05/21 22:10:02 peter Exp $
+/* $Id: token.l.in,v 1.6 2001/06/13 05:43:59 mu Exp $
  * Main lexer
  *
  *  Copyright (C) 2001  Peter Johnson
 #include "symrec.h"
 #include "bytecode.h"
 #include "errwarn.h"
+#include "util.h"
 #include "bison.tab.h"
 
 %}
 %option noyywrap
 %option nounput
 %option case-insensitive
-    static char *locallabel_base = (char *)NULL;
+    symrec *locallabel_base = (symrec *)NULL;
+    int line_number;
 
 %x DIRECTIVE DIRECTIVE2
 
@@ -88,14 +90,14 @@ WS       [ \t\r]
 <DIRECTIVE2>{WS}+   ;
 <DIRECTIVE>[a-z]+   {
     BEGIN DIRECTIVE2;
-    yylval.str_val = strdup(yytext);
+    yylval.str_val = y_strdup(yytext);
     if(!yylval.str_val)
        Fatal(FATAL_NOMEM);
     return DIRECTIVE_NAME;
 }
     /* everything printable except for ' ', '[' and ']'. */
 <DIRECTIVE2>[!-@a-z\\^-`{|}~]+ {
-    yylval.str_val = strdup(yytext);
+    yylval.str_val = y_strdup(yytext);
     if(!yylval.str_val)
        Fatal(FATAL_NOMEM);
     return DIRECTIVE_VAL;
@@ -220,21 +222,33 @@ gs        { yylval.int_val = 5; return REG_GS; }
 
     /* special non-local ..@label */
 \.\.@[a-z0-9_$#@~.?]+ {
-    symrec *s = getsym(yytext);
-    if(!s)
-       s = putsym(yytext, ID);
-    yylval.sym = s;
-    return s->type;
+    yylval.syminfo.name = y_strdup (yytext);
+    if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
+    yylval.syminfo.line = line_number;
+
+    return SPECIAL_ID;
 }
 
     /* local label (.label) */
 \.[a-z0-9_$#@~?][a-z0-9_$#@~.?]* {
-    /* TODO: append yytext to locallabel_base before testing */
-    symrec *s = getsym(yytext);
-    if(!s)
-       s = putsym(yytext, ID);
-    yylval.sym = s;
-    return s->type;
+    if (locallabel_base == NULL) 
+    {
+       Warning (WARN_NO_BASE_LABEL, (char *)NULL, yytext);
+       yylval.syminfo.name = y_strdup (yytext);
+       if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
+    }
+    else
+    {
+       yylval.syminfo.name = malloc (strlen (yytext)
+                                 + strlen (locallabel_base->name)
+                                 + 1);
+       if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
+       strcpy (yylval.syminfo.name, locallabel_base->name);
+       strcat (yylval.syminfo.name, yytext);
+    }
+    yylval.syminfo.line = line_number;
+
+    return LOCAL_ID;
 }
 
     /* instructions */
@@ -242,19 +256,11 @@ gs        { yylval.int_val = 5; return REG_GS; }
 
     /* label */
 [a-z_?][a-z0-9_$#@~.?]* {
-    symrec *s = getsym(yytext);
-    if(!s)
-       s = putsym(yytext, ID);
-    yylval.sym = s;
-
-    /* TODO: optimize to decrease number of allocations */
-    if(locallabel_base)
-       free(locallabel_base);
-    locallabel_base = strdup(yytext);
-    if(!locallabel_base)
-       Fatal(FATAL_NOMEM);
+    yylval.syminfo.name = y_strdup (yytext);
+    if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
+    yylval.syminfo.line = line_number;
 
-    return s->type;
+    return ID;
 }
 
 ;.*    ;
index 6820f05df72dfd48111b0d57f280df3b14df429e..bb0b71bb82b43f75b5082bd8222768c64ab6aa12 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: bison.y.in,v 1.9 2001/05/30 07:41:27 peter Exp $
+/* $Id: bison.y.in,v 1.10 2001/06/13 05:43:59 mu Exp $
  * Main bison parser
  *
- *  Copyright (C) 2001  Peter Johnson
+ *  Copyright (C) 2001  Peter Johnson, Michael Urman
  *
  *  This file is part of YASM.
  *
@@ -40,6 +40,10 @@ extern void yyerror(char *);
     char *str_val;
     double double_val;
     symrec *sym;
+    struct {
+       char *name;
+       int line;
+    } syminfo;
     effaddr ea_val;
     immval im_val;
     bytecode bc;
@@ -63,14 +67,14 @@ extern void yyerror(char *);
 %token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
 %token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
 %token START_SECTION_OFFSET ENTRY_POINT
-%token <symID
+%token <syminfo> ID LOCAL_ID SPECIAL_ID
 
 /* instruction tokens (dynamically generated) */
 /* @TOKENS@ */
 
 /* @TYPES@ */
 
-%type <bc> line exp instr instrbase
+%type <bc> line exp instr instrbase label
 
 %type <int_val> fpureg reg32 reg16 reg8 segreg
 %type <ea_val> mem memaddr memexp
@@ -79,6 +83,7 @@ extern void yyerror(char *);
 %type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
 %type <ea_val> rm8 rm16 rm32 rm64 rm128
 %type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <sym> label_id
 
 %left '-' '+'
 %left '*' '/'
@@ -90,6 +95,8 @@ input: /* empty */
 
 line: '\n'     { $$.len = 0; }
     | exp '\n' { DebugPrintBC(&$1); $$ = $1; }
+    | label exp '\n' { DebugPrintBC(&$2); $$ = $2; }
+    | label '\n'
     | directive '\n' { }
     | error '\n' { Error(ERR_INVALID_LINE, (char *)NULL); yyerrok; }
 ;
@@ -97,6 +104,15 @@ line: '\n'  { $$.len = 0; }
 exp: instr
 ;
 
+label: label_id { $1->value = 0; } /* TODO: calculate offset */
+    | label_id ':' { $1->value = 0; } /* TODO: calculate offset */
+;
+
+label_id: ID { $$ = locallabel_base = sym_def_get ($1.name, SYM_LABEL); }
+    | SPECIAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
+    | LOCAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
+;
+
 /* directives */
 directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']' {
        printf("Directive: Name='%s' Value='%s'\n", $2, $3);
index fb7b71d2d5b465cc01b777508326076f0c303941..2c4983eeba4710d820203026f4bd0520d8b9f88c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: errwarn.c,v 1.5 2001/05/30 07:38:42 peter Exp $
+/* $Id: errwarn.c,v 1.6 2001/06/13 05:43:59 mu Exp $
  * Error and warning reporting and related functions.
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -51,7 +51,8 @@ static char *warn_msgs[] = {
     "ignoring unrecognized character '%s'",
     "%s value exceeds bounds",
     "multiple segment overrides, using leftmost",
-    "multiple LOCK or REP prefixes, using leftmost"
+    "multiple LOCK or REP prefixes, using leftmost",
+    "no non-local label before '%s'"
 };
 
 /* hate to define these as static buffers; better solution would be to use
index d46703a0000e363eb0c771847069df886070784a..bad9abbd5dac96842d6761ada29b7e8369a6d661 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: errwarn.h,v 1.4 2001/05/30 07:38:42 peter Exp $
+/* $Id: errwarn.h,v 1.5 2001/06/13 05:43:59 mu Exp $
  * Error and warning reporting and related functions header file.
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -49,7 +49,8 @@ typedef enum {
     WARN_UNREC_CHAR,
     WARN_VALUE_EXCEEDS_BOUNDS,
     WARN_MULT_SEG_OVERRIDE,
-    WARN_MULT_LOCKREP_PREFIX
+    WARN_MULT_LOCKREP_PREFIX,
+    WARN_NO_BASE_LABEL
 } warn_num;
 
 void Warning(warn_num, char *, ...);
index 8aee77cf943d6dc08e228d9ce765250a3483f3e0..8e183374ab50d6573883935423adef1bfc67427a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: globals.h,v 1.1 2001/05/15 05:28:06 peter Exp $
+/* $Id: globals.h,v 1.2 2001/06/13 05:43:59 mu Exp $
  * Globals header file
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -24,5 +24,6 @@
 
 extern unsigned int line_number;
 extern unsigned int mode_bits;
+extern struct symrec_s *locallabel_base;
 
 #endif
index ba42d1099711dec0ff7b729f3fe0b63ba0652ba1..81208ecb967227db95705e57b0f2c8949baa6abd 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: linemgr.h,v 1.1 2001/05/15 05:28:06 peter Exp $
+/* $Id: linemgr.h,v 1.2 2001/06/13 05:43:59 mu Exp $
  * Globals header file
  *
  *  Copyright (C) 2001  Peter Johnson
@@ -24,5 +24,6 @@
 
 extern unsigned int line_number;
 extern unsigned int mode_bits;
+extern struct symrec_s *locallabel_base;
 
 #endif
index 6820f05df72dfd48111b0d57f280df3b14df429e..bb0b71bb82b43f75b5082bd8222768c64ab6aa12 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: bison.y.in,v 1.9 2001/05/30 07:41:27 peter Exp $
+/* $Id: bison.y.in,v 1.10 2001/06/13 05:43:59 mu Exp $
  * Main bison parser
  *
- *  Copyright (C) 2001  Peter Johnson
+ *  Copyright (C) 2001  Peter Johnson, Michael Urman
  *
  *  This file is part of YASM.
  *
@@ -40,6 +40,10 @@ extern void yyerror(char *);
     char *str_val;
     double double_val;
     symrec *sym;
+    struct {
+       char *name;
+       int line;
+    } syminfo;
     effaddr ea_val;
     immval im_val;
     bytecode bc;
@@ -63,14 +67,14 @@ extern void yyerror(char *);
 %token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
 %token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
 %token START_SECTION_OFFSET ENTRY_POINT
-%token <symID
+%token <syminfo> ID LOCAL_ID SPECIAL_ID
 
 /* instruction tokens (dynamically generated) */
 /* @TOKENS@ */
 
 /* @TYPES@ */
 
-%type <bc> line exp instr instrbase
+%type <bc> line exp instr instrbase label
 
 %type <int_val> fpureg reg32 reg16 reg8 segreg
 %type <ea_val> mem memaddr memexp
@@ -79,6 +83,7 @@ extern void yyerror(char *);
 %type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
 %type <ea_val> rm8 rm16 rm32 rm64 rm128
 %type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <sym> label_id
 
 %left '-' '+'
 %left '*' '/'
@@ -90,6 +95,8 @@ input: /* empty */
 
 line: '\n'     { $$.len = 0; }
     | exp '\n' { DebugPrintBC(&$1); $$ = $1; }
+    | label exp '\n' { DebugPrintBC(&$2); $$ = $2; }
+    | label '\n'
     | directive '\n' { }
     | error '\n' { Error(ERR_INVALID_LINE, (char *)NULL); yyerrok; }
 ;
@@ -97,6 +104,15 @@ line: '\n'  { $$.len = 0; }
 exp: instr
 ;
 
+label: label_id { $1->value = 0; } /* TODO: calculate offset */
+    | label_id ':' { $1->value = 0; } /* TODO: calculate offset */
+;
+
+label_id: ID { $$ = locallabel_base = sym_def_get ($1.name, SYM_LABEL); }
+    | SPECIAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
+    | LOCAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
+;
+
 /* directives */
 directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']' {
        printf("Directive: Name='%s' Value='%s'\n", $2, $3);
index 1c9cd278488fafb29910bfe9c401b14bcdbfeb78..ef594f2a28c1e2f426da93bd9b570d88f426b716 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: nasm-bison.y,v 1.9 2001/05/30 07:41:27 peter Exp $
+/* $Id: nasm-bison.y,v 1.10 2001/06/13 05:43:59 mu Exp $
  * Main bison parser
  *
- *  Copyright (C) 2001  Peter Johnson
+ *  Copyright (C) 2001  Peter Johnson, Michael Urman
  *
  *  This file is part of YASM.
  *
@@ -40,6 +40,10 @@ extern void yyerror(char *);
     char *str_val;
     double double_val;
     symrec *sym;
+    struct {
+       char *name;
+       int line;
+    } syminfo;
     effaddr ea_val;
     immval im_val;
     bytecode bc;
@@ -63,14 +67,14 @@ extern void yyerror(char *);
 %token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
 %token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
 %token START_SECTION_OFFSET ENTRY_POINT
-%token <symID
+%token <syminfo> ID LOCAL_ID SPECIAL_ID
 
 /* instruction tokens (dynamically generated) */
 /* @TOKENS@ */
 
 /* @TYPES@ */
 
-%type <bc> line exp instr instrbase
+%type <bc> line exp instr instrbase label
 
 %type <int_val> fpureg reg32 reg16 reg8 segreg
 %type <ea_val> mem memaddr memexp
@@ -79,6 +83,7 @@ extern void yyerror(char *);
 %type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
 %type <ea_val> rm8 rm16 rm32 rm64 rm128
 %type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
+%type <sym> label_id
 
 %left '-' '+'
 %left '*' '/'
@@ -90,6 +95,8 @@ input: /* empty */
 
 line: '\n'     { $$.len = 0; }
     | exp '\n' { DebugPrintBC(&$1); $$ = $1; }
+    | label exp '\n' { DebugPrintBC(&$2); $$ = $2; }
+    | label '\n'
     | directive '\n' { }
     | error '\n' { Error(ERR_INVALID_LINE, (char *)NULL); yyerrok; }
 ;
@@ -97,6 +104,15 @@ line: '\n'  { $$.len = 0; }
 exp: instr
 ;
 
+label: label_id { $1->value = 0; } /* TODO: calculate offset */
+    | label_id ':' { $1->value = 0; } /* TODO: calculate offset */
+;
+
+label_id: ID { $$ = locallabel_base = sym_def_get ($1.name, SYM_LABEL); }
+    | SPECIAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
+    | LOCAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
+;
+
 /* directives */
 directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']' {
        printf("Directive: Name='%s' Value='%s'\n", $2, $3);
index 2ceff815c268cb3f7156892df613e1fca70358d8..7aa6cc96e6ba1c8d4987b8095253405803829b43 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: token.l.in,v 1.5 2001/05/21 22:10:02 peter Exp $
+/* $Id: token.l.in,v 1.6 2001/06/13 05:43:59 mu Exp $
  * Main lexer
  *
  *  Copyright (C) 2001  Peter Johnson
 #include "symrec.h"
 #include "bytecode.h"
 #include "errwarn.h"
+#include "util.h"
 #include "bison.tab.h"
 
 %}
 %option noyywrap
 %option nounput
 %option case-insensitive
-    static char *locallabel_base = (char *)NULL;
+    symrec *locallabel_base = (symrec *)NULL;
+    int line_number;
 
 %x DIRECTIVE DIRECTIVE2
 
@@ -88,14 +90,14 @@ WS       [ \t\r]
 <DIRECTIVE2>{WS}+   ;
 <DIRECTIVE>[a-z]+   {
     BEGIN DIRECTIVE2;
-    yylval.str_val = strdup(yytext);
+    yylval.str_val = y_strdup(yytext);
     if(!yylval.str_val)
        Fatal(FATAL_NOMEM);
     return DIRECTIVE_NAME;
 }
     /* everything printable except for ' ', '[' and ']'. */
 <DIRECTIVE2>[!-@a-z\\^-`{|}~]+ {
-    yylval.str_val = strdup(yytext);
+    yylval.str_val = y_strdup(yytext);
     if(!yylval.str_val)
        Fatal(FATAL_NOMEM);
     return DIRECTIVE_VAL;
@@ -220,21 +222,33 @@ gs        { yylval.int_val = 5; return REG_GS; }
 
     /* special non-local ..@label */
 \.\.@[a-z0-9_$#@~.?]+ {
-    symrec *s = getsym(yytext);
-    if(!s)
-       s = putsym(yytext, ID);
-    yylval.sym = s;
-    return s->type;
+    yylval.syminfo.name = y_strdup (yytext);
+    if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
+    yylval.syminfo.line = line_number;
+
+    return SPECIAL_ID;
 }
 
     /* local label (.label) */
 \.[a-z0-9_$#@~?][a-z0-9_$#@~.?]* {
-    /* TODO: append yytext to locallabel_base before testing */
-    symrec *s = getsym(yytext);
-    if(!s)
-       s = putsym(yytext, ID);
-    yylval.sym = s;
-    return s->type;
+    if (locallabel_base == NULL) 
+    {
+       Warning (WARN_NO_BASE_LABEL, (char *)NULL, yytext);
+       yylval.syminfo.name = y_strdup (yytext);
+       if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
+    }
+    else
+    {
+       yylval.syminfo.name = malloc (strlen (yytext)
+                                 + strlen (locallabel_base->name)
+                                 + 1);
+       if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
+       strcpy (yylval.syminfo.name, locallabel_base->name);
+       strcat (yylval.syminfo.name, yytext);
+    }
+    yylval.syminfo.line = line_number;
+
+    return LOCAL_ID;
 }
 
     /* instructions */
@@ -242,19 +256,11 @@ gs        { yylval.int_val = 5; return REG_GS; }
 
     /* label */
 [a-z_?][a-z0-9_$#@~.?]* {
-    symrec *s = getsym(yytext);
-    if(!s)
-       s = putsym(yytext, ID);
-    yylval.sym = s;
-
-    /* TODO: optimize to decrease number of allocations */
-    if(locallabel_base)
-       free(locallabel_base);
-    locallabel_base = strdup(yytext);
-    if(!locallabel_base)
-       Fatal(FATAL_NOMEM);
+    yylval.syminfo.name = y_strdup (yytext);
+    if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
+    yylval.syminfo.line = line_number;
 
-    return s->type;
+    return ID;
 }
 
 ;.*    ;
index aff2e6eac49d44ad0fb38e27f6a2d27df4085b70..12a7ba462cfdac4e72befd5a265a8f1e69d66d05 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: symrec.c,v 1.1 2001/05/15 05:24:04 peter Exp $
+/* $Id: symrec.c,v 1.2 2001/06/13 05:43:59 mu Exp $
  * Symbol table handling
  *
- *  Copyright (C) 2001  Peter Johnson
+ *  Copyright (C) 2001  Michael Urman
  *
  *  This file is part of YASM.
  *
 #include <stdlib.h>
 #include <string.h>
 #include "symrec.h"
+#include "globals.h"
+#include "errwarn.h"
 
-/* The symbol table: a chain of `symrec'. */
-symrec *sym_table = (symrec *)NULL;
+/* private functions */
+static symtab *symtab_get (char *);
+static symtab *symtab_new (char *, SymType);
+static symtab *symtab_get_or_new (char *, SymType);
+static void symtab_insert (symtab *);
 
+/* The symbol table: a chain of `symtab'. */
+symtab *sym_table = (symtab *)NULL;
+
+/* insert a symtab into the global sym_table */
+void symtab_insert (symtab *tab)
+{
+    tab->next = (symtab *)sym_table;
+    sym_table = tab;
+}
+
+/* find a symtab in the global sym_table */
+symtab *symtab_get (char *name)
+{
+    symtab *tab;
+    for (tab = sym_table; tab != NULL; tab = tab->next)
+    {
+       if (strcmp (tab->rec.name, name) == 0)
+       {
+           return tab;
+       }
+    }
+    return NULL;
+}
+
+/* call a function with each symrec.  stop early if 0 returned */
+void sym_foreach (int(*mapfunc)(symrec *))
+{
+    symtab *tab;
+    for (tab = sym_table; tab != NULL; tab = tab->next)
+    {
+       if (mapfunc(&(tab->rec)) == 0)
+       {
+           return;
+       }
+    }
+}
+
+/* create a new symtab */
+symtab *symtab_new (char *name, SymType type)
+{
+    symtab *tab;
+    tab = malloc(sizeof(symtab));
+    if (tab == NULL) return NULL;
+    tab->rec.name = malloc(strlen(name)+1);
+    if (tab->rec.name == NULL)
+    {
+       free (tab);
+       return NULL;
+    }
+    strcpy(tab->rec.name, name);
+    tab->rec.type = type;
+    tab->rec.value = 0;
+    tab->rec.line = line_number;
+    tab->rec.status = SYM_NOSTATUS;
+    symtab_insert (tab);
+    return tab;
+}
+
+symtab *symtab_get_or_new (char *name, SymType type)
+{
+    symtab *tab;
+    tab = symtab_get (name);
+    if (tab == NULL)
+    {
+       tab = symtab_new (name, type);
+       if (tab == NULL)
+       {
+           Fatal (FATAL_NOMEM);
+       }
+    }
+    return tab;
+}
+
+symrec *sym_use_get (char *name, SymType type)
+{
+    symtab *tab;
+    tab = symtab_get_or_new (name, type);
+    tab->rec.status |= SYM_USED;
+    return &(tab->rec);
+}
+
+symrec *sym_def_get (char *name, SymType type)
+{
+    symtab *tab;
+    tab = symtab_get_or_new (name, type);
+    tab->rec.status |= SYM_DECLARED;
+    return &(tab->rec);
+}
+
+#if 0
 symrec *putsym(char *sym_name, int sym_type)
 {
     symrec *ptr;
@@ -47,4 +142,4 @@ symrec *getsym(char *sym_name)
            return ptr;
     return 0;
 }
-
+#endif /* 0 */
index 0ad25246c2bad00aff33be45805493e7c60007a2..525c4bd5824c57c2dd043cabad7160fac214d618 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: symrec.h,v 1.2 2001/05/18 21:40:54 peter Exp $
+/* $Id: symrec.h,v 1.3 2001/06/13 05:43:59 mu Exp $
  * Symbol table handling header file
  *
- *  Copyright (C) 2001  Peter Johnson
+ *  Copyright (C) 2001  Michael Urman
  *
  *  This file is part of YASM.
  *
 #ifndef _SYMREC_H_
 #define _SYMREC_H_
 
+typedef enum {
+    SYM_NOSTATUS = 0,
+    SYM_USED    = 1 << 0,  /* for using variables before declared */
+    SYM_DECLARED = 1 << 1,  /* once it's been declared */
+    SYM_VALUED  = 1 << 2   /* once its value has been determined */
+} SymStatus;
+
+typedef enum {
+    SYM_CONSTANT,          /* for EQU defined symbols */
+    SYM_LABEL,             /* for labels */
+    SYM_DATA               /* for variables */
+} SymType;
+
 typedef struct symrec_s {
     char *name;
-    int type;
-    union {
-       double var;
-       double (*fnctptr)(void);
-    } value;
-    struct symrec_s *next;
+    SymType type;
+    SymStatus status;
+    int line;
+    double value;
 } symrec;
 
-extern symrec *sym_table;
+typedef struct symtab_s {
+    symrec rec;
+    struct symtab_s *next;
+} symtab;
+
+extern symtab *sym_table;
+
+/*symrec *putsym(char *, SymType);*/
+/*symrec *getsym(char *);*/
 
-symrec *putsym(char *, int);
-symrec *getsym(char *);
+symrec *sym_use_get (char *, SymType);
+symrec *sym_def_get (char *, SymType);
+void sym_foreach (int(*)(symrec *));
 
 #endif
index 2ceff815c268cb3f7156892df613e1fca70358d8..7aa6cc96e6ba1c8d4987b8095253405803829b43 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: token.l.in,v 1.5 2001/05/21 22:10:02 peter Exp $
+/* $Id: token.l.in,v 1.6 2001/06/13 05:43:59 mu Exp $
  * Main lexer
  *
  *  Copyright (C) 2001  Peter Johnson
 #include "symrec.h"
 #include "bytecode.h"
 #include "errwarn.h"
+#include "util.h"
 #include "bison.tab.h"
 
 %}
 %option noyywrap
 %option nounput
 %option case-insensitive
-    static char *locallabel_base = (char *)NULL;
+    symrec *locallabel_base = (symrec *)NULL;
+    int line_number;
 
 %x DIRECTIVE DIRECTIVE2
 
@@ -88,14 +90,14 @@ WS       [ \t\r]
 <DIRECTIVE2>{WS}+   ;
 <DIRECTIVE>[a-z]+   {
     BEGIN DIRECTIVE2;
-    yylval.str_val = strdup(yytext);
+    yylval.str_val = y_strdup(yytext);
     if(!yylval.str_val)
        Fatal(FATAL_NOMEM);
     return DIRECTIVE_NAME;
 }
     /* everything printable except for ' ', '[' and ']'. */
 <DIRECTIVE2>[!-@a-z\\^-`{|}~]+ {
-    yylval.str_val = strdup(yytext);
+    yylval.str_val = y_strdup(yytext);
     if(!yylval.str_val)
        Fatal(FATAL_NOMEM);
     return DIRECTIVE_VAL;
@@ -220,21 +222,33 @@ gs        { yylval.int_val = 5; return REG_GS; }
 
     /* special non-local ..@label */
 \.\.@[a-z0-9_$#@~.?]+ {
-    symrec *s = getsym(yytext);
-    if(!s)
-       s = putsym(yytext, ID);
-    yylval.sym = s;
-    return s->type;
+    yylval.syminfo.name = y_strdup (yytext);
+    if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
+    yylval.syminfo.line = line_number;
+
+    return SPECIAL_ID;
 }
 
     /* local label (.label) */
 \.[a-z0-9_$#@~?][a-z0-9_$#@~.?]* {
-    /* TODO: append yytext to locallabel_base before testing */
-    symrec *s = getsym(yytext);
-    if(!s)
-       s = putsym(yytext, ID);
-    yylval.sym = s;
-    return s->type;
+    if (locallabel_base == NULL) 
+    {
+       Warning (WARN_NO_BASE_LABEL, (char *)NULL, yytext);
+       yylval.syminfo.name = y_strdup (yytext);
+       if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
+    }
+    else
+    {
+       yylval.syminfo.name = malloc (strlen (yytext)
+                                 + strlen (locallabel_base->name)
+                                 + 1);
+       if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
+       strcpy (yylval.syminfo.name, locallabel_base->name);
+       strcat (yylval.syminfo.name, yytext);
+    }
+    yylval.syminfo.line = line_number;
+
+    return LOCAL_ID;
 }
 
     /* instructions */
@@ -242,19 +256,11 @@ gs        { yylval.int_val = 5; return REG_GS; }
 
     /* label */
 [a-z_?][a-z0-9_$#@~.?]* {
-    symrec *s = getsym(yytext);
-    if(!s)
-       s = putsym(yytext, ID);
-    yylval.sym = s;
-
-    /* TODO: optimize to decrease number of allocations */
-    if(locallabel_base)
-       free(locallabel_base);
-    locallabel_base = strdup(yytext);
-    if(!locallabel_base)
-       Fatal(FATAL_NOMEM);
+    yylval.syminfo.name = y_strdup (yytext);
+    if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
+    yylval.syminfo.line = line_number;
 
-    return s->type;
+    return ID;
 }
 
 ;.*    ;