/* * file: parse.c * * contains: get_label and getor * * This routine will search for a label in the line buffer, and * if one is found, will move it to LABBUF. The line pointer is * left pointing to the character after the label. */ #include "asm.h" #define tolow(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) + 0x20) : (c)) extern MAC *mp_ptr; extern TABLE orlstp2; extern TABLE orlstp3; extern TABLE orlstp4; extern TABLE orlstp5; extern TABLE orlstp6; extern TABLE orlstp7; char nrands; /*. ************************************************************************* * * * * * * * * * * ************************************************************************* */ int get_label(lp) register unsigned char *lp; { register unsigned char *sav_lp; register int local, mlocalx; int x; char buff[18]; #if DEBUG printf("get_label:\t%s\n", lp); #endif linpnt = lp; /* check for block comment section */ if (*lp == COMTTK) { ++lp; if (alpha(lp) == 0) flpseg ^= 1; return(DUMMY); } lp = skipsp(lp); if (flpseg || term(lp)) return(DUMMY); sav_lp = lp; if (*lp == MACRO) return(DUMMY); local = 0; mlocalx = 0; /* see if 1st character valid for labels */ if (lp[0] == LOCAL && lp[1] == LOCAL) { local = 1; lp += 2; } else if (*lp == MLOCAL) { turn_on(AFMLOC); mlocalx = 1; ++lp; } if (!alpha(lp)) return(MORE); /* * move the symbol to LABBUF */ lp = gsym(lp, labbuf); if (local || mlocalx) { turn_on(AFGLOC); (void) sprintf(buff, "%u", local ? locnum : mlocnum); x = slenth - len(buff); labbuf[x] = 0; (void) strcat(labbuf, buff); } /* check what terminated the label (if it really was a label) */ if (*lp != ':') { if (sav_lp != linpnt) { labbuf[0] = 0; linpnt = sav_lp; return(MORE); } } else { #if DEBUG printf("found: %s\n", labbuf); #endif ++lp; } if (local) turn_on(AFLOC | AFLOCL); turn_on(AFGLAB); /* set the new line pointer */ lp = skipsp(lp); linpnt = lp; /* return proper flag for remainder of the line */ return(term(lp) ? EMPTY : MORE); } /* * This routine will locate operator (if any) and puts it's token * and value into ORTKBF. * The line pointer is left pointing to the character after the operator. */ /*. ************************************************************************* * * * * * * * * * * ************************************************************************* */ void getor(lp) register char *lp; { register TABLE *fp; register char *sp; register int lenth; #if DEBUG printf("getor: *%s*\n", lp); #endif /* * operator MUST begin with an alpha. else fatal error */ if (*lp == MACRO) return; if (!alpha(lp)) return; /* * move the operator to SYMBUF, counting it's length as we go */ sp = (char *) symbuf; lenth = 0; while (alpnum(lp)) { *sp++ = *lp++; if (++lenth > 7) return; } *sp = 0; /* * operator terminator MUST be CR, HT, or SPACE */ if (!(chkspc(lp) || term(lp))) return; /* * save pointer for macro handler */ linpnt = skipsp(lp); /* see if it's a macro being expanded */ if (macnum && (mp_ptr = maclook(symbuf))) { ortkbf[0] = -1; nrands = -1; return; } if (lenth == 1 || lenth == 2) fp = &orlstp2; else if (lenth == 3) fp = &orlstp3; else if (lenth == 4) fp = &orlstp4; else if (lenth == 5) fp = &orlstp5; else if (lenth == 6) fp = &orlstp6; else if (lenth == 7) fp = &orlstp7; while(fp->t_name[0]) { #if DEBUG printf("%s\n", fp->t_name); #endif if (match(fp->t_name,symbuf,1)) { ortkbf[0] = fp->t_token; ortkbf[1] = fp->t_value; nrands = fp->t_operands; #if DEBUG printf("found: %s with token of %x and value of %x\n", fp->t_name, ortkbf[0], ortkbf[1]); #endif return; } ++fp; } } /*. ************************************************************************* * * * gtod * * * * This routine will locate operand (if any) and set it's tokens * * into ODBT1/ODBT2, and corresponding values into ODINT1/ODINT2. * * The line pointer is left pointing to the character after the * * last operand. * * * * * * * ************************************************************************* */ void gtod(lp) register char *lp; { #if DEBUG printf("gtod: *%s*\n", lp); #endif if ((lp = (char *) getopd(lp, &opbyt1, &odint1, 1)) != EMPTY) (void) getopd(lp, &opbyt2, &odint2, 2); } /*. ************************************************************************* * * * getopd * * ------ * * * * parse for 1 operand * * * * * * * ************************************************************************* */ int getopd(lp,token,value,loop) register unsigned char *lp; int *token, *value; char loop; { extern BRACK bracket[]; register unsigned char *sp; register unsigned char *bp; register int count,p1; register BRACK *bk; /* pointer to bracket list */ int c, bflag, pflag; #if DEBUG printf("getopd\n"); #endif bflag = 0; pflag = 0; p1 = 0; /* * see if we're defining a macro or end of line */ if (*lp == MACRO || term(lp)) return(EMPTY); /* * comma by itself is a fatal error */ if (*lp == COMMA) { dnops(); return(EMPTY); } /* * handle litorg definitions here */ if (lp[0] == LITORG && lp[1] == SQUOTE) { if (loop == 1) { dnops(); return(EMPTY); } prolit(lp); *token = INTTOK; return(EMPTY); } /* * get a pointer to the back of the expression */ bp = lp; while(*bp) { if ((*bp < ' ' && *bp != HT) || *bp == ',' || *bp == ';') break; if (*bp == SQUOTE) { bp++; /* bp = skipquote(bp);*/ } if (*bp == '(') { ++p1; ++pflag; } if (*bp == ')') --p1; bp++; } /* * backup to last character in expression */ bp--; /* * backup over any white characters */ while (*bp == SPACE || *bp == HT) bp--; /* * if we have an unbalanced expression, give error */ if (p1) { eror('B'); return(EMPTY); } parflg = -1; /* * see if the expression is surrounded in parens */ if (*lp == LPAREN && *bp == RPAREN && pflag == 1) { c = *lp++; bflag = 1; } sp = lp; /* * see if it's possibly a register operation or expression */ for(count = 0; count < 3; count++) { if (alpnum(lp) == 0) break; symbuf[count] = *lp++; } if (*lp == SQUOTE && count) symbuf[count++] = *lp++; symbuf[count] = 0; if (count && (c = regtok(symbuf))) { /* * we have found a register or condition flag */ if (c == CTOK) { if (*ortkbf & CONBIT) c = CCOND; } if ((c & XYMASK) == IXORIY) { /* * found 'IX' or 'IY', check for displacement */ if (*lp == '+' || *lp == '-') { c = (c & 0xf) | 0xc0; eval(lp); *value = evalue; if (mathfg & MFRLEX) { #if DEBUG printf("getopd:\n"); #endif eror('V'); } } } } else { c = INTTOK; eval(sp); *value = evalue; } if (bflag) { bk = bracket; while(bk->b_tok1) { if (c == bk->b_tok1) { c = bk->b_tok2; break; } ++bk; } } *token = c; bp = skipsp(++bp); if (*bp == COMMA) ++bp; bp = skipsp(bp); linpnt = bp; if(term(bp)) return(EMPTY); else return((int) bp); } /*. ************************************************************************* * * * regtok * * ------ * * * * lookup for registers as operators * * * * * * * ************************************************************************* */ int regtok(ptr) register char *ptr; { extern REG reglst[]; register int sub,low,high,retcode; #if DEBUG fprintf(stderr, "regtok: look at *%s*\n",ptr); #endif if (*ptr < 'A') return(0); low = -1; high = 31; while ((sub = (high-low)/2 + low) != low && sub != high) { #if DEBUG fprintf(stderr, "%s\n", reglst[sub].r_name); #endif if ((retcode = check_low(ptr,reglst[sub].r_name)) == TOO_HIGH) low = sub; else if (retcode == TOO_LOW) high = sub; else { #if DEBUG fprintf(stderr, "regtok: found *%s*\n",reglst[sub].r_name); #endif return(reglst[sub].r_token); } } return(0); } /*. ************************************************************************* * * * check_low * * --------- * * * * check to see if symbol (fp) is greater than symbol (bp) * * * * * * * ************************************************************************* */ int check_low(fp, bp) register char *fp, *bp; { #if DEBUG printf("check_low: *%s* *%s*\n",fp,bp); fflush(stdout); #endif while (*fp && *bp) { #if DEBUG printf("check_low: fp=*%c* bp=*%c*\n",tolow(*fp),tolow(*bp)); #endif if (tolow(*fp) > tolow(*bp)) return(TOO_HIGH); else if (tolow(*fp) < tolow(*bp)) return(TOO_LOW); fp++; bp++; } /* * at this point, one string is at its end */ if (*fp) return(TOO_HIGH); if (*bp) return(TOO_LOW); return(MATCH); }