2017-04-22 18:39:52 +00:00
|
|
|
/******************************************************
|
|
|
|
* C02 Label Parsing, Generation, and Lookup Routines *
|
|
|
|
******************************************************/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
#include "asm.h"
|
|
|
|
#include "parse.h"
|
|
|
|
#include "label.h"
|
|
|
|
|
2018-07-19 03:49:39 +00:00
|
|
|
const char lblflg[] = {LFNONE, LFNONE, LFNONE, LFBGN, LFEND, LFBGN, LFEND, LFEND, LFNONE, LFNONE}; //Label Type Flags
|
|
|
|
// enum ltypes {LTNONE, LTIF, LTELSE, LTLOOP, LTEND, LTDO, LTDWHL, LTSLCT, LTCASE, LTFUNC}; //Label Types
|
2018-02-07 04:24:55 +00:00
|
|
|
|
2017-06-27 00:16:23 +00:00
|
|
|
/* Find Last Label of Specified Types *
|
|
|
|
* Args: lbtyp1: First label type *
|
|
|
|
* lbtyp2: Second label type *
|
|
|
|
* Sets: tmplbl - Label name *
|
|
|
|
* Returns: Index into label table *
|
|
|
|
* (-1 if not found) */
|
2018-03-04 03:32:39 +00:00
|
|
|
int lstlbl(int lbflag) {
|
2017-05-01 01:17:50 +00:00
|
|
|
int i;
|
2018-03-04 19:04:04 +00:00
|
|
|
DEBUG("Searching for label flag %d\n", lbflag)
|
2018-03-05 20:03:04 +00:00
|
|
|
for (i = lblcnt - 1; i>-1; i--)
|
2018-02-07 04:24:55 +00:00
|
|
|
if (lblflg[lbltyp[i]] == lbflag) break;
|
2018-03-04 19:04:04 +00:00
|
|
|
DEBUG("Search produced label index %d\n", i)
|
2018-03-05 20:03:04 +00:00
|
|
|
if (i>=0) strcpy(tmplbl, lblnam[i]);
|
2017-05-01 01:17:50 +00:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set Block Flag for Last Label */
|
2018-03-05 20:03:04 +00:00
|
|
|
void setblk(int blkflg) { lblblk[lblcnt-1] = blkflg; }
|
2017-05-01 01:17:50 +00:00
|
|
|
|
2017-04-22 18:39:52 +00:00
|
|
|
/* Set label for next line of *
|
|
|
|
* Assembly Language Code *
|
|
|
|
* to word */
|
2018-03-04 03:32:39 +00:00
|
|
|
void setlbl(char *lblset) {
|
2018-03-04 19:04:04 +00:00
|
|
|
DEBUG("Setting Label '%s'\n", lblset)
|
2017-06-27 00:16:23 +00:00
|
|
|
if (strlen(lblasm) > 0) {
|
|
|
|
DEBUG("Emitting Label '%s'\n'", lblasm);
|
2017-04-22 18:39:52 +00:00
|
|
|
asmlin("",""); //Emit Block End Label on it's own line
|
2017-06-27 00:16:23 +00:00
|
|
|
}
|
2018-03-05 20:03:04 +00:00
|
|
|
if (strlen(lblset) > LABLEN) ERROR("Label '%s' exceeds maximum size\n", word, EXIT_FAILURE)
|
2017-04-22 18:39:52 +00:00
|
|
|
strcpy(lblasm, lblset);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* parse label in code */
|
2018-03-04 03:32:39 +00:00
|
|
|
void prslbl(void) {
|
2018-03-04 19:04:04 +00:00
|
|
|
DEBUG("Parsing Label '%s''\n", word)
|
2017-06-27 00:16:23 +00:00
|
|
|
CCMNT(nxtchr);
|
2017-04-22 18:39:52 +00:00
|
|
|
skpchr(); //skip ':'
|
|
|
|
setlbl(word);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* generate new label */
|
2018-03-04 03:32:39 +00:00
|
|
|
void newlbl(char* lbname) {
|
2017-05-16 00:25:11 +00:00
|
|
|
sprintf(lbname, LABFMT, lblnxt++);
|
2018-03-04 19:04:04 +00:00
|
|
|
DEBUG("Generated new label '%s'\n", lbname)
|
2017-04-22 18:39:52 +00:00
|
|
|
}
|
|
|
|
|
2018-02-13 22:25:57 +00:00
|
|
|
/* Check Label Contents *
|
|
|
|
* If lbname is blank, generate new *
|
|
|
|
* label and copy into lbname */
|
2018-03-04 03:32:39 +00:00
|
|
|
void chklbl(char* lbname) {
|
2018-02-07 02:31:19 +00:00
|
|
|
if (lbname[0]) return;
|
|
|
|
newlbl(lbname);
|
|
|
|
}
|
|
|
|
|
2018-07-30 02:49:44 +00:00
|
|
|
/* Request Label *
|
2017-06-27 00:16:23 +00:00
|
|
|
* if label is already set, returns that label *
|
|
|
|
* else generates new label and sets it */
|
2018-03-04 03:32:39 +00:00
|
|
|
void reqlbl(char* lbname) {
|
2018-07-30 02:49:44 +00:00
|
|
|
DEBUG("Requesting Label\n",0)
|
|
|
|
if (lblasm[0] == 0) {newlbl(lbname); setlbl(lbname);}
|
|
|
|
else {strcpy(lbname,lblasm); DEBUG("Found lblasm set to \"%s\"\n", lblasm)}
|
2017-06-27 00:16:23 +00:00
|
|
|
}
|
|
|
|
|
2018-07-22 00:51:41 +00:00
|
|
|
/* End Function Block */
|
|
|
|
void endfnc(void) {
|
|
|
|
DEBUG("Ending function definition with lsrtrn set to %d\n", lsrtrn)
|
|
|
|
if (!lsrtrn) asmlin("RTS", "");
|
|
|
|
infunc = FALSE;
|
|
|
|
DEBUG("Set infunc to %d\n", infunc)
|
|
|
|
}
|
|
|
|
|
2017-05-01 01:17:50 +00:00
|
|
|
/* Pop Label from Stack and Emit on Next Line */
|
2018-03-04 03:32:39 +00:00
|
|
|
int poplbl(void) {
|
2017-04-22 18:39:52 +00:00
|
|
|
int lbtype = lbltyp[--lblcnt];
|
2018-03-04 19:04:04 +00:00
|
|
|
DEBUG("Popped label type %d\n", lbtype)
|
2018-03-05 20:03:04 +00:00
|
|
|
switch (lbtype) {
|
2018-07-22 00:51:41 +00:00
|
|
|
case LTFUNC: endfnc(); break; //Return From Subroutine
|
2018-03-05 20:03:04 +00:00
|
|
|
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
|
2017-05-16 00:25:11 +00:00
|
|
|
}
|
2018-03-05 20:03:04 +00:00
|
|
|
if (lbtype != LTCASE) inblck = lblblk[lblcnt-1];
|
2017-05-01 01:17:50 +00:00
|
|
|
return lbtype;
|
2017-04-22 18:39:52 +00:00
|
|
|
}
|
|
|
|
|
2018-02-06 02:51:30 +00:00
|
|
|
/* Get Top Label and Return Type */
|
2018-03-04 03:32:39 +00:00
|
|
|
int toplbl(char *rtlbl) {
|
2018-02-06 02:51:30 +00:00
|
|
|
if (lblcnt) {
|
|
|
|
strcpy(rtlbl, lblnam[lblcnt-1]);
|
2018-03-04 19:04:04 +00:00
|
|
|
DEBUG("Found top label %s\n", rtlbl)
|
2018-02-06 02:51:30 +00:00
|
|
|
return lbltyp[lblcnt-1];
|
|
|
|
}
|
|
|
|
rtlbl[0] = 0; //Clear Label
|
|
|
|
return LTNONE;
|
|
|
|
}
|
|
|
|
|
2017-05-01 01:17:50 +00:00
|
|
|
/* Push Label onto Stack *
|
|
|
|
* Args: lbltyp - Label type *
|
|
|
|
* Uses: curlbl - Label to push */
|
2018-03-04 03:32:39 +00:00
|
|
|
void pshlbl(int lbtype, char* lbname) {
|
2018-03-04 19:04:04 +00:00
|
|
|
DEBUG("Pushing label type %d\n", lbtype)
|
2017-05-16 00:25:11 +00:00
|
|
|
strcpy(lblnam[lblcnt], lbname);
|
2017-05-01 01:17:50 +00:00
|
|
|
lbltyp[lblcnt] = lbtype;
|
|
|
|
lblblk[lblcnt++] = FALSE;
|
2018-03-04 19:04:04 +00:00
|
|
|
DEBUG("Pushed label '%s' onto stack\n", lbname)
|
2017-05-01 01:17:50 +00:00
|
|
|
}
|