diff --git a/source/compiler/sc.h b/source/compiler/sc.h index f2250f1..a5378fa 100644 --- a/source/compiler/sc.h +++ b/source/compiler/sc.h @@ -870,15 +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 (epmBLOCK) multiline ('{}' block) syntax - * 1 (epmEXPR) used within an expression - * 2 (epmGLOBAL) used outside of function + * 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 */ -#define epmBLOCK 1 -#define epmEXPR 2 -#define epmGLOBAL 4 +#define epmACTIVE 1 +#define epmBLOCK 2 +#define epmEXPR 4 +#define epmGLOBAL 8 SC_VDECL int emit_parsing_mode; #if !defined SC_LIGHT diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 7bc0138..b427b98 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6538,6 +6538,13 @@ 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)) { @@ -6580,7 +6587,7 @@ SC_FUNC void emit_parse_line(void) } else { sym=fetchlab(st); if ((sym->usage & uDEFINE)!=0) - error(021,st); /* symbol already defined */ + error(21,st); /* symbol already defined */ setlabel((int)sym->addr); sym->usage|=uDEFINE; } /* if */ @@ -6591,6 +6598,10 @@ SC_FUNC void emit_parse_line(void) } else if ((emit_parsing_mode & epmEXPR)==0) { matchtoken(';'); } /* if */ + + /* write the staging buffer again */ + stgout(0); + emit_parsing_mode &= ~epmACTIVE; } static void doemit(void) diff --git a/source/compiler/sc3.c b/source/compiler/sc3.c index c516a0b..9aff411 100644 --- a/source/compiler/sc3.c +++ b/source/compiler/sc3.c @@ -1452,25 +1452,11 @@ static int hier2(value *lval) case t__EMIT: { cell val; char* st; - int opt_bck; - - /* write the staging buffer to the output file and temporarily disable - * bytecode optimisation so instructions generated by the `emit`/`__emit` - * operator won't get altered by the optimizer - */ - stgout(0); - opt_bck=pc_optimize; - pc_optimize=sOPTIMIZE_NONE; - - /* parse the `emit`/`__emit` expression */ emit_parsing_mode |= epmEXPR; lex(&val,&st); emit_parse_line(); emit_parsing_mode &= ~epmEXPR; lval->ident=iEXPRESSION; - - /* restore the bytecode optimisation level and return */ - pc_optimize=opt_bck; return FALSE; } /* case */ default: diff --git a/source/compiler/sc7.c b/source/compiler/sc7.c index f8d2c9d..0c1613e 100644 --- a/source/compiler/sc7.c +++ b/source/compiler/sc7.c @@ -1770,7 +1770,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 && sc_status==statWRITE) { + if (pc_optimize>sOPTIMIZE_NONE && (emit_parsing_mode & epmACTIVE)==0 && sc_status==statWRITE) { do { matches=0; start=debut;