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 */ SC_VDECL jmp_buf errbuf; /* target of longjmp() on a fatal error */
/* Possible entries for "emit_parsing_mode" /* Possible entries for "emit_flags"
* Bits: 0 (epmACTIVE) 'emit'/'__emit' parsing is active * Bits: 0 (epmBLOCK) multiline ('{}' block) syntax
* 1 (epmBLOCK) multiline ('{}' block) syntax * 1 (epmEXPR) used within an expression
* 2 (epmEXPR) used within an expression * 2 (epmGLOBAL) used outside of a function
* 3 (epmGLOBAL) used outside of function
*/ */
#define epmACTIVE 1 #define efBLOCK 1
#define epmBLOCK 2 #define efEXPR 2
#define epmEXPR 4 #define efGLOBAL 4
#define epmGLOBAL 8 SC_VDECL int emit_flags;
SC_VDECL int emit_parsing_mode; SC_VDECL int emit_stgbuf_idx;
#if !defined SC_LIGHT #if !defined SC_LIGHT
SC_VDECL int sc_makereport; /* generate a cross-reference report */ SC_VDECL int sc_makereport; /* generate a cross-reference report */

View File

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

View File

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

View File

@ -1437,6 +1437,8 @@ SC_FUNC void stgout(int index)
filewrite(stgpipe+idx); filewrite(stgpipe+idx);
} /* if */ } /* if */
} /* if */ } /* if */
if (stgidx<=emit_stgbuf_idx)
emit_stgbuf_idx=-1;
pipeidx=0; /* reset second pipe */ pipeidx=0; /* reset second pipe */
} }
@ -1770,7 +1772,7 @@ static void stgopt(char *start,char *end,int (*outputfunc)(char *str))
assert(sequences!=NULL); assert(sequences!=NULL);
/* do not match anything if debug-level is maximum */ /* 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 { do {
matches=0; matches=0;
start=debut; 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 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 #if !defined SC_LIGHT
SC_VDEFINE int sc_makereport=FALSE; /* generate a cross-reference report */ SC_VDEFINE int sc_makereport=FALSE; /* generate a cross-reference report */