1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2024-11-02 08:06:55 +00:00
C02/vars.c

266 lines
6.0 KiB
C
Raw Normal View History

/*************************************
* C02 Variable Management Routines *
*************************************/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include "common.h"
#include "files.h"
#include "asm.h"
#include "parse.h"
#include "label.h"
#include "vars.h"
/* Lookup variable name in variable table *
* Returns index into varnam array *
* FALSE if variable was not found */
int lookup(char *name)
{
int i;
DEBUG("Looking up variable '%s'\n", word);
for (i=0; i<varcnt; i++) {
if (strcmp(varnam[i], name) == 0)
return i;
}
return -1;
}
/* Check if variable has been defined */
int symdef(char *name)
{
if (lookup(name) < 0)
return FALSE;
else
return TRUE;
}
/* Check for variable *
* Generates error if variable is undefined */
void chksym(char *name)
{
if (!symdef(name))
ERROR("Undeclared variable '%s' encountered\n", word, EXIT_FAILURE);
}
/* Parse Variable Name *
* Generates error if not a simple variable */
void reqvar()
{
prsvar();
if (valtyp != VARIABLE)
expctd("Variable");
}
/* Check for Array specifier and get size *
* Sets: value - array size (as string) *
* "" if not an array */
void pvarsz()
{
DEBUG("Checking for array definition\n", 0);
value[0] = 0;
if (match('[')) {
skpchr();
if (alcvar) {
DEBUG("Parsing array size\n", 0);
prsnum(0xFF);
}
expect(']');
}
if (!alcvar)
strcpy(value, "*");
}
/* Parse Data Constant */
void prsdtc()
{
dtype = DTBYTE;
prscon(0xff);
}
/* Parse Data String */
void prsdts()
{
dtype = DTSTR;
2017-05-01 01:17:50 +00:00
getstr();
strcpy(value, word);
DEBUG("Parsed Data String '%s'\n", value);
}
2017-05-01 01:17:50 +00:00
/* Store variable data *
* Uses: value - Data to store *
* Sets: datvar[] - Variable Data *
* datlen[] - Data Length */
2017-05-01 01:17:50 +00:00
void setdat()
{
int i;
if (dtype == DTBYTE) {
DEBUG("Setting variable data to '%d'\n", cnstnt);
dlen = 1;
datvar[dsize++] = cnstnt;
}
else {
DEBUG("Setting variable data to '%s'\n", value);
dlen = strlen(value);
for (i=0; i<dlen; i++)
datvar[dsize++] = value[i];
}
datlen[varcnt] = dlen;
dattyp[varcnt] = dtype;
}
/* Parse and store variable data */
void prsdat()
{
DEBUG("Checking for variable data\n", 0);
if (!look('=')) {
datlen[varcnt] = 0;
return;
}
skpspc();
if (isnpre())
2017-05-01 01:17:50 +00:00
prsdtc(0xff); //Parse Data Constant
else if (match('"'))
2017-05-01 01:17:50 +00:00
prsdts(); //Parse Data String
else
expctd("numeric or string constant");
setdat(); //Store Data Value
}
/* Add Variable to Variable table *
2017-05-01 01:17:50 +00:00
* Uses: word - variable name *
* value - variable size */
void setvar(int t)
{
DEBUG("Adding variable '%s'\n", word);
strncpy(varnam[varcnt], vrname, VARLEN);
2017-05-01 01:17:50 +00:00
vartyp[varcnt] = t;
strncpy(varsiz[varcnt], value, 3);
DEBUG("Added at index %d\n", varcnt);
}
/* Parse and Compile Variable Declaration *
* Uses: word - variable name */
void addvar(int t)
{
strcpy(vrname, word); //Save Variable Name
if (symdef(vrname))
ERROR("Duplicate declaration of variable '%s\n", word,EXIT_FAILURE);
if (t == VTVOID)
ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE);
2017-05-01 01:17:50 +00:00
pvarsz(); //Check for Array Declaration and Get Size
setvar(t); //Add to Variable Table
prsdat(); //Parse Variable Data
varcnt++; //Increment Variable Counter
}
/* Add Function Definition */
void addfnc()
{
strcpy(fncnam, word); //Save Function Name
prmcnt = 0; //Set Number of Parameters
skpspc(); //Skip Spaces
if (isalph()) { //Parse Parameters
reqvar(); //Get First Parameter
strcpy(prmtra, value);
prmcnt++;
if (look(',')) {
reqvar(); //Get Second Parameter
strcpy(prmtry, value);
prmcnt++;
if (look(',')) {
reqvar(); //Third Parameter
strcpy(prmtrx, value);
prmcnt++;
}
}
}
expect(')');
if (look(';')) //Forward Definition
return;
setlbl(fncnam); //Set Function Entry Point
if (prmcnt > 0)
asmlin("STA", prmtra); //Store First Parameter
if (prmcnt > 1)
asmlin("STY", prmtry); //Store Second Parameter
if (prmcnt > 2)
asmlin("STX", prmtrx); //Store Third Parameter
endlbl[0] = 0; //Create Dummy End Label
pshlbl(LTFUNC, endlbl); //and Push onto Stack
bgnblk(TRUE); //Start Program Block
}
/* (Check For and) Parse Variable Declaration*/
void pdecl(int t)
{
DEBUG("Processing variable declarations(s) of type %d\n", t);
while(TRUE) {
getwrd();
if (look('(')) {
addfnc(); //Add Function Call
return;
}
addvar(t);
if (!look(','))
break;
}
expect(';');
}
/* Write Variable Data */
void vardat(int i)
{
int j;
DEBUG("Building Data for Variable '%s'\n", varnam[i]);
value[0] = 0;
for (j=0; j<datlen[i]; j++) {
if (j) strcat(value,",");
2017-05-01 01:17:50 +00:00
sprintf(word, "$%hhX", datvar[dlen++]);
strcat(value, word);
}
if (dattyp[i] == DTSTR) strcat(value, ",$00");
DEBUG("Allocating Data for Variable '%s'\n", varnam[i]);
asmlin(BYTEOP, value);
}
/* Write Variable Table */
void vartbl()
{
int i;
DEBUG("Writing Variable Table", 0);
dlen = 0;
for (i=0; i<varcnt; i++) {
strcpy(lblasm, varnam[i]);
DEBUG("Set Label to '%s'\n", lblasm);
if (strcmp(varsiz[i], "*") == 0)
continue;
else if (datlen[i])
vardat(i); //Write Variable Data
else if (strlen(varsiz[i]) > 0) {
DEBUG("Allocating array '%s'\n", varnam[i]);
asmlin(STROP, varsiz[i]);
}
else {
DEBUG("Allocating variable '%s'\n", varnam[i]);
asmlin(BYTEOP, "0");
}
}
}
/* Print Variable Table to Log File */
void logvar()
{
int i;
2017-05-01 01:17:50 +00:00
fprintf(logfil, "\n%-31s %s %s %s\n", "Variable", "Type", "Size", "Data");
for (i=0; i<varcnt; i++)
{
2017-05-01 01:17:50 +00:00
fprintf(logfil, "%-31s %4d %4s %1d-%d\n", varnam[i], vartyp[i], varsiz[i], dattyp[i], datlen[i]);
}
}