Skip to content

Commit

Permalink
Add __file, __date, __time constants
Browse files Browse the repository at this point in the history
Closes #105, fixes #144.
  • Loading branch information
Zeex committed Feb 4, 2017
1 parent 0cd10a7 commit 8d6f051
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 56 deletions.
33 changes: 19 additions & 14 deletions source/compiler/sc.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,28 +198,29 @@ typedef struct s_symbol {
* 5 (uENUMROOT) the constant is the "root" of an enumeration
* 6 (uENUMFIELD) the constant is a field in a named enumeration
*/
#define uDEFINE 0x001
#define uREAD 0x002
#define uWRITTEN 0x004
#define uRETVALUE 0x004 /* function returns (or should return) a value */
#define uCONST 0x008
#define uDEFINE 0x001
#define uREAD 0x002
#define uWRITTEN 0x004
#define uRETVALUE 0x004 /* function returns (or should return) a value */
#define uCONST 0x008
#define uPROTOTYPED 0x008
#define uPREDEF 0x008 /* constant is pre-defined */
#define uPUBLIC 0x010
#define uNATIVE 0x020
#define uENUMROOT 0x020
#define uSTOCK 0x040
#define uENUMFIELD 0x040
#define uMISSING 0x080
#define uFORWARD 0x100
#define uPREDEF 0x008 /* constant is pre-defined */
#define uPUBLIC 0x010
#define uNATIVE 0x020
#define uENUMROOT 0x020
#define uSTOCK 0x040
#define uENUMFIELD 0x040
#define uMISSING 0x080
#define uFORWARD 0x100
/* uRETNONE is not stored in the "usage" field of a symbol. It is
* used during parsing a function, to detect a mix of "return;" and
* "return value;" in a few special cases.
*/
#define uRETNONE 0x10
#define uRETNONE 0x10

#define flgDEPRECATED 0x01 /* symbol is deprecated (avoid use) */
#define flagNAKED 0x10 /* function is naked */
#define flagPREDEF 0x20 /* symbol is pre-defined; successor of uPREDEF */

#define uTAGOF 0x40 /* set in the "hasdefault" field of the arginfo struct */
#define uSIZEOF 0x80 /* set in the "hasdefault" field of the arginfo struct */
Expand Down Expand Up @@ -527,6 +528,8 @@ SC_FUNC constvalue *append_constval(constvalue *table,const char *name,cell val,
SC_FUNC constvalue *find_constval(constvalue *table,char *name,int index);
SC_FUNC void delete_consttable(constvalue *table);
SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag);
SC_FUNC symbol *add_builtin_constant(char *name,cell val,int vclass,int tag);
SC_FUNC symbol *add_builtin_string_constant(char *name,const char *val,int vclass);
SC_FUNC void exporttag(int tag);
SC_FUNC void sc_attachdocumentation(symbol *sym);

Expand Down Expand Up @@ -583,7 +586,9 @@ SC_FUNC void begcseg(void);
SC_FUNC void begdseg(void);
SC_FUNC void setline(int chkbounds);
SC_FUNC void setfiledirect(char *name);
SC_FUNC void setfileconst(char *name);
SC_FUNC void setlinedirect(int line);
SC_FUNC void setlineconst(int line);
SC_FUNC void setlabel(int index);
SC_FUNC void markexpr(optmark type,const char *name,cell offset);
SC_FUNC void startfunc(char *fname);
Expand Down
137 changes: 106 additions & 31 deletions source/compiler/sc1.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#if defined __WIN32__ || defined _WIN32 || defined __MSDOS__
#include <conio.h>
Expand Down Expand Up @@ -81,6 +82,7 @@ static void setconfig(char *root);
static void setcaption(void);
static void about(void);
static void setconstants(void);
static void setstringconstants(void);
static void parse(void);
static void dumplits(void);
static void dumpzero(int count);
Expand Down Expand Up @@ -570,8 +572,8 @@ int pc_compile(int argc, char *argv[])
sc_needsemicolon ? "true" : "false",
sc_tabsize);
pc_writeasm(outf,string);
setfiledirect(inpfname);
} /* if */
setfiledirect(inpfname);
/* do the first pass through the file (or possibly two or more "first passes") */
sc_parsenum=0;
inpfmark=pc_getpossrc(inpf_org);
Expand All @@ -596,7 +598,8 @@ int pc_compile(int argc, char *argv[])
fline=skipinput; /* reset line number */
sc_reparse=FALSE; /* assume no extra passes */
sc_status=statFIRST; /* resetglobals() resets it to IDLE */

setstringconstants();
setfileconst(inpfname);
if (strlen(incfname)>0) {
if (strcmp(incfname,sDEF_PREFIX)==0) {
plungefile(incfname,FALSE,TRUE); /* parse "default.inc" */
Expand Down Expand Up @@ -660,7 +663,9 @@ int pc_compile(int argc, char *argv[])
fline=skipinput; /* reset line number */
lexinit(); /* clear internal flags of lex() */
sc_status=statWRITE; /* allow to write --this variable was reset by resetglobals() */
setstringconstants();
writeleader(&glbtab);
setfileconst(inpfname);
insert_dbgfile(inpfname);
if (strlen(incfname)>0) {
if (strcmp(incfname,sDEF_PREFIX)==0)
Expand Down Expand Up @@ -1457,58 +1462,74 @@ static void setconstants(void)
append_constval(&tagname_tab,"_",0,0);/* "untagged" */
append_constval(&tagname_tab,"bool",1,0);

add_constant("true",1,sGLOBAL,1); /* boolean flags */
add_constant("false",0,sGLOBAL,1);
add_constant("EOS",0,sGLOBAL,0); /* End Of String, or '\0' */
add_builtin_constant("true",1,sGLOBAL,1); /* boolean flags */
add_builtin_constant("false",0,sGLOBAL,1);
add_builtin_constant("EOS",0,sGLOBAL,0); /* End Of String, or '\0' */
#if PAWN_CELL_SIZE==16
add_constant("cellbits",16,sGLOBAL,0);
add_builtin_constant("cellbits",16,sGLOBAL,0);
#if defined _I16_MAX
add_constant("cellmax",_I16_MAX,sGLOBAL,0);
add_constant("cellmin",_I16_MIN,sGLOBAL,0);
add_builtin_constant("cellmax",_I16_MAX,sGLOBAL,0);
add_builtin_constant("cellmin",_I16_MIN,sGLOBAL,0);
#else
add_constant("cellmax",SHRT_MAX,sGLOBAL,0);
add_constant("cellmin",SHRT_MIN,sGLOBAL,0);
add_builtin_constant("cellmax",SHRT_MAX,sGLOBAL,0);
add_builtin_constant("cellmin",SHRT_MIN,sGLOBAL,0);
#endif
#elif PAWN_CELL_SIZE==32
add_constant("cellbits",32,sGLOBAL,0);
add_builtin_constant("cellbits",32,sGLOBAL,0);
#if defined _I32_MAX
add_constant("cellmax",_I32_MAX,sGLOBAL,0);
add_constant("cellmin",_I32_MIN,sGLOBAL,0);
add_builtin_constant("cellmax",_I32_MAX,sGLOBAL,0);
add_builtin_constant("cellmin",_I32_MIN,sGLOBAL,0);
#else
add_constant("cellmax",INT_MAX,sGLOBAL,0);
add_constant("cellmin",INT_MIN,sGLOBAL,0);
add_builtin_constant("cellmax",INT_MAX,sGLOBAL,0);
add_builtin_constant("cellmin",INT_MIN,sGLOBAL,0);
#endif
#elif PAWN_CELL_SIZE==64
#if !defined _I64_MIN
#define _I64_MIN (-9223372036854775807ULL - 1)
#define _I64_MAX 9223372036854775807ULL
#endif
add_constant("cellbits",64,sGLOBAL,0);
add_constant("cellmax",_I64_MAX,sGLOBAL,0);
add_constant("cellmin",_I64_MIN,sGLOBAL,0);
add_builtin_constant("cellbits",64,sGLOBAL,0);
add_builtin_constant("cellmax",_I64_MAX,sGLOBAL,0);
add_builtin_constant("cellmin",_I64_MIN,sGLOBAL,0);
#else
#error Unsupported cell size
#endif
add_constant("charbits",sCHARBITS,sGLOBAL,0);
add_constant("charmin",0,sGLOBAL,0);
add_constant("charmax",~(-1 << sCHARBITS) - 1,sGLOBAL,0);
add_constant("ucharmax",(1 << (sizeof(cell)-1)*8)-1,sGLOBAL,0);
add_builtin_constant("charbits",sCHARBITS,sGLOBAL,0);
add_builtin_constant("charmin",0,sGLOBAL,0);
add_builtin_constant("charmax",~(-1 << sCHARBITS) - 1,sGLOBAL,0);
add_builtin_constant("ucharmax",(1 << (sizeof(cell)-1)*8)-1,sGLOBAL,0);

add_constant("__Pawn",VERSION_INT,sGLOBAL,0);
add_constant("__PawnBuild",VERSION_BUILD,sGLOBAL,0);
add_constant("__line",0,sGLOBAL,0);
add_constant("__compat",pc_compat,sGLOBAL,0);
add_builtin_constant("__Pawn",VERSION_INT,sGLOBAL,0);
add_builtin_constant("__PawnBuild",VERSION_BUILD,sGLOBAL,0);
add_builtin_constant("__line",0,sGLOBAL,0);
add_builtin_constant("__compat",pc_compat,sGLOBAL,0);

debug=0;
if ((sc_debug & (sCHKBOUNDS | sSYMBOLIC))==(sCHKBOUNDS | sSYMBOLIC))
debug=2;
else if ((sc_debug & sCHKBOUNDS)==sCHKBOUNDS)
debug=1;
add_constant("debug",debug,sGLOBAL,0);
add_builtin_constant("debug",debug,sGLOBAL,0);

append_constval(&sc_automaton_tab,"",0,0); /* anonymous automaton */
}

static void setstringconstants()
{
time_t now;
char timebuf[sizeof("11:22:33")];
char datebuf[sizeof("10 Jan 2017")];

assert(sc_status!=statIDLE);
add_builtin_string_constant("__file","",sGLOBAL);

now = time(NULL);
strftime(timebuf,sizeof(timebuf),"%H:%M:%S",localtime(&now));
add_builtin_string_constant("__time",timebuf,sGLOBAL);
strftime(datebuf,sizeof(datebuf),"%d %b %Y",localtime(&now));
add_builtin_string_constant("__date",datebuf,sGLOBAL);
}

static int getclassspec(int initialtok,int *fpublic,int *fstatic,int *fstock,int *fconst)
{
int tok,err;
Expand Down Expand Up @@ -4898,9 +4919,9 @@ SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag)
* constants are stored in the symbols table, this also finds previously
* defind constants. */
sym=findglb(name,sSTATEVAR);
if (!sym)
if (sym==NULL)
sym=findloc(name);
if (sym) {
if (sym!=NULL) {
int redef=0;
if (sym->ident!=iCONSTEXPR)
redef=1; /* redefinition a function/variable to a constant is not allowed */
Expand Down Expand Up @@ -4942,8 +4963,62 @@ SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag)
redef_enumfield:
sym=addsym(name,val,iCONSTEXPR,vclass,tag,uDEFINE);
assert(sym!=NULL); /* fatal error 103 must be given on error */
if (sc_status == statIDLE)
sym->usage |= uPREDEF;
return sym;
}

/* add_builtin_constant
*
* Adds a predefined constant to the symbol table.
*/
SC_FUNC symbol *add_builtin_constant(char *name,cell val,int vclass,int tag)
{
symbol *sym;

sym=add_constant(name,val,vclass,tag);
sym->flags|=flagPREDEF;
return sym;
}

/* add_builtin_string_constant
*
* Adds a predefined string constant to the symbol table.
*/
SC_FUNC symbol *add_builtin_string_constant(char *name,const char *val,
int vclass)
{
symbol *sym;

/* Test whether a global or local symbol with the same name exists. Since
* constants are stored in the symbols table, this also finds previously
* defind constants. */
sym=findglb(name,sSTATEVAR);
if (sym==NULL)
sym=findloc(name);
if (sym!=NULL) {
int redef=0;
if (sym->ident!=iARRAY) {
error(21,name); /* symbol already defined */
return NULL;
} /* if */
} else {
sym=addsym(name,0,iARRAY,vclass,0,uDEFINE | uSTOCK);
} /* if */
sym->addr=(litidx+glb_declared)*sizeof(cell);
/* Store this constant only if it's used somewhere. This can be detected
* in the second stage. */
if (sc_status==statIDLE
|| (sc_status==statWRITE && (sym->usage & uREAD)!=0)) {
assert(litidx==0);
begdseg();
while (*val!='\0')
litadd(*val++);
litadd(0);
glb_declared+=litidx;
dumplits();
litidx=0;
}
sym->usage|=uDEFINE;
sym->flags|=flagPREDEF;
return sym;
}

Expand Down
21 changes: 10 additions & 11 deletions source/compiler/sc2.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ static char extensions[][6] = { "", ".inc", ".p", ".pawn" };
icomment=0; /* not in a comment */
insert_dbgfile(inpfname);
setfiledirect(inpfname);
setfileconst(inpfname);
listline=-1; /* force a #line directive when changing the file */
sc_is_utf8=(short)scan_utf8(inpf,real_path);
free(real_path);
Expand Down Expand Up @@ -350,7 +351,6 @@ static void readline(unsigned char *line)
{
int i,num,cont;
unsigned char *ptr;
symbol *sym;

if (lptr==term_expr)
return;
Expand Down Expand Up @@ -429,9 +429,7 @@ static void readline(unsigned char *line)
line+=strlen((char*)line);
} /* if */
fline+=1;
sym=findconst("__line",NULL);
assert(sym!=NULL);
sym->addr=fline;
setlineconst(fline);
} while (num>=0 && cont);
}

Expand Down Expand Up @@ -1356,12 +1354,12 @@ static int command(void)
outval(val | 0x80000000,FALSE);
code_idx+=opargs(1);
break;
} else {
} else {
strcpy(s2+1, str);
error(1,sc_tokens[tSYMBOL-tFIRST],s2);
break;
} /* if */
} /* if */
} /* if */
if (tok<256)
sprintf(s2,"%c",(char)tok);
else
Expand Down Expand Up @@ -2203,8 +2201,8 @@ SC_FUNC int lex(cell *lexvalue,char **lexsym)
} else if (*lptr=='\"' || *lptr=='#' || *lptr==sc_ctrlchar && (*(lptr+1)=='\"' || *(lptr+1)=='#'))
{ /* unpacked string literal */
_lextok=tSTRING;
stringflags= (*lptr==sc_ctrlchar) ? RAWMODE : 0;
stringflags |= (*lptr=='#' || (*lptr==sc_ctrlchar && *(lptr+1)=='#')) ? STRINGIZE : 0;
stringflags=(*lptr==sc_ctrlchar) ? RAWMODE : 0;
stringflags|=(*lptr=='#' || (*lptr==sc_ctrlchar && *(lptr+1)=='#')) ? STRINGIZE : 0;
*lexvalue=_lexval=litidx;
lptr+=1; /* skip double quote */
if ((stringflags & RAWMODE)!=0)
Expand Down Expand Up @@ -2748,7 +2746,7 @@ SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_
assert(0);
break;
} /* switch */
if (mustdelete) {
if (mustdelete && (sym->flags & flagPREDEF)==0) {
root->next=sym->next;
free_symbol(sym);
} else {
Expand All @@ -2757,7 +2755,8 @@ SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_
*/
if (sym->ident==iFUNCTN && (sym->usage & uDEFINE)==0)
sym->usage |= uMISSING;
if (sym->ident==iFUNCTN || sym->ident==iVARIABLE || sym->ident==iARRAY)
if ((sym->ident==iFUNCTN || sym->ident==iVARIABLE || sym->ident==iARRAY)
&& (sym->flags & flagPREDEF)==0)
sym->usage &= ~uDEFINE; /* clear "defined" flag */
/* set all states as "undefined" too */
if (sym->states!=NULL)
Expand All @@ -2770,7 +2769,7 @@ SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_
sym->usage &= ~uPROTOTYPED;
root=sym; /* skip the symbol */
} /* if */
} /* if */
} /* while */
}

/* The purpose of the hash is to reduce the frequency of a "name"
Expand Down
17 changes: 17 additions & 0 deletions source/compiler/sc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,14 @@ SC_FUNC void setfiledirect(char *name)
} /* if */
}

SC_FUNC void setfileconst(char *name)
{
symbol *sym;

sym=add_builtin_string_constant("__file",name,sGLOBAL);
sym->fnumber=fcurrent;
}

SC_FUNC void setlinedirect(int line)
{
if (sc_status==statFIRST && sc_listing) {
Expand All @@ -279,6 +287,15 @@ SC_FUNC void setlinedirect(int line)
} /* if */
}

SC_FUNC void setlineconst(int line)
{
symbol *sym;

sym=findconst("__line",NULL);
assert(sym!=NULL);
sym->addr=fline;
}

/* setlabel
*
* Post a code label (specified as a number), on a new line.
Expand Down

0 comments on commit 8d6f051

Please sign in to comment.