1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2024-08-30 15:29:04 +00:00
C02/expr.c

211 lines
4.5 KiB
C
Raw Normal View History

/***********************************
* C02 Expression Parsing 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 "vars.h"
2017-05-01 01:17:50 +00:00
#include "label.h"
#include "expr.h"
/* Parse value (constant or identifier) *
* Sets: value - the value (as a string) *
* valtyp - value type */
void prsval()
{
DEBUG("Parsing value\n", 0);
//expdef(); //Check for and expand define -- BROKEN!
if (iscpre())
prscon(0xff); //Parse Constant
2017-05-01 01:17:50 +00:00
else if (isalph()) {
prsvar(); //Parse Variable
2017-05-01 01:17:50 +00:00
}
else
expctd("constant or variable");
skpspc();
}
/* Parse array index *
* Sets: value - array index or *
* "" if no index defined */
void prsidx()
{
expect('[');
prsval();
DEBUG("Parsed array index '%s'\n", value);
expect(']');
}
2017-05-01 01:17:50 +00:00
/* Parse term in expression *
* Sets: term - the term (as a string) *
* trmtxt - type of term */
void prstrm()
{
DEBUG("Parsing term\n", 0);
prsval();
if (valtyp == FUNCTION) {
ERROR("Function call only allowed in first term\n", 0, EXIT_FAILURE);
}
strcpy(term, value);
DEBUG("Parsed term %s\n", term);
trmtxt = valtyp;
if (trmtxt == ARRAY) {
prsidx();
asmlin("LDX", value);
strcat(term, ",X");
}
skpspc();
}
2017-05-01 01:17:50 +00:00
/* Compile Address Reference */
void prcadr(char* symbol)
{
strcpy(word,"#<");
2017-05-01 01:17:50 +00:00
strcat(word,symbol);
asmlin("LDX", word);
strcpy(word,"#>");
2017-05-01 01:17:50 +00:00
strcat(word,symbol);
asmlin("LDY", word);
2017-05-01 01:17:50 +00:00
}
/* Parse and Compile Address of Operator */
void prsadr()
{
prsvar();
DEBUG("Parsing address of variable '%s'\n", value);
prcadr(value); //Compile Address Reference
}
2017-05-01 01:17:50 +00:00
/* Parse and Create Anonymous String */
void prsstr()
{
DEBUG("Parsing anonymous string\n", 0);
newlbl(vrname); //Generate Variable Name
2017-05-01 01:17:50 +00:00
value[0] = 0; //Use Variable Size 0
setvar(VTCHAR); //Set Variable Name, Type, and Size
prsdts(); //Parse Data String
setdat(); //Set Variable Data
varcnt++; //Increment Variable Counter
prcadr(vrname); //Compile Address Reference
2017-05-01 01:17:50 +00:00
}
2017-05-01 01:17:50 +00:00
/* Parse Additional Function Parameters */
void prsfnp()
{
2017-05-01 01:17:50 +00:00
if (look(',')) {
if (look('&'))
prsadr();
else if (match('"'))
prsstr();
else {
prstrm();
asmlin("LDY", term);
if (look(',')) {
prsval();
asmlin("LDX", value);
}
}
}
}
/* Parse function call */
void prsfnc()
{
DEBUG("Processing Function Call '%s'...\n", term);
if (fnscnt >= MAXFNS)
ERROR("Maximum Function Call Depth Exceeded", 0, EXIT_FAILURE);
strcpy(fnstck[fnscnt++], term);
skpchr(); //skip open paren
CCMNT('(');
if (look('&'))
2017-05-01 01:17:50 +00:00
prsadr();
else if (match('"'))
prsstr();
else if (isvpre()) {
2017-05-01 01:17:50 +00:00
prsxpr(0);
prsfnp();
}
expect(')');
2017-05-01 01:17:50 +00:00
asmlin("JSR", fnstck[--fnscnt]);
skpspc();
}
/* Parse first term of expession *
* First term can include function calls */
void prsftm()
{
prsval();
DEBUG("Processing first term '%s'...\n", value);
strcpy(term, value);
trmtxt = valtyp;
if (trmtxt == FUNCTION) {
2017-05-01 01:17:50 +00:00
prsfnc(); //Parse Expression Function
return;
}
if (trmtxt == ARRAY) {
prsidx();
asmlin("LDX", value);
strcat(term, ",X");
}
asmlin("LDA", term);
}
/* Process Arithmetic or Bitwise Operator *
* and the term that follows it */
void prcopr()
{
DEBUG("Processing operator '%c'\n", oper);
switch(oper)
{
case '+':
asmlin("CLC", "");
asmlin("ADC", term);
break;
case '-':
asmlin("SEC", "");
asmlin("SBC", term);
break;
case '&':
asmlin("AND", term);
break;
case '|':
case '!': //For systems that don't have pipe in character set
asmlin("ORA", term);
break;
case '^': //Looks like an up-arrow in some character sets
asmlin("EOR", term);
break;
default:
printf("Unrecognized operator '%c'\n", oper);
exterr(EXIT_FAILURE);
}
}
/* Parse and compile expression */
void prsxpr(char trmntr)
{
DEBUG("Parsing expression\n", 0);
skpspc();
2017-05-01 01:17:50 +00:00
if (match('-')) {
DEBUG("Processing unary minus", 0);
asmlin("LDA", "#$00"); //Handle Unary Minus
}
else
prsftm(); //Parse First Term
while (isoper())
{
prsopr(); //Parse Operator
prstrm(); //Parse Term
prcopr(); //Process Operator
}
if (trmntr)
expect(trmntr);
}