1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2024-07-06 12:28:57 +00:00
C02/stmnt.c

210 lines
4.1 KiB
C

/************************************
* C02 Statement 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 "vars.h"
#include "expr.h"
#include "label.h"
#include "stmnt.h"
/* parse and compile if statement */
void pif() {
DEBUG("Parsing IF statement '%c'\n", nxtchr);
expect('(');
newlbl(LTIF);
prscnd(')'); //Parse Conditional Expession
}
/* parse and compile else statement */
void pelse() {
DEBUG("Parsing ELSE statement '%c'\n", nxtchr);
strcpy(lbltmp, lblasm);
lblasm[0] = 0;
newlbl(LTIF);
asmlin("JMP", curlbl);
strcpy(lblasm, lbltmp);
}
/* parse and compile for statement */
void pfor() {
ERROR("Unsupported statement FOR encountered",0, EXIT_FAILURE);
}
/* parse and compile if statement */
void pgoto() {
DEBUG("Parsing GOTO statement\n", 0);
getwrd();
ACMNT(word);
asmlin("JMP", word);
expect(';');
}
/* parse and compile if statement */
void pretrn() {
DEBUG("Parsing RETURN statement\n", 0);
if (!look(';'))
prsxpr(';');
asmlin("RTS", "");
}
/* parse and compile while statement */
void pwhile() {
DEBUG("Parsing WHILE statement '%c'\n", nxtchr);
expect('(');
newlbl(LTLOOP); //create Loop Label
setlbl(curlbl);
newlbl(LTEND); //Create End Label
prscnd(')'); //Parse Conditional Expession
}
/* generate unimplemented statement error */
void punimp() {
ERROR("Unimplemented statement '%s' encountered", word, EXIT_FAILURE);
}
/* Parse and compile assignment */
void prsasn()
{
DEBUG("Parsing assignment of variable '%s''\n", asnvar);
skpchr(); //skip equals sign
ACMNT("=");
prsxpr(';');
if (strlen(asnidx)) {
asmlin("LDX", asnidx);
strcat(asnvar,",X");
}
asmlin("STA", asnvar);
}
void prcpop() {
DEBUG("Processing post operation '%c'\n", oper);
switch(oper)
{
case '+':
asmlin("INC", asnvar);
break;
case '-':
asmlin("DEC", asnvar);
break;
case '<':
asmlin("ASL", asnvar);
break;
case '>':
asmlin("LSR", asnvar);
break;
default:
printf("Unrecognized post operator '%c'\n", oper);
exterr(EXIT_FAILURE);
}
}
/* Parse Post Operator */
void prspop() {
oper = getnxt();
CCMNT(oper); CCMNT(oper);
DEBUG("Checking for post operation '%c'\n", oper);
if (nxtchr == oper) {
skpchr();
prcpop(); //Process Post-Op
expect(';');
}
else
expctd("post operator");
}
/* Parse function call in first expression */
void prsfnc()
{
char fnname[255]; /*Function name*/
DEBUG("Processing function call '%s'...\n", term);
strcpy(fnname, word);
skpchr(); //skip open paren
CCMNT('(');
skpspc();
if (match(')')) //if no arguments
skpchr(); // skip close paren
else { //otherwise
if (look('&')) {
prsadr(')');
}
else
prsxpr(')'); //parse expression
}
asmlin("JSR", fnname);
expect(';');
}
/* parse and compile identifier (variable or function call) */
void prssym()
{
DEBUG("Parsing Identifier %s\n", word);
valtyp = get_vartyp();
if (valtyp == FUNCTION) {
prsfnc(); //Parse Function Call
return;
}
chksym(word);
strcpy(asnvar, word); //sav variable to assign to
if (valtyp == ARRAY) {
prsidx(); //Parse Array Index
strncpy(asnidx, value, VARLEN);
}
else
asnidx[0] = 0;
if (ispopr(nxtchr))
prspop(); //Parse Post Operator
else
{
skpspc();
if (match('='))
prsasn(); //Parse Assignment
else
expctd("=");
}
}
/* parse and compile program statement */
void pstmnt()
{
DEBUG("Parsing statement '%s'\n", word);
if(match(':')) {
prslbl(); //Parse Label
return;
}
if (wordis("if")) {
pif();
return;
}
if (wordis("else")) {
pelse();
return;
}
if (wordis("while")) {
pwhile();
return;
}
if (wordis("for")) {
punimp();
return;
}
else if (wordis("goto"))
pgoto();
else if (wordis("return"))
pretrn();
else
prssym();
if (lblcnt) {
lbllin();
}
}