mirror of
https://github.com/dschmenk/PLASMA.git
synced 2025-03-26 12:30:21 +00:00
Clean up scan_rewind string parsing and add branch optimizations
This commit is contained in:
parent
d7d50f3d37
commit
7d35fd7726
@ -473,7 +473,7 @@ void emit_idconst(char *name, int value)
|
|||||||
int emit_data(int vartype, int consttype, long constval, int constsize)
|
int emit_data(int vartype, int consttype, long constval, int constsize)
|
||||||
{
|
{
|
||||||
int datasize, i;
|
int datasize, i;
|
||||||
char *str;
|
unsigned char *str;
|
||||||
if (consttype == 0)
|
if (consttype == 0)
|
||||||
{
|
{
|
||||||
datasize = constsize;
|
datasize = constsize;
|
||||||
@ -481,9 +481,10 @@ int emit_data(int vartype, int consttype, long constval, int constsize)
|
|||||||
}
|
}
|
||||||
else if (consttype & STRING_TYPE)
|
else if (consttype & STRING_TYPE)
|
||||||
{
|
{
|
||||||
datasize = constsize;
|
str = (unsigned char *)constval;
|
||||||
str = (char *)constval;
|
constsize = *str++;
|
||||||
printf("\t%s\t$%02X\n", DB, --constsize);
|
datasize = constsize + 1;
|
||||||
|
printf("\t%s\t$%02X\n", DB, constsize);
|
||||||
while (constsize-- > 0)
|
while (constsize-- > 0)
|
||||||
{
|
{
|
||||||
printf("\t%s\t$%02X", DB, *str++);
|
printf("\t%s\t$%02X", DB, *str++);
|
||||||
@ -546,10 +547,10 @@ void emit_const(int cval)
|
|||||||
else
|
else
|
||||||
printf("\t%s\t$2C,$%02X,$%02X\t\t; CW\t%d\n", DB, cval&0xFF,(cval>>8)&0xFF, cval);
|
printf("\t%s\t$2C,$%02X,$%02X\t\t; CW\t%d\n", DB, cval&0xFF,(cval>>8)&0xFF, cval);
|
||||||
}
|
}
|
||||||
void emit_conststr(long conststr, int strsize)
|
void emit_conststr(long conststr)
|
||||||
{
|
{
|
||||||
printf("\t%s\t$2E\t\t\t; CS\n", DB);
|
printf("\t%s\t$2E\t\t\t; CS\n", DB);
|
||||||
emit_data(0, STRING_TYPE, conststr, strsize);
|
emit_data(0, STRING_TYPE, conststr, 0);
|
||||||
}
|
}
|
||||||
void emit_lb(void)
|
void emit_lb(void)
|
||||||
{
|
{
|
||||||
@ -908,14 +909,14 @@ void release_seq(t_opseq *seq)
|
|||||||
/*
|
/*
|
||||||
* Crunch sequence (peephole optimize)
|
* Crunch sequence (peephole optimize)
|
||||||
*/
|
*/
|
||||||
int crunch_seq(t_opseq *seq)
|
int crunch_seq(t_opseq **seq)
|
||||||
{
|
{
|
||||||
t_opseq *opnext, *opnextnext;
|
t_opseq *opnext, *opnextnext;
|
||||||
t_opseq *op = seq;
|
t_opseq *op = *seq;
|
||||||
int crunched = 0;
|
int crunched = 0;
|
||||||
int freeops = 0;
|
int freeops = 0;
|
||||||
int shiftcnt;
|
int shiftcnt;
|
||||||
|
|
||||||
while (op && (opnext = op->nextop))
|
while (op && (opnext = op->nextop))
|
||||||
{
|
{
|
||||||
switch (op->code)
|
switch (op->code)
|
||||||
@ -972,26 +973,40 @@ int crunch_seq(t_opseq *seq)
|
|||||||
op->code = SAW_CODE;
|
op->code = SAW_CODE;
|
||||||
freeops = 1;
|
freeops = 1;
|
||||||
break;
|
break;
|
||||||
case BINARY_CODE(MUL_TOKEN):
|
case BRFALSE_CODE:
|
||||||
for (shiftcnt = 0; shiftcnt < 16; shiftcnt++)
|
if (op->val)
|
||||||
{
|
{
|
||||||
if (op->val == (1 << shiftcnt))
|
opnextnext = opnext->nextop; // Remove never taken branch
|
||||||
{
|
if (op == *seq)
|
||||||
op->val = shiftcnt;
|
*seq = opnextnext;
|
||||||
opnext->code = BINARY_CODE(SHL_TOKEN);
|
opnext->nextop = NULL;
|
||||||
break;
|
release_seq(op);
|
||||||
}
|
opnext = opnextnext;
|
||||||
|
crunched = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
op->code = BRNCH_CODE; // Always taken branch
|
||||||
|
op->tag = opnext->tag;
|
||||||
|
freeops = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BINARY_CODE(DIV_TOKEN):
|
case BRTRUE_CODE:
|
||||||
for (shiftcnt = 0; shiftcnt < 16; shiftcnt++)
|
if (!op->val)
|
||||||
{
|
{
|
||||||
if (op->val == (1 << shiftcnt))
|
opnextnext = opnext->nextop; // Remove never taken branch
|
||||||
{
|
if (op == *seq)
|
||||||
op->val = shiftcnt;
|
*seq = opnextnext;
|
||||||
opnext->code = BINARY_CODE(SHR_TOKEN);
|
opnext->nextop = NULL;
|
||||||
break;
|
release_seq(op);
|
||||||
}
|
opnext = opnextnext;
|
||||||
|
crunched = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
op->code = BRNCH_CODE; // Always taken branch
|
||||||
|
op->tag = opnext->tag;
|
||||||
|
freeops = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CONST_CODE: // Collapse constant operation
|
case CONST_CODE: // Collapse constant operation
|
||||||
@ -1072,6 +1087,28 @@ int crunch_seq(t_opseq *seq)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break; // CONST_CODE
|
break; // CONST_CODE
|
||||||
|
case BINARY_CODE(MUL_TOKEN):
|
||||||
|
for (shiftcnt = 0; shiftcnt < 16; shiftcnt++)
|
||||||
|
{
|
||||||
|
if (op->val == (1 << shiftcnt))
|
||||||
|
{
|
||||||
|
op->val = shiftcnt;
|
||||||
|
opnext->code = BINARY_CODE(SHL_TOKEN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BINARY_CODE(DIV_TOKEN):
|
||||||
|
for (shiftcnt = 0; shiftcnt < 16; shiftcnt++)
|
||||||
|
{
|
||||||
|
if (op->val == (1 << shiftcnt))
|
||||||
|
{
|
||||||
|
op->val = shiftcnt;
|
||||||
|
opnext->code = BINARY_CODE(SHR_TOKEN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break; // CONST_CODE
|
break; // CONST_CODE
|
||||||
case LADDR_CODE:
|
case LADDR_CODE:
|
||||||
@ -1212,11 +1249,10 @@ t_opseq *cat_seq(t_opseq *seq1, t_opseq *seq2)
|
|||||||
int emit_seq(t_opseq *seq)
|
int emit_seq(t_opseq *seq)
|
||||||
{
|
{
|
||||||
t_opseq *op;
|
t_opseq *op;
|
||||||
|
int emitted = 0;
|
||||||
|
|
||||||
if (!seq)
|
|
||||||
return (0);
|
|
||||||
if (outflags & OPTIMIZE)
|
if (outflags & OPTIMIZE)
|
||||||
while (crunch_seq(seq));
|
while (crunch_seq(&seq));
|
||||||
while (seq)
|
while (seq)
|
||||||
{
|
{
|
||||||
op = seq;
|
op = seq;
|
||||||
@ -1255,7 +1291,7 @@ int emit_seq(t_opseq *seq)
|
|||||||
emit_const(op->val);
|
emit_const(op->val);
|
||||||
break;
|
break;
|
||||||
case STR_CODE:
|
case STR_CODE:
|
||||||
emit_conststr(op->val, op->offsz);
|
emit_conststr(op->val);
|
||||||
break;
|
break;
|
||||||
case LB_CODE:
|
case LB_CODE:
|
||||||
emit_lb();
|
emit_lb();
|
||||||
@ -1329,15 +1365,26 @@ int emit_seq(t_opseq *seq)
|
|||||||
case DUP_CODE:
|
case DUP_CODE:
|
||||||
emit_dup();
|
emit_dup();
|
||||||
break;
|
break;
|
||||||
|
break;
|
||||||
case PUSH_EXP_CODE:
|
case PUSH_EXP_CODE:
|
||||||
emit_push_exp();
|
emit_push_exp();
|
||||||
break;
|
break;
|
||||||
case PULL_EXP_CODE:
|
case PULL_EXP_CODE:
|
||||||
emit_pull_exp();
|
emit_pull_exp();
|
||||||
break;
|
break;
|
||||||
|
case BRNCH_CODE:
|
||||||
|
emit_brnch(op->tag);
|
||||||
|
break;
|
||||||
|
case BRFALSE_CODE:
|
||||||
|
emit_brfls(op->tag);
|
||||||
|
break;
|
||||||
|
case BRTRUE_CODE:
|
||||||
|
emit_brtru(op->tag);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
emitted++;
|
||||||
seq = seq->nextop;
|
seq = seq->nextop;
|
||||||
/*
|
/*
|
||||||
* Free this op
|
* Free this op
|
||||||
@ -1345,5 +1392,5 @@ int emit_seq(t_opseq *seq)
|
|||||||
op->nextop = freeop_lst;
|
op->nextop = freeop_lst;
|
||||||
freeop_lst = op;
|
freeop_lst = op;
|
||||||
}
|
}
|
||||||
return (1);
|
return (emitted);
|
||||||
}
|
}
|
||||||
|
@ -61,11 +61,14 @@ typedef struct _opseq {
|
|||||||
#define DUP_CODE 0x0319
|
#define DUP_CODE 0x0319
|
||||||
#define PUSH_EXP_CODE 0x031A
|
#define PUSH_EXP_CODE 0x031A
|
||||||
#define PULL_EXP_CODE 0x031B
|
#define PULL_EXP_CODE 0x031B
|
||||||
|
#define BRNCH_CODE 0x031C
|
||||||
|
#define BRFALSE_CODE 0x031D
|
||||||
|
#define BRTRUE_CODE 0x031E
|
||||||
|
|
||||||
#define gen_uop(seq,op) gen_seq(seq,UNARY_CODE(op),0,0,0,0)
|
#define gen_uop(seq,op) gen_seq(seq,UNARY_CODE(op),0,0,0,0)
|
||||||
#define gen_op(seq,op) gen_seq(seq,BINARY_CODE(op),0,0,0,0)
|
#define gen_op(seq,op) gen_seq(seq,BINARY_CODE(op),0,0,0,0)
|
||||||
#define gen_const(seq,val) gen_seq(seq,CONST_CODE,val,0,0,0)
|
#define gen_const(seq,val) gen_seq(seq,CONST_CODE,val,0,0,0)
|
||||||
#define gen_str(seq,str,len) gen_seq(seq,STR_CODE,str,0,len,0)
|
#define gen_str(seq,str) gen_seq(seq,STR_CODE,str,0,0,0)
|
||||||
#define gen_lcladr(seq,idx) gen_seq(seq,LADDR_CODE,0,0,idx,0)
|
#define gen_lcladr(seq,idx) gen_seq(seq,LADDR_CODE,0,0,idx,0)
|
||||||
#define gen_gbladr(seq,tag,typ) gen_seq(seq,GADDR_CODE,0,tag,0,typ)
|
#define gen_gbladr(seq,tag,typ) gen_seq(seq,GADDR_CODE,0,tag,0,typ)
|
||||||
#define gen_idxb(seq) gen_seq(seq,ADD_CODE,0,0,0,0)
|
#define gen_idxb(seq) gen_seq(seq,ADD_CODE,0,0,0,0)
|
||||||
@ -78,6 +81,8 @@ typedef struct _opseq {
|
|||||||
#define gen_pushexp(seq) gen_seq(seq,PUSH_EXP_CODE,0,0,0,0)
|
#define gen_pushexp(seq) gen_seq(seq,PUSH_EXP_CODE,0,0,0,0)
|
||||||
#define gen_pullexp(seq) gen_seq(seq,PULL_EXP_CODE,0,0,0,0)
|
#define gen_pullexp(seq) gen_seq(seq,PULL_EXP_CODE,0,0,0,0)
|
||||||
#define gen_drop(seq) gen_seq(seq,DROP_CODE,0,0,0,0)
|
#define gen_drop(seq) gen_seq(seq,DROP_CODE,0,0,0,0)
|
||||||
|
#define gen_brfls(seq,tag) gen_seq(seq,BRFALSE_CODE,0,tag,0,0)
|
||||||
|
#define gen_brtru(seq,tag) gen_seq(seq,BRTRUE_CODE,0,tag,0,0)
|
||||||
|
|
||||||
void emit_flags(int flags);
|
void emit_flags(int flags);
|
||||||
void emit_header(void);
|
void emit_header(void);
|
||||||
@ -94,7 +99,7 @@ void emit_idconst(char *name, int value);
|
|||||||
int emit_data(int vartype, int consttype, long constval, int constsize);
|
int emit_data(int vartype, int consttype, long constval, int constsize);
|
||||||
void emit_codetag(int tag);
|
void emit_codetag(int tag);
|
||||||
void emit_const(int cval);
|
void emit_const(int cval);
|
||||||
void emit_conststr(long conststr, int strsize);
|
void emit_conststr(long conststr);
|
||||||
void emit_lb(void);
|
void emit_lb(void);
|
||||||
void emit_lw(void);
|
void emit_lw(void);
|
||||||
void emit_llb(int index);
|
void emit_llb(int index);
|
||||||
@ -137,7 +142,7 @@ void emit_start(void);
|
|||||||
void emit_rld(void);
|
void emit_rld(void);
|
||||||
void emit_esd(void);
|
void emit_esd(void);
|
||||||
void release_seq(t_opseq *seq);
|
void release_seq(t_opseq *seq);
|
||||||
int crunch_seq(t_opseq *seq);
|
int crunch_seq(t_opseq **seq);
|
||||||
t_opseq *gen_seq(t_opseq *seq, int opcode, long cval, int tag, int offsz, int type);
|
t_opseq *gen_seq(t_opseq *seq, int opcode, long cval, int tag, int offsz, int type);
|
||||||
t_opseq *cat_seq(t_opseq *seq1, t_opseq *seq2);
|
t_opseq *cat_seq(t_opseq *seq1, t_opseq *seq2);
|
||||||
int emit_seq(t_opseq *seq);
|
int emit_seq(t_opseq *seq);
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "plasm.h"
|
#include "plasm.h"
|
||||||
|
|
||||||
char *statement, *tokenstr, *scanpos = (char*) "";
|
char *statement, *tokenstr, *scanpos = "", *strpos = "";
|
||||||
t_token scantoken, prevtoken;
|
t_token scantoken, prevtoken;
|
||||||
int tokenlen;
|
int tokenlen;
|
||||||
long constval;
|
long constval;
|
||||||
@ -224,68 +224,68 @@ t_token scan(void)
|
|||||||
scanpos += 4;
|
scanpos += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((scanpos[0] & 0x7F) == '\"') // Hack for string quote char in case we have to rewind later
|
else if (scanpos[0] == '\"') // Hack for string quote char in case we have to rewind later
|
||||||
{
|
{
|
||||||
char *scanshift, quotechar;
|
|
||||||
int scanoffset;
|
int scanoffset;
|
||||||
/*
|
/*
|
||||||
* String constant.
|
* String constant.
|
||||||
*/
|
*/
|
||||||
quotechar = scanpos[0];
|
scantoken = STRING_TOKEN;
|
||||||
*scanpos |= 0x80; // Set high bit in case of rewind
|
constval = (long)strpos++;
|
||||||
scantoken = STRING_TOKEN;
|
scanpos++;
|
||||||
constval = (long)++scanpos;
|
while (*scanpos && *scanpos != '\"')
|
||||||
while (*scanpos && *scanpos != quotechar)
|
|
||||||
{
|
{
|
||||||
if (*scanpos == '\\')
|
if (*scanpos == '\\')
|
||||||
{
|
{
|
||||||
scanoffset = 1;
|
scanoffset = 2;
|
||||||
switch (scanpos[1])
|
switch (scanpos[1])
|
||||||
{
|
{
|
||||||
case 'n':
|
case 'n':
|
||||||
*scanpos = 0x0D;
|
*strpos++ = 0x0D;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
*scanpos = 0x0A;
|
*strpos++ = 0x0A;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
*scanpos = '\t';
|
*strpos++ = '\t';
|
||||||
break;
|
break;
|
||||||
case '\'':
|
case '\'':
|
||||||
*scanpos = '\'';
|
*strpos++ = '\'';
|
||||||
break;
|
break;
|
||||||
case '\"':
|
case '\"':
|
||||||
*scanpos = '\"';
|
*strpos++ = '\"';
|
||||||
break;
|
break;
|
||||||
case '\\':
|
case '\\':
|
||||||
*scanpos = '\\';
|
*strpos++ = '\\';
|
||||||
break;
|
break;
|
||||||
case '0':
|
case '0':
|
||||||
*scanpos = '\0';
|
*strpos++ = '\0';
|
||||||
break;
|
break;
|
||||||
case '$':
|
case '$':
|
||||||
if (hexdigit(scanpos[2]) < 0 || hexdigit(scanpos[3]) < 0) {
|
if (hexdigit(scanpos[2]) < 0 || hexdigit(scanpos[3]) < 0) {
|
||||||
parse_error("Bad string constant");
|
parse_error("Bad string constant");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
*scanpos = hexdigit(scanpos[2]) * 16 + hexdigit(scanpos[3]);
|
*strpos++ = hexdigit(scanpos[2]) * 16 + hexdigit(scanpos[3]);
|
||||||
scanoffset = 3;
|
scanoffset = 4;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
parse_error("Bad string constant");
|
parse_error("Bad string constant");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
for (scanshift = scanpos + 1; *scanshift; scanshift++)
|
scanpos += scanoffset;
|
||||||
scanshift[0] = scanshift[scanoffset];
|
|
||||||
}
|
}
|
||||||
scanpos++;
|
else
|
||||||
|
*strpos++ = *scanpos++;
|
||||||
}
|
}
|
||||||
if (!*scanpos)
|
if (!*scanpos)
|
||||||
{
|
{
|
||||||
parse_error("Unterminated string");
|
parse_error("Unterminated string");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
*scanpos++ |= 0x80; // Set high bit in case of rewind
|
*((unsigned char *)constval) = (long)strpos - constval - 1;
|
||||||
|
*strpos++ = '\0';
|
||||||
|
scanpos++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -404,30 +404,34 @@ void scan_rewind(char *backptr)
|
|||||||
}
|
}
|
||||||
int scan_lookahead(void)
|
int scan_lookahead(void)
|
||||||
{
|
{
|
||||||
char *backpos = scanpos;
|
char *backscan = scanpos;
|
||||||
char *backstr = tokenstr;
|
char *backtkn = tokenstr;
|
||||||
|
char *backstr = strpos;
|
||||||
int prevtoken = scantoken;
|
int prevtoken = scantoken;
|
||||||
int prevlen = tokenlen;
|
int prevlen = tokenlen;
|
||||||
int look = scan();
|
int look = scan();
|
||||||
scanpos = backpos;
|
scanpos = backscan;
|
||||||
tokenstr = backstr;
|
tokenstr = backtkn;
|
||||||
|
strpos = backstr;
|
||||||
scantoken = prevtoken;
|
scantoken = prevtoken;
|
||||||
tokenlen = prevlen;
|
tokenlen = prevlen;
|
||||||
return (look);
|
return (look);
|
||||||
}
|
}
|
||||||
char inputline[512];
|
char inputline[512];
|
||||||
|
char conststr[1024];
|
||||||
int next_line(void)
|
int next_line(void)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
t_token token;
|
t_token token;
|
||||||
char* new_filename;
|
char* new_filename;
|
||||||
|
strpos = conststr;
|
||||||
if (inputfile == NULL)
|
if (inputfile == NULL)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* First-time init
|
* First-time init
|
||||||
*/
|
*/
|
||||||
inputfile = stdin;
|
inputfile = stdin;
|
||||||
filename = (char*) "<stdin>";
|
filename = "<stdin>";
|
||||||
}
|
}
|
||||||
if (*scanpos == ';')
|
if (*scanpos == ';')
|
||||||
{
|
{
|
||||||
@ -491,9 +495,8 @@ int next_line(void)
|
|||||||
outer_inputfile = inputfile;
|
outer_inputfile = inputfile;
|
||||||
outer_filename = filename;
|
outer_filename = filename;
|
||||||
outer_lineno = lineno;
|
outer_lineno = lineno;
|
||||||
new_filename = (char*) malloc(tokenlen-1);
|
new_filename = (char *) malloc(*((unsigned char *)constval) + 1);
|
||||||
strncpy(new_filename, (char*)constval, tokenlen-2);
|
strncpy(new_filename, (char *)(constval + 1), *((unsigned char *)constval) + 1);
|
||||||
new_filename[tokenlen-2] = 0;
|
|
||||||
inputfile = fopen(new_filename, "r");
|
inputfile = fopen(new_filename, "r");
|
||||||
if (inputfile == NULL)
|
if (inputfile == NULL)
|
||||||
{
|
{
|
||||||
|
@ -220,7 +220,7 @@ int parse_constval(void)
|
|||||||
case CLOSE_PAREN_TOKEN:
|
case CLOSE_PAREN_TOKEN:
|
||||||
break;
|
break;
|
||||||
case STRING_TOKEN:
|
case STRING_TOKEN:
|
||||||
size = tokenlen - 1;
|
size = 1;
|
||||||
value = constval;
|
value = constval;
|
||||||
type = STRING_TYPE;
|
type = STRING_TYPE;
|
||||||
if (mod)
|
if (mod)
|
||||||
@ -412,7 +412,7 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
/*
|
/*
|
||||||
* This is a special case. Just emit the string and return
|
* This is a special case. Just emit the string and return
|
||||||
*/
|
*/
|
||||||
codeseq = gen_str(codeseq, constval, tokenlen - 1);
|
codeseq = gen_str(codeseq, constval);
|
||||||
scan();
|
scan();
|
||||||
return (codeseq);
|
return (codeseq);
|
||||||
}
|
}
|
||||||
@ -487,7 +487,7 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
scan_rewind(tokenstr);
|
scan_rewind(tokenstr);
|
||||||
if (cfnparms && (cfnparms != value))
|
if ((type & FUNC_TYPE) && (cfnparms != value))
|
||||||
parse_warn("Parameter count mismatch");
|
parse_warn("Parameter count mismatch");
|
||||||
if (stackdepth)
|
if (stackdepth)
|
||||||
*stackdepth = cfnvals + cfnparms - value;
|
*stackdepth = cfnvals + cfnparms - value;
|
||||||
@ -766,6 +766,7 @@ int parse_stmnt(void)
|
|||||||
int tag_prevbrk, tag_prevcnt, tag_else, tag_endif, tag_while, tag_wend, tag_repeat, tag_for, tag_choice, tag_of;
|
int tag_prevbrk, tag_prevcnt, tag_else, tag_endif, tag_while, tag_wend, tag_repeat, tag_for, tag_choice, tag_of;
|
||||||
int type, addr, step, cfnvals;
|
int type, addr, step, cfnvals;
|
||||||
char *idptr;
|
char *idptr;
|
||||||
|
t_opseq *seq;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Optimization for last function LEAVE and OF clause.
|
* Optimization for last function LEAVE and OF clause.
|
||||||
@ -775,14 +776,15 @@ int parse_stmnt(void)
|
|||||||
switch (scantoken)
|
switch (scantoken)
|
||||||
{
|
{
|
||||||
case IF_TOKEN:
|
case IF_TOKEN:
|
||||||
if (!emit_seq(parse_expr(NULL, NULL)))
|
if (!(seq = parse_expr(NULL, NULL)))
|
||||||
{
|
{
|
||||||
parse_error("Bad expression");
|
parse_error("Bad expression");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
tag_else = tag_new(BRANCH_TYPE);
|
tag_else = tag_new(BRANCH_TYPE);
|
||||||
tag_endif = tag_new(BRANCH_TYPE);
|
tag_endif = tag_new(BRANCH_TYPE);
|
||||||
emit_brfls(tag_else);
|
seq = gen_brfls(seq, tag_else);
|
||||||
|
emit_seq(seq);
|
||||||
scan();
|
scan();
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -791,13 +793,14 @@ int parse_stmnt(void)
|
|||||||
break;
|
break;
|
||||||
emit_brnch(tag_endif);
|
emit_brnch(tag_endif);
|
||||||
emit_codetag(tag_else);
|
emit_codetag(tag_else);
|
||||||
if (!emit_seq(parse_expr(NULL, NULL)))
|
if (!(seq = parse_expr(NULL, NULL)))
|
||||||
{
|
{
|
||||||
parse_error("Bad expression");
|
parse_error("Bad expression");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
tag_else = tag_new(BRANCH_TYPE);
|
tag_else = tag_new(BRANCH_TYPE);
|
||||||
emit_brfls(tag_else);
|
seq = gen_brfls(seq, tag_else);
|
||||||
|
emit_seq(seq);
|
||||||
} while (1);
|
} while (1);
|
||||||
if (scantoken == ELSE_TOKEN)
|
if (scantoken == ELSE_TOKEN)
|
||||||
{
|
{
|
||||||
@ -826,13 +829,14 @@ int parse_stmnt(void)
|
|||||||
tag_prevbrk = break_tag;
|
tag_prevbrk = break_tag;
|
||||||
break_tag = tag_wend;
|
break_tag = tag_wend;
|
||||||
emit_codetag(tag_while);
|
emit_codetag(tag_while);
|
||||||
if (!emit_seq(parse_expr(NULL, NULL)))
|
if (!(seq = parse_expr(NULL, NULL)))
|
||||||
{
|
{
|
||||||
parse_error("Bad expression");
|
parse_error("Bad expression");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
emit_brfls(tag_wend);
|
seq = gen_brfls(seq, tag_wend);
|
||||||
while (parse_stmnt()) next_line();
|
emit_seq(seq);
|
||||||
|
while (parse_stmnt()) next_line();
|
||||||
if (scantoken != LOOP_TOKEN)
|
if (scantoken != LOOP_TOKEN)
|
||||||
{
|
{
|
||||||
parse_error("Missing WHILE/END");
|
parse_error("Missing WHILE/END");
|
||||||
@ -859,12 +863,13 @@ int parse_stmnt(void)
|
|||||||
}
|
}
|
||||||
emit_codetag(cont_tag);
|
emit_codetag(cont_tag);
|
||||||
cont_tag = tag_prevcnt;
|
cont_tag = tag_prevcnt;
|
||||||
if (!emit_seq(parse_expr(NULL, NULL)))
|
if (!(seq = parse_expr(NULL, NULL)))
|
||||||
{
|
{
|
||||||
parse_error("Bad expression");
|
parse_error("Bad expression");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
emit_brfls(tag_repeat);
|
seq = gen_brfls(seq, tag_repeat);
|
||||||
|
emit_seq(seq);
|
||||||
emit_codetag(break_tag);
|
emit_codetag(break_tag);
|
||||||
break_tag = tag_prevbrk;
|
break_tag = tag_prevbrk;
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user