/****************************************************** * C02 Label Parsing, Generation, and Lookup Routines * ******************************************************/ #include #include #include #include #include #include "common.h" #include "files.h" #include "asm.h" #include "parse.h" #include "label.h" #include "vars.h" /* Add New Program Label */ void addlab(char *name) { if (fndvar(name)) ERROR("Label %s conflicts with variable with same name", name, EXIT_FAILURE) if (fndlab(name)) ERROR("Duplicate program label %s\n", name, EXIT_FAILURE) DEBUG("label.addlab: Adding Program Label %s ", name) DETAIL("at index %d\n", labcnt) strcpy(labnam[labcnt++], name); } int fndlab(char *name) { DEBUG("label.fndlab: Looking for Program Label %s\n", name) for (labidx=0; labidx-1; i--) if (lblflg[lbltyp[i]] == lbflag) break; DEBUG("label.lstlbl: Search produced label index %d\n", i) if (i>=0) strcpy(tmplbl, lblnam[i]); return i; } /* Set Block Flag for Last Label */ void setblk(int blkflg) { lblblk[lblcnt-1] = blkflg; } /* Set label for next line of * * Assembly Language Code * * to word */ void setlbl(char *lblset) { DEBUG("label.setlbl: Setting Label '%s'\n", lblset) if (strlen(lblasm) > 0) { DEBUG("label.setlbl: Emitting Label '%s'\n'", lblasm); asmlin("",""); //Emit Block End Label on it's own line } if (strlen(lblset) > LBLLEN) ERROR("Label '%s' exceeds maximum size\n", word, EXIT_FAILURE) strcpy(lblasm, lblset); } /* Parse Program Label */ void prslab(void) { DEBUG("label.prslab: Parsing Label '%s''\n", word) addlab(word); CCMNT(nxtchr); skpchr(); //skip ':' } /* generate new label */ void newlbl(char* lbname) { sprintf(lbname, LBLFMT, lblnxt++); DEBUG("label.newlbl: Generated new label '%s'\n", lbname) } /* Check Label Contents * * If lbname is blank, generate new * * label and copy into lbname */ void chklbl(char* lbname) { if (lbname[0]) return; newlbl(lbname); } /* Request Label * * if label is already set, returns that label * * else generates new label and sets it */ void reqlbl(char* lbname) { DEBUG("label.reqlbl: Requesting Label\n",0) if (lblasm[0] == 0) {newlbl(lbname); setlbl(lbname);} else {strcpy(lbname,lblasm); DEBUG("label.reqlbl: Found lblasm set to \"%s\"\n", lblasm)} } /* End Function Block */ void endfnc(void) { DEBUG("label.endfnc: Ending function definition with lsrtrn set to %d\n", lsrtrn) if (!lsrtrn) asmlin("RTS", ""); asmlin(LOCEND, ""); infunc = FALSE; DEBUG("label.endfnc: Set infunc to %d\n", infunc) } /* Pop Label from Stack and Emit on Next Line */ int poplbl(void) { int lbtype = lbltyp[--lblcnt]; DEBUG("label.poplbl: Popped label type %d\n", lbtype) switch (lbtype) { case LTFUNC: endfnc(); break; //Return From Subroutine case LTDO: strcpy(loplbl, lblnam[lblcnt]); break; case LTDWHL: strcpy(endlbl, lblnam[lblcnt]); break; case LTCASE: strcpy(cndlbl, lblnam[lblcnt]); break; case LTLOOP: asmlin("JMP", lblnam[lblcnt--]); //Jump to Beginning of Loop default: setlbl(lblnam[lblcnt]); //Emit End of Loop Label } if (lbtype != LTCASE) inblck = lblblk[lblcnt-1]; return lbtype; } /* Get Top Label and Return Type */ int toplbl(char *rtlbl) { if (lblcnt) { strcpy(rtlbl, lblnam[lblcnt-1]); DEBUG("label.toplbl: Found top label %s\n", rtlbl) return lbltyp[lblcnt-1]; } rtlbl[0] = 0; //Clear Label return LTNONE; } /* Push Label onto Stack * * Args: lbltyp - Label type * * Uses: curlbl - Label to push */ void pshlbl(int lbtype, char* lbname) { DEBUG("label.pshlbl: Pushing label type %d\n", lbtype) strcpy(lblnam[lblcnt], lbname); lbltyp[lblcnt] = lbtype; lblblk[lblcnt++] = FALSE; DEBUG("label.pshlbl: Pushed label '%s' onto stack\n", lbname) }