C02/src/dclrtn.c

180 lines
5.9 KiB
C

/************************************
* C02 Declaration Compiling 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"
#include "vars.h"
#include "cond.h"
#include "expr.h"
#include "stmnt.h"
#include "dclrtn.h"
int addprm(char* prmtr) {
reqvar(FALSE); //Get Variable Name
if (vartyp == VTINT) {
strcpy(prmtrx, value);
strcpy(prmtry, value);
strcat(prmtry, "+1");
return TRUE;
}
strcpy(prmtr, value); //Copy to Parameter Variable
return FALSE;
}
/* Add Function Definition */
void addfnc(void) {
if (infunc) ERROR("Nested Function Definitions Not Allowed\n", 0, EXIT_FAILURE)
expect('(');
strcpy(fncnam, word); //Save Function Name
prmtra[0] = 0; //Initialze Parameters
prmtry[0] = 0;
prmtrx[0] = 0;
skpspc(); //Skip Spaces
if (isalph() || match('.')) { //Parse Parameters
if (!look('.')) {if (addprm(prmtra)) goto addfne;} //Get First Parameter
if (look(',')) { //Look for Comma
if (addprm(prmtry)) goto addfne; //Get Second Parameter
if (look(',')) { //Look for Comma
addprm(prmtrx); //Get Third Parameter
}
}
}
addfne:
expect(')');
if (look(';')) return; //Forward Definition
infunc = TRUE; //Set Inside Function Definition Flag
DEBUG("dclrtn.addfnc: Set infunc to %d\n", infunc)
setlbl(fncnam); //Set Function Entry Point
asmlin(LOCOP, ""); //Set Local Variables Boundary
if (prmtra[0]) asmlin("STA", prmtra); //Store First Parameter
if (prmtry[0]) asmlin("STY", prmtry); //Store Second Parameter
if (prmtrx[0]) asmlin("STX", prmtrx); //Store Third Parameter
endlbl[0] = 0; //Create Dummy End Label
pshlbl(LTFUNC, endlbl); //and Push onto Stack
bgnblk('{'); //Start Program Block
}
/* Add Constant to Contant Table *
* Args: numval = value as int *
* Uses: defnam = constant name *
* word = value as parsed *
* value = value as number */
void addcon(int numval) {
strncpy(connam[concnt], defnam, VARLEN);
if (alcvar) setlbl(defnam); //Set label Assembler Line
conval[concnt++] = numval; //Get Value
if (alcvar) asmlin(EQUOP, value); //Write Definition
DEBUG("dclrtn.addcon: Defined constant '%s'", defnam)
DETAIL(" as '%s'\n", value)
if (!alcvar) SCMNT(""); //Clear Comment
}
/* Parse Enum Declaration
*/
void penum(int m, int bitmsk) {
int enmval = (bitmsk) ? 1 : 0;
DEBUG("dclrtn.enum: Processing Enum Declarations with BITMSK %d\n", bitmsk)
if (m != MTNONE) ERROR("Illegal Modifier %d in Enum Definition", m, EXIT_FAILURE)
expect('{');
do {
if (enmval > 0xFF) ERROR("Maximum ENUM or BITMASK value exceeded\n", 0, EXIT_FAILURE)
if (look('.'))
DEBUG("dclrtn.penum: Skipping sequence %d\n", enmval)
else {
getwrd(); //get defined identifier
DEBUG("dclrtn.penum: Enumerating '%s'", word)
DEBUG("dclrtn.penum: as %d\n", enmval);
strncpy(defnam, word, VARLEN);
sprintf(value, "%d", enmval);
addcon(enmval);
}
if (bitmsk) enmval = enmval << 1;
else enmval++;
} while (look(','));
expect('}');
expect(';');
DEBUG("dclrtn.penum: Enum Declaration Completed\n", 0)
}
/* Parse Enum Declaration*/
void pstrct(int m) {
DEBUG("dclrtn.pstrct: Processing Struct Declarations\n", 0)
getwrd(); //Parse Structure Name
if (look('{')) defstc(); //Parse Struct Definition
else addstc(); //Parse and Compile Struct Declaration
cmtlin(); //Write out declaration comment
}
/* Parse Variable/Function Declaration*/
void pdecl(int m, int t) {
DEBUG("dclrtn.pdegl: Processing declaration(s) of type %d\n", t)
do {
getwrd();
if (match('(')) {
if (m > MTNONE) ERROR("dclrtn.pdegl: Illegal Modifier %d in Function Definition\n", m, EXIT_FAILURE)
addfnc(); //Add Function Call
return;
}
addvar(m, t);
} while (look(','));
expect(';');
DEBUG("dclrtn.pdegl: Declaration completed\n", 0)
cmtlin(); //Write out declaration comment
}
/* Check for and Parse Type Keyword *
* Returns: Type (enum types) */
int ctype(int reqtyp) {
if (wordis("BITMASK")) return TBITMASK;
else if (wordis("STRUCT")) return TSTRUCT;
else if (wordis("ENUM")) return TENUM;
else if (wordis("CHAR")) return TCHAR;
else if (wordis("INT")) return TINT;
else if (wordis("VOID")) return TVOID;
else if (reqtyp) ERROR("Type Declaration Expected\n", 0, EXIT_FAILURE)
return TNONE;
}
/* Check for and Parse Type Keyword *
* Args: m - Modifier Type */
int ptype(int m) {
int type = ctype(FALSE);
switch (type) {
case TSTRUCT: pstrct(m); break; //Parse 'struct' declaration
case TENUM: penum(m, FALSE); break; //Parse 'enum' declaration
case TBITMASK: penum(m, TRUE); break; //Parse 'enum' declaration
case TCHAR: pdecl(m, VTCHAR); break; //Parse 'char' declaration
case TINT: pdecl(m, VTINT); break; //Parse 'int' declaration
case TVOID: pdecl(m, VTVOID); break; //Parse 'void' declaration
default: return FALSE;
}
return TRUE;
}
int pmtype(int m) {
getwrd();
if (m == MTALGN && wordis("CONST")) {m = m | MTCONST; getwrd();}
DEBUG("dclrtn.pmtype: Parsing type %s\n", word)
return ptype(m);
}
/* Check for and Parse Modifier */
int pmodfr(void) {
DEBUG("dclrtn.pmodfr: Parsing modifier '%s'\n", word)
int result = TRUE;
if (wordis("ALIAS")) { pmtype(MTALS); }
else if (wordis("ALIGNED")) { pmtype(MTALGN); }
else if (wordis("CONST")) { pmtype(MTCONST); }
else if (wordis("ZEROPAGE")) { pmtype(MTZP); }
else result = FALSE;
return result;
}