home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / nasm20b / nasm_src / sym_asm.c < prev    next >
C/C++ Source or Header  |  1993-01-19  |  7KB  |  236 lines

  1. /* ---------------------------------------------------------------------- */
  2. /*                   Copyright (C) 1991 by Natürlich!                     */
  3. /*                      This file is copyrighted!                         */
  4. /*                Refer to the documentation for details.                 */
  5. /* ---------------------------------------------------------------------- */
  6. #include <stdio.h>
  7. #include "defines.h"
  8. #include "nasm.h"
  9. #include "debug.h"
  10. #include "labels.h"
  11. #include "exprfast.h"
  12.  
  13. extern label huge *h_local[SEP],  huge *t_local[SEP],  huge *l_local,
  14.              huge *h_global[SEP], huge *t_global[SEP], huge *l_global,
  15.              huge *h_macro[SEP],  huge *t_macro[SEP],  huge *l_macro;
  16. extern int        u_local, u_global, u_macro;
  17. extern char       is_where[], err_defined[];
  18. extern int        _in_macro, runnable, _in_instr;
  19. extern lword      l_hash;
  20.  
  21.  
  22. label *find_label( s)
  23. register char  *s;
  24. {
  25.    register label huge  *p;
  26.    register lword       hash;
  27.    register int         res;
  28.  
  29.    ENTER("find_label");
  30.  
  31.    l_hash = hash = calc_hash( s + 1);
  32.    p = h_macro[ u_macro = is_where[*s]];
  33.    while( p && (p->hash < hash ||
  34.             (p->hash == hash && (res = strcmp( p->name, s)) < 0)))
  35.       p = p->next;
  36.    l_macro = p;
  37.  
  38.    if( ! found( p, hash) || res)  /* if not found or at end of table */
  39.    {
  40.       if( *s == '?' || *s == ':')
  41.       {
  42.          l_hash = hash = calc_hash( s + 2);
  43.          p = h_local[ u_local = is_where[ s[1]]];
  44.          while( p && (p->hash < hash ||
  45.                 (p->hash == hash && (res = strcmp( p->name, s)) < 0)))
  46.             p = p->next;
  47.          l_local = p;
  48.       }
  49.       else
  50.       {
  51.          p = h_global[ u_global = is_where[*s]];
  52.          while( p && (p->hash < hash ||
  53.                 (p->hash == hash && (res = strcmp( p->name, s)) < 0)))
  54.             p = p->next;
  55.          l_global = p;
  56.       }
  57.       if( ! found(p, hash) || res)
  58.       {
  59.          LEAVE();
  60.          return( 0);
  61.       }
  62.    }
  63.    LEAVE();
  64.    return( p);
  65. }
  66.  
  67.  
  68. void  undefine( s)
  69. char  *s;
  70. {
  71.    register label huge  *p;
  72.    int                  is_local = (*s == '?' || *s == ':');
  73.    
  74.    u_local = u_global = -1;     /* if we find a macro label this remains -1 */
  75.    if( p = find_label( s))
  76.       if( ! p->refs)
  77.          if( u_local < 0 && u_global < 0)
  78.          {
  79.             auslinker( h_macro, t_macro, l_macro, u_macro, p);
  80.          }
  81.          else
  82.             if( is_local)
  83.             {
  84.                 auslinker( h_local, t_local, l_local, u_local, p);
  85.             }
  86.             else
  87.             {
  88.                auslinker( h_global, t_global, l_global, u_global, p);
  89.             }
  90.       else
  91.          nerror("Label has pending forward references");
  92.    else
  93.       nwarning("Label is unknown to me");
  94. }
  95. /* ---------------------------------------------------------- */
  96. /*         This routine is called when a forward label        */
  97. /*         is encountered:                                    */
  98. /*    -- Note that the tables have already been searched --   */
  99. /* e.g.:                                                      */
  100. /*             sta foo                                        */
  101. /* not:  foo   lda foo                                        */
  102. /* not:  foo:  =  56                                          */
  103. /* not:  foo   *=$600                                         */
  104. /* ---------------------------------------------------------- */
  105. label *enter_flabel( s, ex)
  106. char                 *s;
  107. register expr huge   *ex;
  108. {
  109.    register label    *p;
  110.    int               is_local = (*s == '?' || *s == ':');
  111.  
  112.    ENTER("enter forward label");
  113. #if DEBUG
  114.    fprintf( ESTREAM, "with %s as name, and some s_expr @$%lX\n", s, ex);
  115. #endif
  116.    if( is_local)
  117.       p = llab_alloc();
  118.    else
  119.       p = lab_alloc();
  120.    p->refs = 0;
  121.    p->name = s;
  122.    p->hash = l_hash;
  123.    if( runnable)
  124.       p->type = L_NORMAL | L_REF;
  125.    else
  126.       p->type = L_PC | L_NORMAL | L_REF;
  127.    refer( p, ex);
  128.  
  129.    if( is_local)
  130.    {
  131.       MESS("linking into local");
  132.       einlinker( h_local, t_local, l_local, u_local, p);
  133.    }
  134.    else
  135.       if( _in_macro)
  136.       {
  137.          MESS("linking into macro");
  138.          einlinker( h_macro, t_macro, l_macro, u_macro, p);
  139.       }
  140.       else
  141.       {
  142.          MESS("linking into global");
  143.          einlinker( h_global, t_global, l_global, u_global, p);
  144.       }
  145.    LEAVE();
  146.    return( p);
  147. }
  148.  
  149. void  page0decl( s)
  150. register char  *s;
  151. {
  152.    register label huge  *p;
  153.    register expr huge   *ex;
  154.    int                  is_local = (*s == '?' || *s == ':');
  155.  
  156.    ENTER("page0decl");
  157.    if( runnable)
  158.    {
  159.       nwarning(".ZEXT probably not meaningful with -r option");
  160.       nmessage("But we're gonna do it anyway!");
  161.    }
  162.    if( ! find_label( s))      /* if not found or at end of table */
  163.       if( ! is_local)
  164.       {
  165.          p = lab_alloc();
  166.          p->refs = 0;
  167.          p->name = s;
  168.          p->hash = l_hash;
  169.          p->type = L_ZERO | L_LINKZERO;
  170.          ex = exp_alloc();
  171.          ex->fix = FIX_NOTHING;
  172.          refer( p, ex);
  173.          einlinker( h_global, t_global, l_global, u_global, p);
  174.       }
  175.       else
  176.          nserror("Can't use local labels here", s);
  177.    else
  178.       nserror( err_defined, s);
  179.    LEAVE();
  180. }
  181.  
  182. /* ---------------------------------------------------------- */
  183. /*   The variety of label dumping routines, really BEG for a  */
  184. /*   a one-that-does-it-all-routine                           */
  185. /* ---------------------------------------------------------- */
  186. void dump_open()
  187. {
  188.    register int         i, j, k;
  189.    int                  f = 0;
  190.    register label huge  *p;
  191.    
  192.    ENTER("dump_open");
  193.    for( k = 0; k != 2; k++)                           
  194.       for( i = 0; i != SEP; i++)                      
  195.          if( p = k ? h_macro[ i] : h_global[ i])
  196.                       do
  197.                    if( dumpable( p))
  198.                {
  199.                   if( ! f)
  200.                   {
  201.                      f = 1;
  202.                      j = 0;
  203.                      printf("Linkable symbols:\n");
  204.                   }
  205.                   if( ++j == 7)
  206.                   {
  207.                      j = 0;
  208.                      putchar( '\n');
  209.                   }
  210.                   printf( "%c%-8.8s ",
  211.                          (char) (p->type & L_ZERO 
  212.                                   ?  (p->refs ? ',' : '#')
  213.                                   :  (p->refs ? ' ' : '*')),  
  214.                           p->name);
  215.                }
  216.             while( p = p->next);      
  217.    puts( "\n");
  218.    LEAVE();
  219. }
  220.  
  221. /* ---------------------------------------------------------- */
  222. /*     Remove all labels starting with @ from macro table     */
  223. /* ---------------------------------------------------------- */
  224. void clean_mats()
  225. {
  226.    register label huge  *p;
  227.    
  228.    ENTER("dump_open");
  229.    for( p = h_macro[ 1]; p; p = p->next)
  230.       if( p->refs)
  231.          nerror("'@' macro label still has open refs", p->name);
  232.    h_macro[ 1] = 0;
  233.    LEAVE();
  234. }
  235.  
  236.