diff --git a/source/compiler/sc.h b/source/compiler/sc.h index 6adf043..89e08ed 100644 --- a/source/compiler/sc.h +++ b/source/compiler/sc.h @@ -46,21 +46,16 @@ #include "../amx/amx.h" #if defined _MSC_VER - #define OPHANDLER_CALL __fastcall -#elif defined __GNUC__ - #if defined __clang__ - #define OPHANDLER_CALL __attribute__((fastcall)) - #elif (defined __i386__ || defined __x86_64__ || defined __amd64__) - #if !defined __x86_64__ && !defined __amd64__ && (__GNUC__>=4 || __GNUC__==3 && __GNUC_MINOR__>=4) - #define OPHANDLER_CALL __attribute__((fastcall)) - #else - #define OPHANDLER_CALL __attribute__((regparam(3))) - #endif + #define SC_FASTCALL __fastcall +#elif defined __GNUC__ && (defined __i386__ || defined __x86_64__ || defined __amd64__) + #if !defined __x86_64__ && !defined __amd64__ && (__GNUC__>=4 || __GNUC__==3 && __GNUC_MINOR__>=4) + #define SC_FASTCALL __attribute__((fastcall)) #else - #define OPHANDLER_CALL + #define SC_FASTCALL __attribute__((regparam(3))) #endif -#else - #define OPHANDLER_CALL +#endif +#if !defined SC_FASTCALL + #define SC_FASTCALL #endif /* Note: the "cell" and "ucell" types are defined in AMX.H */ @@ -407,8 +402,15 @@ typedef struct s_valuepair { #define tSYMBOL 336 #define tLABEL 337 #define tSTRING 338 -#define tEXPR 339 /* for assigment to "lastst" only (see SC1.C) */ -#define tENDLESS 340 /* endless loop, for assigment to "lastst" only */ +/* argument types for emit/__emit */ +#define teNUMERIC 339 /* integer/rational number */ +#define teDATA 340 /* data (variable name or address) */ +#define teLOCAL 341 /* local variable (name or offset) */ +#define teFUNCTN 342 /* Pawn function */ +#define teNATIVE 343 /* native function */ +/* for assigment to "lastst" only (see SC1.C) */ +#define tEXPR 344 +#define tENDLESS 345 /* endless loop */ /* (reversed) evaluation of staging buffer */ #define sSTARTREORDER 0x01 @@ -699,7 +701,7 @@ SC_FUNC void dec(value *lval); SC_FUNC void jmp_ne0(int number); SC_FUNC void jmp_eq0(int number); SC_FUNC void outval(cell val,int newline); -SC_FUNC void outinstr(const char *name, int nargs, ucell *args); +SC_FUNC void outinstr(const char *name,ucell args[],int numargs); /* function prototypes in SC5.C */ SC_FUNC int error(int number,...); @@ -868,7 +870,16 @@ SC_VDECL FILE *outf; /* file written to */ SC_VDECL jmp_buf errbuf; /* target of longjmp() on a fatal error */ -SC_VDECL int emit_block_parsing; +/* 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 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 */ diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 217deb0..c0a6ed8 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -139,7 +139,7 @@ static void delwhile(void); static int *readwhile(void); static void doemit(void); -typedef void (OPHANDLER_CALL *OPCODE_PROC)(char *name); +typedef void (SC_FASTCALL *OPCODE_PROC)(char *name); typedef struct { cell opcode; char *name; @@ -895,7 +895,8 @@ static void resetglobals(void) sc_curstates=0; pc_memflags=0; pc_naked=FALSE; - emit_block_parsing=FALSE; + emit_flags=0; + emit_stgbuf_idx=-1; } static void initglobals(void) @@ -1669,9 +1670,11 @@ static void parse(void) break; case tEMIT: case t__EMIT: - emit_block_parsing=FALSE; + emit_flags |= efGLOBAL; lex(&val,&str); emit_parse_line(); + needtoken(';'); + emit_flags &= ~efGLOBAL; break; case tNEW: if (getclassspec(tok,&fpublic,&fstatic,&fstock,&fconst)) @@ -5116,13 +5119,12 @@ 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_block_parsing) { + if ((emit_flags & efBLOCK)!=0) { emit_parse_line(); + if (matchtoken('}')) + emit_flags &= ~efBLOCK; return; - } + } /* if */ if (tok!='{') { insert_dbgline(fline); setline(TRUE); @@ -5229,6 +5231,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 */ @@ -5847,582 +5864,6 @@ static void dolabel(void) sym->usage|=uDEFINE; /* label is now defined */ } -static void check_empty(const unsigned char *lptr) -{ - /* verifies that the string contains only whitespace */ - while (*lptr<=' ' && *lptr!='\0') - lptr++; - if (*lptr!='\0'&&*lptr!='}') - error(38); /* extra characters on line */ -} - -static void emit_invalid_token(int need_token, int current_token) -{ - char s[sNAMEMAX+ 2]; - extern char *sc_tokens[]; - - if (current_token<256) { - sprintf(s,"%c",(char)current_token); - } else { - strcpy(s,sc_tokens[current_token-tFIRST]); - } /* if */ - error(1,sc_tokens[tSYMBOL-tFIRST],s); -} - -static void emit_param_num(char *name, ucell *p, int size) -{ - char *str; - cell val; - symbol *sym; - int tok; - char ival[sNAMEMAX+2]="-"; - extern char *sc_tokens[]; - int curp=0; - - do { - switch (tok=lex(&val, &str)) { - case tRATIONAL: - case tNUMBER: - p[curp]=val; - break; - case tSYMBOL: - sym=findloc(str); - if (sym==NULL) - sym=findglb(str,sSTATEVAR); - if (sym==NULL || (sym->ident!=iFUNCTN && sym->ident!=iREFFUNC && (sym->usage & uDEFINE)==0) || sym->ident==iLABEL) { - error(17,str); /* undefined symbol */ - } else { - if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) { - if ((sym->usage & uNATIVE)!=0) { - if ((sym->usage & uREAD)==0 && sym->addr>=0) - sym->addr=ntv_funcid++; - } - p[curp]=sym->addr; - markusage(sym,uREAD); - } else { - p[curp]=sym->addr; - markusage(sym,uREAD|uWRITTEN); - } /* if */ - } /* if */ - break; - default: - if ((char)tok=='-') { - tok=lex(&val,&str); - if (tok==tNUMBER) { - p[curp]=-val; - break; - } else if (tok==tRATIONAL) { - p[curp]=val|0x80000000; - break; - } else { - strcpy(ival+1,str); - error(1,sc_tokens[tSYMBOL-tFIRST],ival); - break; - } /* if */ - } /* if */ - if (tok<256) { - sprintf(ival,"%c",(char)tok); - } else { - strcpy(ival,sc_tokens[tok-tFIRST]); - } /* if */ - error(1,sc_tokens[tSYMBOL-tFIRST],ival); - } /* switch */ - } while (++curp < size); -} - -static void emit_param_data(char *name, ucell *p, int size) -{ - cell val; - char *str; - symbol *sym; - int curp=0; - int tok; - extern char *sc_tokens[]; - - do { - tok=lex(&val,&str); - if (tok!=tSYMBOL) { - emit_invalid_token(tSYMBOL, tok); - } /* if */ - sym=findloc(str); - if (sym==NULL || sym->vclass!=sSTATIC) - sym=findglb(str,sGLOBAL); - if (sym==NULL) { - error(17,str); - } else { - if (sym->ident!=iVARIABLE) { - error(17,str); /* undefined symbol */ - } /* if */ - markusage(sym,uREAD|uWRITTEN); - p[curp]=sym->addr; - } /* if */ - } while (++curp < size); -} - -static void OPHANDLER_CALL emit_noop(char *name) -{ - (void)name; -} - -static void OPHANDLER_CALL emit_parm0(char *name) -{ - outinstr(name, 0, NULL); -} - -static void OPHANDLER_CALL emit_parm1_num(char *name) -{ - ucell p[1]; - - emit_param_num(name, p, arraysize(p)); - outinstr(name,arraysize(p),p); -} - -static void OPHANDLER_CALL emit_parm1_gvar(char *name) -{ - ucell p[1]; - - emit_param_data(name, p, arraysize(p)); - outinstr(name,arraysize(p),p); -} - -static void OPHANDLER_CALL emit_parm1_lbl(char *name) -{ - char *str; - cell val; - symbol *sym; - int tok; - - tok=lex(&val,&str); - if (tok!=tSYMBOL) { - emit_invalid_token(tSYMBOL, tok); - } /* if */ - sym=fetchlab(str); - sym->usage|=uREAD; - outinstr(name,1,&sym->addr); -} - -static void OPHANDLER_CALL emit_parm2_num(char *name) -{ - ucell p[2]; - - emit_param_num(name, p, arraysize(p)); - outinstr(name,arraysize(p),p); -} - -static void OPHANDLER_CALL emit_parm2_gvar(char *name) -{ - ucell p[2]; - - emit_param_data(name, p, arraysize(p)); - outinstr(name,arraysize(p),p); -} - -static void OPHANDLER_CALL emit_parm2_gvar_num(char *name) -{ - cell val; - char *str; - ucell p[2]; - symbol *sym; - int curp=0; - int tok; - extern char *sc_tokens[]; - - tok=lex(&val,&str); - if (tok!=tSYMBOL) { - emit_invalid_token(tSYMBOL, tok); - } /* if */ - sym=findloc(str); - if (sym==NULL || sym->vclass!=sSTATIC) - sym=findglb(str,sGLOBAL); - if (sym==NULL) { - error(17,str); - } else { - if (sym->ident!=iVARIABLE) { - error(17,str); /* undefined symbol */ - } /* if */ - markusage(sym,uREAD); - p[0]=sym->addr; - tok=lex(&val,&str); - if (tok!=tNUMBER) { - emit_invalid_token(tNUMBER, tok); - } /* if */ - p[1]=val; - outinstr(name,arraysize(p),p); - } /* if */ -} - -static void OPHANDLER_CALL emit_parm3_num(char *name) -{ - ucell p[3]; - - emit_param_num(name, p, arraysize(p)); - outinstr(name,arraysize(p),p); -} - -static void OPHANDLER_CALL emit_parm3_gvar(char *name) -{ - ucell p[3]; - - emit_param_data(name, p, arraysize(p)); - outinstr(name,arraysize(p),p); -} - -static void OPHANDLER_CALL emit_parm4_num(char *name) -{ - ucell p[4]; - - emit_param_num(name, p, arraysize(p)); - outinstr(name,arraysize(p),p); -} - -static void OPHANDLER_CALL emit_parm4_gvar(char *name) -{ - ucell p[4]; - - emit_param_data(name, p, arraysize(p)); - outinstr(name,arraysize(p),p); -} - -static void OPHANDLER_CALL emit_parm5_num(char *name) -{ - ucell p[5]; - - emit_param_num(name, p, arraysize(p)); - outinstr(name,arraysize(p),p); -} - -static void OPHANDLER_CALL emit_parm5_gvar(char *name) -{ - ucell p[5]; - - emit_param_data(name, p, arraysize(p)); - outinstr(name,arraysize(p),p); -} - -static void OPHANDLER_CALL emit_do_case(char *name) -{ - /* case