/********************************************************************/
/* NEGA.C */
/********************************************************************/
/* The NEGA compiler, v3.22 */
/* Copyright (C) Mar. 1997 by Tylisha C. Andersen */
/* Original idea developed by Jim Neil, c. 1989 */
/********************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#define isxalpha(c) xalphatbl[(unsigned char) (c)]
int FindCond(char *in, char *out);
int GetLine(char *buf);
int GetStatement(void);
int GetToken(char *buf, int flg);
void InitToken(void);
int IsEmpty(char *buf);
int ParseBumping(void);
int ParseCond(char *in, char *out, int flip);
int ParseStatement(void);
int PeekToken(char *buf);
int ReadLine(char *buf);
void StripComments(char *buf);
void soutput(char *s, char *fmt, ...);
void xerror(int en);
/********************************************************************/
/* Data section */
/********************************************************************/
char xalphatbl[256] = { // see isxalpha() macro
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
};
char InName[128], OutName[128];
char ErrorBuf[400], GenBuf[300];
char SendBuf[3000], FollowBuf[1000];
char LineBuf[300];
long LineCtr = 0;
int LinePos;
int BlkStack[30], BlkType[30];
int BlkPtr = -1, NextBlk = 1;
int MainBlk = -1;
char Strs[32][128];
char Stat[64];
FILE *InFile = NULL, *OutFile = NULL;
/********************************************************************/
/* Main procedure */
/********************************************************************/
main(int argc, char *argv[])
{
printf("▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\n"
"█│ The NEGA compiler v3.22 (symbolic assembler) │█\n"
"█│ Copyright (C) Mar. 1997 by Tylisha C. Andersen │█\n"
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀\n\n");
if(argc < 2) {
printf("Syntax: NEGA file[.N]\n");
exit(1);
}
strcpy(InName, argv[1]);
strupr(InName);
if(!strchr(InName, '.'))
strcat(InName, ".N");
strcpy(OutName, InName);
strcpy(strchr(OutName, '.'), ".ASM");
if((InFile = fopen(InName, "rb")) == NULL) {
sprintf(ErrorBuf, "can't open input file %s", InName);
xerror(0);
}
if((OutFile = fopen(OutName, "wb")) == NULL) {
sprintf(ErrorBuf, "can't open output file %s", OutName);
xerror(1);
}
setvbuf(InFile, NULL, 16384, _IOFBF);
setvbuf(OutFile, NULL, 16384, _IOFBF);
printf("input: %s\n", InName);
printf("output: %s\n\n", OutName);
while(ParseStatement());
printf("\rprocessed %ld lines\n", LineCtr);
fclose(InFile);
fclose(OutFile);
return 0;
}
/********************************************************************/
/* Parse one statement */
/********************************************************************/
int ParseStatement(void)
{
int i, j, true_blk, to_follow = 0;
int k, sshift;
char f_char, *p;
static char cond1[5], cond2[5];
static char sbuf[5], ibuf[64];
if(!PeekToken(&f_char)) return 0; // peek token to get char
if(!GetStatement()) return 0; // get the statement
if(BlkType[true_blk = BlkPtr] == 0) // find the true block
true_blk--;
FollowBuf[0] = SendBuf[0] = 0; // clear output buffers
to_follow = ParseBumping(); // parse pointer bumping
if(strchr(Stat, '{') || strchr(Stat, '}')) {
////////////////////////////////////////////////////// BLOCK STRUCTURES
FindCond(Stat, cond1); // decode condition(s)
FindCond(Stat, cond2);
if((p = strchr(Stat, ',')) != NULL) {
////////////////////////////////////////////////////// ELSE CLAUSE
if(!strchr(Stat, '{')) goto ps_blkerr; // ELSE must have '{'
strcpy(ibuf, p + 1); *(p + 1) = 0; // separate into halves
if(ibuf[j = 0] == '.') j = 1; // check for long jump indicator
// j = long jump flag
k = 0; // assume end jump ok
if(!strcmp(Stat, "},")) // nothing
;
else if(Stat[0] != '}') {
i = true_blk; // find the penultimate block
if(--i < 0) goto ps_noblk;
if(BlkType[i] == 0) i--;
if(!strcmp(Stat, ".},") || !strcmp(Stat, "..},")) {
soutput(SendBuf, "\tjmp\t%s?End%04X\n",
Stat[1] == '.' ? "" : "short ", BlkStack[i]);
k = 1; // end jump not needed
} else if(!strcmp(Stat, "?C},") && !strcmp(cond1, "=="))
soutput(SendBuf, "\tjcxz\t?End%04X\n", BlkStack[i]);
else if(!strcmp(Stat, "-C},") && !strcmp(cond1, "=="))
soutput(SendBuf, "\tloopz\t?End%04X\n", BlkStack[i]);
else if(!strcmp(Stat, "-C},") && !strcmp(cond1, "<>"))
soutput(SendBuf, "\tloopnz\t?End%04X\n", BlkStack[i]);
else if(!strcmp(Stat, "-.},"))
soutput(SendBuf, "\tloop\t?End%04X\n", BlkStack[i]);
else {
ParseCond(cond1, sbuf, 0); // parse conditions
if(!strcmp(Stat, "C},") || !strcmp(Stat, ".C},"))
soutput(SendBuf, "\tj%s\t%s?End%04X\n", sbuf, Stat[0] == '.' ? "" : "short ", BlkStack[i]);
else goto ps_blkerr;
}
} else {
ParseCond(cond1, sbuf, 0); // parse other conditions
if(!strcmp(Stat, "}C,")) soutput(SendBuf, "\tj%s\t?Top%04X\n", sbuf, BlkStack[BlkPtr]);
else if(!strcmp(Stat, "}.,")) soutput(SendBuf, "\tjmp\t?Top%04X\n", BlkStack[BlkPtr]);
else if(!strcmp(Stat, "}-.,")) soutput(SendBuf, "\tloop\t?Top%04X\n", BlkStack[BlkPtr]);
else if(!strcmp(Stat, "}.C,")) { // distant loop
ParseCond(cond1, sbuf, k = 1); // parse as reverse
if(!j) { // short jump to end
soutput(SendBuf, "\tj%s\t?End%04X\n", sbuf, BlkStack[true_blk]);
soutput(SendBuf, "\tjmp\t?Top%04X\n", BlkStack[BlkPtr]);
} else { // long jump to end
soutput(SendBuf, "\tj%s\t?Els%04X\n", sbuf, NextBlk);
soutput(SendBuf, "\tjmp\t?Top%04X\n", BlkStack[BlkPtr]);
soutput(SendBuf, "?Els%04X:\n", NextBlk++);
soutput(SendBuf, "\tjmp\t?End%04X\n", BlkStack[true_blk]);
}
} else if(!strcmp(Stat, "}?C;") && !strcmp(cond1, "==")) {
soutput(SendBuf, "\tjcxz\t?Top%04X\n", BlkStack[BlkPtr]);
} else if(!strcmp(Stat, "}-C;") && !strcmp(cond1, "==")) {
soutput(SendBuf, "\tloopz\t?Top%04X\n", BlkStack[BlkPtr]);
} else if(!strcmp(Stat, "}-C;") && !strcmp(cond1, "<>")) {
soutput(SendBuf, "\tloopnz\t?Top%04X\n", BlkStack[BlkPtr]);
} else goto ps_blkerr;
}
if(strchr(Stat, 'C')) // cond1 = second conditional
strcpy(cond1, cond2);
if(!k) { // output jump to end if not done already
soutput(SendBuf, "\tjmp\t%s?End%04X\n",
j ? "" : "short ", BlkStack[true_blk]);
}
soutput(SendBuf, "?Els%04X:\n", BlkStack[BlkPtr]);
if(BlkType[BlkPtr] == 1) // if true block, add an else block
if(++BlkPtr >= 30) goto ps_nesterr;
BlkStack[BlkPtr] = NextBlk++; // set up new block
BlkType[BlkPtr] = 0;
if(!strcmp(ibuf, "{") || !strcmp(ibuf, ".{"))
; // nothing
else if(!strcmp(ibuf, "C{")) { // conditional else
ParseCond(cond1, sbuf, 1);
soutput(SendBuf, "\tj%s\t?Els%04X\n", sbuf, BlkStack[BlkPtr]);
} else if(!strcmp(ibuf, ".C{")) { // IF clause (near jump)
ParseCond(cond1, sbuf, 0);
soutput(SendBuf, "\tj%s\t?Top%04X\n", sbuf, BlkStack[BlkPtr]);
soutput(SendBuf, "\tjmp\t?Els%04X\n", BlkStack[BlkPtr]);
} else if(!strcmp(ibuf, "?C{") && !strcmp(cond1, "<>")) {
soutput(SendBuf, "\tjcxz\t?Els%04X\n", BlkStack[BlkPtr]);
} else if(!strcmp(ibuf, "-.{")) {
soutput(SendBuf, "\tloop\t?Els%04X\n", BlkStack[BlkPtr]);
} else if(!strcmp(ibuf, "-C{") && !strcmp(cond1, "<>")) {
soutput(SendBuf, "\tloopne\t?Els%04X\n", BlkStack[BlkPtr]);
} else if(!strcmp(ibuf, "-C{") && !strcmp(cond1, "==")) {
soutput(SendBuf, "\tloope\t?Els%04X\n", BlkStack[BlkPtr]);
} else goto ps_blkerr;
soutput(SendBuf, "?Top%04X:\n", BlkStack[BlkPtr]);
} else if(strchr(Stat, ';')) {
////////////////////////////////////////////////////// END OF BLOCK
if(BlkPtr < 0) goto ps_blkerr; // no block here?
if(!strcmp(Stat, "};")) // nothing
;
else if(Stat[0] != '}') {
i = true_blk; // find the penultimate block
if(--i < 0) goto ps_noblk;
if(BlkType[i] == 0) i--;
if(!strcmp(Stat, ".};") || !strcmp(Stat, "..};"))
soutput(SendBuf, "\tjmp\t%s?End%04X\n", Stat[1] == '.' ? "" : "short ", BlkStack[i]);
else if(!strcmp(Stat, "?C};") && !strcmp(cond1, "=="))
soutput(SendBuf, "\tjcxz\t?End%04X\n", BlkStack[i]);
else if(!strcmp(Stat, "-C};") && !strcmp(cond1, "=="))
soutput(SendBuf, "\tloopz\t?End%04X\n", BlkStack[i]);
else if(!strcmp(Stat, "-C};") && !strcmp(cond1, "<>"))
soutput(SendBuf, "\tloopnz\t?End%04X\n", BlkStack[i]);
else if(!strcmp(Stat, "-.};"))
soutput(SendBuf, "\tloop\t?End%04X\n", BlkStack[i]);
else {
ParseCond(cond1, sbuf, 0); // parse conditions
if(!strcmp(Stat, "C};") || !strcmp(Stat, ".C};"))
soutput(SendBuf, "\tj%s\t%s?End%04X\n", sbuf, Stat[0] == '.' ? "" : "short ", BlkStack[i]);
else goto ps_blkerr;
}
} else {
ParseCond(cond1, sbuf, 0); // parse other conditions
if(!strcmp(Stat, "}C;")) soutput(SendBuf, "\tj%s\t?Top%04X\n", sbuf, BlkStack[BlkPtr]);
else if(!strcmp(Stat, "}.;")) soutput(SendBuf, "\tjmp\t?Top%04X\n", BlkStack[BlkPtr]);
else if(!strcmp(Stat, "}-.;")) soutput(SendBuf, "\tloop\t?Top%04X\n", BlkStack[BlkPtr]);
else if(!strcmp(Stat, "}.C;")) { // distant loop
ParseCond(cond1, sbuf, 1); // parse as reverse
soutput(SendBuf, "\tj%s\t?Els%04X\n", sbuf, BlkStack[BlkPtr]);
soutput(SendBuf, "\tjmp\t?Top%04X\n", BlkStack[BlkPtr]);
} else if(!strcmp(Stat, "}?C;") && !strcmp(cond1, "==")) {
soutput(SendBuf, "\tjcxz\t?Top%04X\n", BlkStack[BlkPtr]);
} else if(!strcmp(Stat, "}-C;") && !strcmp(cond1, "==")) {
soutput(SendBuf, "\tloopz\t?Top%04X\n", BlkStack[BlkPtr]);
} else if(!strcmp(Stat, "}-C;") && !strcmp(cond1, "<>")) {
soutput(SendBuf, "\tloopnz\t?Top%04X\n", BlkStack[BlkPtr]);
} else goto ps_blkerr;
}
soutput(SendBuf, "?Els%04X:\n", BlkStack[BlkPtr]);
if(BlkType[BlkPtr] == 0) BlkPtr--;
soutput(SendBuf, "?End%04X:\n", BlkStack[BlkPtr--]);
} else {
////////////////////////////////////////////////////// START OF BLOCK
if(++BlkPtr >= 30) goto ps_nesterr; // add a true block
BlkStack[BlkPtr] = NextBlk++;
BlkType[BlkPtr] = 1;
if(!strcmp(Stat, "{")) // nothing
;
else if(!strcmp(Stat, "C{")) { // IF clause (short jump)
ParseCond(cond1, sbuf, 1);
soutput(SendBuf, "\tj%s\t?Els%04X\n", sbuf, BlkStack[BlkPtr]);
} else if(!strcmp(Stat, ".C{")) { // IF clause (near jump)
ParseCond(cond1, sbuf, 0);
soutput(SendBuf, "\tj%s\t?Top%04X\n", sbuf, BlkStack[BlkPtr]);
soutput(SendBuf, "\tjmp\t?Els%04X\n", BlkStack[BlkPtr]);
} else if(!strcmp(Stat, "?C{") && !strcmp(cond1, "<>")) {
soutput(SendBuf, "\tjcxz\t?Els%04X\n", BlkStack[BlkPtr]);
} else if(!strcmp(Stat, ".{")) {
soutput(SendBuf, "\tjmp\tshort ?Els%04X\n", BlkStack[BlkPtr]);
} else if(!strcmp(Stat, "..{")) {
soutput(SendBuf, "\tjmp\t?Els%04X\n", BlkStack[BlkPtr]);
} else if(!strcmp(Stat, "-.{")) {
soutput(SendBuf, "\tloop\t?Els%04X\n", BlkStack[BlkPtr]);
} else if(!strcmp(Stat, "-C{") && !strcmp(cond1, "<>")) {
soutput(SendBuf, "\tloopne\t?Els%04X\n", BlkStack[BlkPtr]);
} else if(!strcmp(Stat, "-C{") && !strcmp(cond1, "==")) {
soutput(SendBuf, "\tloope\t?Els%04X\n", BlkStack[BlkPtr]);
} else goto ps_blkerr;
soutput(SendBuf, "?Top%04X:\n", BlkStack[BlkPtr]);
}
} else if(f_char == 'A') {
////////////////////////////////////////////////////// ALPHA STATEMENT
if(!memcmp(Stat, "A=A=", 4)) { // reverse-output command?
p = Stat;
while(!memcmp(p, "A=", 2)) // check for POP sequence
p += 2;
if(*p == ';') { // if POP sequence, then
i = (p - 2 - Stat) / 2;
for(; i >= 0; i--) // output the POPs
soutput(SendBuf, "\tpop\t%s\n", Strs[i]);
goto ps_output;
} else { // chained assignments
j = (p - 2 - Stat) / 2; // j = work register
p = Stat; i = 0;
for(i = 0; i < j; i++) { // output in order
soutput(FollowBuf, "\tmov\t%s,%s\n",
Strs[i], Strs[j]);
}
for(i = 0; i < 32 - j; i++) // shift out assignment commands
strcpy(Strs[i], Strs[i + j]);
memmove(Stat, Stat + j * 2, 64 - j * 2);
to_follow = 1; // set follow flag
}
}
j = 1; // current operand
sshift = 0; // no shift for now
////////////////////////////////////////////////////// First-op-only commands
if(!memcmp(Stat, "A,", 2)) {
if(!memcmp(Stat, "A,A*A", 5)) { // three-operand IMUL
soutput(SendBuf, "\timul\t%s,%s,%s\n", Strs[0], Strs[1], Strs[2]);
sshift = 4; j++;
} else if(!strcmp(Stat, "A,A<A;")) { // shift left double
soutput(SendBuf, "\tshld\t%s,%s,%s\n", Strs[0], Strs[1], Strs[2]);
goto ps_output;
} else if(!strcmp(Stat, "A,A>A;")) { // shift right double
soutput(SendBuf, "\tshrd\t%s,%s,%s\n", Strs[1], Strs[0], Strs[2]);
goto ps_output;
} else if(!strcmp(Stat, "A,A=A;")) { // LDS, LES, etc.
soutput(SendBuf, "\tl%s\t%s,%s\n", Strs[0], Strs[1], Strs[2]);
goto ps_output;
}
} else if(!strcmp(Stat, "A=;")) { // single POP
soutput(SendBuf, "\tpop\t%s\n", Strs[0]); goto ps_output;
} else if(!memcmp(Stat, "A=A", 3)) { soutput(SendBuf, "\tmov\t%s,%s\n", Strs[0], Strs[1]); sshift = 2;
} else if(!memcmp(Stat, "A=+A", 4)) { soutput(SendBuf, "\tmovzx\t%s,%s\n",Strs[0], Strs[1]); sshift = 3;
} else if(!memcmp(Stat, "A=-A", 4)) { soutput(SendBuf, "\tmovsx\t%s,%s\n",Strs[0], Strs[1]); sshift = 4;
} else if(!memcmp(Stat, "A=+-A",5)) { soutput(SendBuf, "\tmovsx\t%s,%s\n",Strs[0], Strs[1]); sshift = 4;
} else if(!memcmp(Stat, "A==A", 4)) { soutput(SendBuf, "\txchg\t%s,%s\n", Strs[0], Strs[1]); sshift = 3;
} else if(!memcmp(Stat, "A===A",5)) { soutput(SendBuf, "\tlea\t%s,%s\n", Strs[0], Strs[1]); sshift = 4;
} else if(!memcmp(Stat, "A=", 2)) {
strcpy(ibuf, Stat + 2); // conditional set (SETNZ, SETBE, etc.)
i = strlen(ibuf) - 1;
if(ibuf[i] == ';') {
ibuf[i] = 0;
if(ParseCond(ibuf, sbuf, 0)) {
soutput(SendBuf, "\tset%s\t%s\n", sbuf, Strs[0]);
goto ps_output;
}
}
}
////////////////////////////////////////////////////// General commands
while(1) {
if(sshift > 0) { // shift out first part
memmove(Stat+1, Stat+1 + sshift, 63 - sshift);
j++; // next operand
}
if(!strcmp(Stat, "A;") && j > 1) {
goto ps_output;
} else if(!strcmp(Stat, "A+;")) { soutput(SendBuf, "\tinc\t%s\n", Strs[0]); goto ps_output;
} else if(!strcmp(Stat, "A-;")) { soutput(SendBuf, "\tdec\t%s\n", Strs[0]); goto ps_output;
} else if(!strcmp(Stat, "A++;")) { soutput(SendBuf, "\tinc\t%s\n\tinc\t%s\n", Strs[0], Strs[0]);
goto ps_output;
} else if(!strcmp(Stat, "A--;")) { soutput(SendBuf, "\tdec\t%s\n\tdec\t%s\n", Strs[0], Strs[0]);
goto ps_output;
} else if(!strcmp(Stat, "A&A?")) { soutput(SendBuf, "\ttest\t%s,%s\n", Strs[0], Strs[j]); goto ps_output;
} else if(!strcmp(Stat, "A-A?")) { soutput(SendBuf, "\tcmp\t%s,%s\n", Strs[0], Strs[j]); goto ps_output;
} else if(!strcmp(Stat, "A?")) { soutput(SendBuf, "\ttest\t%s,%s\n", Strs[0], Strs[0]); goto ps_output;
} else if(!memcmp(Stat, "A+++", 4)) { soutput(SendBuf, "\tinc\t%s\n", Strs[0]); j--; sshift = 1;
} else if(!memcmp(Stat, "A---", 4)) { soutput(SendBuf, "\tdec\t%s\n", Strs[0]); j--; sshift = 1;
} else if(!memcmp(Stat, "A+A", 3)) { soutput(SendBuf, "\tadd\t%s,%s\n", Strs[0], Strs[j]); sshift = 2;
} else if(!memcmp(Stat, "A++A", 4)) { soutput(SendBuf, "\tadc\t%s,%s\n", Strs[0], Strs[j]); sshift = 3;
} else if(!memcmp(Stat, "A-A", 3)) { soutput(SendBuf, "\tsub\t%s,%s\n", Strs[0], Strs[j]); sshift = 2;
} else if(!memcmp(Stat, "A--A", 4)) { soutput(SendBuf, "\tsbb\t%s,%s\n", Strs[0], Strs[j]); sshift = 3;
} else if(!memcmp(Stat, "A&A", 3)) { soutput(SendBuf, "\tand\t%s,%s\n", Strs[0], Strs[j]); sshift = 2;
} else if(!memcmp(Stat, "A|A", 3)) { soutput(SendBuf, "\tor\t%s,%s\n", Strs[0], Strs[j]); sshift = 2;
} else if(!memcmp(Stat, "A^A", 3)) { soutput(SendBuf, "\txor\t%s,%s\n", Strs[0], Strs[j]); sshift = 2;
} else if(!memcmp(Stat, "A*A", 3)) { soutput(SendBuf, "\timul\t%s,%s\n",Strs[0], Strs[j]); sshift = 2;
} else if(!memcmp(Stat, "A<A", 3)) { soutput(SendBuf, "\tshl\t%s,%s\n", Strs[0], Strs[j]); sshift = 2;
} else if(!memcmp(Stat, "A>A", 3)) { soutput(SendBuf, "\tshr\t%s,%s\n", Strs[0], Strs[j]); sshift = 2;
} else if(!memcmp(Stat, "A+->A",5)) { soutput(SendBuf, "\tsar\t%s,%s\n", Strs[0], Strs[j]); sshift = 4;
} else if(!memcmp(Stat, "A<<A", 4)) { soutput(SendBuf, "\trol\t%s,%s\n", Strs[0], Strs[j]); sshift = 3;
} else if(!memcmp(Stat, "A>>A", 4)) { soutput(SendBuf, "\tror\t%s,%s\n", Strs[0], Strs[j]); sshift = 3;
} else if(!memcmp(Stat, "A<<<A",5)) { soutput(SendBuf, "\trcl\t%s,%s\n", Strs[0], Strs[j]); sshift = 4;
} else if(!memcmp(Stat, "A>>>A",5)) { soutput(SendBuf, "\trcr\t%s,%s\n", Strs[0], Strs[j]); sshift = 4;
} else if(!memcmp(Stat, "A**A", 4)) { soutput(SendBuf, "\tmul\t%s,%s\n", Strs[0], Strs[j]); sshift = 3;
} else if(!memcmp(Stat, "A/A", 3)) { soutput(SendBuf, "\tidiv\t%s,%s\n",Strs[0], Strs[j]); sshift = 2;
} else if(!memcmp(Stat, "A//A", 4)) { soutput(SendBuf, "\tdiv\t%s,%s\n", Strs[0], Strs[j]); sshift = 3;
} else {
if(j == 1) goto ps_passthru; // pass-through?
else goto ps_error;
}
}
} else switch(f_char) { // OTHER STATEMENTS (by char)
case '!':
if(!strcmp(Stat, "!A;")) soutput(SendBuf, "\tint\t%s\n", Strs[0]);
else if(!strcmp(Stat, "!+;")) soutput(SendBuf, "\tsti\n");
else if(!strcmp(Stat, "!-;")) soutput(SendBuf, "\tcli\n");
else if(!strcmp(Stat, "!.=;")) soutput(SendBuf, "\tiret\n");
else if(!strcmp(Stat, "!+-;")) soutput(SendBuf, "\tinto\n");
else goto ps_error;
break;
case '\"':
if(!strcmp(Stat, "\"*;")) soutput(SendBuf, "\taam\n");
else if(!strcmp(Stat, "\"+;")) soutput(SendBuf, "\taaa\n");
else if(!strcmp(Stat, "\"-;")) soutput(SendBuf, "\taas\n");
else if(!strcmp(Stat, "\"/;")) soutput(SendBuf, "\taad\n");
else if(!strcmp(Stat, "\"*A;")) soutput(SendBuf, "\tdb\t0D4h,%s\n", Strs[0]);
else if(!strcmp(Stat, "\"/A;")) soutput(SendBuf, "\tdb\t0D5h,%s\n", Strs[0]);
else goto ps_error;
break;
case '#':
if(!strcmp(Stat, "#+-;")) soutput(SendBuf, "\tfabs\n");
else if(!strcmp(Stat, "#+;")) soutput(SendBuf, "\tfadd\n");
else if(!strcmp(Stat, "#+A;")) soutput(SendBuf, "\tfadd\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#A+A;")) soutput(SendBuf, "\tfadd\t%s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "#+.;")) soutput(SendBuf, "\tfaddp\n");
else if(!strcmp(Stat, "#+A.;")) soutput(SendBuf, "\tfaddp\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#A+A.;")) soutput(SendBuf, "\tfaddp\t%s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "#-+;")) soutput(SendBuf, "\tfchs\n");
else if(!strcmp(Stat, "#-?;")) soutput(SendBuf, "\tfcom\n");
else if(!strcmp(Stat, "#-A?;")) soutput(SendBuf, "\tfcom\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#-?.;")) soutput(SendBuf, "\tfcomp\n");
else if(!strcmp(Stat, "#-A?.;")) soutput(SendBuf, "\tfcomp\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#-?..;")) soutput(SendBuf, "\tfcompp\n");
else if(!strcmp(Stat, "#=-;")) soutput(SendBuf, "\tfdecstp\n");
else if(!strcmp(Stat, "#/;")) soutput(SendBuf, "\tfdiv\n");
else if(!strcmp(Stat, "#/A;")) soutput(SendBuf, "\tfdiv\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#A/A;")) soutput(SendBuf, "\tfdiv\t%s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "#/.;")) soutput(SendBuf, "\tfdivp\n");
else if(!strcmp(Stat, "#/A.;")) soutput(SendBuf, "\tfdivp\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#A/A.;")) soutput(SendBuf, "\tfdivp\t%s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "#//;")) soutput(SendBuf, "\tfdivr\n");
else if(!strcmp(Stat, "#//A;")) soutput(SendBuf, "\tfdivr\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#A//A;")) soutput(SendBuf, "\tfdivr\t%s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "#//.;")) soutput(SendBuf, "\tfdivrp\n");
else if(!strcmp(Stat, "#//A.;")) soutput(SendBuf, "\tfdivrp\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#A//A.;")) soutput(SendBuf, "\tfdivrp\t%s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "#&A;")) soutput(SendBuf, "\tffree\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#>+A;")) soutput(SendBuf, "\tfiadd\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#>-A?;")) soutput(SendBuf, "\tficom\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#>-A?.;")) soutput(SendBuf, "\tficomp\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#>/A;")) soutput(SendBuf, "\tfidiv\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#>//A;")) soutput(SendBuf, "\tfidivr\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#>=A;")) soutput(SendBuf, "\tfild\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#>*A;")) soutput(SendBuf, "\tfimul\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#=+;")) soutput(SendBuf, "\tfincstp\n");
else if(!strcmp(Stat, "#;")) soutput(SendBuf, "\tfinit\n");
else if(!strcmp(Stat, "#!;")) soutput(SendBuf, "\tfninit\n");
else if(!strcmp(Stat, "#>A=;")) soutput(SendBuf, "\tfist\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#>A=.;")) soutput(SendBuf, "\tfistp\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#>-A;")) soutput(SendBuf, "\tfisub\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#>--A;")) soutput(SendBuf, "\tfisubr\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#=A;")) soutput(SendBuf, "\tfld\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#*;")) soutput(SendBuf, "\tfmul\n");
else if(!strcmp(Stat, "#*A;")) soutput(SendBuf, "\tfmul\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#A*A;")) soutput(SendBuf, "\tfmul\t%s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "#*.;")) soutput(SendBuf, "\tfmulp\n");
else if(!strcmp(Stat, "#*A.;")) soutput(SendBuf, "\tfmulp\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#A*A.;")) soutput(SendBuf, "\tfmulp\t%s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "#%;")) soutput(SendBuf, "\tfprem\n");
else if(!strcmp(Stat, "#%%;")) soutput(SendBuf, "\tfprem1\n");
else if(!strcmp(Stat, "#<>;")) soutput(SendBuf, "\tfrndint\n");
else if(!strcmp(Stat, "#**;")) soutput(SendBuf, "\tfscale\n");
else if(!strcmp(Stat, "#A=;")) soutput(SendBuf, "\tfst\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#A=.;")) soutput(SendBuf, "\tfstp\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#A=?;")) soutput(SendBuf, "\tfstsw\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#!A=?;")) soutput(SendBuf, "\tfnstsw\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#-;")) soutput(SendBuf, "\tfsub\n");
else if(!strcmp(Stat, "#-A;")) soutput(SendBuf, "\tfsub\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#A-A;")) soutput(SendBuf, "\tfsub\t%s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "#-.;")) soutput(SendBuf, "\tfsubp\n");
else if(!strcmp(Stat, "#-A.;")) soutput(SendBuf, "\tfsubp\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#A-A.;")) soutput(SendBuf, "\tfsubp\t%s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "#--;")) soutput(SendBuf, "\tfsubr\n");
else if(!strcmp(Stat, "#--A;")) soutput(SendBuf, "\tfsubr\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#A--A;")) soutput(SendBuf, "\tfsubr\t%s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "#--.;")) soutput(SendBuf, "\tfsubrp\n");
else if(!strcmp(Stat, "#--A.;")) soutput(SendBuf, "\tfsubrp\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#A--A.;")) soutput(SendBuf, "\tfsubrp\t%s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "#?;")) soutput(SendBuf, "\tftst\n");
else if(!strcmp(Stat, "#<>?;")) soutput(SendBuf, "\tfucom\n");
else if(!strcmp(Stat, "#<>A?;")) soutput(SendBuf, "\tfucom\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#<>?.;")) soutput(SendBuf, "\tfucomp\n");
else if(!strcmp(Stat, "#<>A?.;")) soutput(SendBuf, "\tfucomp\t%s\n", Strs[0]);
else if(!strcmp(Stat, "#<>?..;")) soutput(SendBuf, "\tfucompp\n");
else if(!strcmp(Stat, "#.;")) soutput(SendBuf, "\tfwait\n");
else if(!strcmp(Stat, "#??;")) soutput(SendBuf, "\tfxam\n");
else if(!strcmp(Stat, "#==;")) soutput(SendBuf, "\tfxch\n");
else if(!strcmp(Stat, "#==A;")) soutput(SendBuf, "\tfxch\t%s\n", Strs[0]);
else goto ps_error;
break;
case '%':
if(!strcmp(Stat, "%.A;"))
soutput(SendBuf, "\textrn\t%s:proc\n\tcall\t%s\n", Strs[0], Strs[0]);
else if(!strcmp(Stat, "%=;")) soutput(SendBuf, "\tpopa\n");
else goto ps_error;
break;
case '&':
if(!strcmp(Stat, "&&A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, "&&;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "&;")) soutput(SendBuf, "\tclc\n");
else if(!strcmp(Stat, "&A;")) soutput(SendBuf, "\tsub\t%s,%s\n", Strs[0], Strs[0]);
else goto ps_error;
break;
case '\'':
if(!strcmp(Stat, "\'+;")) soutput(SendBuf, "\tdaa\n");
else if(!strcmp(Stat, "\'-;")) soutput(SendBuf, "\tdas\n");
else goto ps_error;
break;
case '*':
if(!strcmp(Stat, "**A;")) soutput(SendBuf, "\tmul\t%s\n", Strs[0]);
else if(!strcmp(Stat, "*A;")) soutput(SendBuf, "\timul\t%s\n", Strs[0]);
else if(!strcmp(Stat, "*;")) soutput(SendBuf, "\tcbw\n");
else if(!strcmp(Stat, "**;")) soutput(SendBuf, "\tcwd\n");
else if(!strcmp(Stat, "****;")) soutput(SendBuf, "\tcdq\n");
else if(!strcmp(Stat, "*=;")) soutput(SendBuf, "\tstosb\n");
else if(!strcmp(Stat, "**=;")) soutput(SendBuf, "\tstosw\n");
else if(!strcmp(Stat, "****=;")) soutput(SendBuf, "\tstosd\n");
else if(!strcmp(Stat, "*=*;")) soutput(SendBuf, "\tmovsb\n");
else if(!strcmp(Stat, "**=**;")) soutput(SendBuf, "\tmovsw\n");
else if(!strcmp(Stat, "****=****;")) soutput(SendBuf, "\tmovsd\n");
else if(!strcmp(Stat, "*-?")) soutput(SendBuf, "\tscasb\n");
else if(!strcmp(Stat, "**-?")) soutput(SendBuf, "\tscasw\n");
else if(!strcmp(Stat, "****-?")) soutput(SendBuf, "\tscasd\n");
else if(!strcmp(Stat, "*-*?")) soutput(SendBuf, "\tcmpsb\n");
else if(!strcmp(Stat, "**-**?")) soutput(SendBuf, "\tcmpsw\n");
else if(!strcmp(Stat, "****-****?")) soutput(SendBuf, "\tcmpsd\n");
else if(!strcmp(Stat, "*=@;")) soutput(SendBuf, "\tinsb\n");
else if(!strcmp(Stat, "**=@;")) soutput(SendBuf, "\tinsw\n");
else if(!strcmp(Stat, "****=@;")) soutput(SendBuf, "\tinsd\n");
else if(!strcmp(Stat, "**=@@;")) soutput(SendBuf, "\tinsw\n");
else if(!strcmp(Stat, "****=@@@@;")) soutput(SendBuf, "\tinsd\n");
else if(!strcmp(Stat, "*A=;")) soutput(SendBuf, "\tstos\t%s\n", Strs[0]);
else if(!strcmp(Stat, "*A=*A;")) soutput(SendBuf, "\tmovs\t%s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "*A-?")) soutput(SendBuf, "\tscas\t%s\n", Strs[0]);
else if(!strcmp(Stat, "*A-*A?")) soutput(SendBuf, "\tcmps\t%s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "*A=@;")) soutput(SendBuf, "\tins\t%s\n", Strs[0]);
else goto ps_error;
break;
case '+':
if(!strcmp(Stat, "++A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, "+-A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, "++;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "+-;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "+;")) soutput(SendBuf, "\tcld\n");
else goto ps_error;
break;
case '-':
if(!strcmp(Stat, "-.;")) { // Break by LOOP
if(true_blk < 0) goto ps_noblk;
soutput(SendBuf, "\tloop\t?End%04X\n", BlkStack[true_blk]);
} else if(!strcmp(Stat, "-==;")) { // Break by LOOPZ
if(true_blk < 0) goto ps_noblk;
soutput(SendBuf, "\tloopz\t?End%04X\n", BlkStack[true_blk]);
} else if(!strcmp(Stat, "-<>;")) { // Break by LOOPNZ
if(true_blk < 0) goto ps_noblk;
soutput(SendBuf, "\tloopnz\t?End%04X\n", BlkStack[true_blk]);
}
else if(!strcmp(Stat, "--A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, "-+A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, "--;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "-+;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "-;")) soutput(SendBuf, "\tstd\n");
else if(!strcmp(Stat, "-A;")) soutput(SendBuf, "\tneg\t%s\n", Strs[0]);
else if(!strcmp(Stat, "-.A;")) soutput(SendBuf, "\tloop\t%s\n", Strs[0]);
else if(!strcmp(Stat, "-==A;")) soutput(SendBuf, "\tloopz\t%s\n", Strs[0]);
else if(!strcmp(Stat, "-<>A;")) soutput(SendBuf, "\tloopnz\t%s\n", Strs[0]);
else goto ps_error;
break;
case '.':
if(!strcmp(Stat, ".A;") || !strcmp(Stat, "..A;")) {
if(Strs[0][1] == 0 && isdigit(Strs[0][0])) {
j = Strs[0][0] - '0'; // break multi-level
for(i = 0; i < j; i++) {
if(--true_blk < 0) goto ps_noblk;
if(BlkType[true_blk] == 0) true_blk--;
}
soutput(SendBuf, "\tjmp\t%s?End%04X\n",
Stat[1] == '.' ? "" : "short ", BlkStack[true_blk]);
} else {
soutput(SendBuf, "\tjmp\t%s%s\n",
Stat[1] == '.' ? "" : "short ", Strs[0]);
}
} else if(!strcmp(Stat, ".;") || !strcmp(Stat, "..;")) {
if(true_blk < 0) goto ps_noblk; // break out of block
soutput(SendBuf, "\tjmp\t%s?End%04X\n",
Stat[1] == '.' ? "" : "short ", BlkStack[true_blk]);
}
else if(!strcmp(Stat, ".=;")) soutput(SendBuf, "\tret\n");
else if(!strcmp(Stat, ".=A;")) soutput(SendBuf, "\tret\t%s\n", Strs[0]);
else if(!strcmp(Stat, "...;")) soutput(SendBuf, "\twait\n");
else if(!strcmp(Stat, "....;")) soutput(SendBuf, "\thlt\n");
else if(strchr(Stat, 'A'))
goto ps_parsejcc0;
else goto ps_parsebrk0;
break;
case '/':
if(!strcmp(Stat, "//A;")) soutput(SendBuf, "\tdiv\t%s\n", Strs[0]);
else if(!strcmp(Stat, "/A;")) soutput(SendBuf, "\tidiv\t%s\n", Strs[0]);
else goto ps_error;
break;
case '<':
if(!strcmp(Stat, "<<A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, "<<=A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, "<A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, "<=A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, "<>A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, "<<;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "<<=;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "<;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "<=;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "<>;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "<>=*;")) soutput(SendBuf, "\trep\tlodsb\n");
else if(!strcmp(Stat, "<>=**;")) soutput(SendBuf, "\trep\tlodsw\n");
else if(!strcmp(Stat, "<>=****;")) soutput(SendBuf, "\trep\tlodsd\n");
else if(!strcmp(Stat, "<>*=;")) soutput(SendBuf, "\trep\tstosb\n");
else if(!strcmp(Stat, "<>**=;")) soutput(SendBuf, "\trep\tstosw\n");
else if(!strcmp(Stat, "<>****=;")) soutput(SendBuf, "\trep\tstosd\n");
else if(!strcmp(Stat, "<>*=*;")) soutput(SendBuf, "\trep\tmovsb\n");
else if(!strcmp(Stat, "<>**=**;")) soutput(SendBuf, "\trep\tmovsw\n");
else if(!strcmp(Stat, "<>****=****;")) soutput(SendBuf, "\trep\tmovsd\n");
else if(!strcmp(Stat, "<>*-?")) soutput(SendBuf, "\trepne\tscasb\n");
else if(!strcmp(Stat, "<>**-?")) soutput(SendBuf, "\trepne\tscasw\n");
else if(!strcmp(Stat, "<>****-?")) soutput(SendBuf, "\trepne\tscasd\n");
else if(!strcmp(Stat, "<>*-*?")) soutput(SendBuf, "\trepne\tcmpsb\n");
else if(!strcmp(Stat, "<>**-**?")) soutput(SendBuf, "\trepne\tcmpsw\n");
else if(!strcmp(Stat, "<>****-****?")) soutput(SendBuf, "\trepne\tcmpsd\n");
else if(!strcmp(Stat, "<>*=@;")) soutput(SendBuf, "\trep\tinsb\n");
else if(!strcmp(Stat, "<>**=@@;")) soutput(SendBuf, "\trep\tinsw\n");
else if(!strcmp(Stat, "<>****=@@@@;")) soutput(SendBuf, "\trep\tinsd\n");
else if(!strcmp(Stat, "<>**=@;")) soutput(SendBuf, "\trep\tinsw\n");
else if(!strcmp(Stat, "<>****=@;")) soutput(SendBuf, "\trep\tinsd\n");
else if(!strcmp(Stat, "<>@=*;")) soutput(SendBuf, "\trep\toutsb\n");
else if(!strcmp(Stat, "<>@=**;")) soutput(SendBuf, "\trep\toutsw\n");
else if(!strcmp(Stat, "<>@=****;")) soutput(SendBuf, "\trep\toutsd\n");
else if(!strcmp(Stat, "<>@@=**;")) soutput(SendBuf, "\trep\toutsw\n");
else if(!strcmp(Stat, "<>@@@@=****;")) soutput(SendBuf, "\trep\toutsd\n");
else if(!strcmp(Stat, "<>=*A;")) soutput(SendBuf, "\trep\tlods %s\n", Strs[0]);
else if(!strcmp(Stat, "<>*A=;")) soutput(SendBuf, "\trep\tstos %s\n", Strs[0]);
else if(!strcmp(Stat, "<>*A=*A;")) soutput(SendBuf, "\trep\tmovs %s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "<>*A-?")) soutput(SendBuf, "\trepne\tscas %s\n", Strs[0]);
else if(!strcmp(Stat, "<>*A-*A?")) soutput(SendBuf, "\trepne\tcmps %s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "<>*A=@;")) soutput(SendBuf, "\trep\tins %s\n", Strs[0]);
else if(!strcmp(Stat, "<>@=*A;")) soutput(SendBuf, "\trep\touts %s\n", Strs[0]);
else goto ps_error;
break;
case '=':
if(!memcmp(Stat, "=A", 2)) { // PUSH sequence
i = 0; p = Stat;
while(!memcmp(p, "=A", 2)) {
soutput(SendBuf, "\tpush\t%s\n", Strs[i]);
p += 2; i++;
};
if(*p != ';') goto ps_error;
}
else if(!strcmp(Stat, "==A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, "=<<A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, "=>>A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, "=<A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, "=>A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, "==;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "=<<;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "=<;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "=>>;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "=>;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "=.A;")) soutput(SendBuf, "\tcall\t%s\n", Strs[0]);
else if(!strcmp(Stat, "=??;")) soutput(SendBuf, "\tpushf\n");
else if(!strcmp(Stat, "=????;")) soutput(SendBuf, "\tpushfd\n");
else if(!strcmp(Stat, "=?;")) soutput(SendBuf, "\tlahf\n");
else if(!strcmp(Stat, "=;")) soutput(SendBuf, "\tdb\t0D6h\n");
else if(!strcmp(Stat, "=+A;")) soutput(SendBuf, "\tenter\t%s,0\n", Strs[0]);
else if(!strcmp(Stat, "=-;")) soutput(SendBuf, "\tleave\n");
else if(!strcmp(Stat, "=%;")) soutput(SendBuf, "\tpusha\n");
else if(!strcmp(Stat, "=@;")) soutput(SendBuf, "\tin\tal,dx\n");
else if(!strcmp(Stat, "=@@;")) soutput(SendBuf, "\tin\tax,dx\n");
else if(!strcmp(Stat, "=@@@@;")) soutput(SendBuf, "\tin\teax,dx\n");
else if(!strcmp(Stat, "=@A;")) soutput(SendBuf, "\tin\tal,%s\n", Strs[0]);
else if(!strcmp(Stat, "=@@A;")) soutput(SendBuf, "\tin\tax,%s\n", Strs[0]);
else if(!strcmp(Stat, "=@@@@A;")) soutput(SendBuf, "\tin\teax,%s\n", Strs[0]);
else if(!strcmp(Stat, "=*;")) soutput(SendBuf, "\tlodsb\n");
else if(!strcmp(Stat, "=**;")) soutput(SendBuf, "\tlodsw\n");
else if(!strcmp(Stat, "=****;")) soutput(SendBuf, "\tlodsd\n");
else if(!strcmp(Stat, "=*A;")) soutput(SendBuf, "\tlods\t%s\n", Strs[0]);
else if(!strcmp(Stat, "===*;")) soutput(SendBuf, "\trep\tlodsb\n");
else if(!strcmp(Stat, "===**;")) soutput(SendBuf, "\trep\tlodsw\n");
else if(!strcmp(Stat, "===****;")) soutput(SendBuf, "\trep\tlodsd\n");
else if(!strcmp(Stat, "==*=;")) soutput(SendBuf, "\trep\tstosb\n");
else if(!strcmp(Stat, "==**=;")) soutput(SendBuf, "\trep\tstosw\n");
else if(!strcmp(Stat, "==****=;")) soutput(SendBuf, "\trep\tstosd\n");
else if(!strcmp(Stat, "==*=*;")) soutput(SendBuf, "\trep\tmovsb\n");
else if(!strcmp(Stat, "==**=**;")) soutput(SendBuf, "\trep\tmovsw\n");
else if(!strcmp(Stat, "==****=****;")) soutput(SendBuf, "\trep\tmovsd\n");
else if(!strcmp(Stat, "==*-?")) soutput(SendBuf, "\trepe\tscasb\n");
else if(!strcmp(Stat, "==**-?")) soutput(SendBuf, "\trepe\tscasw\n");
else if(!strcmp(Stat, "==****-?")) soutput(SendBuf, "\trepe\tscasd\n");
else if(!strcmp(Stat, "==*-*?")) soutput(SendBuf, "\trepe\tcmpsb\n");
else if(!strcmp(Stat, "==**-**?")) soutput(SendBuf, "\trepe\tcmpsw\n");
else if(!strcmp(Stat, "==****-****?")) soutput(SendBuf, "\trepe\tcmpsd\n");
else if(!strcmp(Stat, "==*=@;")) soutput(SendBuf, "\trep\tinsb\n");
else if(!strcmp(Stat, "==**=@;")) soutput(SendBuf, "\trep\tinsw\n");
else if(!strcmp(Stat, "==****=@;")) soutput(SendBuf, "\trep\tinsd\n");
else if(!strcmp(Stat, "==**=@@;")) soutput(SendBuf, "\trep\tinsw\n");
else if(!strcmp(Stat, "==****=@@@@;")) soutput(SendBuf, "\trep\tinsd\n");
else if(!strcmp(Stat, "==@=*;")) soutput(SendBuf, "\trep\toutsb\n");
else if(!strcmp(Stat, "==@=**;")) soutput(SendBuf, "\trep\toutsw\n");
else if(!strcmp(Stat, "==@=****;")) soutput(SendBuf, "\trep\toutsd\n");
else if(!strcmp(Stat, "==@@=**;")) soutput(SendBuf, "\trep\toutsw\n");
else if(!strcmp(Stat, "==@@@@=****;")) soutput(SendBuf, "\trep\toutsd\n");
else if(!strcmp(Stat, "===*A;")) soutput(SendBuf, "\trep\tlods %s\n", Strs[0]);
else if(!strcmp(Stat, "==*A=;")) soutput(SendBuf, "\trep\tstos %s\n", Strs[0]);
else if(!strcmp(Stat, "==*A=*A;")) soutput(SendBuf, "\trep\tmovs %s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "==*A-?")) soutput(SendBuf, "\trepe\tscas %s\n", Strs[0]);
else if(!strcmp(Stat, "==*A-*A?")) soutput(SendBuf, "\trepe\tcmps %s,%s\n", Strs[0], Strs[1]);
else if(!strcmp(Stat, "==*A=@;")) soutput(SendBuf, "\trep\tins %s\n", Strs[0]);
else if(!strcmp(Stat, "==@=*A;")) soutput(SendBuf, "\trep\touts %s\n", Strs[0]);
else goto ps_error;
break;
case '>':
if(!strcmp(Stat, ">>A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, ">>=A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, ">A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, ">=A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, ">>;")) goto ps_parsebrk0;
else if(!strcmp(Stat, ">>=;")) goto ps_parsebrk0;
else if(!strcmp(Stat, ">;")) goto ps_parsebrk0;
else if(!strcmp(Stat, ">=;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "><;")) soutput(SendBuf, "\txlatb\n");
else if(!strcmp(Stat, "><A;")) soutput(SendBuf, "\txlat\t%s\n", Strs[0]);
else goto ps_error;
break;
case '?':
if(!strcmp(Stat, "?==;")) { // Break on CXZ
if(true_blk < 0) goto ps_noblk;
soutput(SendBuf, "\tjcxz\t?End%04X\n", BlkStack[true_blk]);
}
else if(!strcmp(Stat, "?=;")) soutput(SendBuf, "\tsahf\n", Strs[1]);
else if(!strcmp(Stat, "?==A;")) soutput(SendBuf, "\tjcxz\t%s\n", Strs[0]);
else if(!strcmp(Stat, "??=;")) soutput(SendBuf, "\tpopf\n");
else if(!strcmp(Stat, "????=;")) soutput(SendBuf, "\tpopfd\n");
else goto ps_error;
break;
case '@':
if(!strcmp(Stat, "@=;")) soutput(SendBuf, "\tout\tdx,al\n");
else if(!strcmp(Stat, "@@=;")) soutput(SendBuf, "\tout\tdx,ax\n");
else if(!strcmp(Stat, "@@@@=;")) soutput(SendBuf, "\tout\tdx,eax\n");
else if(!strcmp(Stat, "@A=;")) soutput(SendBuf, "\tout\t%s,al\n", Strs[0]);
else if(!strcmp(Stat, "@@A=;")) soutput(SendBuf, "\tout\t%s,ax\n", Strs[0]);
else if(!strcmp(Stat, "@@@@A=;")) soutput(SendBuf, "\tout\t%s,eax\n", Strs[0]);
else if(!strcmp(Stat, "@=*;")) soutput(SendBuf, "\toutsb\n");
else if(!strcmp(Stat, "@=**;")) soutput(SendBuf, "\toutsw\n");
else if(!strcmp(Stat, "@=****;")) soutput(SendBuf, "\toutsd\n");
else if(!strcmp(Stat, "@@=**;")) soutput(SendBuf, "\toutsw\n");
else if(!strcmp(Stat, "@@@@=****;")) soutput(SendBuf, "\toutsd\n");
else if(!strcmp(Stat, "@=*A;")) soutput(SendBuf, "\touts\t%s\n", Strs[0]);
else goto ps_error;
break;
case '^':
if(!strcmp(Stat, "^;")) soutput(SendBuf, "\tcmc\n");
else if(!strcmp(Stat, "^A;")) soutput(SendBuf, "\tnot\t%s\n", Strs[0]);
else goto ps_error;
break;
case '|':
if(!strcmp(Stat, "||A;")) goto ps_parsejcc0;
else if(!strcmp(Stat, "||;")) goto ps_parsebrk0;
else if(!strcmp(Stat, "|;")) soutput(SendBuf, "\tstc\n");
else goto ps_error;
break;
case ';':
break;
default:
goto ps_error;
}
////////////////////////////////////////////// OUTPUT SEQUENCE
ps_output:
fputs(SendBuf, OutFile); // send output buffer
if(to_follow)
fputs(FollowBuf, OutFile); // send follow codes (if any)
return 1;
////////////////////////////////////////////// CONDITIONAL JUMP
ps_parsejcc0:
if(!FindCond(Stat, cond1)) // find the condition code
goto ps_error;
if(Strs[0][1] == 0 && isdigit(Strs[0][0])) {
j = Strs[0][0] - '0'; // break, multi-level
for(i = 0; i < j; i++) {
if(--true_blk < 0) goto ps_noblk;
if(BlkType[true_blk] == 0) true_blk--;
}
sprintf(ibuf, "?End%04X", BlkStack[true_blk]);
} else strcpy(ibuf, Strs[0]);
if(Stat[0] == '.') {
ParseCond(cond1, sbuf, 1);
soutput(SendBuf, "\tj%s\t?End%04X\n", sbuf, NextBlk);
soutput(SendBuf, "\tjmp\t%s\n", ibuf);
soutput(SendBuf, "?End%04X:\n", NextBlk++);
} else {
ParseCond(cond1, sbuf, 0);
soutput(SendBuf, "\tj%s\t%s\n", sbuf, ibuf);
}
goto ps_output;
////////////////////////////////////////////// CONDITIONAL BREAK
ps_parsebrk0:
if(true_blk < 0) goto ps_noblk;
FindCond(Stat, cond1);
if(Stat[0] == '.') {
ParseCond(cond1, sbuf, 1);
soutput(SendBuf, "\tj%s\t?End%04X\n", sbuf, NextBlk);
soutput(SendBuf, "\tjmp\t?End%04X\n", BlkStack[true_blk]);
soutput(SendBuf, "?End%04X:\n", NextBlk++);
} else {
ParseCond(cond1, sbuf, 0);
soutput(SendBuf, "\tj%s\t?End%04X\n", sbuf, BlkStack[true_blk]);
}
goto ps_output;
////////////////////////////////////////////// ERROR CONDITIONS
ps_error:
sprintf(ErrorBuf, "syntax error at or near line %ld", LineCtr);
xerror(2);
ps_nesterr:
sprintf(ErrorBuf, "nesting too deep at or near line %ld", LineCtr);
xerror(5);
ps_blkerr:
sprintf(ErrorBuf, "block syntax error at or near line %ld", LineCtr);
xerror(6);
ps_noblk:
sprintf(ErrorBuf, "block does not exist at or near line %ld", LineCtr);
xerror(7);
////////////////////////////////////////////// PASS-THROUGH CODE
ps_passthru:
p = Stat; i = 0; // p = pointer, i = string ctr.
soutput(SendBuf, "\t");
if(*p == 0) return 1; // empty statement?
while(*(p+1) != 0) { // send each piece
if(*p == 'A') soutput(SendBuf, "%s ", Strs[i++]);
else soutput(SendBuf, "%c ", *p);
p++;
}
fprintf(OutFile, "%s\n", SendBuf); // send output buffer
return 1;
}
/********************************************************************/
/* Parse pointer bumping (if any) */
/********************************************************************/
int ParseBumping(void)
{
int i, j, n, d, l, r = 0;
char *s, *p, a[128];
l = strlen(Stat); // get string length
for(i = n = 0; i < l; i++) // count the strings
if(Stat[i] == 'A') n++;
for(n--; n >= 0; n--) {
s = Strs[n];
do {
d = 0;
if((p = strchr(s, '[')) != NULL) { // look for '[+' or '[-'
l = strlen(s);
if(*(p+1) == '+' || *(p+1) == '-') {
i = (p+2) - s; // extract alphanumeric string
for(; i < l; i++) if(isxalpha(s[i])) break;
for(j = 0; i+j < l; j++) {
if(!isxalpha(s[i+j])) break;
a[j] = s[i+j];
}
a[j] = 0; // finish up
soutput(SendBuf, "\t%s\t%s\n",
*(p+1) == '+' ? "inc" : "dec", a);
memmove(p+1, p+2, 126 - (p - s)); d = 1;
}
}
if((p = strchr(s+1, ']')) != NULL) { // look for '+]' or '-]'
l = strlen(s);
if(*(p-1) == '+' || *(p-1) == '-') {
i = (p-2) - s; // extract alpha string
for(; i >= 0; i--) if(isxalpha(s[i])) break;
a[0] = 0;
for(; i >= 0; i--) {
if(!isxalpha(s[i])) break;
memmove(a+1, a, 127);
a[0] = s[i];
}
soutput(FollowBuf, "\t%s\t%s\n", // finish up
*(p-1) == '+' ? "inc" : "dec", a);
memmove(p-1, p, 128 - (p - s)); d = r = 1;
}
}
} while(d);
}
return(r);
}
/********************************************************************/
/* Parse a conditional string */
/********************************************************************/
int ParseCond(char *in, char *out, int flip)
{
static char *outs[16] = { // output strings
"o", "no", "b", "ae", "z", "nz", "be", "a",
"s", "ns", "pe", "po", "l", "ge", "le", "g" };
static char *ins[20] = { // input strings
"+-", "-+", "<<", ">>=", "=>>", "==", "<>", "<<=", "=<<", ">>",
"--", "++", "&&", "||", "<", ">=", "=>", "<=", "=<", ">" };
static int inv[20] = { // string values
0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8,
9, 10, 11, 12, 13, 13, 14, 14, 15 };
int i, n = -1;
for(i = 0; i < 20; i++) // find the string
if(!strcmp(in, ins[i]))
n = inv[i];
if(n == -1) { // not a condition?
*out = 0; // return a blank string
return 0;
}
if(flip) n ^= 1; // opposite condition if needed
strcpy(out, outs[n]); // return the condition string
return 1;
}
/********************************************************************/
/* Find a conditional in a statement */
/********************************************************************/
int FindCond(char *in, char *out)
{
static char *conds[20] = { // List of conditions
">>=", "=>>", "<<=", "=<<", ">=", "=>", "<=", "=<", "+-", "-+",
"--", "++", "<>", "<<", ">>", "<", ">", "==", "&&", "||" };
static unsigned char cond_len[20] = { // Length of each condition
3,3,3,3,2,2,2,2,2,2, 2,2,2,2,2,1,1,2,2,2 };
int i, j, l = strlen(in), m;
for(i = 0; i < l; i++) {
for(j = 0; j < 20; j++) {
m = cond_len[j]; // get length of string
if(!memcmp(in + i, conds[j], m)) { // found a condition?
strcpy(out, conds[j]); // copy it into the output buffer
memmove(in + i + 1, in + i + m, l - i - m + 1);
in[i] = 'C'; // replace it by a 'C' in the main string
return 1;
}
}
}
out[0] = 0; // not found, return a blank string
return 0;
}
/********************************************************************/
/* Get one statement */
/********************************************************************/
int GetStatement(void)
{
static char buf[300];
char *p = Stat, oc = -1, c = -1;
int stn = 0;
do {
if(Stat[0] != '#') oc = c; // oc = prev. char unless FPU instruction
if(!GetToken(buf, p - Stat)) return 0; // get a token
if(isxalpha(*buf) || buf[1] != 0) { // if alphanumeric or string,
strcpy(Strs[stn++], buf); // then add it to string the list
*p++ = c = 'A'; // and code it as an 'A'
} else *p++ = c = *buf; // otherwise, code it as itself
if(p - Stat > 60 || stn > 30) { // out of space?
sprintf(ErrorBuf, "statement too big at or near line %d", LineCtr);
xerror(3);
}
} while(c != ';' && c != '{' && // terminators are ';' and '{', sometines '?'.
(c != '?' || !strchr("A-*", oc))); // '?' is terminator only if after 'A', '-', or '*'.
*p++ = 0;
return 1;
}
/********************************************************************/
/* Init token parsing */
/********************************************************************/
void InitToken(void)
{
GetLine(LineBuf);
LinePos = 0;
}
/********************************************************************/
/* Return one token */
/********************************************************************/
int GetToken(char *buf, int flg)
{
int is_bracket, level, is_string = 0;
int c, i, p = 0, is_alpha = 0;
char deli[5] = "([\'\"";
if(!flg) deli[2] = 0; // strings OK?
while(1) {
c = LineBuf[LinePos++]; // get char
if(c == 0) { // end of line?
if(!GetLine(LineBuf)) return 0; // get line
LinePos = 0; // reset line pos
} else if(isspace(c)) { // skip spaces
} else if(isxalpha(c) || strchr(deli, c)) {
is_string = 1; // set is_string flag
if(flg && (c == '\'' || c == '\"')) {
i = c; // handle quoted strings
do {
if(i == 0) goto gt_strerr; // end of line?
buf[p++] = i; // add char to string
} while((i = LineBuf[LinePos++]) != c);
buf[p++] = i; continue; // add last char, continue
}
level = !isxalpha(c); // expression/alphanumeric string
if(c == '(' && is_alpha) { // opening parenthesis needs space
buf[p++] = ' '; // if last one was alpha
}
if(c == '[') { // handle opening bracket
is_bracket = 1; buf[p++] = c;
} else is_bracket = 0;
if(isxalpha(c)) { // need first char if alpha string
if(is_alpha) buf[p++] = ' '; // last one was alpha, separate with space
is_alpha = 1; buf[p++] = c;
} else is_alpha = 0;
while(1) { // string handling loop
c = LineBuf[LinePos++]; // get char
if(isspace(c) || c == 0) { // process white space:
if(level == 0) break; // end of alpha string
buf[p++] = ' '; // encode as a single space
do { // white space loop
if(c == 0) { // process newlines
if(!GetLine(LineBuf)) return 0;
LinePos = 0;
}
c = LineBuf[LinePos++]; // get next char
} while(isspace(c) || c == 0); // loop while whitespace
}
buf[p++] = c; // add character to buffer
if(c == '(') { ++level; continue; } // opening parenthesis
if(c == ')') if(--level == 0) { // closing parenthesis
if(is_bracket) goto gt_error; // should be bracket, generate error
if(!is_alpha) p--; // if it didn't begin as alpha, remove parenthesis
is_alpha = 1; break; // need space in all cases, break
}
if(c == '[' && level == 0) { // process opening bracket
is_bracket = level = 1;
continue;
}
if(c == ']' && level == 1 && // process ending bracket
is_bracket) break;
if(c == '\'' || c == '\"') { // quoted strings
while((i = LineBuf[LinePos++]) != c) {
if(i == 0) goto gt_strerr; // end of line?
buf[p++] = i; // add char to string
}
buf[p++] = i; continue; // add last char, continue
}
if(!isxalpha(c) && level == 0) { // end of alpha string, recycle last char
p--; LinePos--; break;
}
}
} else { // special char
if(is_string) LinePos--; // terminates a string
else buf[p++] = c; // not string, add char
buf[p++] = 0; // add terminating null
return 1; // break
}
}
gt_error: // error in expression
sprintf(ErrorBuf, "error in expression at or near line %ld", LineCtr);
xerror(3);
gt_strerr: // end of line in quoted string
sprintf(ErrorBuf, "unterminated quoted string at or near line %ld", LineCtr);
xerror(4);
return 0; // to fix compiler warning
}
/********************************************************************/
/* Return the next token without removing it from the stream */
/********************************************************************/
int PeekToken(char *p)
{
int c, lp = LinePos;
while(1) {
c = LineBuf[lp++]; // get char
if(c == 0) { // end of line?
if(!GetLine(LineBuf)) return 0; // get line
LinePos = lp = 0; // reset line pos
continue;
} else if(isspace(c)) { // skip spaces
continue;
} else {
if(isxalpha(c) || strchr("([", c)) // identifier, expression,
*p = 'A'; // or address = return an 'A'
else *p = c; // otherwise, return the char
return 1;
}
}
}
/********************************************************************/
/* Get line with full pass-through, stripping comments, etc. */
/********************************************************************/
int GetLine(char *buf)
{
int i;
do {
if(!ReadLine(buf)) return 0; // read a line
if(!isspace(buf[0])) {
i = 0; // statement starts line, label, etc.
if(strchr(buf, ':')) { // if there's a ':', then
while(isalnum(buf[i]) || // check for a label
strchr("$_", buf[i])) i++;
if(buf[i] == ':') { // If a label, then pass it through:
i = 0;
while(1) {
fputc(buf[i], OutFile); // output one char
if(buf[i] == ':') break; // char is ':', break
i++;
}
}
}
if(buf[i] != ':') { // if no label, then
i = 0;
while(buf[i] != ';') { // while no semicolon,
if(buf[i] == 0) { // if end of line, then
if(!ReadLine(buf)) return 0; // read a line, reset the counter
i = 0; continue; // and continue
}
fputc(buf[i++], OutFile); // output the char
}
}
fputs("\n", OutFile); // output newline
memmove(buf, buf + i + 1, 300 - i - 1); // shift over buffer
}
} while(IsEmpty(buf));
return 1;
}
/********************************************************************/
/* Read a line, passing delimited lines */
/********************************************************************/
int ReadLine(char *buf)
{
char *p;
while(1) {
if(!fgets(buf, 300, InFile)) return 0; // read one line
if(!(++LineCtr & 0x3F)) // increment counter, put count every 64 lines
fprintf(stderr, "\rlines in: %06ld", LineCtr);
if(buf[0] == '!') { // is it a pass-through line?
fputs(buf + 1, OutFile); // if so, then send it, and loop back for another
continue; // make sure string is empty...
}
if((p = strchr(buf, 0x0D)) != NULL) *p = 0; // strip off CR and/or LF at the end
if((p = strchr(buf, 0x0A)) != NULL) *p = 0;
StripComments(buf); // strip off comments (if any)
if(!IsEmpty(buf)) return 1;
}
}
/********************************************************************/
/* Strip comments (and trailing spaces) from end of line */
/********************************************************************/
void StripComments(char *buf)
{
char c, e = 0;
int i = -1;
while((c = buf[++i]) != 0) { // while not null, if in a string ignore
if(e) { // everything except the delimiter char;
if(c == e) e = 0; // otherwise cut the string if '\' found.
} else {
if(c == '\'' || c == '\"') {
e = c;
} else if(c == '\\') {
buf[i] = 0;
break;
}
}
}
i = strlen(buf) - 1; // remove trailing spaces
while(isspace(buf[i])) buf[i--] = 0;
}
/********************************************************************/
/* Check whether line is empty */
/********************************************************************/
int IsEmpty(char *buf)
{
int i = 0;
while(buf[i] != 0) {
if(!isspace(buf[i++]))
return 0;
}
return 1;
}
/********************************************************************/
/* Error handling */
/********************************************************************/
void xerror(int en)
{
fprintf(stderr, "\nerror %02x: %s\n\n", en, ErrorBuf);
if(InFile != NULL) fclose(InFile);
if(OutFile != NULL) fclose(OutFile);
exit(en);
}
/********************************************************************/
/* String printf + concatenation */
/********************************************************************/
void soutput(char *s, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsprintf(s + strlen(s), fmt, ap);
va_end(ap);
}