Annotation of researchv9/cmd/sun/c2/scan.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)scan.c 1.1 86/02/03 Copyr 1985 Sun Micro";
                      3: #endif
                      4: 
                      5: /*
                      6:  * Copyright (c) 1985 by Sun Microsystems, Inc.
                      7:  */
                      8: 
                      9: #include "as.h"
                     10: 
                     11: /* process lines from source file, returns when EOF detected */
                     12: 
                     13: #define LSIZE  4*BUFSIZ+2      /* max size of input line + fudge */
                     14: 
                     15: char *sassign(),*sdefer(),*exp(),*term();
                     16: struct ins_bkt * sopcode();
                     17: int slabel();
                     18: 
                     19: char iline[LSIZE];     /* current input line resides */
                     20: int  line_no;          /* current input line number */
                     21: char code[CODE_MAX];   /* where generated code is stored */
                     22: long dot;              /* offset in current csect */
                     23: int  bc;               /* size of code for current line */
                     24: int  opshow = 0;
                     25: long break_line = -1, break_pass = 1;
                     26: 
                     27: /* for local labels: ``[0-9]:'', and references ``[0-9][bh]'' */
                     28: extern char *ll_format;
                     29: extern int   ll_val[10];
                     30: 
                     31: scan()
                     32: {
                     33:        register int i;
                     34:        register char *p;        /* pointer into input line */
                     35:        char *token;             /* pointer to beginning of last token */
                     36:        struct ins_bkt * opindex;/* index of opcode on current line */
                     37: # ifdef C2
                     38:        char *docomment();
                     39: # endif
                     40: 
                     41: #ifdef AS
                     42:        /* setup stupid local-lable array */
                     43:        for( i = 0; i < 10; ll_val[i++] = -1 ) ;
                     44: #endif
                     45: 
                     46:        while (iline[LSIZE-2]='\0', fgets(iline,LSIZE,stdin) == iline) {
                     47:              line_no++;
                     48: #ifdef AS
                     49:              if (line_no == break_line && pass == break_pass) break_here();
                     50: #endif
                     51: #ifdef C2
                     52:              if (line_no == break_line ) break_here();
                     53: #endif
                     54:              /* a cheap way to find if the line was too long */
                     55:              if (iline[LSIZE-2] != '\0'){ PROG_ERROR(E_LINELONG); continue; }
                     56:              p = iline;
                     57: 
                     58:              /* see what's the first thing on the line. if newline or comment
                     59:               * char just ignore line all together.  if start of symbol see
                     60:               * what follows.  otherwise error.
                     61:               */
                     62:  restart:      skipb(p);
                     63:              i = cinfo[*p];    /* see what we know about next char */
                     64:              /* hack to make # in col 1 a comment -- for cpp leavings */
                     65:              if (i == EOL || i == IMM) {
                     66:                    /* further hack to make ; in line act as seperator. */
                     67:                    if (*p == ';'){ p++; goto restart;}
                     68: # ifdef C2
                     69:                    p = docomment(p);
                     70:                    if (p==NULL) 
                     71:                        return 1; /* special return */
                     72: # endif
                     73:                    continue;
                     74:              }
                     75:              if (!(i & (S|D))) { PROG_ERROR(E_BADCHAR); continue; }
                     76:              bc = 0;
                     77: # ifdef AS
                     78:              code_length = 0;
                     79: # endif
                     80: 
                     81:              /* what follows is either label or opcode, gobble it up */
                     82:              token = p;
                     83:              skips(p);
                     84:              skipb(p);
                     85:              i = cinfo[*p];
                     86: 
                     87:              /* if next char is ":", this is label definition */
                     88:              if (i == COL) { p++; slabel(token); goto restart; }
                     89: 
                     90:            /* if next char is "=", this is label assignment */
                     91:            if (i == EQL) {
                     92:                p = sassign(++p,token);
                     93:                if (cinfo[*p] != EOL) PROG_ERROR(E_BADCHAR);
                     94:                /* hack to make ; in line act as seperator. */
                     95:                if (*p == ';'){ p++; goto restart;}
                     96:                continue;
                     97:            }
                     98: 
                     99:            /* otherwise this must be opcode, find its index */
                    100:            if ((opindex = sopcode(token)) == 0) {
                    101:                PROG_ERROR(E_OPCODE);
                    102:                continue;
                    103:            }
                    104: 
                    105:            if (i == EOL) { numops = 0; goto doins; }
                    106: 
                    107:            /* keep reading operands until we run out of room or hit EOL */
                    108:            for (numops = 1; numops <= OPERANDS_MAX; numops++) {
                    109:                  p = soperand(p,&operands[numops-1]);
                    110:                  skipb(p);
                    111:                  i = cinfo[*p];
                    112:                  if (i == COM) { p++; skipb(p); continue; }
                    113:                  if (i == EOL) goto doins;
                    114:                  PROG_ERROR(E_OPERAND);
                    115:                  goto next;
                    116:            }
                    117:            PROG_ERROR(E_NUMOPS);
                    118:   next:              continue;
                    119: 
                    120:   doins:      
                    121:            instruction(opindex);
                    122:            dot += bc;
                    123:            dot_bkt->value_s = dot;
                    124:          
                    125:            /* hack to make ; in line act as seperator. */
                    126:            if (*p == ';'){ p++; goto restart;}
                    127:        }
                    128:        return 0; /* normal exit */
                    129: } /* end Scan */
                    130: 
                    131: /* lookup token in opcode hash table, return 0 if not found */
                    132: struct ins_bkt * 
                    133: sopcode(token)
                    134:   register char *token;
                    135: {
                    136:   register struct ins_ptr *ipp;
                    137:   char *mnem = token;
                    138:   char savechar;
                    139: 
                    140:   /* make asciz version of mnemonic */
                    141:   while (cinfo[*token] & T) token++;
                    142:   savechar = *token;
                    143:   *token = '\0';
                    144: 
                    145:   /* look through appropriate hash bucket */
                    146:   ipp = ins_hash_tab[hash(mnem)];
                    147:   while (ipp) { 
                    148:        if (strcmp(ipp->name_p,mnem) == 0) break;
                    149:          ipp = ipp->next_p;
                    150:        }
                    151:   *token = savechar;
                    152: 
                    153:   if( ipp == 0) return 0;
                    154:   return(ipp->this_p);
                    155: } /* end sopcode */
                    156: 
                    157: 
                    158: /* handle assignment to a label, return updated line pointer */
                    159: char *
                    160: sassign(lptr,token)
                    161:   register char *token;
                    162:   register char *lptr;
                    163: {
                    164:   register char *p;
                    165:   register struct sym_bkt *sbp;
                    166:   struct oper value;
                    167:   char nextc;
                    168:   static struct oper zero_oper  = { T_NULL, 0, 0, 0, 0, NULL};
                    169: 
                    170:   /* make asciz version of label */
                    171:   p = token;
                    172:   while (cinfo[*p] & T) p++;
                    173:   nextc = *p;
                    174:   *p = '\0';
                    175:   value = zero_oper;
                    176: 
                    177:   /* find/enter symbol in the symbol table, and get its new value */
                    178:   sbp = lookup(token);
                    179:   lptr = exp(lptr,&value);
                    180: 
                    181:   /* if assignment is to dot, we'll treat it specially */
                    182:   if (sbp == dot_bkt) {
                    183: #ifdef AS
                    184:        int deltadot;
                    185: #endif AS
                    186:        if (value.sym_o && value.sym_o->csect_s!=cur_csect_name)
                    187:            PROG_ERROR(E_OPERAND);
                    188: #ifdef AS
                    189:        deltadot = value.value_o - dot;
                    190:        if (deltadot<0)
                    191:            PROG_ERROR(E_OPERAND);
                    192:        operands[0].value_o = deltadot;
                    193:        skip_op( NULL );
                    194: #endif
                    195:   } else {
                    196:        if (value.sym_o != NULL) {
                    197:                sbp->value_s = value.sym_o->value_s;
                    198:        } else {
                    199:                sbp->value_s = value.value_o;
                    200:        }
                    201:        sbp->csect_s = (value.sym_o!=NULL) ? value.sym_o->csect_s : C_UNDEF;
                    202:        if (sbp->attr_s & S_LABEL) {
                    203:             PROG_ERROR(E_EQUALS);
                    204:        } else if (value.type_o == T_REG)
                    205:            sbp->attr_s = (sbp->attr_s&S_EXT) | S_REG | S_DEC | S_DEF;
                    206:        else
                    207:            sbp->attr_s = (sbp->attr_s&S_EXT)  |
                    208:                ((value.sym_o!=NULL) ?
                    209:                 (value.sym_o->attr_s & ~(S_LABEL|S_PERM)): (S_DEC | S_DEF));
                    210:    }
                    211: 
                    212:    if (opshow) fprintf(stderr,"sassign(%s) = %ld, %ld\n",
                    213:        token, value.value_o, sbp->attr_s);
                    214: #if C2
                    215:     /* echo assignment immediately. RHS involving (.) will break. Fix later */
                    216:     printf("   %s      =       ", sbp->name_s);
                    217:     printoperand( &value );
                    218:     putchar('\n');
                    219: #endif
                    220: 
                    221:     *p = nextc;
                    222: 
                    223:     /* return update line pointer */
                    224:     skipb(lptr);
                    225:     return(lptr);
                    226: } /* end sassign */
                    227: 
                    228: /* hashing routine for Symbol and Instruction hash tables */
                    229: hash(s)
                    230:        register char *s;
                    231: {
                    232:        register int i = 0;
                    233: 
                    234:        while (*s) i = i*10 + *s++ - ' ';
                    235:        i = i % HASH_MAX;
                    236:        return(i<0 ? i+HASH_MAX : i);
                    237: } /* end hash */
                    238: 
                    239: 
                    240: break_here(){ }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.