emit/__emit: Another syntax change
This commit is contained in:
parent
54fd3aee3a
commit
939c06011d
@ -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 */
|
||||||
|
@ -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 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
@ -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;
|
||||||
|
@ -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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user