emit/__emit: Another syntax change

This commit is contained in:
Daniel_Cortez 2017-12-10 03:16:12 +07:00
parent 54fd3aee3a
commit 939c06011d
5 changed files with 61 additions and 67 deletions

View File

@ -870,17 +870,16 @@ SC_VDECL FILE *outf; /* file written to */
SC_VDECL jmp_buf errbuf; /* target of longjmp() on a fatal error */
/* Possible entries for "emit_parsing_mode"
* Bits: 0 (epmACTIVE) 'emit'/'__emit' parsing is active
* 1 (epmBLOCK) multiline ('{}' block) syntax
* 2 (epmEXPR) used within an expression
* 3 (epmGLOBAL) used outside of function
/* Possible entries for "emit_flags"
* Bits: 0 (epmBLOCK) multiline ('{}' block) syntax
* 1 (epmEXPR) used within an expression
* 2 (epmGLOBAL) used outside of a function
*/
#define epmACTIVE 1
#define epmBLOCK 2
#define epmEXPR 4
#define epmGLOBAL 8
SC_VDECL int emit_parsing_mode;
#define efBLOCK 1
#define efEXPR 2
#define efGLOBAL 4
SC_VDECL int emit_flags;
SC_VDECL int emit_stgbuf_idx;
#if !defined SC_LIGHT
SC_VDECL int sc_makereport; /* generate a cross-reference report */

View File

@ -895,7 +895,8 @@ static void resetglobals(void)
sc_curstates=0;
pc_memflags=0;
pc_naked=FALSE;
emit_parsing_mode=0;
emit_flags=0;
emit_stgbuf_idx=-1;
}
static void initglobals(void)
@ -1652,10 +1653,11 @@ static void parse(void)
break;
case tEMIT:
case t__EMIT:
emit_parsing_mode |= epmGLOBAL;
emit_flags |= efGLOBAL;
lex(&val,&str);
emit_parse_line();
emit_parsing_mode &= ~epmGLOBAL;
needtoken(';');
emit_flags &= ~efGLOBAL;
break;
case tNEW:
if (getclassspec(tok,&fpublic,&fstatic,&fstock,&fconst))
@ -5100,11 +5102,10 @@ static void statement(int *lastindent,int allow_decl)
errorset(sRESET,0);
tok=lex(&val,&st);
if (tok==tEMIT || tok==t__EMIT) {
doemit();
return;
} else if ((emit_parsing_mode & epmBLOCK)!=0) {
if ((emit_flags & efBLOCK)!=0) {
emit_parse_line();
if (matchtoken('}'))
emit_flags &= ~efBLOCK;
return;
} /* if */
if (tok!='{') {
@ -5213,6 +5214,21 @@ static void statement(int *lastindent,int allow_decl)
matchtoken(tSTATIC);
decl_enum(sLOCAL,FALSE);
break;
case tEMIT:
case t__EMIT: {
extern char *sc_tokens[];
const char *bck_lptr=lptr-strlen(sc_tokens[tok-tFIRST]);
if (matchtoken('{')) {
lexpush();
emit_flags |= efBLOCK;
lastst=tEMIT;
break;
} /* if */
lptr=bck_lptr;
lexclr(FALSE);
tok=lex(&val,&st);
} /* case */
/* drop through */
default: /* non-empty expression */
sc_allowproccall=optproccall;
lexpush(); /* analyze token later */
@ -5908,7 +5924,7 @@ fetchtok:
*p=(neg!=FALSE) ? -sym->addr : sym->addr;
break;
case '(':
if ((emit_parsing_mode & epmEXPR)==0)
if ((emit_flags & efEXPR)==0)
stgset(TRUE);
stgget(&index,&cidx);
errorset(sEXPRMARK,0);
@ -5917,7 +5933,7 @@ fetchtok:
error(8); /* must be constant expression */
errorset(sEXPRRELEASE,0);
stgdel(index,cidx);
if ((emit_parsing_mode & epmEXPR)==0)
if ((emit_flags & efEXPR)==0)
stgset(FALSE);
needtoken(')');
*p=(neg!=FALSE) ? -val : val;
@ -6641,13 +6657,6 @@ SC_FUNC void emit_parse_line(void)
symbol *sym;
char name[MAX_INSTR_LEN];
extern char *sc_tokens[];
/* write the staging buffer to the output file so instructions
* generated by the `emit`/`__emit` operator could be written
* separately without getting altered by the optimizer
*/
stgout(0);
emit_parsing_mode |= epmACTIVE;
tok=tokeninfo(&val,&st);
if (tok==tSYMBOL || (tok>tMIDDLE && tok<=tLAST)) {
@ -6670,21 +6679,9 @@ SC_FUNC void emit_parse_line(void)
if (emit_opcodelist[i].name==NULL && *name!='\0')
error(104,name); /* invalid assembler instruction */
emit_opcodelist[i].func(name);
if ((emit_parsing_mode & epmEXPR)==0) {
/* make sure the string only contains whitespaces
* and/or an optional trailing '}' or ';'
*/
while (*lptr<=' ' && *lptr!='\0')
lptr++;
if (*lptr!='\0' && *lptr!='}' && (*lptr!=';' || (emit_parsing_mode & epmBLOCK)!=0))
error(38); /* extra characters on line */
} /* if */
} else if (tok==tLABEL) {
if ((emit_parsing_mode & epmEXPR)!=0) {
if ((emit_flags & (efEXPR | efGLOBAL))!=0) {
error(29); /* invalid expression, assumed zero */
} else if ((emit_parsing_mode & epmGLOBAL)!=0) {
error(11); /* invalid outside functions */
} else if (find_constval(&tagname_tab,st,0)!=NULL) {
error(221,st); /* label name shadows tagname */
} else {
@ -6695,29 +6692,16 @@ SC_FUNC void emit_parse_line(void)
sym->usage|=uDEFINE;
} /* if */
} /* if */
if ((emit_parsing_mode & epmBLOCK)!=0) {
if (matchtoken('}'))
emit_parsing_mode &= ~epmBLOCK;
} else if ((emit_parsing_mode & epmEXPR)==0) {
matchtoken(';');
} /* if */
/* write the staging buffer again */
stgout(0);
emit_parsing_mode &= ~epmACTIVE;
}
static void doemit(void)
{
cell val;
char *st;
if (matchtoken('{')) {
lexpush();
emit_parsing_mode |= epmBLOCK;
} else {
lex(&val,&st);
emit_parse_line();
if ((emit_flags & (efEXPR | efGLOBAL))==0) {
assert((emit_flags & efBLOCK)!=0);
/* make sure the string only contains whitespaces
* and an optional trailing '}'
*/
while (*lptr<=' ' && *lptr!='\0')
lptr++;
if (*lptr!='\0' && *lptr!='}')
error(38); /* extra characters on line */
} /* if */
}

View File

@ -1452,11 +1452,19 @@ static int hier2(value *lval)
case t__EMIT: {
cell val;
char* st;
emit_parsing_mode |= epmEXPR;
lex(&val,&st);
emit_parse_line();
emit_parsing_mode &= ~epmEXPR;
int block_syntax=matchtoken('(');
emit_flags |= efEXPR;
if (emit_stgbuf_idx==-1)
emit_stgbuf_idx=stgidx;
do {
lex(&val,&st);
emit_parse_line();
} while ((block_syntax!=0) && matchtoken(','));
if (block_syntax!=0)
needtoken(')');
emit_flags &= ~efEXPR;
lval->ident=iEXPRESSION;
pc_sideeffect=TRUE;
return FALSE;
} /* case */
default:

View File

@ -1437,6 +1437,8 @@ SC_FUNC void stgout(int index)
filewrite(stgpipe+idx);
} /* if */
} /* if */
if (stgidx<=emit_stgbuf_idx)
emit_stgbuf_idx=-1;
pipeidx=0; /* reset second pipe */
}
@ -1770,7 +1772,7 @@ static void stgopt(char *start,char *end,int (*outputfunc)(char *str))
assert(sequences!=NULL);
/* do not match anything if debug-level is maximum */
if (pc_optimize>sOPTIMIZE_NONE && (emit_parsing_mode & epmACTIVE)==0 && sc_status==statWRITE) {
if (pc_optimize>sOPTIMIZE_NONE && sc_status==statWRITE && emit_stgbuf_idx==-1) {
do {
matches=0;
start=debut;

View File

@ -105,7 +105,8 @@ SC_VDEFINE FILE *outf = NULL; /* (intermediate) text file written to */
SC_VDEFINE jmp_buf errbuf;
SC_VDEFINE int emit_parsing_mode=0;
SC_VDEFINE int emit_flags;
SC_VDEFINE int emit_stgbuf_idx;
#if !defined SC_LIGHT
SC_VDEFINE int sc_makereport=FALSE; /* generate a cross-reference report */