diff --git a/compiler/libpc300/libpc300.sln b/compiler/libpc300/libpc300.sln
index 96b5d99b..7f2a48ab 100755
--- a/compiler/libpc300/libpc300.sln
+++ b/compiler/libpc300/libpc300.sln
@@ -7,6 +7,7 @@ Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Debug32 = Debug32
+ Debug64 = Debug64
Release = Release
Release32 = Release32
Release64 = Release64
@@ -16,6 +17,8 @@ Global
{19B72687-080B-437A-917A-12AEB0031635}.Debug.Build.0 = Release|Win32
{19B72687-080B-437A-917A-12AEB0031635}.Debug32.ActiveCfg = Debug32|Win32
{19B72687-080B-437A-917A-12AEB0031635}.Debug32.Build.0 = Debug32|Win32
+ {19B72687-080B-437A-917A-12AEB0031635}.Debug64.ActiveCfg = Debug64|Win32
+ {19B72687-080B-437A-917A-12AEB0031635}.Debug64.Build.0 = Debug64|Win32
{19B72687-080B-437A-917A-12AEB0031635}.Release.ActiveCfg = Release|Win32
{19B72687-080B-437A-917A-12AEB0031635}.Release.Build.0 = Release|Win32
{19B72687-080B-437A-917A-12AEB0031635}.Release32.ActiveCfg = Release32|Win32
diff --git a/compiler/libpc300/libpc300.vcproj b/compiler/libpc300/libpc300.vcproj
index 165649e7..ac5e594b 100755
--- a/compiler/libpc300/libpc300.vcproj
+++ b/compiler/libpc300/libpc300.vcproj
@@ -249,6 +249,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/compiler/libpc300/sc.h b/compiler/libpc300/sc.h
index 6d885527..0c36990c 100755
--- a/compiler/libpc300/sc.h
+++ b/compiler/libpc300/sc.h
@@ -629,7 +629,12 @@ SC_FUNC void jmp_eq0(int number);
SC_FUNC void outval(cell val,int newline);
/* function prototypes in SC5.C */
-SC_FUNC int error(int number,...) __attribute__((visibility("protected")));
+#if defined WIN32
+#define INVISIBLE
+#else
+#define INVISIBLE __attribute__((visibility("protected")))
+#endif
+SC_FUNC int error(int number,...) INVISIBLE;
SC_FUNC void errorset(int code);
/* function prototypes in SC6.C */
diff --git a/compiler/libpc300/sc1.c b/compiler/libpc300/sc1.c
index a3ac9292..a592bb27 100755
--- a/compiler/libpc300/sc1.c
+++ b/compiler/libpc300/sc1.c
@@ -1,26 +1,26 @@
-/* Pawn compiler
+/* Pawn compiler
*
- * Function and variable definition and declaration, statement parser.
+ * Function and variable definition and declaration, statement parser.
*
- * Copyright (c) ITB CompuPhase, 1997-2005
+ * Copyright (c) ITB CompuPhase, 1997-2005
*
- * This software is provided "as-is", without any express or implied warranty.
- * In no event will the authors be held liable for any damages arising from
- * the use of this software.
+ * This software is provided "as-is", without any express or implied warranty.
+ * In no event will the authors be held liable for any damages arising from
+ * the use of this software.
*
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
*
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software in
- * a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software in
+ * a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
*
- * Version: $Id$
+ * Version: $Id$
*/
#include
#include
@@ -30,136 +30,136 @@
#include
#include
-#if defined __WIN32__ || defined _WIN32 || defined __MSDOS__
+#if defined __WIN32__ || defined _WIN32 || defined __MSDOS__
#include
#include
#endif
-#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
+#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
#include
- #include /* from BinReloc, see www.autopackage.org */
+ #include /* from BinReloc, see www.autopackage.org */
#endif
-#if defined FORTIFY
+#if defined FORTIFY
#include "fortify.h"
#endif
-#if defined __BORLANDC__ || defined __WATCOMC__
+#if defined __BORLANDC__ || defined __WATCOMC__
#include
- static unsigned total_drives; /* dummy variable */
- #define dos_setdrive(i) _dos_setdrive(i,&total_drives)
+ static unsigned total_drives; /* dummy variable */
+ #define dos_setdrive(i) _dos_setdrive(i,&total_drives)
#elif defined _MSC_VER && defined _WIN32
- #include /* for _chdrive() */
- #define dos_setdrive(i) _chdrive(i)
+ #include /* for _chdrive() */
+ #define dos_setdrive(i) _chdrive(i)
#endif
-#if defined __BORLANDC__
- #include /* for chdir() */
+#if defined __BORLANDC__
+ #include /* for chdir() */
#elif defined __WATCOMC__
- #include /* for chdir() */
+ #include /* for chdir() */
#endif
-#if defined __WIN32__ || defined _WIN32 || defined _Windows
+#if defined __WIN32__ || defined _WIN32 || defined _Windows
#include
#endif
#include "sc.h"
-#define VERSION_STR "3.0.3367"
-#define VERSION_INT 0x300
+#define VERSION_STR "3.0.3367"
+#define VERSION_INT 0x300
-static void resetglobals(void);
-static void initglobals(void);
-static void setopt(int argc,char **argv,char *oname,char *ename,char *pname,
- char *rname,char *codepage);
-static void setconfig(char *root);
-static void setcaption(void);
-static void about(void);
-static void setconstants(void);
-static void parse(void);
-static void dumplits(void);
-static void dumpzero(int count);
-static void declfuncvar(int fpublic,int fstatic,int fstock,int fconst);
-static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,
- int stock,int fconst);
+static void resetglobals(void);
+static void initglobals(void);
+static void setopt(int argc,char **argv,char *oname,char *ename,char *pname,
+ char *rname,char *codepage);
+static void setconfig(char *root);
+static void setcaption(void);
+static void about(void);
+static void setconstants(void);
+static void parse(void);
+static void dumplits(void);
+static void dumpzero(int count);
+static void declfuncvar(int fpublic,int fstatic,int fstock,int fconst);
+static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,
+ int stock,int fconst);
static int declloc(int fstatic);
-static void decl_const(int table);
-static void decl_enum(int table);
-static cell needsub(int *tag,constvalue **enumroot);
-static void initials(int ident,int tag,cell *size,int dim[],int numdim,
- constvalue *enumroot);
-static cell initarray(int ident,int tag,int dim[],int numdim,int cur,
- int startlit,int counteddim[],constvalue *lastdim,
- constvalue *enumroot,int *errorfound);
-static cell initvector(int ident,int tag,cell size,int fillzero,
- constvalue *enumroot,int *errorfound);
-static cell init(int ident,int *tag,int *errorfound);
-static void funcstub(int native);
-static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stock);
+static void decl_const(int table);
+static void decl_enum(int table);
+static cell needsub(int *tag,constvalue **enumroot);
+static void initials(int ident,int tag,cell *size,int dim[],int numdim,
+ constvalue *enumroot);
+static cell initarray(int ident,int tag,int dim[],int numdim,int cur,
+ int startlit,int counteddim[],constvalue *lastdim,
+ constvalue *enumroot,int *errorfound);
+static cell initvector(int ident,int tag,cell size,int fillzero,
+ constvalue *enumroot,int *errorfound);
+static cell init(int ident,int *tag,int *errorfound);
+static void funcstub(int native);
+static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stock);
static int declargs(symbol *sym);
-static void doarg(char *name,int ident,int offset,int tags[],int numtags,
- int fpublic,int fconst,arginfo *arg);
-static void make_report(symbol *root,FILE *log,char *sourcefile);
-static void reduce_referrers(symbol *root);
-static long max_stacksize(symbol *root);
-static int testsymbols(symbol *root,int level,int testlabs,int testconst);
-static void destructsymbols(symbol *root,int level);
+static void doarg(char *name,int ident,int offset,int tags[],int numtags,
+ int fpublic,int fconst,arginfo *arg);
+static void make_report(symbol *root,FILE *log,char *sourcefile);
+static void reduce_referrers(symbol *root);
+static long max_stacksize(symbol *root);
+static int testsymbols(symbol *root,int level,int testlabs,int testconst);
+static void destructsymbols(symbol *root,int level);
static constvalue *find_constval_byval(constvalue *table,cell val);
-static void statement(int *lastindent,int allow_decl);
-static void compound(int stmt_sameline);
-static int doexpr(int comma,int chkeffect,int allowarray,int mark_endexpr,
- int *tag,symbol **symptr,int chkfuncresult);
-static void doassert(void);
-static void doexit(void);
-static void test(int label,int parens,int invert);
-static void doif(void);
-static void dowhile(void);
-static void dodo(void);
-static void dofor(void);
-static void doswitch(void);
-static void dogoto(void);
-static void dolabel(void);
+static void statement(int *lastindent,int allow_decl);
+static void compound(int stmt_sameline);
+static int doexpr(int comma,int chkeffect,int allowarray,int mark_endexpr,
+ int *tag,symbol **symptr,int chkfuncresult);
+static void doassert(void);
+static void doexit(void);
+static void test(int label,int parens,int invert);
+static void doif(void);
+static void dowhile(void);
+static void dodo(void);
+static void dofor(void);
+static void doswitch(void);
+static void dogoto(void);
+static void dolabel(void);
static symbol *fetchlab(char *name);
-static void doreturn(void);
-static void dobreak(void);
-static void docont(void);
-static void dosleep(void);
-static void dostate(void);
-static void addwhile(int *ptr);
-static void delwhile(void);
+static void doreturn(void);
+static void dobreak(void);
+static void docont(void);
+static void dosleep(void);
+static void dostate(void);
+static void addwhile(int *ptr);
+static void delwhile(void);
static int *readwhile(void);
-static int lastst = 0; /* last executed statement type */
-static int nestlevel = 0; /* number of active (open) compound statements */
-static int rettype = 0; /* the type that a "return" expression should have */
-static int skipinput = 0; /* number of lines to skip from the first input file */
-static int optproccall = TRUE; /* support "procedure call" */
-static int verbosity = 1; /* verbosity level, 0=quiet, 1=normal, 2=verbose */
-static int sc_reparse = 0; /* needs 3th parse because of changed prototypes? */
-static int sc_parsenum = 0; /* number of the extra parses */
-static int wq[wqTABSZ]; /* "while queue", internal stack for nested loops */
-static int *wqptr; /* pointer to next entry */
-#if !defined SC_LIGHT
- static char *sc_documentation=NULL;/* main documentation */
+static int lastst = 0; /* last executed statement type */
+static int nestlevel = 0; /* number of active (open) compound statements */
+static int rettype = 0; /* the type that a "return" expression should have */
+static int skipinput = 0; /* number of lines to skip from the first input file */
+static int optproccall = TRUE; /* support "procedure call" */
+static int verbosity = 1; /* verbosity level, 0=quiet, 1=normal, 2=verbose */
+static int sc_reparse = 0; /* needs 3th parse because of changed prototypes? */
+static int sc_parsenum = 0; /* number of the extra parses */
+static int wq[wqTABSZ]; /* "while queue", internal stack for nested loops */
+static int *wqptr; /* pointer to next entry */
+#if !defined SC_LIGHT
+ static char *sc_documentation=NULL;/* main documentation */
#endif
-#if defined __WIN32__ || defined _WIN32 || defined _Windows
+#if defined __WIN32__ || defined _WIN32 || defined _Windows
static HWND hwndFinish = 0;
#endif
-#if !defined NO_MAIN
+#if !defined NO_MAIN
-#if defined __TURBOC__ && !defined __32BIT__
- extern unsigned int _stklen = 0x2000;
+#if defined __TURBOC__ && !defined __32BIT__
+ extern unsigned int _stklen = 0x2000;
#endif
-int main(int argc, char *argv[])
+int main(int argc, char *argv[])
{
return pc_compile(argc,argv);
}
/* pc_printf()
- * Called for general purpose "console" output. This function prints general
- * purpose messages; errors go through pc_error(). The function is modelled
+ * Called for general purpose "console" output. This function prints general
+ * purpose messages; errors go through pc_error(). The function is modelled
* after printf().
*/
-int pc_printf(const char *message,...)
+int pc_printf(const char *message,...)
{
int ret;
va_list argptr;
@@ -172,32 +172,32 @@ int pc_printf(const char *message,...)
}
/* pc_error()
- * Called for producing error output.
- * number the error number (as documented in the manual)
- * message a string describing the error with embedded %d and %s tokens
- * filename the name of the file currently being parsed
- * firstline the line number at which the expression started on which
- * the error was found, or -1 if there is no "starting line"
- * lastline the line number at which the error was detected
- * argptr a pointer to the first of a series of arguments (for macro
- * "va_arg")
+ * Called for producing error output.
+ * number the error number (as documented in the manual)
+ * message a string describing the error with embedded %d and %s tokens
+ * filename the name of the file currently being parsed
+ * firstline the line number at which the expression started on which
+ * the error was found, or -1 if there is no "starting line"
+ * lastline the line number at which the error was detected
+ * argptr a pointer to the first of a series of arguments (for macro
+ * "va_arg")
* Return:
- * If the function returns 0, the parser attempts to continue compilation.
- * On a non-zero return value, the parser aborts.
+ * If the function returns 0, the parser attempts to continue compilation.
+ * On a non-zero return value, the parser aborts.
*/
-int pc_error(int number,char *message,char *filename,int firstline,int lastline,va_list argptr)
+int pc_error(int number,char *message,char *filename,int firstline,int lastline,va_list argptr)
{
-static char *prefix[3]={ "error", "fatal error", "warning" };
+static char *prefix[3]={ "error", "fatal error", "warning" };
if (number!=0) {
- char *pre;
+ char *pre;
- pre=prefix[number/100];
- if (firstline>=0)
- fprintf(stderr,"%s(%d -- %d) : %s %03d: ",filename,firstline,lastline,pre,number);
- else
- fprintf(stderr,"%s(%d) : %s %03d: ",filename,lastline,pre,number);
- } /* if */
+ pre=prefix[number/100];
+ if (firstline>=0)
+ fprintf(stderr,"%s(%d -- %d) : %s %03d: ",filename,firstline,lastline,pre,number);
+ else
+ fprintf(stderr,"%s(%d) : %s %03d: ",filename,lastline,pre,number);
+ } /* if */
vfprintf(stderr,message,argptr);
fflush(stderr);
return 0;
@@ -205,15 +205,15 @@ static char *prefix[3]={ "error", "fatal error", "warning" };
/* pc_opensrc()
* Opens a source file (or include file) for reading. The "file" does not have
- * to be a physical file, one might compile from memory.
- * filename the name of the "file" to read from
+ * to be a physical file, one might compile from memory.
+ * filename the name of the "file" to read from
* Return:
- * The function must return a pointer, which is used as a "magic cookie" to
- * all I/O functions. When failing to open the file for reading, the
- * function must return NULL.
+ * The function must return a pointer, which is used as a "magic cookie" to
+ * all I/O functions. When failing to open the file for reading, the
+ * function must return NULL.
* Note:
- * Several "source files" may be open at the same time. Specifically, one
- * file can be open for reading and another for writing.
+ * Several "source files" may be open at the same time. Specifically, one
+ * file can be open for reading and another for writing.
*/
void *pc_opensrc(char *filename)
{
@@ -221,25 +221,25 @@ void *pc_opensrc(char *filename)
}
/* pc_createsrc()
- * Creates/overwrites a source file for writing. The "file" does not have
- * to be a physical file, one might compile from memory.
- * filename the name of the "file" to create
+ * Creates/overwrites a source file for writing. The "file" does not have
+ * to be a physical file, one might compile from memory.
+ * filename the name of the "file" to create
* Return:
- * The function must return a pointer, which is used as a "magic cookie" to
- * all I/O functions. When failing to open the file for reading, the
- * function must return NULL.
+ * The function must return a pointer, which is used as a "magic cookie" to
+ * all I/O functions. When failing to open the file for reading, the
+ * function must return NULL.
* Note:
- * Several "source files" may be open at the same time. Specifically, one
- * file can be open for reading and another for writing.
+ * Several "source files" may be open at the same time. Specifically, one
+ * file can be open for reading and another for writing.
*/
-void *pc_createsrc(char *filename)
+void *pc_createsrc(char *filename)
{
return fopen(filename,"w");
}
/* pc_closesrc()
- * Closes a source file (or include file). The "handle" parameter has the
- * value that pc_opensrc() returned in an earlier call.
+ * Closes a source file (or include file). The "handle" parameter has the
+ * value that pc_opensrc() returned in an earlier call.
*/
void pc_closesrc(void *handle)
{
@@ -248,104 +248,104 @@ void pc_closesrc(void *handle)
}
/* pc_resetsrc()
- * "position" may only hold a pointer that was previously obtained from
+ * "position" may only hold a pointer that was previously obtained from
* pc_getpossrc()
*/
void pc_resetsrc(void *handle,void *position)
{
assert(handle!=NULL);
- fsetpos((FILE*)handle,(fpos_t *)position);
+ fsetpos((FILE*)handle,(fpos_t *)position);
}
/* pc_readsrc()
- * Reads a single line from the source file (or up to a maximum number of
- * characters if the line in the input file is too long).
+ * Reads a single line from the source file (or up to a maximum number of
+ * characters if the line in the input file is too long).
*/
-char *pc_readsrc(void *handle,unsigned char *target,int maxchars)
+char *pc_readsrc(void *handle,unsigned char *target,int maxchars)
{
return fgets((char*)target,maxchars,(FILE*)handle);
}
/* pc_writesrc()
- * Writes to to the source file. There is no automatic line ending; to end a
+ * Writes to to the source file. There is no automatic line ending; to end a
* line, write a "\n".
*/
-int pc_writesrc(void *handle,unsigned char *source)
+int pc_writesrc(void *handle,unsigned char *source)
{
- return fputs((char*)source,(FILE*)handle) >= 0;
+ return fputs((char*)source,(FILE*)handle) >= 0;
}
-void *pc_getpossrc(void *handle)
+void *pc_getpossrc(void *handle)
{
- static fpos_t lastpos; /* may need to have a LIFO stack of such positions */
+ static fpos_t lastpos; /* may need to have a LIFO stack of such positions */
fgetpos((FILE*)handle,&lastpos);
return &lastpos;
}
-int pc_eofsrc(void *handle)
+int pc_eofsrc(void *handle)
{
return feof((FILE*)handle);
}
-/* should return a pointer, which is used as a "magic cookie" to all I/O
+/* should return a pointer, which is used as a "magic cookie" to all I/O
* functions; return NULL for failure
*/
void *pc_openasm(char *filename)
{
- #if defined __MSDOS__ || defined SC_LIGHT
- return fopen(filename,"w+");
+ #if defined __MSDOS__ || defined SC_LIGHT
+ return fopen(filename,"w+");
#else
- return mfcreate(filename);
+ return mfcreate(filename);
#endif
}
void pc_closeasm(void *handle, int deletefile)
{
- #if defined __MSDOS__ || defined SC_LIGHT
- if (handle!=NULL)
- fclose((FILE*)handle);
- if (deletefile)
- remove(outfname);
+ #if defined __MSDOS__ || defined SC_LIGHT
+ if (handle!=NULL)
+ fclose((FILE*)handle);
+ if (deletefile)
+ remove(outfname);
#else
- if (handle!=NULL) {
- if (!deletefile)
- mfdump((MEMFILE*)handle);
- mfclose((MEMFILE*)handle);
- } /* if */
+ if (handle!=NULL) {
+ if (!deletefile)
+ mfdump((MEMFILE*)handle);
+ mfclose((MEMFILE*)handle);
+ } /* if */
#endif
}
void pc_resetasm(void *handle)
{
assert(handle!=NULL);
- #if defined __MSDOS__ || defined SC_LIGHT
- fflush((FILE*)handle);
- fseek((FILE*)handle,0,SEEK_SET);
+ #if defined __MSDOS__ || defined SC_LIGHT
+ fflush((FILE*)handle);
+ fseek((FILE*)handle,0,SEEK_SET);
#else
- mfseek((MEMFILE*)handle,0,SEEK_SET);
+ mfseek((MEMFILE*)handle,0,SEEK_SET);
#endif
}
-int pc_writeasm(void *handle,char *string)
+int pc_writeasm(void *handle,char *string)
{
- #if defined __MSDOS__ || defined SC_LIGHT
- return fputs(string,(FILE*)handle) >= 0;
+ #if defined __MSDOS__ || defined SC_LIGHT
+ return fputs(string,(FILE*)handle) >= 0;
#else
- return mfputs((MEMFILE*)handle,string);
+ return mfputs((MEMFILE*)handle,string);
#endif
}
-char *pc_readasm(void *handle, char *string, int maxchars)
+char *pc_readasm(void *handle, char *string, int maxchars)
{
- #if defined __MSDOS__ || defined SC_LIGHT
- return fgets(string,maxchars,(FILE*)handle);
+ #if defined __MSDOS__ || defined SC_LIGHT
+ return fgets(string,maxchars,(FILE*)handle);
#else
- return mfgets((MEMFILE*)handle,string,maxchars);
+ return mfgets((MEMFILE*)handle,string,maxchars);
#endif
}
-/* Should return a pointer, which is used as a "magic cookie" to all I/O
+/* Should return a pointer, which is used as a "magic cookie" to all I/O
* functions; return NULL for failure.
*/
void *pc_openbin(char *filename)
@@ -357,12 +357,12 @@ void pc_closebin(void *handle,int deletefile)
{
fclose((FILE*)handle);
if (deletefile)
- remove(binfname);
+ remove(binfname);
}
/* pc_resetbin()
- * Can seek to any location in the file.
- * The offset is always from the start of the file.
+ * Can seek to any location in the file.
+ * The offset is always from the start of the file.
*/
void pc_resetbin(void *handle,long offset)
{
@@ -370,7 +370,7 @@ void pc_resetbin(void *handle,long offset)
fseek((FILE*)handle,offset,SEEK_SET);
}
-int pc_writebin(void *handle,void *buffer,int size)
+int pc_writebin(void *handle,void *buffer,int size)
{
return (int)fwrite(buffer,1,size,(FILE*)handle) == size;
}
@@ -380,15 +380,15 @@ long pc_lengthbin(void *handle)
return ftell((FILE*)handle);
}
-#endif /* !defined NO_MAIN */
+#endif /* !defined NO_MAIN */
-/* "main" of the compiler
+/* "main" of the compiler
*/
-#if defined __cplusplus
+#if defined __cplusplus
extern "C"
#endif
-int pc_compile(int argc, char *argv[])
+int pc_compile(int argc, char *argv[])
{
int entry,i,jmpcode;
int retcode;
@@ -399,202 +399,202 @@ int pc_compile(int argc, char *argv[])
void *inpfmark;
int lcl_packstr,lcl_needsemicolon,lcl_tabsize;
#if !defined SC_LIGHT
- int hdrsize;
+ int hdrsize;
#endif
- /* set global variables to their initial value */
+ /* set global variables to their initial value */
binf=NULL;
initglobals();
errorset(sRESET);
errorset(sEXPRRELEASE);
lexinit();
- /* make sure that we clean up on a fatal error; do this before the first
+ /* make sure that we clean up on a fatal error; do this before the first
* call to error(). */
if ((jmpcode=setjmp(errbuf))!=0)
- goto cleanup;
+ goto cleanup;
/* allocate memory for fixed tables */
inpfname=(char*)malloc(_MAX_PATH);
if (inpfname==NULL)
- error(103); /* insufficient memory */
+ error(103); /* insufficient memory */
litq=(cell*)malloc(litmax*sizeof(cell));
if (litq==NULL)
- error(103); /* insufficient memory */
+ error(103); /* insufficient memory */
if (!phopt_init())
- error(103); /* insufficient memory */
+ error(103); /* insufficient memory */
setopt(argc,argv,outfname,errfname,incfname,reportname,codepage);
- /* set output names that depend on the input name */
+ /* set output names that depend on the input name */
if (sc_listing)
- set_extension(outfname,".lst",TRUE);
+ set_extension(outfname,".lst",TRUE);
else
- set_extension(outfname,".asm",TRUE);
+ set_extension(outfname,".asm",TRUE);
strcpy(binfname,outfname);
set_extension(binfname,".amx",TRUE);
if (strlen(errfname)!=0)
- remove(errfname); /* delete file on startup */
+ remove(errfname); /* delete file on startup */
else if (verbosity>0)
- setcaption();
- setconfig(argv[0]); /* the path to the include and codepage files */
+ setcaption();
+ setconfig(argv[0]); /* the path to the include and codepage files */
sc_ctrlchar_org=sc_ctrlchar;
lcl_packstr=sc_packstr;
lcl_needsemicolon=sc_needsemicolon;
lcl_tabsize=sc_tabsize;
#if !defined NO_CODEPAGE
- if (!cp_set(codepage)) /* set codepage */
- error(108); /* codepage mapping file not found */
+ if (!cp_set(codepage)) /* set codepage */
+ error(108); /* codepage mapping file not found */
#endif
- /* optionally create a temporary input file that is a collection of all
+ /* optionally create a temporary input file that is a collection of all
* input files
*/
- assert(get_sourcefile(0)!=NULL); /* there must be at least one source file */
+ assert(get_sourcefile(0)!=NULL); /* there must be at least one source file */
if (get_sourcefile(1)!=NULL) {
- /* there are at least two or more source files */
- char *tname,*sname;
- FILE *ftmp,*fsrc;
- int fidx;
- #if defined __WIN32__ || defined _WIN32
- tname=_tempnam(NULL,"pawn");
- #elif defined __MSDOS__ || defined _Windows
- tname=tempnam(NULL,"pawn");
- #elif defined(MACOS) && !defined(__MACH__)
- /* tempnam is not supported for the Macintosh CFM build. */
- error(104,get_sourcefile(1));
- tname=NULL;
- sname=NULL;
- #else
- tname=tempnam(NULL,"pawn");
- #endif
- ftmp=(FILE*)pc_createsrc(tname);
- for (fidx=0; (sname=get_sourcefile(fidx))!=NULL; fidx++) {
- unsigned char tstring[128];
- fsrc=(FILE*)pc_opensrc(sname);
- if (fsrc==NULL)
- error(100,sname);
- pc_writesrc(ftmp,(unsigned char*)"#file ");
- pc_writesrc(ftmp,(unsigned char*)sname);
- pc_writesrc(ftmp,(unsigned char*)"\n");
- while (!pc_eofsrc(fsrc)) {
- pc_readsrc(fsrc,tstring,sizeof tstring);
- pc_writesrc(ftmp,tstring);
- } /* while */
- pc_closesrc(fsrc);
- } /* for */
- pc_closesrc(ftmp);
- strcpy(inpfname,tname);
- free(tname);
- } else {
- strcpy(inpfname,get_sourcefile(0));
- } /* if */
+ /* there are at least two or more source files */
+ char *tname,*sname;
+ FILE *ftmp,*fsrc;
+ int fidx;
+ #if defined __WIN32__ || defined _WIN32
+ tname=_tempnam(NULL,"pawn");
+ #elif defined __MSDOS__ || defined _Windows
+ tname=tempnam(NULL,"pawn");
+ #elif defined(MACOS) && !defined(__MACH__)
+ /* tempnam is not supported for the Macintosh CFM build. */
+ error(104,get_sourcefile(1));
+ tname=NULL;
+ sname=NULL;
+ #else
+ tname=tempnam(NULL,"pawn");
+ #endif
+ ftmp=(FILE*)pc_createsrc(tname);
+ for (fidx=0; (sname=get_sourcefile(fidx))!=NULL; fidx++) {
+ unsigned char tstring[128];
+ fsrc=(FILE*)pc_opensrc(sname);
+ if (fsrc==NULL)
+ error(100,sname);
+ pc_writesrc(ftmp,(unsigned char*)"#file ");
+ pc_writesrc(ftmp,(unsigned char*)sname);
+ pc_writesrc(ftmp,(unsigned char*)"\n");
+ while (!pc_eofsrc(fsrc)) {
+ pc_readsrc(fsrc,tstring,sizeof tstring);
+ pc_writesrc(ftmp,tstring);
+ } /* while */
+ pc_closesrc(fsrc);
+ } /* for */
+ pc_closesrc(ftmp);
+ strcpy(inpfname,tname);
+ free(tname);
+ } else {
+ strcpy(inpfname,get_sourcefile(0));
+ } /* if */
inpf_org=(FILE*)pc_opensrc(inpfname);
if (inpf_org==NULL)
- error(100,inpfname);
+ error(100,inpfname);
freading=TRUE;
- outf=(FILE*)pc_openasm(outfname); /* first write to assembler file (may be temporary) */
+ outf=(FILE*)pc_openasm(outfname); /* first write to assembler file (may be temporary) */
if (outf==NULL)
- error(101,outfname);
+ error(101,outfname);
/* immediately open the binary file, for other programs to check */
- if (sc_asmfile || sc_listing) {
- binf=NULL;
- } else {
- binf=(FILE*)pc_openbin(binfname);
- if (binf==NULL)
- error(101,binfname);
- } /* if */
- setconstants(); /* set predefined constants and tagnames */
- for (i=0; i0) {
- if (strcmp(incfname,sDEF_PREFIX)==0) {
- plungefile(incfname,FALSE,TRUE); /* parse "default.inc" */
- } else {
- if (!plungequalifiedfile(incfname)) /* parse "prefix" include file */
- error(100,incfname); /* cannot read from ... (fatal error) */
- } /* if */
- } /* if */
- preprocess(); /* fetch first line */
- parse(); /* process all input */
- sc_parsenum++;
- } while (sc_reparse);
+ if (strlen(incfname)>0) {
+ if (strcmp(incfname,sDEF_PREFIX)==0) {
+ plungefile(incfname,FALSE,TRUE); /* parse "default.inc" */
+ } else {
+ if (!plungequalifiedfile(incfname)) /* parse "prefix" include file */
+ error(100,incfname); /* cannot read from ... (fatal error) */
+ } /* if */
+ } /* if */
+ preprocess(); /* fetch first line */
+ parse(); /* process all input */
+ sc_parsenum++;
+ } while (sc_reparse);
- /* second (or third) pass */
- sc_status=statWRITE; /* set, to enable warnings */
+ /* second (or third) pass */
+ sc_status=statWRITE; /* set, to enable warnings */
state_conflict(&glbtab);
- /* write a report, if requested */
+ /* write a report, if requested */
#if !defined SC_LIGHT
- if (sc_makereport) {
- FILE *frep=stdout;
- if (strlen(reportname)>0)
- frep=fopen(reportname,"wb"); /* avoid translation of \n to \r\n in DOS/Windows */
- if (frep!=NULL) {
- make_report(&glbtab,frep,get_sourcefile(0));
- if (strlen(reportname)>0)
- fclose(frep);
- } /* if */
- if (sc_documentation!=NULL) {
- free(sc_documentation);
- sc_documentation=NULL;
- } /* if */
- } /* if */
+ if (sc_makereport) {
+ FILE *frep=stdout;
+ if (strlen(reportname)>0)
+ frep=fopen(reportname,"wb"); /* avoid translation of \n to \r\n in DOS/Windows */
+ if (frep!=NULL) {
+ make_report(&glbtab,frep,get_sourcefile(0));
+ if (strlen(reportname)>0)
+ fclose(frep);
+ } /* if */
+ if (sc_documentation!=NULL) {
+ free(sc_documentation);
+ sc_documentation=NULL;
+ } /* if */
+ } /* if */
#endif
if (sc_listing)
- goto cleanup;
+ goto cleanup;
- /* ??? for re-parsing the listing file instead of the original source
+ /* ??? for re-parsing the listing file instead of the original source
* file (and doing preprocessing twice):
* - close input file, close listing file
- * - re-open listing file for reading (inpf)
- * - open assembler file (outf)
+ * - re-open listing file for reading (inpf)
+ * - open assembler file (outf)
*/
- /* reset "defined" flag of all functions and global variables */
+ /* reset "defined" flag of all functions and global variables */
reduce_referrers(&glbtab);
delete_symbols(&glbtab,0,TRUE,FALSE);
#if !defined NO_DEFINE
- delete_substtable();
+ delete_substtable();
#endif
resetglobals();
sc_ctrlchar=sc_ctrlchar_org;
@@ -605,85 +605,85 @@ int pc_compile(int argc, char *argv[])
/* reset the source file */
inpf=inpf_org;
freading=TRUE;
- pc_resetsrc(inpf,inpfmark); /* reset file position */
- fline=skipinput; /* reset line number */
- lexinit(); /* clear internal flags of lex() */
- sc_status=statWRITE; /* allow to write --this variable was reset by resetglobals() */
+ pc_resetsrc(inpf,inpfmark); /* reset file position */
+ fline=skipinput; /* reset line number */
+ lexinit(); /* clear internal flags of lex() */
+ sc_status=statWRITE; /* allow to write --this variable was reset by resetglobals() */
writeleader(&glbtab);
insert_dbgfile(inpfname);
if (strlen(incfname)>0) {
- if (strcmp(incfname,sDEF_PREFIX)==0)
- plungefile(incfname,FALSE,TRUE); /* parse "default.inc" (again) */
- else
- plungequalifiedfile(incfname); /* parse implicit include file (again) */
- } /* if */
- preprocess(); /* fetch first line */
- parse(); /* process all input */
- /* inpf is already closed when readline() attempts to pop of a file */
- writetrailer(); /* write remaining stuff */
+ if (strcmp(incfname,sDEF_PREFIX)==0)
+ plungefile(incfname,FALSE,TRUE); /* parse "default.inc" (again) */
+ else
+ plungequalifiedfile(incfname); /* parse implicit include file (again) */
+ } /* if */
+ preprocess(); /* fetch first line */
+ parse(); /* process all input */
+ /* inpf is already closed when readline() attempts to pop of a file */
+ writetrailer(); /* write remaining stuff */
- entry=testsymbols(&glbtab,0,TRUE,FALSE); /* test for unused or undefined
- * functions and variables */
+ entry=testsymbols(&glbtab,0,TRUE,FALSE); /* test for unused or undefined
+ * functions and variables */
if (!entry)
- error(13); /* no entry point (no public functions) */
+ error(13); /* no entry point (no public functions) */
cleanup:
- if (inpf!=NULL) /* main source file is not closed, do it now */
- pc_closesrc(inpf);
- /* write the binary file (the file is already open) */
+ if (inpf!=NULL) /* main source file is not closed, do it now */
+ pc_closesrc(inpf);
+ /* write the binary file (the file is already open) */
if (!(sc_asmfile || sc_listing) && errnum==0 && jmpcode==0) {
- assert(binf!=NULL);
- pc_resetasm(outf); /* flush and loop back, for reading */
- #if !defined SC_LIGHT
- hdrsize=
- #endif
- assemble(binf,outf); /* assembler file is now input */
- } /* if */
+ assert(binf!=NULL);
+ pc_resetasm(outf); /* flush and loop back, for reading */
+ #if !defined SC_LIGHT
+ hdrsize=
+ #endif
+ assemble(binf,outf); /* assembler file is now input */
+ } /* if */
if (outf!=NULL) {
- pc_closeasm(outf,!(sc_asmfile || sc_listing));
- outf=NULL;
- } /* if */
+ pc_closeasm(outf,!(sc_asmfile || sc_listing));
+ outf=NULL;
+ } /* if */
if (binf!=NULL) {
- pc_closebin(binf,errnum!=0);
- binf=NULL;
- } /* if */
+ pc_closebin(binf,errnum!=0);
+ binf=NULL;
+ } /* if */
#if !defined SC_LIGHT
- if (errnum==0 && strlen(errfname)==0) {
- long stacksize=max_stacksize(&glbtab);
- int flag_exceed=0;
- if (sc_amxlimit > 0 && (long)(hdrsize+code_idx+glb_declared*sizeof(cell)+sc_stksize*sizeof(cell)) >= sc_amxlimit)
- flag_exceed=1;
- if ((sc_debug & sSYMBOLIC)!=0 || verbosity>=2 || stacksize+32>=(long)sc_stksize || flag_exceed) {
- pc_printf("Header size: %8ld bytes\n", (long)hdrsize);
- pc_printf("Code size: %8ld bytes\n", (long)code_idx);
- pc_printf("Data size: %8ld bytes\n", (long)glb_declared*sizeof(cell));
- pc_printf("Stack/heap size: %8ld bytes; ", (long)sc_stksize*sizeof(cell));
- if (stacksize<0)
- pc_printf("max. usage is unknown, due to recursion\n");
- else if (stacksize>0)
- pc_printf("estimated max. usage=%ld cells (%ld bytes)\n",stacksize,stacksize*sizeof(cell));
- pc_printf("Total requirements:%8ld bytes\n", (long)hdrsize+(long)code_idx+(long)glb_declared*sizeof(cell)+(long)sc_stksize*sizeof(cell));
- } /* if */
- if (flag_exceed)
- error(106,sc_amxlimit); /* this causes a jump back to label "cleanup" */
- } /* if */
+ if (errnum==0 && strlen(errfname)==0) {
+ long stacksize=max_stacksize(&glbtab);
+ int flag_exceed=0;
+ if (sc_amxlimit > 0 && (long)(hdrsize+code_idx+glb_declared*sizeof(cell)+sc_stksize*sizeof(cell)) >= sc_amxlimit)
+ flag_exceed=1;
+ if ((sc_debug & sSYMBOLIC)!=0 || verbosity>=2 || stacksize+32>=(long)sc_stksize || flag_exceed) {
+ pc_printf("Header size: %8ld bytes\n", (long)hdrsize);
+ pc_printf("Code size: %8ld bytes\n", (long)code_idx);
+ pc_printf("Data size: %8ld bytes\n", (long)glb_declared*sizeof(cell));
+ pc_printf("Stack/heap size: %8ld bytes; ", (long)sc_stksize*sizeof(cell));
+ if (stacksize<0)
+ pc_printf("max. usage is unknown, due to recursion\n");
+ else if (stacksize>0)
+ pc_printf("estimated max. usage=%ld cells (%ld bytes)\n",stacksize,stacksize*sizeof(cell));
+ pc_printf("Total requirements:%8ld bytes\n", (long)hdrsize+(long)code_idx+(long)glb_declared*sizeof(cell)+(long)sc_stksize*sizeof(cell));
+ } /* if */
+ if (flag_exceed)
+ error(106,sc_amxlimit); /* this causes a jump back to label "cleanup" */
+ } /* if */
#endif
if (inpfname!=NULL) {
- if (get_sourcefile(1)!=NULL)
- remove(inpfname); /* the "input file" was in fact a temporary file */
- free(inpfname);
- } /* if */
+ if (get_sourcefile(1)!=NULL)
+ remove(inpfname); /* the "input file" was in fact a temporary file */
+ free(inpfname);
+ } /* if */
if (litq!=NULL)
- free(litq);
+ free(litq);
phopt_cleanup();
stgbuffer_cleanup();
clearstk();
- assert(jmpcode!=0 || loctab.next==NULL);/* on normal flow, local symbols
- * should already have been deleted */
- delete_symbols(&loctab,0,TRUE,TRUE); /* delete local variables if not yet
- * done (i.e. on a fatal error) */
+ assert(jmpcode!=0 || loctab.next==NULL);/* on normal flow, local symbols
+ * should already have been deleted */
+ delete_symbols(&loctab,0,TRUE,TRUE); /* delete local variables if not yet
+ * done (i.e. on a fatal error) */
delete_symbols(&glbtab,0,TRUE,TRUE);
delete_consttable(&tagname_tab);
delete_consttable(&libname_tab);
@@ -695,487 +695,487 @@ cleanup:
delete_sourcefiletable();
delete_dbgstringtable();
#if !defined NO_DEFINE
- delete_substtable();
+ delete_substtable();
#endif
#if !defined SC_LIGHT
- delete_docstringtable();
- if (sc_documentation!=NULL)
- free(sc_documentation);
+ delete_docstringtable();
+ if (sc_documentation!=NULL)
+ free(sc_documentation);
#endif
delete_autolisttable();
if (errnum!=0) {
- if (strlen(errfname)==0)
- pc_printf("\n%d Error%s.\n",errnum,(errnum>1) ? "s" : "");
- retcode=2;
- } else if (warnnum!=0){
- if (strlen(errfname)==0)
- pc_printf("\n%d Warning%s.\n",warnnum,(warnnum>1) ? "s" : "");
- retcode=1;
- } else {
- retcode=jmpcode;
- if (retcode==0 && verbosity>=2)
- pc_printf("\nDone.\n");
- } /* if */
- #if defined __WIN32__ || defined _WIN32 || defined _Windows
- if (IsWindow(hwndFinish))
- PostMessage(hwndFinish,RegisterWindowMessage("PawnNotify"),retcode,0L);
+ if (strlen(errfname)==0)
+ pc_printf("\n%d Error%s.\n",errnum,(errnum>1) ? "s" : "");
+ retcode=2;
+ } else if (warnnum!=0){
+ if (strlen(errfname)==0)
+ pc_printf("\n%d Warning%s.\n",warnnum,(warnnum>1) ? "s" : "");
+ retcode=1;
+ } else {
+ retcode=jmpcode;
+ if (retcode==0 && verbosity>=2)
+ pc_printf("\nDone.\n");
+ } /* if */
+ #if defined __WIN32__ || defined _WIN32 || defined _Windows
+ if (IsWindow(hwndFinish))
+ PostMessage(hwndFinish,RegisterWindowMessage("PawnNotify"),retcode,0L);
#endif
#if defined FORTIFY
- Fortify_ListAllMemory();
+ Fortify_ListAllMemory();
#endif
return retcode;
}
-#if defined __cplusplus
+#if defined __cplusplus
extern "C"
#endif
-int pc_addconstant(char *name,cell value,int tag)
+int pc_addconstant(char *name,cell value,int tag)
{
- errorset(sFORCESET); /* make sure error engine is silenced */
+ errorset(sFORCESET); /* make sure error engine is silenced */
sc_status=statIDLE;
add_constant(name,value,sGLOBAL,tag);
return 1;
}
-#if defined __cplusplus
+#if defined __cplusplus
extern "C"
#endif
-int pc_addtag(char *name)
+int pc_addtag(char *name)
{
cell val;
constvalue *ptr;
int last,tag;
if (name==NULL) {
- /* no tagname was given, check for one */
- if (lex(&val,&name)!=tLABEL) {
- lexpush();
- return 0; /* untagged */
- } /* if */
- } /* if */
+ /* no tagname was given, check for one */
+ if (lex(&val,&name)!=tLABEL) {
+ lexpush();
+ return 0; /* untagged */
+ } /* if */
+ } /* if */
- assert(strchr(name,':')==NULL); /* colon should already have been stripped */
+ assert(strchr(name,':')==NULL); /* colon should already have been stripped */
last=0;
ptr=tagname_tab.next;
- while (ptr!=NULL) {
- tag=(int)(ptr->value & TAGMASK);
- if (strcmp(name,ptr->name)==0)
- return tag; /* tagname is known, return its sequence number */
- tag &= (int)~FIXEDTAG;
- if (tag>last)
- last=tag;
- ptr=ptr->next;
- } /* while */
+ while (ptr!=NULL) {
+ tag=(int)(ptr->value & TAGMASK);
+ if (strcmp(name,ptr->name)==0)
+ return tag; /* tagname is known, return its sequence number */
+ tag &= (int)~FIXEDTAG;
+ if (tag>last)
+ last=tag;
+ ptr=ptr->next;
+ } /* while */
- /* tagname currently unknown, add it */
- tag=last+1; /* guaranteed not to exist already */
+ /* tagname currently unknown, add it */
+ tag=last+1; /* guaranteed not to exist already */
if (isupper(*name))
- tag |= (int)FIXEDTAG;
+ tag |= (int)FIXEDTAG;
append_constval(&tagname_tab,name,(cell)tag,0);
return tag;
}
-static void resetglobals(void)
+static void resetglobals(void)
{
- /* reset the subset of global variables that is modified by the first pass */
- curfunc=NULL; /* pointer to current function */
- lastst=0; /* last executed statement type */
- nestlevel=0; /* number of active (open) compound statements */
- rettype=0; /* the type that a "return" expression should have */
- litidx=0; /* index to literal table */
- stgidx=0; /* index to the staging buffer */
- sc_labnum=0; /* top value of (internal) labels */
- staging=0; /* true if staging output */
- declared=0; /* number of local cells declared */
- glb_declared=0; /* number of global cells declared */
- code_idx=0; /* number of bytes with generated code */
- ntv_funcid=0; /* incremental number of native function */
- curseg=0; /* 1 if currently parsing CODE, 2 if parsing DATA */
- freading=FALSE; /* no input file ready yet */
- fline=0; /* the line number in the current file */
- fnumber=0; /* the file number in the file table (debugging) */
- fcurrent=0; /* current file being processed (debugging) */
- sc_intest=FALSE; /* true if inside a test */
- sideeffect=0; /* true if an expression causes a side-effect */
- stmtindent=0; /* current indent of the statement */
- indent_nowarn=FALSE; /* do not skip warning "217 loose indentation" */
- sc_allowtags=TRUE; /* allow/detect tagnames */
+ /* reset the subset of global variables that is modified by the first pass */
+ curfunc=NULL; /* pointer to current function */
+ lastst=0; /* last executed statement type */
+ nestlevel=0; /* number of active (open) compound statements */
+ rettype=0; /* the type that a "return" expression should have */
+ litidx=0; /* index to literal table */
+ stgidx=0; /* index to the staging buffer */
+ sc_labnum=0; /* top value of (internal) labels */
+ staging=0; /* true if staging output */
+ declared=0; /* number of local cells declared */
+ glb_declared=0; /* number of global cells declared */
+ code_idx=0; /* number of bytes with generated code */
+ ntv_funcid=0; /* incremental number of native function */
+ curseg=0; /* 1 if currently parsing CODE, 2 if parsing DATA */
+ freading=FALSE; /* no input file ready yet */
+ fline=0; /* the line number in the current file */
+ fnumber=0; /* the file number in the file table (debugging) */
+ fcurrent=0; /* current file being processed (debugging) */
+ sc_intest=FALSE; /* true if inside a test */
+ sideeffect=0; /* true if an expression causes a side-effect */
+ stmtindent=0; /* current indent of the statement */
+ indent_nowarn=FALSE; /* do not skip warning "217 loose indentation" */
+ sc_allowtags=TRUE; /* allow/detect tagnames */
sc_status=statIDLE;
sc_allowproccall=FALSE;
- pc_addlibtable=TRUE; /* by default, add a "library table" to the output file */
+ pc_addlibtable=TRUE; /* by default, add a "library table" to the output file */
sc_alignnext=FALSE;
pc_docexpr=FALSE;
}
-static void initglobals(void)
+static void initglobals(void)
{
resetglobals();
- sc_asmfile=FALSE; /* do not create .ASM file */
- sc_listing=FALSE; /* do not create .LST file */
- skipinput=0; /* number of lines to skip from the first input file */
- sc_ctrlchar=CTRL_CHAR;/* the escape character */
- litmax=sDEF_LITMAX; /* current size of the literal table */
- errnum=0; /* number of errors */
- warnnum=0; /* number of warnings */
- optproccall=TRUE; /* support "procedure call" */
-#if PAWN_CELL_SIZE==32
- verbosity=1; /* verbosity level, no copyright banner */
+ sc_asmfile=FALSE; /* do not create .ASM file */
+ sc_listing=FALSE; /* do not create .LST file */
+ skipinput=0; /* number of lines to skip from the first input file */
+ sc_ctrlchar=CTRL_CHAR;/* the escape character */
+ litmax=sDEF_LITMAX; /* current size of the literal table */
+ errnum=0; /* number of errors */
+ warnnum=0; /* number of warnings */
+ optproccall=TRUE; /* support "procedure call" */
+#if PAWN_CELL_SIZE==32
+ verbosity=1; /* verbosity level, no copyright banner */
#else
verbosity=0;
#endif
- sc_debug=sCHKBOUNDS|sSYMBOLIC; /* by default: bounds checking+assertions */
- sc_packstr=FALSE; /* strings are unpacked by default */
+ sc_debug=sCHKBOUNDS|sSYMBOLIC; /* by default: bounds checking+assertions */
+ sc_packstr=FALSE; /* strings are unpacked by default */
sc_compress=FALSE;
- sc_needsemicolon=FALSE;/* semicolon required to terminate expressions? */
+ sc_needsemicolon=FALSE;/* semicolon required to terminate expressions? */
sc_dataalign=sizeof(cell);
- sc_stksize=sDEF_AMXSTACK;/* default stack size */
- sc_amxlimit=0; /* no limit on size of the abstract machine */
- sc_tabsize=8; /* assume a TAB is 8 spaces */
- sc_rationaltag=0; /* assume no support for rational numbers */
- rational_digits=0; /* number of fractional digits */
+ sc_stksize=sDEF_AMXSTACK;/* default stack size */
+ sc_amxlimit=0; /* no limit on size of the abstract machine */
+ sc_tabsize=8; /* assume a TAB is 8 spaces */
+ sc_rationaltag=0; /* assume no support for rational numbers */
+ rational_digits=0; /* number of fractional digits */
- outfname[0]='\0'; /* output file name */
- errfname[0]='\0'; /* error file name */
- inpf=NULL; /* file read from */
- inpfname=NULL; /* pointer to name of the file currently read from */
- outf=NULL; /* file written to */
- litq=NULL; /* the literal queue */
- glbtab.next=NULL; /* clear global variables/constants table */
- loctab.next=NULL; /* " local " / " " */
+ outfname[0]='\0'; /* output file name */
+ errfname[0]='\0'; /* error file name */
+ inpf=NULL; /* file read from */
+ inpfname=NULL; /* pointer to name of the file currently read from */
+ outf=NULL; /* file written to */
+ litq=NULL; /* the literal queue */
+ glbtab.next=NULL; /* clear global variables/constants table */
+ loctab.next=NULL; /* " local " / " " */
tagname_tab.next=NULL;/* tagname table */
- libname_tab.next=NULL;/* library table (#pragma library "..." syntax) */
+ libname_tab.next=NULL;/* library table (#pragma library "..." syntax) */
- pline[0]='\0'; /* the line read from the input file */
- lptr=NULL; /* points to the current position in "pline" */
- curlibrary=NULL; /* current library */
- inpf_org=NULL; /* main source file */
+ pline[0]='\0'; /* the line read from the input file */
+ lptr=NULL; /* points to the current position in "pline" */
+ curlibrary=NULL; /* current library */
+ inpf_org=NULL; /* main source file */
- wqptr=wq; /* initialize while queue pointer */
+ wqptr=wq; /* initialize while queue pointer */
-#if !defined SC_LIGHT
+#if !defined SC_LIGHT
sc_documentation=NULL;
- sc_makereport=FALSE; /* do not generate a cross-reference report */
+ sc_makereport=FALSE; /* do not generate a cross-reference report */
#endif
}
/* set_extension
- * Set the default extension, or force an extension. To erase the
- * extension of a filename, set "extension" to an empty string.
+ * Set the default extension, or force an extension. To erase the
+ * extension of a filename, set "extension" to an empty string.
*/
-SC_FUNC void set_extension(char *filename,char *extension,int force)
+SC_FUNC void set_extension(char *filename,char *extension,int force)
{
char *ptr;
- assert(extension!=NULL && (*extension=='\0' || *extension=='.'));
+ assert(extension!=NULL && (*extension=='\0' || *extension=='.'));
assert(filename!=NULL);
ptr=strrchr(filename,'.');
if (ptr!=NULL) {
- /* ignore extension on a directory or at the start of the filename */
- if (strchr(ptr,DIRSEP_CHAR)!=NULL || ptr==filename || *(ptr-1)==DIRSEP_CHAR)
- ptr=NULL;
- } /* if */
- if (force && ptr!=NULL)
- *ptr='\0'; /* set zero terminator at the position of the period */
- if (force || ptr==NULL)
- strcat(filename,extension);
+ /* ignore extension on a directory or at the start of the filename */
+ if (strchr(ptr,DIRSEP_CHAR)!=NULL || ptr==filename || *(ptr-1)==DIRSEP_CHAR)
+ ptr=NULL;
+ } /* if */
+ if (force && ptr!=NULL)
+ *ptr='\0'; /* set zero terminator at the position of the period */
+ if (force || ptr==NULL)
+ strcat(filename,extension);
}
static const char *option_value(const char *optptr)
{
- return (*(optptr+1)=='=' || *(optptr+1)==':') ? optptr+2 : optptr+1;
+ return (*(optptr+1)=='=' || *(optptr+1)==':') ? optptr+2 : optptr+1;
}
-static int toggle_option(const char *optptr, int option)
+static int toggle_option(const char *optptr, int option)
{
switch (*option_value(optptr)) {
case '\0':
- option=!option;
- break;
+ option=!option;
+ break;
case '-':
- option=FALSE;
- break;
+ option=FALSE;
+ break;
case '+':
- option=TRUE;
- break;
+ option=TRUE;
+ break;
default:
- about();
- } /* switch */
+ about();
+ } /* switch */
return option;
}
-/* Parsing command line options is indirectly recursive: parseoptions()
- * calls parserespf() to handle options in a a response file and
- * parserespf() calls parseoptions() at its turn after having created
- * an "option list" from the contents of the file.
+/* Parsing command line options is indirectly recursive: parseoptions()
+ * calls parserespf() to handle options in a a response file and
+ * parserespf() calls parseoptions() at its turn after having created
+ * an "option list" from the contents of the file.
*/
-static void parserespf(char *filename,char *oname,char *ename,char *pname,
- char *rname, char *codepage);
+static void parserespf(char *filename,char *oname,char *ename,char *pname,
+ char *rname, char *codepage);
-static void parseoptions(int argc,char **argv,char *oname,char *ename,char *pname,
- char *rname, char *codepage)
+static void parseoptions(int argc,char **argv,char *oname,char *ename,char *pname,
+ char *rname, char *codepage)
{
char str[_MAX_PATH],*name;
- const char *ptr;
+ const char *ptr;
int arg,i,isoption;
- for (arg=1; arg 2
- sc_compress=toggle_option(ptr,sc_compress);
- #else
- about();
- #endif
- break;
- case 'c':
- strncpy(codepage,option_value(ptr),MAXCODEPAGE); /* set name of codepage */
- codepage[MAXCODEPAGE]='\0';
- break;
-#if defined dos_setdrive
- case 'D': /* set active directory */
- ptr=option_value(ptr);
- if (ptr[1]==':')
- dos_setdrive(toupper(*ptr)-'A'+1); /* set active drive */
- chdir(ptr);
- break;
+ for (arg=1; arg 2
+ sc_compress=toggle_option(ptr,sc_compress);
+ #else
+ about();
+ #endif
+ break;
+ case 'c':
+ strncpy(codepage,option_value(ptr),MAXCODEPAGE); /* set name of codepage */
+ codepage[MAXCODEPAGE]='\0';
+ break;
+#if defined dos_setdrive
+ case 'D': /* set active directory */
+ ptr=option_value(ptr);
+ if (ptr[1]==':')
+ dos_setdrive(toupper(*ptr)-'A'+1); /* set active drive */
+ chdir(ptr);
+ break;
#endif
- case 'd':
- switch (*option_value(ptr)) {
- case '0':
- sc_debug=0;
- break;
- case '1':
- sc_debug=sCHKBOUNDS; /* assertions and bounds checking */
- break;
- case '2':
- sc_debug=sCHKBOUNDS | sSYMBOLIC; /* also symbolic info */
- break;
- case '3':
- sc_debug=sCHKBOUNDS | sSYMBOLIC | sNOOPTIMIZE;
- /* also avoid peephole optimization */
- break;
- default:
- about();
- } /* switch */
- break;
- case 'e':
- strncpy(ename,option_value(ptr),_MAX_PATH); /* set name of error file */
- ename[_MAX_PATH-1]='\0';
- break;
-#if defined __WIN32__ || defined _WIN32 || defined _Windows
- case 'H':
- hwndFinish=(HWND)atoi(option_value(ptr));
- if (!IsWindow(hwndFinish))
- hwndFinish=(HWND)0;
- break;
+ case 'd':
+ switch (*option_value(ptr)) {
+ case '0':
+ sc_debug=0;
+ break;
+ case '1':
+ sc_debug=sCHKBOUNDS; /* assertions and bounds checking */
+ break;
+ case '2':
+ sc_debug=sCHKBOUNDS | sSYMBOLIC; /* also symbolic info */
+ break;
+ case '3':
+ sc_debug=sCHKBOUNDS | sSYMBOLIC | sNOOPTIMIZE;
+ /* also avoid peephole optimization */
+ break;
+ default:
+ about();
+ } /* switch */
+ break;
+ case 'e':
+ strncpy(ename,option_value(ptr),_MAX_PATH); /* set name of error file */
+ ename[_MAX_PATH-1]='\0';
+ break;
+#if defined __WIN32__ || defined _WIN32 || defined _Windows
+ case 'H':
+ hwndFinish=(HWND)atoi(option_value(ptr));
+ if (!IsWindow(hwndFinish))
+ hwndFinish=(HWND)0;
+ break;
#endif
- case 'i':
- strncpy(str,option_value(ptr),sizeof str); /* set name of include directory */
- str[sizeof(str)-1]='\0';
- i=strlen(str);
- if (i>0) {
- if (str[i-1]!=DIRSEP_CHAR) {
- str[i]=DIRSEP_CHAR;
- str[i+1]='\0';
- } /* if */
- insert_path(str);
- } /* if */
- break;
- case 'l':
- if (*(ptr+1)!='\0')
- about();
- sc_listing=TRUE; /* skip second pass & code generation */
- break;
- case 'o':
- strncpy(oname,option_value(ptr),_MAX_PATH); /* set name of (binary) output file */
- oname[_MAX_PATH-1]='\0';
- break;
- case 'p':
- strncpy(pname,option_value(ptr),_MAX_PATH); /* set name of implicit include file */
- pname[_MAX_PATH-1]='\0';
- break;
-#if !defined SC_LIGHT
- case 'r':
- strncpy(rname,option_value(ptr),_MAX_PATH); /* set name of report file */
- rname[_MAX_PATH-1]='\0';
- sc_makereport=TRUE;
- if (strlen(rname)>0) {
- set_extension(rname,".xml",FALSE);
- } else if ((name=get_sourcefile(0))!=NULL) {
- assert(strlen(rname)==0);
- assert(strlen(name)<_MAX_PATH);
- if ((ptr=strrchr(name,DIRSEP_CHAR))!=NULL)
- ptr++; /* strip path */
- else
- ptr=name;
- assert(strlen(ptr)<_MAX_PATH);
- strcpy(rname,ptr);
- set_extension(rname,".xml",TRUE);
- } /* if */
- break;
+ case 'i':
+ strncpy(str,option_value(ptr),sizeof str); /* set name of include directory */
+ str[sizeof(str)-1]='\0';
+ i=strlen(str);
+ if (i>0) {
+ if (str[i-1]!=DIRSEP_CHAR) {
+ str[i]=DIRSEP_CHAR;
+ str[i+1]='\0';
+ } /* if */
+ insert_path(str);
+ } /* if */
+ break;
+ case 'l':
+ if (*(ptr+1)!='\0')
+ about();
+ sc_listing=TRUE; /* skip second pass & code generation */
+ break;
+ case 'o':
+ strncpy(oname,option_value(ptr),_MAX_PATH); /* set name of (binary) output file */
+ oname[_MAX_PATH-1]='\0';
+ break;
+ case 'p':
+ strncpy(pname,option_value(ptr),_MAX_PATH); /* set name of implicit include file */
+ pname[_MAX_PATH-1]='\0';
+ break;
+#if !defined SC_LIGHT
+ case 'r':
+ strncpy(rname,option_value(ptr),_MAX_PATH); /* set name of report file */
+ rname[_MAX_PATH-1]='\0';
+ sc_makereport=TRUE;
+ if (strlen(rname)>0) {
+ set_extension(rname,".xml",FALSE);
+ } else if ((name=get_sourcefile(0))!=NULL) {
+ assert(strlen(rname)==0);
+ assert(strlen(name)<_MAX_PATH);
+ if ((ptr=strrchr(name,DIRSEP_CHAR))!=NULL)
+ ptr++; /* strip path */
+ else
+ ptr=name;
+ assert(strlen(ptr)<_MAX_PATH);
+ strcpy(rname,ptr);
+ set_extension(rname,".xml",TRUE);
+ } /* if */
+ break;
#endif
- case 'S':
- i=atoi(option_value(ptr));
- if (i>64)
- sc_stksize=(cell)i; /* stack size has minimum size */
- else
- about();
- break;
- case 's':
- skipinput=atoi(option_value(ptr));
- break;
- case 't':
- sc_tabsize=atoi(option_value(ptr));
- break;
- case 'v':
- verbosity= isdigit(*option_value(ptr)) ? atoi(option_value(ptr)) : 2;
- break;
- case 'w':
- i=(int)strtol(option_value(ptr),(char **)&ptr,10);
- if (*ptr=='-')
- pc_enablewarning(i,0);
- else if (*ptr=='+')
- pc_enablewarning(i,1);
- else if (*ptr=='\0')
- pc_enablewarning(i,2);
- break;
- case 'X':
- i=atoi(option_value(ptr));
- if (i>64)
- sc_amxlimit=(cell)i; /* abstract machine size has minimum size */
- else
- about();
- break;
- case '\\': /* use \ instead for escape characters */
- sc_ctrlchar='\\';
- break;
- case '^': /* use ^ instead for escape characters */
- sc_ctrlchar='^';
- break;
- case ';':
- sc_needsemicolon=toggle_option(ptr,sc_needsemicolon);
- break;
- case '(':
- optproccall=!toggle_option(ptr,!optproccall);
- break;
- default: /* wrong option */
- about();
- } /* switch */
- } else if (argv[arg][0]=='@') {
- #if !defined SC_LIGHT
- parserespf(&argv[arg][1],oname,ename,pname,rname,codepage);
- #endif
- } else if ((ptr=strchr(argv[arg],'='))!=NULL) {
- i=(int)(ptr-argv[arg]);
- if (i>sNAMEMAX) {
- i=sNAMEMAX;
- error(200,argv[arg],sNAMEMAX); /* symbol too long, truncated to sNAMEMAX chars */
- } /* if */
- strncpy(str,argv[arg],i);
- str[i]='\0'; /* str holds symbol name */
- i=atoi(ptr+1);
- add_constant(str,i,sGLOBAL,0);
- } else {
- strncpy(str,argv[arg],sizeof(str)-5); /* -5 because default extension is 4 characters */
- str[sizeof(str)-5]='\0';
- set_extension(str,".p",FALSE);
- insert_sourcefile(str);
- /* The output name is the first input name with a different extension,
- * but it is stored in a different directory
- */
- if (strlen(oname)==0) {
- if ((ptr=strrchr(str,DIRSEP_CHAR))!=NULL)
- ptr++; /* strip path */
- else
- ptr=str;
- assert(strlen(ptr)<_MAX_PATH);
- strcpy(oname,ptr);
- } /* if */
- set_extension(oname,".asm",TRUE);
-#if !defined SC_LIGHT
- if (sc_makereport && strlen(rname)==0) {
- if ((ptr=strrchr(str,DIRSEP_CHAR))!=NULL)
- ptr++; /* strip path */
- else
- ptr=str;
- assert(strlen(ptr)<_MAX_PATH);
- strcpy(rname,ptr);
- set_extension(rname,".xml",TRUE);
- } /* if */
+ case 'S':
+ i=atoi(option_value(ptr));
+ if (i>64)
+ sc_stksize=(cell)i; /* stack size has minimum size */
+ else
+ about();
+ break;
+ case 's':
+ skipinput=atoi(option_value(ptr));
+ break;
+ case 't':
+ sc_tabsize=atoi(option_value(ptr));
+ break;
+ case 'v':
+ verbosity= isdigit(*option_value(ptr)) ? atoi(option_value(ptr)) : 2;
+ break;
+ case 'w':
+ i=(int)strtol(option_value(ptr),(char **)&ptr,10);
+ if (*ptr=='-')
+ pc_enablewarning(i,0);
+ else if (*ptr=='+')
+ pc_enablewarning(i,1);
+ else if (*ptr=='\0')
+ pc_enablewarning(i,2);
+ break;
+ case 'X':
+ i=atoi(option_value(ptr));
+ if (i>64)
+ sc_amxlimit=(cell)i; /* abstract machine size has minimum size */
+ else
+ about();
+ break;
+ case '\\': /* use \ instead for escape characters */
+ sc_ctrlchar='\\';
+ break;
+ case '^': /* use ^ instead for escape characters */
+ sc_ctrlchar='^';
+ break;
+ case ';':
+ sc_needsemicolon=toggle_option(ptr,sc_needsemicolon);
+ break;
+ case '(':
+ optproccall=!toggle_option(ptr,!optproccall);
+ break;
+ default: /* wrong option */
+ about();
+ } /* switch */
+ } else if (argv[arg][0]=='@') {
+ #if !defined SC_LIGHT
+ parserespf(&argv[arg][1],oname,ename,pname,rname,codepage);
+ #endif
+ } else if ((ptr=strchr(argv[arg],'='))!=NULL) {
+ i=(int)(ptr-argv[arg]);
+ if (i>sNAMEMAX) {
+ i=sNAMEMAX;
+ error(200,argv[arg],sNAMEMAX); /* symbol too long, truncated to sNAMEMAX chars */
+ } /* if */
+ strncpy(str,argv[arg],i);
+ str[i]='\0'; /* str holds symbol name */
+ i=atoi(ptr+1);
+ add_constant(str,i,sGLOBAL,0);
+ } else {
+ strncpy(str,argv[arg],sizeof(str)-5); /* -5 because default extension is 4 characters */
+ str[sizeof(str)-5]='\0';
+ set_extension(str,".p",FALSE);
+ insert_sourcefile(str);
+ /* The output name is the first input name with a different extension,
+ * but it is stored in a different directory
+ */
+ if (strlen(oname)==0) {
+ if ((ptr=strrchr(str,DIRSEP_CHAR))!=NULL)
+ ptr++; /* strip path */
+ else
+ ptr=str;
+ assert(strlen(ptr)<_MAX_PATH);
+ strcpy(oname,ptr);
+ } /* if */
+ set_extension(oname,".asm",TRUE);
+#if !defined SC_LIGHT
+ if (sc_makereport && strlen(rname)==0) {
+ if ((ptr=strrchr(str,DIRSEP_CHAR))!=NULL)
+ ptr++; /* strip path */
+ else
+ ptr=str;
+ assert(strlen(ptr)<_MAX_PATH);
+ strcpy(rname,ptr);
+ set_extension(rname,".xml",TRUE);
+ } /* if */
#endif
- } /* if */
- } /* for */
+ } /* if */
+ } /* for */
}
-#if !defined SC_LIGHT
-static void parserespf(char *filename,char *oname,char *ename,char *pname,
- char *rname,char *codepage)
+#if !defined SC_LIGHT
+static void parserespf(char *filename,char *oname,char *ename,char *pname,
+ char *rname,char *codepage)
{
-#define MAX_OPTIONS 100
+#define MAX_OPTIONS 100
FILE *fp;
- char *string, *ptr, **argv;
+ char *string, *ptr, **argv;
int argc;
long size;
if ((fp=fopen(filename,"r"))==NULL)
- error(100,filename); /* error reading input file */
- /* load the complete file into memory */
+ error(100,filename); /* error reading input file */
+ /* load the complete file into memory */
fseek(fp,0L,SEEK_END);
size=ftell(fp);
fseek(fp,0L,SEEK_SET);
assert(size [filename...] [options]\n\n");
- pc_printf("Options:\n");
- pc_printf(" -A alignment in bytes of the data segment and the stack\n");
- pc_printf(" -a output assembler code\n");
-#if AMX_COMPACTMARGIN > 2
- pc_printf(" -C[+/-] compact encoding for output file (default=%c)\n", sc_compress ? '+' : '-');
+ setcaption();
+ pc_printf("Usage: pawncc [filename...] [options]\n\n");
+ pc_printf("Options:\n");
+ pc_printf(" -A alignment in bytes of the data segment and the stack\n");
+ pc_printf(" -a output assembler code\n");
+#if AMX_COMPACTMARGIN > 2
+ pc_printf(" -C[+/-] compact encoding for output file (default=%c)\n", sc_compress ? '+' : '-');
#endif
- pc_printf(" -c codepage name or number; e.g. 1252 for Windows Latin-1\n");
-#if defined dos_setdrive
- pc_printf(" -Dpath active directory path\n");
+ pc_printf(" -c codepage name or number; e.g. 1252 for Windows Latin-1\n");
+#if defined dos_setdrive
+ pc_printf(" -Dpath active directory path\n");
#endif
- pc_printf(" -d0 no symbolic information, no run-time checks\n");
- pc_printf(" -d1 [default] run-time checks, no symbolic information\n");
- pc_printf(" -d2 full debug information and dynamic checking\n");
- pc_printf(" -d3 full debug information, dynamic checking, no optimization\n");
- pc_printf(" -e set name of error file (quiet compile)\n");
-#if defined __WIN32__ || defined _WIN32 || defined _Windows
- pc_printf(" -H window handle to send a notification message on finish\n");
+ pc_printf(" -d0 no symbolic information, no run-time checks\n");
+ pc_printf(" -d1 [default] run-time checks, no symbolic information\n");
+ pc_printf(" -d2 full debug information and dynamic checking\n");
+ pc_printf(" -d3 full debug information, dynamic checking, no optimization\n");
+ pc_printf(" -e set name of error file (quiet compile)\n");
+#if defined __WIN32__ || defined _WIN32 || defined _Windows
+ pc_printf(" -H window handle to send a notification message on finish\n");
#endif
- pc_printf(" -i path for include files\n");
- pc_printf(" -l create list file (preprocess only)\n");
- pc_printf(" -o set base name of (P-code) output file\n");
- pc_printf(" -p set name of \"prefix\" file\n");
-#if !defined SC_LIGHT
- pc_printf(" -r[name] write cross reference report to console or to specified file\n");
+ pc_printf(" -i path for include files\n");
+ pc_printf(" -l create list file (preprocess only)\n");
+ pc_printf(" -o set base name of (P-code) output file\n");
+ pc_printf(" -p set name of \"prefix\" file\n");
+#if !defined SC_LIGHT
+ pc_printf(" -r[name] write cross reference report to console or to specified file\n");
#endif
- pc_printf(" -S stack/heap size in cells (default=%d)\n",(int)sc_stksize);
- pc_printf(" -s skip lines from the input file\n");
- pc_printf(" -t TAB indent size (in character positions, default=%d)\n",sc_tabsize);
- pc_printf(" -v verbosity level; 0=quiet, 1=normal, 2=verbose (default=%d)\n",verbosity);
- pc_printf(" -w disable a specific warning by its number\n");
- pc_printf(" -X abstract machine size limit in bytes\n");
- pc_printf(" -\\ use '\\' for escape characters\n");
- pc_printf(" -^ use '^' for escape characters\n");
- pc_printf(" -;[+/-] require a semicolon to end each statement (default=%c)\n", sc_needsemicolon ? '+' : '-');
- pc_printf(" -([+/-] require parantheses for function invocation (default=%c)\n", optproccall ? '-' : '+');
- pc_printf(" sym=val define constant \"sym\" with value \"val\"\n");
- pc_printf(" sym= define constant \"sym\" with value 0\n");
-#if defined __WIN32__ || defined _WIN32 || defined _Windows || defined __MSDOS__
- pc_printf("\nOptions may start with a dash or a slash; the options \"-d0\" and \"/d0\" are\n");
- pc_printf("equivalent.\n");
+ pc_printf(" -S stack/heap size in cells (default=%d)\n",(int)sc_stksize);
+ pc_printf(" -s skip lines from the input file\n");
+ pc_printf(" -t TAB indent size (in character positions, default=%d)\n",sc_tabsize);
+ pc_printf(" -v verbosity level; 0=quiet, 1=normal, 2=verbose (default=%d)\n",verbosity);
+ pc_printf(" -w disable a specific warning by its number\n");
+ pc_printf(" -X abstract machine size limit in bytes\n");
+ pc_printf(" -\\ use '\\' for escape characters\n");
+ pc_printf(" -^ use '^' for escape characters\n");
+ pc_printf(" -;[+/-] require a semicolon to end each statement (default=%c)\n", sc_needsemicolon ? '+' : '-');
+ pc_printf(" -([+/-] require parantheses for function invocation (default=%c)\n", optproccall ? '-' : '+');
+ pc_printf(" sym=val define constant \"sym\" with value \"val\"\n");
+ pc_printf(" sym= define constant \"sym\" with value 0\n");
+#if defined __WIN32__ || defined _WIN32 || defined _Windows || defined __MSDOS__
+ pc_printf("\nOptions may start with a dash or a slash; the options \"-d0\" and \"/d0\" are\n");
+ pc_printf("equivalent.\n");
#endif
- pc_printf("\nOptions with a value may optionally separate the value from the option letter\n");
- pc_printf("with a colon (\":\") or an equal sign (\"=\"). That is, the options \"-d0\", \"-d=0\"\n");
- pc_printf("and \"-d:0\" are all equivalent.\n");
- } /* if */
- longjmp(errbuf,3); /* user abort */
+ pc_printf("\nOptions with a value may optionally separate the value from the option letter\n");
+ pc_printf("with a colon (\":\") or an equal sign (\"=\"). That is, the options \"-d0\", \"-d=0\"\n");
+ pc_printf("and \"-d:0\" are all equivalent.\n");
+ } /* if */
+ longjmp(errbuf,3); /* user abort */
}
-static void setconstants(void)
+static void setconstants(void)
{
int debug;
@@ -1344,52 +1344,52 @@ 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("true",1,sGLOBAL,1); /* boolean flags */
add_constant("false",0,sGLOBAL,1);
- add_constant("EOS",0,sGLOBAL,0); /* End Of String, or '\0' */
+ add_constant("EOS",0,sGLOBAL,0); /* End Of String, or '\0' */
#if PAWN_CELL_SIZE==16
- add_constant("cellbits",16,sGLOBAL,0);
- #if defined _I16_MAX
- add_constant("cellmax",_I16_MAX,sGLOBAL,0);
- add_constant("cellmin",_I16_MIN,sGLOBAL,0);
- #else
- add_constant("cellmax",SHRT_MAX,sGLOBAL,0);
- add_constant("cellmin",SHRT_MIN,sGLOBAL,0);
- #endif
- #elif PAWN_CELL_SIZE==32
- add_constant("cellbits",32,sGLOBAL,0);
- #if defined _I32_MAX
- add_constant("cellmax",_I32_MAX,sGLOBAL,0);
- add_constant("cellmin",_I32_MIN,sGLOBAL,0);
- #else
- add_constant("cellmax",LONG_MAX,sGLOBAL,0);
- add_constant("cellmin",LONG_MIN,sGLOBAL,0);
- #endif
- #elif PAWN_CELL_SIZE==64
- add_constant("cellbits",64,sGLOBAL,0);
- add_constant("cellmax",_I64_MAX,sGLOBAL,0);
- add_constant("cellmin",_I64_MIN,sGLOBAL,0);
+ add_constant("cellbits",16,sGLOBAL,0);
+ #if defined _I16_MAX
+ add_constant("cellmax",_I16_MAX,sGLOBAL,0);
+ add_constant("cellmin",_I16_MIN,sGLOBAL,0);
+ #else
+ add_constant("cellmax",SHRT_MAX,sGLOBAL,0);
+ add_constant("cellmin",SHRT_MIN,sGLOBAL,0);
+ #endif
+ #elif PAWN_CELL_SIZE==32
+ add_constant("cellbits",32,sGLOBAL,0);
+ #if defined _I32_MAX
+ add_constant("cellmax",_I32_MAX,sGLOBAL,0);
+ add_constant("cellmin",_I32_MIN,sGLOBAL,0);
+ #else
+ add_constant("cellmax",LONG_MAX,sGLOBAL,0);
+ add_constant("cellmin",LONG_MIN,sGLOBAL,0);
+ #endif
+ #elif PAWN_CELL_SIZE==64
+ add_constant("cellbits",64,sGLOBAL,0);
+ add_constant("cellmax",_I64_MAX,sGLOBAL,0);
+ add_constant("cellmin",_I64_MIN,sGLOBAL,0);
#else
- #error Unsupported cell size
+ #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_constant("charmax",~(-1 << sCHARBITS) - 1,sGLOBAL,0);
+ add_constant("ucharmax",(1 << (sizeof(cell)-1)*8)-1,sGLOBAL,0);
add_constant("__Pawn",VERSION_INT,sGLOBAL,0);
debug=0;
- if ((sc_debug & (sCHKBOUNDS | sSYMBOLIC))==(sCHKBOUNDS | sSYMBOLIC))
- debug=2;
+ if ((sc_debug & (sCHKBOUNDS | sSYMBOLIC))==(sCHKBOUNDS | sSYMBOLIC))
+ debug=2;
else if ((sc_debug & sCHKBOUNDS)==sCHKBOUNDS)
- debug=1;
+ debug=1;
add_constant("debug",debug,sGLOBAL,0);
- append_constval(&sc_automaton_tab,"",0,0); /* anonymous automaton */
+ append_constval(&sc_automaton_tab,"",0,0); /* anonymous automaton */
}
-static int getclassspec(int initialtok,int *fpublic,int *fstatic,int *fstock,int *fconst)
+static int getclassspec(int initialtok,int *fpublic,int *fstatic,int *fstock,int *fconst)
{
int tok,err;
cell val;
@@ -1405,216 +1405,216 @@ static int getclassspec(int initialtok,int *fpublic,int *fstatic,int *fstock,int
*fpublic=FALSE;
switch (initialtok) {
case tCONST:
- *fconst=TRUE;
- break;
+ *fconst=TRUE;
+ break;
case tSTOCK:
- *fstock=TRUE;
- break;
+ *fstock=TRUE;
+ break;
case tSTATIC:
- *fstatic=TRUE;
- break;
+ *fstatic=TRUE;
+ break;
case tPUBLIC:
- *fpublic=TRUE;
- break;
- } /* switch */
+ *fpublic=TRUE;
+ break;
+ } /* switch */
err=0;
do {
- tok=lex(&val,&str); /* read in (new) token */
- switch (tok) {
- case tCONST:
- if (*fconst)
- err=42; /* invalid combination of class specifiers */
- *fconst=TRUE;
- break;
- case tSTOCK:
- if (*fstock)
- err=42; /* invalid combination of class specifiers */
- *fstock=TRUE;
- break;
- case tSTATIC:
- if (*fstatic)
- err=42; /* invalid combination of class specifiers */
- *fstatic=TRUE;
- break;
- case tPUBLIC:
- if (*fpublic)
- err=42; /* invalid combination of class specifiers */
- *fpublic=TRUE;
- break;
- default:
- lexpush();
- tok=0; /* force break out of loop */
- } /* switch */
- } while (tok && err==0);
+ tok=lex(&val,&str); /* read in (new) token */
+ switch (tok) {
+ case tCONST:
+ if (*fconst)
+ err=42; /* invalid combination of class specifiers */
+ *fconst=TRUE;
+ break;
+ case tSTOCK:
+ if (*fstock)
+ err=42; /* invalid combination of class specifiers */
+ *fstock=TRUE;
+ break;
+ case tSTATIC:
+ if (*fstatic)
+ err=42; /* invalid combination of class specifiers */
+ *fstatic=TRUE;
+ break;
+ case tPUBLIC:
+ if (*fpublic)
+ err=42; /* invalid combination of class specifiers */
+ *fpublic=TRUE;
+ break;
+ default:
+ lexpush();
+ tok=0; /* force break out of loop */
+ } /* switch */
+ } while (tok && err==0);
/* extra checks */
- if (*fstatic && *fpublic) {
- err=42; /* invalid combination of class specifiers */
- *fstatic=*fpublic=FALSE;
- } /* if */
+ if (*fstatic && *fpublic) {
+ err=42; /* invalid combination of class specifiers */
+ *fstatic=*fpublic=FALSE;
+ } /* if */
if (err)
- error(err);
+ error(err);
return err==0;
}
-/* parse - process all input text
+/* parse - process all input text
*
- * At this level, only static declarations and function definitions are legal.
+ * At this level, only static declarations and function definitions are legal.
*/
-static void parse(void)
+static void parse(void)
{
int tok,fconst,fstock,fstatic,fpublic;
cell val;
char *str;
- while (freading){
- /* first try whether a declaration possibly is native or public */
- tok=lex(&val,&str); /* read in (new) token */
- switch (tok) {
- case 0:
- /* ignore zero's */
- break;
- case tNEW:
- if (getclassspec(tok,&fpublic,&fstatic,&fstock,&fconst))
- declglb(NULL,0,fpublic,fstatic,fstock,fconst);
- break;
- case tSTATIC:
- /* This can be a static function or a static global variable; we know
- * which of the two as soon as we have parsed up to the point where an
- * opening paranthesis of a function would be expected. To back out after
- * deciding it was a declaration of a static variable after all, we have
- * to store the symbol name and tag.
- */
- if (getclassspec(tok,&fpublic,&fstatic,&fstock,&fconst)) {
- assert(!fpublic);
- declfuncvar(fpublic,fstatic,fstock,fconst);
- } /* if */
- break;
- case tCONST:
- decl_const(sGLOBAL);
- break;
- case tENUM:
- decl_enum(sGLOBAL);
- break;
- case tPUBLIC:
- /* This can be a public function or a public variable; see the comment
- * above (for static functions/variables) for details.
- */
- if (getclassspec(tok,&fpublic,&fstatic,&fstock,&fconst)) {
- assert(!fstatic);
- declfuncvar(fpublic,fstatic,fstock,fconst);
- } /* if */
- break;
- case tSTOCK:
- /* This can be a stock function or a stock *global*) variable; see the
- * comment above (for static functions/variables) for details.
- */
- if (getclassspec(tok,&fpublic,&fstatic,&fstock,&fconst)) {
- assert(fstock);
- declfuncvar(fpublic,fstatic,fstock,fconst);
- } /* if */
- break;
- case tLABEL:
- case tSYMBOL:
- case tOPERATOR:
- lexpush();
- if (!newfunc(NULL,-1,FALSE,FALSE,FALSE)) {
- error(10); /* illegal function or declaration */
- lexclr(TRUE); /* drop the rest of the line */
- litidx=0; /* drop the literal queue too */
- } /* if */
- break;
- case tNATIVE:
- funcstub(TRUE); /* create a dummy function */
- break;
- case tFORWARD:
- funcstub(FALSE);
- break;
- case '}':
- error(54); /* unmatched closing brace */
- break;
- case '{':
- error(55); /* start of function body without function header */
- break;
- default:
- if (freading) {
- error(10); /* illegal function or declaration */
- lexclr(TRUE); /* drop the rest of the line */
- litidx=0; /* drop any literal arrays (strings) */
- } /* if */
- } /* switch */
- } /* while */
+ while (freading){
+ /* first try whether a declaration possibly is native or public */
+ tok=lex(&val,&str); /* read in (new) token */
+ switch (tok) {
+ case 0:
+ /* ignore zero's */
+ break;
+ case tNEW:
+ if (getclassspec(tok,&fpublic,&fstatic,&fstock,&fconst))
+ declglb(NULL,0,fpublic,fstatic,fstock,fconst);
+ break;
+ case tSTATIC:
+ /* This can be a static function or a static global variable; we know
+ * which of the two as soon as we have parsed up to the point where an
+ * opening paranthesis of a function would be expected. To back out after
+ * deciding it was a declaration of a static variable after all, we have
+ * to store the symbol name and tag.
+ */
+ if (getclassspec(tok,&fpublic,&fstatic,&fstock,&fconst)) {
+ assert(!fpublic);
+ declfuncvar(fpublic,fstatic,fstock,fconst);
+ } /* if */
+ break;
+ case tCONST:
+ decl_const(sGLOBAL);
+ break;
+ case tENUM:
+ decl_enum(sGLOBAL);
+ break;
+ case tPUBLIC:
+ /* This can be a public function or a public variable; see the comment
+ * above (for static functions/variables) for details.
+ */
+ if (getclassspec(tok,&fpublic,&fstatic,&fstock,&fconst)) {
+ assert(!fstatic);
+ declfuncvar(fpublic,fstatic,fstock,fconst);
+ } /* if */
+ break;
+ case tSTOCK:
+ /* This can be a stock function or a stock *global*) variable; see the
+ * comment above (for static functions/variables) for details.
+ */
+ if (getclassspec(tok,&fpublic,&fstatic,&fstock,&fconst)) {
+ assert(fstock);
+ declfuncvar(fpublic,fstatic,fstock,fconst);
+ } /* if */
+ break;
+ case tLABEL:
+ case tSYMBOL:
+ case tOPERATOR:
+ lexpush();
+ if (!newfunc(NULL,-1,FALSE,FALSE,FALSE)) {
+ error(10); /* illegal function or declaration */
+ lexclr(TRUE); /* drop the rest of the line */
+ litidx=0; /* drop the literal queue too */
+ } /* if */
+ break;
+ case tNATIVE:
+ funcstub(TRUE); /* create a dummy function */
+ break;
+ case tFORWARD:
+ funcstub(FALSE);
+ break;
+ case '}':
+ error(54); /* unmatched closing brace */
+ break;
+ case '{':
+ error(55); /* start of function body without function header */
+ break;
+ default:
+ if (freading) {
+ error(10); /* illegal function or declaration */
+ lexclr(TRUE); /* drop the rest of the line */
+ litidx=0; /* drop any literal arrays (strings) */
+ } /* if */
+ } /* switch */
+ } /* while */
}
-/* dumplits
+/* dumplits
*
- * Dump the literal pool (strings etc.)
+ * Dump the literal pool (strings etc.)
*
- * Global references: litidx (referred to only)
+ * Global references: litidx (referred to only)
*/
-static void dumplits(void)
+static void dumplits(void)
{
int j,k;
k=0;
- while (k=litidx)
- stgwrite("\n"); /* force a newline after 10 dumps */
- /* Note: stgwrite() buffers a line until it is complete. It recognizes
- * the end of line as a sequence of "\n\0", so something like "\n\t"
- * so should not be passed to stgwrite().
- */
- } /* while */
- } /* while */
+ while (k=litidx)
+ stgwrite("\n"); /* force a newline after 10 dumps */
+ /* Note: stgwrite() buffers a line until it is complete. It recognizes
+ * the end of line as a sequence of "\n\0", so something like "\n\t"
+ * so should not be passed to stgwrite().
+ */
+ } /* while */
+ } /* while */
}
-/* dumpzero
+/* dumpzero
*
- * Dump zero's for default initial values
+ * Dump zero's for default initial values
*/
-static void dumpzero(int count)
+static void dumpzero(int count)
{
int i;
if (count<=0)
- return;
+ return;
assert(curseg==2);
defstorage();
i=0;
- while (count-- > 0) {
- outval(0, FALSE);
- i=(i+1) % 16;
- stgwrite((i==0 || count==0) ? "\n" : " ");
- if (i==0 && count>0)
- defstorage();
- } /* while */
+ while (count-- > 0) {
+ outval(0, FALSE);
+ i=(i+1) % 16;
+ stgwrite((i==0 || count==0) ? "\n" : " ");
+ if (i==0 && count>0)
+ defstorage();
+ } /* while */
}
-static void aligndata(int numbytes)
+static void aligndata(int numbytes)
{
- assert(numbytes % sizeof(cell) == 0); /* alignment must be a multiple of
- * the cell size */
+ assert(numbytes % sizeof(cell) == 0); /* alignment must be a multiple of
+ * the cell size */
assert(numbytes!=0);
- if ((((glb_declared+litidx)*sizeof(cell)) % numbytes)!=0) {
- while ((((glb_declared+litidx)*sizeof(cell)) % numbytes)!=0)
- litadd(0);
- } /* if */
+ if ((((glb_declared+litidx)*sizeof(cell)) % numbytes)!=0) {
+ while ((((glb_declared+litidx)*sizeof(cell)) % numbytes)!=0)
+ litadd(0);
+ } /* if */
}
-#if !defined SC_LIGHT
+#if !defined SC_LIGHT
/* sc_attachdocumentation()
* appends documentation comments to the passed-in symbol, or to a global
* string if "sym" is NULL.
@@ -1625,85 +1625,85 @@ void sc_attachdocumentation(symbol *sym)
size_t length;
char *str,*doc;
- if (!sc_makereport || sc_status!=statFIRST || sc_parsenum>0) {
- /* just clear the entire table */
- delete_docstringtable();
- return;
- } /* if */
- /* in the case of state functions, multiple documentation sections may
- * appear; we should concatenate these
+ if (!sc_makereport || sc_status!=statFIRST || sc_parsenum>0) {
+ /* just clear the entire table */
+ delete_docstringtable();
+ return;
+ } /* if */
+ /* in the case of state functions, multiple documentation sections may
+ * appear; we should concatenate these
*/
assert(sym==NULL || sym->documentation==NULL || sym->states!=NULL);
/* first check the size */
length=0;
for (line=0; (str=get_docstring(line))!=NULL && *str!=sDOCSEP; line++) {
- if (length>0)
- length++; /* count 1 extra for a separating space */
- length+=strlen(str);
- } /* for */
- if (sym==NULL && sc_documentation!=NULL) {
- length += strlen(sc_documentation) + 1 + 4; /* plus 4 for "" */
- assert(length>strlen(sc_documentation));
- } /* if */
+ if (length>0)
+ length++; /* count 1 extra for a separating space */
+ length+=strlen(str);
+ } /* for */
+ if (sym==NULL && sc_documentation!=NULL) {
+ length += strlen(sc_documentation) + 1 + 4; /* plus 4 for "" */
+ assert(length>strlen(sc_documentation));
+ } /* if */
- if (length>0) {
- /* allocate memory for the documentation */
- if (sym!=NULL && sym->documentation!=NULL)
- length+=strlen(sym->documentation) + 1 + 4;/* plus 4 for "" */
- doc=(char*)malloc((length+1)*sizeof(char));
- if (doc!=NULL) {
- /* initialize string or concatenate */
- if (sym==NULL && sc_documentation!=NULL) {
- strcpy(doc,sc_documentation);
- strcat(doc,"");
- } else if (sym!=NULL && sym->documentation!=NULL) {
- strcpy(doc,sym->documentation);
- strcat(doc,"");
- free(sym->documentation);
- sym->documentation=NULL;
- } else {
- doc[0]='\0';
- } /* if */
- /* collect all documentation */
- while ((str=get_docstring(0))!=NULL && *str!=sDOCSEP) {
- if (doc[0]!='\0')
- strcat(doc," ");
- strcat(doc,str);
- delete_docstring(0);
- } /* while */
- if (str!=NULL) {
- /* also delete the separator */
- assert(*str==sDOCSEP);
- delete_docstring(0);
- } /* if */
- if (sym!=NULL) {
- assert(sym->documentation==NULL);
- sym->documentation=doc;
- } else {
- if (sc_documentation!=NULL)
- free(sc_documentation);
- sc_documentation=doc;
- } /* if */
- } /* if */
- } else {
- /* delete an empty separator, if present */
- if ((str=get_docstring(0))!=NULL && *str==sDOCSEP)
- delete_docstring(0);
- } /* if */
+ if (length>0) {
+ /* allocate memory for the documentation */
+ if (sym!=NULL && sym->documentation!=NULL)
+ length+=strlen(sym->documentation) + 1 + 4;/* plus 4 for "" */
+ doc=(char*)malloc((length+1)*sizeof(char));
+ if (doc!=NULL) {
+ /* initialize string or concatenate */
+ if (sym==NULL && sc_documentation!=NULL) {
+ strcpy(doc,sc_documentation);
+ strcat(doc,"");
+ } else if (sym!=NULL && sym->documentation!=NULL) {
+ strcpy(doc,sym->documentation);
+ strcat(doc,"");
+ free(sym->documentation);
+ sym->documentation=NULL;
+ } else {
+ doc[0]='\0';
+ } /* if */
+ /* collect all documentation */
+ while ((str=get_docstring(0))!=NULL && *str!=sDOCSEP) {
+ if (doc[0]!='\0')
+ strcat(doc," ");
+ strcat(doc,str);
+ delete_docstring(0);
+ } /* while */
+ if (str!=NULL) {
+ /* also delete the separator */
+ assert(*str==sDOCSEP);
+ delete_docstring(0);
+ } /* if */
+ if (sym!=NULL) {
+ assert(sym->documentation==NULL);
+ sym->documentation=doc;
+ } else {
+ if (sc_documentation!=NULL)
+ free(sc_documentation);
+ sc_documentation=doc;
+ } /* if */
+ } /* if */
+ } else {
+ /* delete an empty separator, if present */
+ if ((str=get_docstring(0))!=NULL && *str==sDOCSEP)
+ delete_docstring(0);
+ } /* if */
}
-static void insert_docstring_separator(void)
+static void insert_docstring_separator(void)
{
char sep[2]={sDOCSEP,'\0'};
insert_docstring(sep);
}
#else
- #define sc_attachdocumentation(s) (void)(s)
+ #define sc_attachdocumentation(s) (void)(s)
#define insert_docstring_separator()
#endif
-static void declfuncvar(int fpublic,int fstatic,int fstock,int fconst)
+static void declfuncvar(int fpublic,int fstatic,int fstock,int fconst)
{
char name[sNAMEMAX+11];
int tok,tag;
@@ -1713,49 +1713,49 @@ static void declfuncvar(int fpublic,int fstatic,int fstock,int fconst)
tag=pc_addtag(NULL);
tok=lex(&val,&str);
- /* if we arrived here, this may not be a declaration of a native function
- * or variable
+ /* if we arrived here, this may not be a declaration of a native function
+ * or variable
*/
- if (tok==tNATIVE) {
- error(42); /* invalid combination of class specifiers */
- return;
- } /* if */
+ if (tok==tNATIVE) {
+ error(42); /* invalid combination of class specifiers */
+ return;
+ } /* if */
if (tok!=tSYMBOL && tok!=tOPERATOR) {
- lexpush();
- needtoken(tSYMBOL);
- lexclr(TRUE); /* drop the rest of the line */
- litidx=0; /* drop the literal queue too */
- return;
- } /* if */
+ lexpush();
+ needtoken(tSYMBOL);
+ lexclr(TRUE); /* drop the rest of the line */
+ litidx=0; /* drop the literal queue too */
+ return;
+ } /* if */
if (tok==tOPERATOR) {
- lexpush(); /* push "operator" keyword back (for later analysis) */
- if (!newfunc(NULL,tag,fpublic,fstatic,fstock)) {
- error(10); /* illegal function or declaration */
- lexclr(TRUE); /* drop the rest of the line */
- litidx=0; /* drop the literal queue too */
- } /* if */
- } else {
- /* so tok is tSYMBOL */
- assert(strlen(str)<=sNAMEMAX);
- strcpy(name,str);
- /* only variables can be "const" or both "public" and "stock" */
- invalidfunc= fconst || (fpublic && fstock);
- if (invalidfunc || !newfunc(name,tag,fpublic,fstatic,fstock)) {
- /* if not a function, try a global variable */
- declglb(name,tag,fpublic,fstatic,fstock,fconst);
- } /* if */
- } /* if */
+ lexpush(); /* push "operator" keyword back (for later analysis) */
+ if (!newfunc(NULL,tag,fpublic,fstatic,fstock)) {
+ error(10); /* illegal function or declaration */
+ lexclr(TRUE); /* drop the rest of the line */
+ litidx=0; /* drop the literal queue too */
+ } /* if */
+ } else {
+ /* so tok is tSYMBOL */
+ assert(strlen(str)<=sNAMEMAX);
+ strcpy(name,str);
+ /* only variables can be "const" or both "public" and "stock" */
+ invalidfunc= fconst || (fpublic && fstock);
+ if (invalidfunc || !newfunc(name,tag,fpublic,fstatic,fstock)) {
+ /* if not a function, try a global variable */
+ declglb(name,tag,fpublic,fstatic,fstock,fconst);
+ } /* if */
+ } /* if */
}
-/* declglb - declare global symbols
+/* declglb - declare global symbols
*
- * Declare a static (global) variable. Global variables are stored in
- * the DATA segment.
+ * Declare a static (global) variable. Global variables are stored in
+ * the DATA segment.
*
- * global references: glb_declared (altered)
+ * global references: glb_declared (altered)
*/
-static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fstock,int fconst)
+static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fstock,int fconst)
{
int ident,tag,ispublic;
int idxtag[sDIMEN_MAX];
@@ -1764,121 +1764,121 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fst
char *str;
int dim[sDIMEN_MAX];
int numdim;
- short filenum;
+ short filenum;
symbol *sym;
constvalue *enumroot;
#if !defined NDEBUG
- cell glbdecl=0;
+ cell glbdecl=0;
#endif
- assert(!fpublic || !fstatic); /* may not both be set */
- insert_docstring_separator(); /* see comment in newfunc() */
- filenum=fcurrent; /* save file number at the start of the declaration */
+ assert(!fpublic || !fstatic); /* may not both be set */
+ insert_docstring_separator(); /* see comment in newfunc() */
+ filenum=fcurrent; /* save file number at the start of the declaration */
do {
- size=1; /* single size (no array) */
- numdim=0; /* no dimensions */
- ident=iVARIABLE;
- if (firstname!=NULL) {
- assert(strlen(firstname)<=sNAMEMAX);
- strcpy(name,firstname); /* save symbol name */
- tag=firsttag;
- firstname=NULL;
- } else {
- tag=pc_addtag(NULL);
- if (lex(&val,&str)!=tSYMBOL) /* read in (new) token */
- error(20,str); /* invalid symbol name */
- assert(strlen(str)<=sNAMEMAX);
- strcpy(name,str); /* save symbol name */
- } /* if */
- sym=findglb(name);
- if (sym==NULL)
- sym=findconst(name);
- if (sym!=NULL && (sym->usage & uDEFINE)!=0)
- error(21,name); /* symbol already defined */
- ispublic=fpublic;
- if (name[0]==PUBLIC_CHAR) {
- ispublic=TRUE; /* implicitly public variable */
- assert(!fstatic);
- } /* if */
- while (matchtoken('[')) {
- ident=iARRAY;
- if (numdim == sDIMEN_MAX) {
- error(53); /* exceeding maximum number of dimensions */
- return;
- } /* if */
- size=needsub(&idxtag[numdim],&enumroot); /* get size; size==0 for "var[]" */
- #if INT_MAX < LONG_MAX
- if (size > INT_MAX)
- error(105); /* overflow, exceeding capacity */
- #endif
- if (ispublic)
- error(56,name); /* arrays cannot be public */
- dim[numdim++]=(int)size;
- } /* while */
- /* if this variable is never used (which can be detected only in the
- * second stage), shut off code generation
- */
- cidx=0; /* only to avoid a compiler warning */
- if (sc_status==statWRITE && sym!=NULL && (sym->usage & (uREAD | uWRITTEN))==0) {
- sc_status=statSKIP;
- cidx=code_idx;
- #if !defined NDEBUG
- glbdecl=glb_declared;
- #endif
- } /* if */
- begdseg(); /* real (initialized) data in data segment */
- assert(litidx==0); /* literal queue should be empty */
- if (sc_alignnext) {
- litidx=0;
- aligndata(sc_dataalign);
- dumplits(); /* dump the literal queue */
- sc_alignnext=FALSE;
- litidx=0; /* global initial data is dumped, so restart at zero */
- } /* if */
- assert(litidx==0); /* literal queue should be empty (again) */
- initials(ident,tag,&size,dim,numdim,enumroot);/* stores values in the literal queue */
- assert(size>=litidx);
- if (numdim==1)
- dim[0]=(int)size;
- dumplits(); /* dump the literal queue */
- dumpzero((int)size-litidx);
- litidx=0;
- if (sym==NULL) { /* define only if not yet defined */
- sym=addvariable(name,sizeof(cell)*glb_declared,ident,sGLOBAL,tag,
- dim,numdim,idxtag);
- } else { /* if declared but not yet defined, adjust the variable's address */
- sym->addr=sizeof(cell)*glb_declared;
- sym->codeaddr=code_idx;
- sym->usage|=uDEFINE;
- } /* if */
- if (ispublic)
- sym->usage|=uPUBLIC;
- if (fconst)
- sym->usage|=uCONST;
- if (fstock)
- sym->usage|=uSTOCK;
- if (fstatic)
- sym->fnumber=filenum;
- sc_attachdocumentation(sym);/* attach any documenation to the variable */
- if (sc_status==statSKIP) {
- sc_status=statWRITE;
- code_idx=cidx;
- assert(glb_declared==glbdecl);
- } else {
- glb_declared+=(int)size; /* add total number of cells */
- } /* if */
- } while (matchtoken(',')); /* enddo */ /* more? */
- needtoken(tTERM); /* if not comma, must be semicolumn */
+ size=1; /* single size (no array) */
+ numdim=0; /* no dimensions */
+ ident=iVARIABLE;
+ if (firstname!=NULL) {
+ assert(strlen(firstname)<=sNAMEMAX);
+ strcpy(name,firstname); /* save symbol name */
+ tag=firsttag;
+ firstname=NULL;
+ } else {
+ tag=pc_addtag(NULL);
+ if (lex(&val,&str)!=tSYMBOL) /* read in (new) token */
+ error(20,str); /* invalid symbol name */
+ assert(strlen(str)<=sNAMEMAX);
+ strcpy(name,str); /* save symbol name */
+ } /* if */
+ sym=findglb(name);
+ if (sym==NULL)
+ sym=findconst(name);
+ if (sym!=NULL && (sym->usage & uDEFINE)!=0)
+ error(21,name); /* symbol already defined */
+ ispublic=fpublic;
+ if (name[0]==PUBLIC_CHAR) {
+ ispublic=TRUE; /* implicitly public variable */
+ assert(!fstatic);
+ } /* if */
+ while (matchtoken('[')) {
+ ident=iARRAY;
+ if (numdim == sDIMEN_MAX) {
+ error(53); /* exceeding maximum number of dimensions */
+ return;
+ } /* if */
+ size=needsub(&idxtag[numdim],&enumroot); /* get size; size==0 for "var[]" */
+ #if INT_MAX < LONG_MAX
+ if (size > INT_MAX)
+ error(105); /* overflow, exceeding capacity */
+ #endif
+ if (ispublic)
+ error(56,name); /* arrays cannot be public */
+ dim[numdim++]=(int)size;
+ } /* while */
+ /* if this variable is never used (which can be detected only in the
+ * second stage), shut off code generation
+ */
+ cidx=0; /* only to avoid a compiler warning */
+ if (sc_status==statWRITE && sym!=NULL && (sym->usage & (uREAD | uWRITTEN))==0) {
+ sc_status=statSKIP;
+ cidx=code_idx;
+ #if !defined NDEBUG
+ glbdecl=glb_declared;
+ #endif
+ } /* if */
+ begdseg(); /* real (initialized) data in data segment */
+ assert(litidx==0); /* literal queue should be empty */
+ if (sc_alignnext) {
+ litidx=0;
+ aligndata(sc_dataalign);
+ dumplits(); /* dump the literal queue */
+ sc_alignnext=FALSE;
+ litidx=0; /* global initial data is dumped, so restart at zero */
+ } /* if */
+ assert(litidx==0); /* literal queue should be empty (again) */
+ initials(ident,tag,&size,dim,numdim,enumroot);/* stores values in the literal queue */
+ assert(size>=litidx);
+ if (numdim==1)
+ dim[0]=(int)size;
+ dumplits(); /* dump the literal queue */
+ dumpzero((int)size-litidx);
+ litidx=0;
+ if (sym==NULL) { /* define only if not yet defined */
+ sym=addvariable(name,sizeof(cell)*glb_declared,ident,sGLOBAL,tag,
+ dim,numdim,idxtag);
+ } else { /* if declared but not yet defined, adjust the variable's address */
+ sym->addr=sizeof(cell)*glb_declared;
+ sym->codeaddr=code_idx;
+ sym->usage|=uDEFINE;
+ } /* if */
+ if (ispublic)
+ sym->usage|=uPUBLIC;
+ if (fconst)
+ sym->usage|=uCONST;
+ if (fstock)
+ sym->usage|=uSTOCK;
+ if (fstatic)
+ sym->fnumber=filenum;
+ sc_attachdocumentation(sym);/* attach any documenation to the variable */
+ if (sc_status==statSKIP) {
+ sc_status=statWRITE;
+ code_idx=cidx;
+ assert(glb_declared==glbdecl);
+ } else {
+ glb_declared+=(int)size; /* add total number of cells */
+ } /* if */
+ } while (matchtoken(',')); /* enddo */ /* more? */
+ needtoken(tTERM); /* if not comma, must be semicolumn */
}
-/* declloc - declare local symbols
+/* declloc - declare local symbols
*
- * Declare local (automatic) variables. Since these variables are relative
- * to the STACK, there is no switch to the DATA segment. These variables
- * cannot be initialized either.
+ * Declare local (automatic) variables. Since these variables are relative
+ * to the STACK, there is no switch to the DATA segment. These variables
+ * cannot be initialized either.
*
- * global references: declared (altered)
- * funcstatus (referred to only)
+ * global references: declared (altered)
+ * funcstatus (referred to only)
*/
static int declloc(int fstatic)
{
@@ -1889,7 +1889,7 @@ static int declloc(int fstatic)
constvalue *enumroot;
cell val,size;
char *str;
- value lval = {0};
+ value lval = {0};
int cur_lit=0;
int dim[sDIMEN_MAX];
int numdim;
@@ -1898,354 +1898,354 @@ static int declloc(int fstatic)
fconst=matchtoken(tCONST);
do {
- ident=iVARIABLE;
- size=1;
- numdim=0; /* no dimensions */
- tag=pc_addtag(NULL);
- if (lex(&val,&str)!=tSYMBOL) /* read in (new) token */
- error(20,str); /* invalid symbol name */
- assert(strlen(str)<=sNAMEMAX);
- strcpy(name,str); /* save symbol name */
- if (name[0]==PUBLIC_CHAR)
- error(56,name); /* local variables cannot be public */
- /* Note: block locals may be named identical to locals at higher
- * compound blocks (as with standard C); so we must check (and add)
- * the "nesting level" of local variables to verify the
- * multi-definition of symbols.
- */
- if ((sym=findloc(name))!=NULL && sym->compound==nestlevel)
- error(21,name); /* symbol already defined */
- /* Although valid, a local variable whose name is equal to that
- * of a global variable or to that of a local variable at a lower
- * level might indicate a bug.
- */
- if ((sym=findloc(name))!=NULL && sym->compound!=nestlevel || findglb(name)!=NULL)
- error(219,name); /* variable shadows another symbol */
- while (matchtoken('[')){
- ident=iARRAY;
- if (numdim == sDIMEN_MAX) {
- error(53); /* exceeding maximum number of dimensions */
- return ident;
- } /* if */
- size=needsub(&idxtag[numdim],&enumroot); /* get size; size==0 for "var[]" */
- #if INT_MAX < LONG_MAX
- if (size > INT_MAX)
- error(105); /* overflow, exceeding capacity */
- #endif
- dim[numdim++]=(int)size;
- } /* while */
- if (ident==iARRAY || fstatic) {
- if (sc_alignnext) {
- aligndata(sc_dataalign);
- sc_alignnext=FALSE;
- } /* if */
- cur_lit=litidx; /* save current index in the literal table */
- initials(ident,tag,&size,dim,numdim,enumroot);
- if (size==0)
- return ident; /* error message already given */
- if (numdim==1)
- dim[0]=(int)size;
- } /* if */
- /* reserve memory (on the stack) for the variable */
- if (fstatic) {
- /* write zeros for uninitialized fields */
- while (litidxusage & uNATIVE)==0);
- if (curfunc->x.stacksizex.stacksize=declared+1; /* +1 for PROC opcode */
- } /* if */
- /* now that we have reserved memory for the variable, we can proceed
- * to initialize it */
- assert(sym!=NULL); /* we declared it, it must be there */
- sym->compound=nestlevel; /* for multiple declaration/shadowing check */
- if (fconst)
- sym->usage|=uCONST;
- if (!fstatic) { /* static variables already initialized */
- if (ident==iVARIABLE) {
- /* simple variable, also supports initialization */
- int ctag = tag; /* set to "tag" by default */
- int explicit_init=FALSE;/* is the variable explicitly initialized? */
- if (matchtoken('=')) {
- doexpr(FALSE,FALSE,FALSE,FALSE,&ctag,NULL,TRUE);
- explicit_init=TRUE;
- } else {
- ldconst(0,sPRI); /* uninitialized variable, set to zero */
- } /* if */
- /* now try to save the value (still in PRI) in the variable */
- lval.sym=sym;
- lval.ident=iVARIABLE;
- lval.constval=0;
- lval.tag=tag;
- check_userop(NULL,ctag,lval.tag,2,NULL,&ctag);
- store(&lval);
- markexpr(sEXPR,NULL,0); /* full expression ends after the store */
- assert(staging); /* end staging phase (optimize expression) */
- stgout(staging_start);
- stgset(FALSE);
- if (!matchtag(tag,ctag,TRUE))
- error(213); /* tag mismatch */
- /* if the variable was not explicitly initialized, reset the
- * "uWRITTEN" flag that store() set */
- if (!explicit_init)
- sym->usage &= ~uWRITTEN;
- } else {
- /* an array */
- assert(cur_lit>=0 && cur_lit<=litidx && litidx<=litmax);
- /* if the array is not completely filled, set all values to zero first */
- assert(size>0 && size>=sym->dim.array.length);
- assert(numdim>1 || size==sym->dim.array.length);
- if (litidx-cur_lit < size)
- fillarray(sym,size*sizeof(cell),0);
- if (cur_litcompound==nestlevel)
+ error(21,name); /* symbol already defined */
+ /* Although valid, a local variable whose name is equal to that
+ * of a global variable or to that of a local variable at a lower
+ * level might indicate a bug.
+ */
+ if ((sym=findloc(name))!=NULL && sym->compound!=nestlevel || findglb(name)!=NULL)
+ error(219,name); /* variable shadows another symbol */
+ while (matchtoken('[')){
+ ident=iARRAY;
+ if (numdim == sDIMEN_MAX) {
+ error(53); /* exceeding maximum number of dimensions */
+ return ident;
+ } /* if */
+ size=needsub(&idxtag[numdim],&enumroot); /* get size; size==0 for "var[]" */
+ #if INT_MAX < LONG_MAX
+ if (size > INT_MAX)
+ error(105); /* overflow, exceeding capacity */
+ #endif
+ dim[numdim++]=(int)size;
+ } /* while */
+ if (ident==iARRAY || fstatic) {
+ if (sc_alignnext) {
+ aligndata(sc_dataalign);
+ sc_alignnext=FALSE;
+ } /* if */
+ cur_lit=litidx; /* save current index in the literal table */
+ initials(ident,tag,&size,dim,numdim,enumroot);
+ if (size==0)
+ return ident; /* error message already given */
+ if (numdim==1)
+ dim[0]=(int)size;
+ } /* if */
+ /* reserve memory (on the stack) for the variable */
+ if (fstatic) {
+ /* write zeros for uninitialized fields */
+ while (litidxusage & uNATIVE)==0);
+ if (curfunc->x.stacksizex.stacksize=declared+1; /* +1 for PROC opcode */
+ } /* if */
+ /* now that we have reserved memory for the variable, we can proceed
+ * to initialize it */
+ assert(sym!=NULL); /* we declared it, it must be there */
+ sym->compound=nestlevel; /* for multiple declaration/shadowing check */
+ if (fconst)
+ sym->usage|=uCONST;
+ if (!fstatic) { /* static variables already initialized */
+ if (ident==iVARIABLE) {
+ /* simple variable, also supports initialization */
+ int ctag = tag; /* set to "tag" by default */
+ int explicit_init=FALSE;/* is the variable explicitly initialized? */
+ if (matchtoken('=')) {
+ doexpr(FALSE,FALSE,FALSE,FALSE,&ctag,NULL,TRUE);
+ explicit_init=TRUE;
+ } else {
+ ldconst(0,sPRI); /* uninitialized variable, set to zero */
+ } /* if */
+ /* now try to save the value (still in PRI) in the variable */
+ lval.sym=sym;
+ lval.ident=iVARIABLE;
+ lval.constval=0;
+ lval.tag=tag;
+ check_userop(NULL,ctag,lval.tag,2,NULL,&ctag);
+ store(&lval);
+ markexpr(sEXPR,NULL,0); /* full expression ends after the store */
+ assert(staging); /* end staging phase (optimize expression) */
+ stgout(staging_start);
+ stgset(FALSE);
+ if (!matchtag(tag,ctag,TRUE))
+ error(213); /* tag mismatch */
+ /* if the variable was not explicitly initialized, reset the
+ * "uWRITTEN" flag that store() set */
+ if (!explicit_init)
+ sym->usage &= ~uWRITTEN;
+ } else {
+ /* an array */
+ assert(cur_lit>=0 && cur_lit<=litidx && litidx<=litmax);
+ /* if the array is not completely filled, set all values to zero first */
+ assert(size>0 && size>=sym->dim.array.length);
+ assert(numdim>1 || size==sym->dim.array.length);
+ if (litidx-cur_lit < size)
+ fillarray(sym,size*sizeof(cell),0);
+ if (cur_lit=0 && cur<=numdim);
+ /* the return value is in cells, not bytes */
+ assert(cur>=0 && cur<=numdim);
if (cur==numdim)
- return 0;
+ return 0;
return dim[cur]+(dim[cur]*calc_arraysize(dim,numdim,cur+1));
}
-static cell adjust_indirectiontables(int dim[],int numdim,int cur,cell increment,
- int startlit,constvalue *lastdim,int *skipdim)
+static cell adjust_indirectiontables(int dim[],int numdim,int cur,cell increment,
+ int startlit,constvalue *lastdim,int *skipdim)
{
static int base;
int d;
cell accum;
- assert(cur>=0 && cur=0 && cur=0);
assert(cur>0 && startlit==-1 || startlit>=0 && startlit<=litidx);
if (cur==0)
- base=startlit;
+ base=startlit;
if (cur==numdim-1)
- return 0;
- /* 2 or more dimensions left, fill in an indirection vector */
+ return 0;
+ /* 2 or more dimensions left, fill in an indirection vector */
assert(dim[cur]>0);
- if (dim[cur+1]>0) {
- for (d=0; dnext; d<*skipdim; d++,ld=ld->next) {
- assert(ld!=NULL);
- } /* for */
- for (d=0; dname,NULL,16)==d);
- litq[base++]=(dim[cur]+accum+increment) * sizeof(cell);
- accum+=ld->value-1;
- *skipdim+=1;
- ld=ld->next;
- } /* for */
- } /* if */
- /* create the indirection tables for the lower level */
- if (cur+20) {
+ for (d=0; dnext; d<*skipdim; d++,ld=ld->next) {
+ assert(ld!=NULL);
+ } /* for */
+ for (d=0; dname,NULL,16)==d);
+ litq[base++]=(dim[cur]+accum+increment) * sizeof(cell);
+ accum+=ld->value-1;
+ *skipdim+=1;
+ ld=ld->next;
+ } /* for */
+ } /* if */
+ /* create the indirection tables for the lower level */
+ if (cur+20);
- if (ident==iARRAY && dim[numdim-1]==0) {
- /* declared as "myvar[];" which is senseless (note: this *does* make
- * sense in the case of a iREFARRAY, which is a function parameter)
- */
- error(9); /* array has zero length -> invalid size */
- } /* if */
- if (ident==iARRAY) {
- assert(numdim>0 && numdim<=sDIMEN_MAX);
- *size=calc_arraysize(dim,numdim,0);
- /* first reserve space for the indirection vectors of the array, then
- * adjust it to contain the proper values
- * (do not use dumpzero(), as it bypasses the literal queue)
- */
- for (tablesize=calc_arraysize(dim,numdim-1,0); tablesize>0; tablesize--)
- litadd(0);
- if (dim[numdim-1]!=0) /* error 9 has already been given */
- adjust_indirectiontables(dim,numdim,0,0,curlit,NULL,NULL);
- } /* if */
- return;
- } /* if */
+ if (!matchtoken('=')) {
+ assert(ident!=iARRAY || numdim>0);
+ if (ident==iARRAY && dim[numdim-1]==0) {
+ /* declared as "myvar[];" which is senseless (note: this *does* make
+ * sense in the case of a iREFARRAY, which is a function parameter)
+ */
+ error(9); /* array has zero length -> invalid size */
+ } /* if */
+ if (ident==iARRAY) {
+ assert(numdim>0 && numdim<=sDIMEN_MAX);
+ *size=calc_arraysize(dim,numdim,0);
+ /* first reserve space for the indirection vectors of the array, then
+ * adjust it to contain the proper values
+ * (do not use dumpzero(), as it bypasses the literal queue)
+ */
+ for (tablesize=calc_arraysize(dim,numdim-1,0); tablesize>0; tablesize--)
+ litadd(0);
+ if (dim[numdim-1]!=0) /* error 9 has already been given */
+ adjust_indirectiontables(dim,numdim,0,0,curlit,NULL,NULL);
+ } /* if */
+ return;
+ } /* if */
- if (ident==iVARIABLE) {
- assert(*size==1);
- init(ident,&ctag,NULL);
- if (!matchtag(tag,ctag,TRUE))
- error(213); /* tag mismatch */
- } else {
- assert(numdim>0);
- if (numdim==1) {
- *size=initvector(ident,tag,dim[0],FALSE,enumroot,NULL);
- } else {
- int errorfound=FALSE;
- int counteddim[sDIMEN_MAX];
- int idx;
- constvalue lastdim={NULL,"",0,0}; /* sizes of the final dimension */
- int skipdim=0;
+ if (ident==iVARIABLE) {
+ assert(*size==1);
+ init(ident,&ctag,NULL);
+ if (!matchtag(tag,ctag,TRUE))
+ error(213); /* tag mismatch */
+ } else {
+ assert(numdim>0);
+ if (numdim==1) {
+ *size=initvector(ident,tag,dim[0],FALSE,enumroot,NULL);
+ } else {
+ int errorfound=FALSE;
+ int counteddim[sDIMEN_MAX];
+ int idx;
+ constvalue lastdim={NULL,"",0,0}; /* sizes of the final dimension */
+ int skipdim=0;
- if (dim[numdim-1]!=0)
- *size=calc_arraysize(dim,numdim,0); /* calc. full size, if known */
- /* already reserve space for the indirection tables (for an array with
- * known dimensions)
- * (do not use dumpzero(), as it bypasses the literal queue)
- */
- for (tablesize=calc_arraysize(dim,numdim-1,0); tablesize>0; tablesize--)
- litadd(0);
- /* now initialize the sub-arrays */
- memset(counteddim,0,sizeof counteddim);
- initarray(ident,tag,dim,numdim,0,curlit,counteddim,&lastdim,enumroot,&errorfound);
- /* check the specified array dimensions with the initialler counts */
- for (idx=0; idxdim[idx]) {
- error(18); /* initialization data exceeds declared size */
- err++;
- } /* if */
- } /* for */
- /* after all arrays have been initalized, we know the (major) dimensions
- * of the array and we can properly adjust the indirection vectors
- */
- if (err==0)
- adjust_indirectiontables(dim,numdim,0,0,curlit,&lastdim,&skipdim);
- delete_consttable(&lastdim); /* clear list of minor dimension sizes */
- } /* if */
- } /* if */
+ if (dim[numdim-1]!=0)
+ *size=calc_arraysize(dim,numdim,0); /* calc. full size, if known */
+ /* already reserve space for the indirection tables (for an array with
+ * known dimensions)
+ * (do not use dumpzero(), as it bypasses the literal queue)
+ */
+ for (tablesize=calc_arraysize(dim,numdim-1,0); tablesize>0; tablesize--)
+ litadd(0);
+ /* now initialize the sub-arrays */
+ memset(counteddim,0,sizeof counteddim);
+ initarray(ident,tag,dim,numdim,0,curlit,counteddim,&lastdim,enumroot,&errorfound);
+ /* check the specified array dimensions with the initialler counts */
+ for (idx=0; idxdim[idx]) {
+ error(18); /* initialization data exceeds declared size */
+ err++;
+ } /* if */
+ } /* for */
+ /* after all arrays have been initalized, we know the (major) dimensions
+ * of the array and we can properly adjust the indirection vectors
+ */
+ if (err==0)
+ adjust_indirectiontables(dim,numdim,0,0,curlit,&lastdim,&skipdim);
+ delete_consttable(&lastdim); /* clear list of minor dimension sizes */
+ } /* if */
+ } /* if */
if (*size==0)
- *size=litidx-curlit; /* number of elements defined */
+ *size=litidx-curlit; /* number of elements defined */
}
-static cell initarray(int ident,int tag,int dim[],int numdim,int cur,
- int startlit,int counteddim[],constvalue *lastdim,
- constvalue *enumroot,int *errorfound)
+static cell initarray(int ident,int tag,int dim[],int numdim,int cur,
+ int startlit,int counteddim[],constvalue *lastdim,
+ constvalue *enumroot,int *errorfound)
{
cell dsize,totalsize;
int idx,abortparse;
- assert(cur>=0 && cur=0 && cur=0);
- assert(cur+2<=numdim);/* there must be 2 dimensions or more to do */
+ assert(cur+2<=numdim);/* there must be 2 dimensions or more to do */
assert(errorfound!=NULL && *errorfound==FALSE);
totalsize=0;
needtoken('{');
- for (idx=0,abortparse=FALSE; !abortparse; idx++) {
- /* In case the major dimension is zero, we need to store the offset
- * to the newly detected sub-array into the indirection table; i.e.
- * this table needs to be expanded and updated.
- * In the current design, the indirection vectors for a multi-dimensional
- * array are adjusted after parsing all initiallers. Hence, it is only
- * necessary at this point to reserve space for an extra cell in the
- * indirection vector.
- */
- if (dim[cur]==0) {
- litinsert(0,startlit);
- } else if (idx>=dim[cur]) {
- error(18); /* initialization data exceeds array size */
- break;
- } /* if */
- if (cur+2=dim[cur]) {
+ error(18); /* initialization data exceeds array size */
+ break;
+ } /* if */
+ if (cur+20) {
- if (idxcounteddim[cur])
- error(18); /* initialization data exceeds declared size */
- } /* if */
+ if (idxcounteddim[cur])
+ error(18); /* initialization data exceeds declared size */
+ } /* if */
counteddim[cur]=idx;
- return totalsize+dim[cur]; /* size of sub-arrays + indirection vector */
+ return totalsize+dim[cur]; /* size of sub-arrays + indirection vector */
}
-/* initvector
- * Initialize a single dimensional array
+/* initvector
+ * Initialize a single dimensional array
*/
-static cell initvector(int ident,int tag,cell size,int fillzero,
- constvalue *enumroot,int *errorfound)
+static cell initvector(int ident,int tag,cell size,int fillzero,
+ constvalue *enumroot,int *errorfound)
{
cell prev1=0,prev2=0;
int ellips=FALSE;
@@ -2254,123 +2254,123 @@ static cell initvector(int ident,int tag,cell size,int fillzero,
assert(ident==iARRAY || ident==iREFARRAY);
if (matchtoken('{')) {
- constvalue *enumfield=(enumroot!=NULL) ? enumroot->next : NULL;
- do {
- int fieldlit=litidx;
- int matchbrace,i;
- if (matchtoken('}')) { /* to allow for trailing ',' after the initialization */
- lexpush();
- break;
- } /* if */
- if ((ellips=matchtoken(tELLIPS))!=0)
- break;
- /* for enumeration fields, allow another level of braces ("{...}") */
- matchbrace=0; /* preset */
- ellips=0;
- if (enumfield!=NULL)
- matchbrace=matchtoken('{');
- for ( ;; ) {
- prev2=prev1;
- prev1=init(ident,&ctag,errorfound);
- if (!matchbrace)
- break;
- if ((ellips=matchtoken(tELLIPS))!=0)
- break;
- if (!matchtoken(',')) {
- needtoken('}');
- break;
- } /* for */
- } /* for */
- /* if this array is based on an enumeration, fill the "field" up with
- * zeros, and toggle the tag
- */
- if (enumroot!=NULL && enumfield==NULL)
- error(227); /* more initiallers than enum fields */
- rtag=tag; /* preset, may be overridden by enum field tag */
- if (enumfield!=NULL) {
- cell step;
- symbol *symfield=findconst(enumfield->name);
- assert(symfield!=NULL);
- assert(fieldlitsymfield->dim.array.length)
- error(228); /* length of initialler exceeds size of the enum field */
- if (ellips) {
- step=prev1-prev2;
- } else {
- step=0;
- prev1=0;
- } /* if */
- for (i=litidx-fieldlit; idim.array.length; i++) {
- prev1+=step;
- litadd(prev1);
- } /* for */
- rtag=symfield->x.idxtag; /* set the expected tag to the index tag */
- enumfield=enumfield->next;
- } /* if */
- if (!matchtag(rtag,ctag,TRUE))
- error(213); /* tag mismatch */
- } while (matchtoken(',')); /* do */
- needtoken('}');
- } else {
- init(ident,&ctag,errorfound);
- if (!matchtag(tag,ctag,TRUE))
- error(213); /* tagname mismatch */
- } /* if */
- /* fill up the literal queue with a series */
+ constvalue *enumfield=(enumroot!=NULL) ? enumroot->next : NULL;
+ do {
+ int fieldlit=litidx;
+ int matchbrace,i;
+ if (matchtoken('}')) { /* to allow for trailing ',' after the initialization */
+ lexpush();
+ break;
+ } /* if */
+ if ((ellips=matchtoken(tELLIPS))!=0)
+ break;
+ /* for enumeration fields, allow another level of braces ("{...}") */
+ matchbrace=0; /* preset */
+ ellips=0;
+ if (enumfield!=NULL)
+ matchbrace=matchtoken('{');
+ for ( ;; ) {
+ prev2=prev1;
+ prev1=init(ident,&ctag,errorfound);
+ if (!matchbrace)
+ break;
+ if ((ellips=matchtoken(tELLIPS))!=0)
+ break;
+ if (!matchtoken(',')) {
+ needtoken('}');
+ break;
+ } /* for */
+ } /* for */
+ /* if this array is based on an enumeration, fill the "field" up with
+ * zeros, and toggle the tag
+ */
+ if (enumroot!=NULL && enumfield==NULL)
+ error(227); /* more initiallers than enum fields */
+ rtag=tag; /* preset, may be overridden by enum field tag */
+ if (enumfield!=NULL) {
+ cell step;
+ symbol *symfield=findconst(enumfield->name);
+ assert(symfield!=NULL);
+ assert(fieldlitsymfield->dim.array.length)
+ error(228); /* length of initialler exceeds size of the enum field */
+ if (ellips) {
+ step=prev1-prev2;
+ } else {
+ step=0;
+ prev1=0;
+ } /* if */
+ for (i=litidx-fieldlit; idim.array.length; i++) {
+ prev1+=step;
+ litadd(prev1);
+ } /* for */
+ rtag=symfield->x.idxtag; /* set the expected tag to the index tag */
+ enumfield=enumfield->next;
+ } /* if */
+ if (!matchtag(rtag,ctag,TRUE))
+ error(213); /* tag mismatch */
+ } while (matchtoken(',')); /* do */
+ needtoken('}');
+ } else {
+ init(ident,&ctag,errorfound);
+ if (!matchtag(tag,ctag,TRUE))
+ error(213); /* tagname mismatch */
+ } /* if */
+ /* fill up the literal queue with a series */
if (ellips) {
- cell step=((litidx-curlit)==1) ? (cell)0 : prev1-prev2;
- if (size==0 || (litidx-curlit)==0)
- error(41); /* invalid ellipsis, array size unknown */
- else if ((litidx-curlit)==(int)size)
- error(18); /* initialisation data exceeds declared size */
- while ((litidx-curlit)<(int)size) {
- prev1+=step;
- litadd(prev1);
- } /* while */
- } /* if */
+ cell step=((litidx-curlit)==1) ? (cell)0 : prev1-prev2;
+ if (size==0 || (litidx-curlit)==0)
+ error(41); /* invalid ellipsis, array size unknown */
+ else if ((litidx-curlit)==(int)size)
+ error(18); /* initialisation data exceeds declared size */
+ while ((litidx-curlit)<(int)size) {
+ prev1+=step;
+ litadd(prev1);
+ } /* while */
+ } /* if */
if (fillzero && size>0) {
- while ((litidx-curlit)<(int)size)
- litadd(0);
- } /* if */
+ while ((litidx-curlit)<(int)size)
+ litadd(0);
+ } /* if */
if (size==0) {
- size=litidx-curlit; /* number of elements defined */
- } else if (litidx-curlit>(int)size) { /* e.g. "myvar[3]={1,2,3,4};" */
- error(18); /* initialisation data exceeds declared size */
- litidx=(int)size+curlit; /* avoid overflow in memory moves */
- } /* if */
+ size=litidx-curlit; /* number of elements defined */
+ } else if (litidx-curlit>(int)size) { /* e.g. "myvar[3]={1,2,3,4};" */
+ error(18); /* initialisation data exceeds declared size */
+ litidx=(int)size+curlit; /* avoid overflow in memory moves */
+ } /* if */
return size;
}
-/* init
+/* init
*
- * Evaluate one initializer.
+ * Evaluate one initializer.
*/
-static cell init(int ident,int *tag,int *errorfound)
+static cell init(int ident,int *tag,int *errorfound)
{
cell i = 0;
if (matchtoken(tSTRING)){
- /* lex() automatically stores strings in the literal table (and
- * increases "litidx") */
- if (ident==iVARIABLE) {
- error(6); /* must be assigned to an array */
- litidx=1; /* reset literal queue */
- } /* if */
- *tag=0;
- } else if (constexpr(&i,tag,NULL)){
- litadd(i); /* store expression result in literal table */
- } else {
- if (errorfound!=NULL)
- *errorfound=TRUE;
- } /* if */
+ /* lex() automatically stores strings in the literal table (and
+ * increases "litidx") */
+ if (ident==iVARIABLE) {
+ error(6); /* must be assigned to an array */
+ litidx=1; /* reset literal queue */
+ } /* if */
+ *tag=0;
+ } else if (constexpr(&i,tag,NULL)){
+ litadd(i); /* store expression result in literal table */
+ } else {
+ if (errorfound!=NULL)
+ *errorfound=TRUE;
+ } /* if */
return i;
}
-/* needsub
+/* needsub
*
- * Get required array size
+ * Get required array size
*/
-static cell needsub(int *tag,constvalue **enumroot)
+static cell needsub(int *tag,constvalue **enumroot)
{
cell val;
symbol *sym;
@@ -2378,34 +2378,34 @@ static cell needsub(int *tag,constvalue **enumroot)
assert(tag!=NULL);
*tag=0;
if (enumroot!=NULL)
- *enumroot=NULL; /* preset */
- if (matchtoken(']')) /* we have already seen "[" */
- return 0; /* zero size (like "char msg[]") */
+ *enumroot=NULL; /* preset */
+ if (matchtoken(']')) /* we have already seen "[" */
+ return 0; /* zero size (like "char msg[]") */
- constexpr(&val,tag,&sym); /* get value (must be constant expression) */
+ constexpr(&val,tag,&sym); /* get value (must be constant expression) */
if (val<0) {
- error(9); /* negative array size is invalid; assumed zero */
- val=0;
- } /* if */
+ error(9); /* negative array size is invalid; assumed zero */
+ val=0;
+ } /* if */
needtoken(']');
if (enumroot!=NULL) {
- /* get the field list for an enumeration */
- assert(*enumroot==NULL);/* should have been preset */
- assert(sym==NULL || sym->ident==iCONSTEXPR);
- if (sym!=NULL && (sym->usage & uENUMROOT)==uENUMROOT) {
- assert(sym->dim.enumlist!=NULL);
- *enumroot=sym->dim.enumlist;
- } /* if */
- } /* if */
+ /* get the field list for an enumeration */
+ assert(*enumroot==NULL);/* should have been preset */
+ assert(sym==NULL || sym->ident==iCONSTEXPR);
+ if (sym!=NULL && (sym->usage & uENUMROOT)==uENUMROOT) {
+ assert(sym->dim.enumlist!=NULL);
+ *enumroot=sym->dim.enumlist;
+ } /* if */
+ } /* if */
- return val; /* return array size */
+ return val; /* return array size */
}
-/* decl_const - declare a single constant
+/* decl_const - declare a single constant
*
*/
-static void decl_const(int vclass)
+static void decl_const(int vclass)
{
char constname[sNAMEMAX+1];
cell val;
@@ -2414,32 +2414,32 @@ static void decl_const(int vclass)
int symbolline;
symbol *sym;
- insert_docstring_separator(); /* see comment in newfunc() */
+ insert_docstring_separator(); /* see comment in newfunc() */
tag=pc_addtag(NULL);
- if (lex(&val,&str)!=tSYMBOL) /* read in (new) token */
- error(20,str); /* invalid symbol name */
- symbolline=fline; /* save line where symbol was found */
- strcpy(constname,str); /* save symbol name */
+ if (lex(&val,&str)!=tSYMBOL) /* read in (new) token */
+ error(20,str); /* invalid symbol name */
+ symbolline=fline; /* save line where symbol was found */
+ strcpy(constname,str); /* save symbol name */
needtoken('=');
constexpr(&val,&exprtag,NULL);/* get value */
needtoken(tTERM);
- /* add_constant() checks for duplicate definitions */
- if (!matchtag(tag,exprtag,FALSE)) {
- /* temporarily reset the line number to where the symbol was defined */
- int orgfline=fline;
- fline=symbolline;
- error(213); /* tagname mismatch */
- fline=orgfline;
- } /* if */
+ /* add_constant() checks for duplicate definitions */
+ if (!matchtag(tag,exprtag,FALSE)) {
+ /* temporarily reset the line number to where the symbol was defined */
+ int orgfline=fline;
+ fline=symbolline;
+ error(213); /* tagname mismatch */
+ fline=orgfline;
+ } /* if */
sym=add_constant(constname,val,vclass,tag);
if (sym!=NULL)
- sc_attachdocumentation(sym);/* attach any documenation to the function */
+ sc_attachdocumentation(sym);/* attach any documenation to the function */
}
-/* decl_enum - declare enumerated constants
+/* decl_enum - declare enumerated constants
*
*/
-static void decl_enum(int vclass)
+static void decl_enum(int vclass)
{
char enumname[sNAMEMAX+1],constname[sNAMEMAX+1];
cell val,value,size;
@@ -2449,118 +2449,118 @@ static void decl_enum(int vclass)
constvalue *enumroot;
symbol *enumsym;
- /* get an explicit tag, if any (we need to remember whether an explicit
- * tag was passed, even if that explicit tag was "_:", so we cannot call
+ /* get an explicit tag, if any (we need to remember whether an explicit
+ * tag was passed, even if that explicit tag was "_:", so we cannot call
* pc_addtag() here
*/
if (lex(&val,&str)==tLABEL) {
- tag=pc_addtag(str);
- explicittag=TRUE;
- } else {
- lexpush();
- tag=0;
- explicittag=FALSE;
- } /* if */
+ tag=pc_addtag(str);
+ explicittag=TRUE;
+ } else {
+ lexpush();
+ tag=0;
+ explicittag=FALSE;
+ } /* if */
- /* get optional enum name (also serves as a tag if no explicit tag was set) */
- if (lex(&val,&str)==tSYMBOL) { /* read in (new) token */
- strcpy(enumname,str); /* save enum name (last constant) */
- if (!explicittag)
- tag=pc_addtag(enumname);
- } else {
- lexpush(); /* analyze again */
- enumname[0]='\0';
- } /* if */
+ /* get optional enum name (also serves as a tag if no explicit tag was set) */
+ if (lex(&val,&str)==tSYMBOL) { /* read in (new) token */
+ strcpy(enumname,str); /* save enum name (last constant) */
+ if (!explicittag)
+ tag=pc_addtag(enumname);
+ } else {
+ lexpush(); /* analyze again */
+ enumname[0]='\0';
+ } /* if */
/* get increment and multiplier */
increment=1;
multiplier=1;
if (matchtoken('(')) {
- if (matchtoken(taADD)) {
- constexpr(&increment,NULL,NULL);
- } else if (matchtoken(taMULT)) {
- constexpr(&multiplier,NULL,NULL);
- } else if (matchtoken(taSHL)) {
- constexpr(&val,NULL,NULL);
- while (val-->0)
- multiplier*=2;
- } /* if */
- needtoken(')');
- } /* if */
+ if (matchtoken(taADD)) {
+ constexpr(&increment,NULL,NULL);
+ } else if (matchtoken(taMULT)) {
+ constexpr(&multiplier,NULL,NULL);
+ } else if (matchtoken(taSHL)) {
+ constexpr(&val,NULL,NULL);
+ while (val-->0)
+ multiplier*=2;
+ } /* if */
+ needtoken(')');
+ } /* if */
if (strlen(enumname)>0) {
- /* already create the root symbol, so the fields can have it as their "parent" */
- enumsym=add_constant(enumname,0,vclass,tag);
- if (enumsym!=NULL)
- enumsym->usage |= uENUMROOT;
- /* start a new list for the element names */
- if ((enumroot=(constvalue*)malloc(sizeof(constvalue)))==NULL)
- error(103); /* insufficient memory (fatal error) */
- memset(enumroot,0,sizeof(constvalue));
- } else {
- enumsym=NULL;
- enumroot=NULL;
- } /* if */
+ /* already create the root symbol, so the fields can have it as their "parent" */
+ enumsym=add_constant(enumname,0,vclass,tag);
+ if (enumsym!=NULL)
+ enumsym->usage |= uENUMROOT;
+ /* start a new list for the element names */
+ if ((enumroot=(constvalue*)malloc(sizeof(constvalue)))==NULL)
+ error(103); /* insufficient memory (fatal error) */
+ memset(enumroot,0,sizeof(constvalue));
+ } else {
+ enumsym=NULL;
+ enumroot=NULL;
+ } /* if */
needtoken('{');
- /* go through all constants */
- value=0; /* default starting value */
+ /* go through all constants */
+ value=0; /* default starting value */
do {
- int idxtag,fieldtag;
- symbol *sym;
- if (matchtoken('}')) { /* quick exit if '}' follows ',' */
- lexpush();
- break;
- } /* if */
- idxtag=pc_addtag(NULL); /* optional explicit item tag */
- tok=lex(&val,&str); /* read in (new) token */
- if (tok!=tSYMBOL)
- error(20,str); /* invalid symbol name */
- strcpy(constname,str); /* save symbol name */
- size=increment; /* default increment of 'val' */
- if (matchtoken('[')) {
- constexpr(&size,&fieldtag,NULL); /* get size */
- needtoken(']');
- } /* if */
- if (matchtoken('='))
- constexpr(&value,NULL,NULL); /* get value */
- /* add_constant() checks whether a variable (global or local) or
- * a constant with the same name already exists
- */
- sym=add_constant(constname,value,vclass,tag);
- if (sym==NULL)
- continue; /* error message already given */
- /* set the item tag and the item size, for use in indexing arrays */
- sym->x.idxtag=idxtag;
- sym->fieldtag=fieldtag;
- sym->dim.array.length=size;
- sym->dim.array.level=0;
- sym->parent=enumsym;
- /* add the constant to a separate list as well */
- if (enumroot!=NULL) {
- sym->usage |= uENUMFIELD;
- append_constval(enumroot,constname,value,0);
- } /* if */
- if (multiplier==1)
- value+=size;
- else
- value*=size*multiplier;
- } while (matchtoken(','));
- needtoken('}'); /* terminates the constant list */
- matchtoken(';'); /* eat an optional ; */
+ int idxtag,fieldtag;
+ symbol *sym;
+ if (matchtoken('}')) { /* quick exit if '}' follows ',' */
+ lexpush();
+ break;
+ } /* if */
+ idxtag=pc_addtag(NULL); /* optional explicit item tag */
+ tok=lex(&val,&str); /* read in (new) token */
+ if (tok!=tSYMBOL)
+ error(20,str); /* invalid symbol name */
+ strcpy(constname,str); /* save symbol name */
+ size=increment; /* default increment of 'val' */
+ if (matchtoken('[')) {
+ constexpr(&size,&fieldtag,NULL); /* get size */
+ needtoken(']');
+ } /* if */
+ if (matchtoken('='))
+ constexpr(&value,NULL,NULL); /* get value */
+ /* add_constant() checks whether a variable (global or local) or
+ * a constant with the same name already exists
+ */
+ sym=add_constant(constname,value,vclass,tag);
+ if (sym==NULL)
+ continue; /* error message already given */
+ /* set the item tag and the item size, for use in indexing arrays */
+ sym->x.idxtag=idxtag;
+ sym->fieldtag=fieldtag;
+ sym->dim.array.length=size;
+ sym->dim.array.level=0;
+ sym->parent=enumsym;
+ /* add the constant to a separate list as well */
+ if (enumroot!=NULL) {
+ sym->usage |= uENUMFIELD;
+ append_constval(enumroot,constname,value,0);
+ } /* if */
+ if (multiplier==1)
+ value+=size;
+ else
+ value*=size*multiplier;
+ } while (matchtoken(','));
+ needtoken('}'); /* terminates the constant list */
+ matchtoken(';'); /* eat an optional ; */
/* set the enum name to the "next" value (typically the last value plus one) */
if (enumsym!=NULL) {
- assert((enumsym->usage & uENUMROOT)!=0);
- enumsym->addr=value;
- /* assign the constant list */
- assert(enumroot!=NULL);
- enumsym->dim.enumlist=enumroot;
- sc_attachdocumentation(enumsym); /* attach any documenation to the enumeration */
- } /* if */
+ assert((enumsym->usage & uENUMROOT)!=0);
+ enumsym->addr=value;
+ /* assign the constant list */
+ assert(enumroot!=NULL);
+ enumsym->dim.enumlist=enumroot;
+ sc_attachdocumentation(enumsym); /* attach any documenation to the enumeration */
+ } /* if */
}
-static int getstates(const char *funcname)
+static int getstates(const char *funcname)
{
char fsaname[sNAMEMAX+1],statename[sNAMEMAX+1];
cell val;
@@ -2572,9 +2572,9 @@ static int getstates(const char *funcname)
int count,listsize,state_id;
if (!matchtoken('<'))
- return 0;
+ return 0;
if (matchtoken('>'))
- return -1; /* special construct: all other states (fall-back) */
+ return -1; /* special construct: all other states (fall-back) */
count=0;
listsize=0;
@@ -2582,150 +2582,150 @@ static int getstates(const char *funcname)
fsa=-1;
do {
- if (!(islabel=matchtoken(tLABEL)) && !needtoken(tSYMBOL))
- break;
- tokeninfo(&val,&str);
- assert(strlen(str)=0 && automaton->index!=fsa)
- error(83,funcname); /* multiple automatons for a single function */
- fsa=automaton->index;
- } /* if */
- state=state_add(statename,fsa);
- /* add this state to the state combination list (it will be attached to the
- * automaton later) */
- state_buildlist(&list,&listsize,&count,(int)state->value);
- } while (matchtoken(','));
+ if (!(islabel=matchtoken(tLABEL)) && !needtoken(tSYMBOL))
+ break;
+ tokeninfo(&val,&str);
+ assert(strlen(str)=0 && automaton->index!=fsa)
+ error(83,funcname); /* multiple automatons for a single function */
+ fsa=automaton->index;
+ } /* if */
+ state=state_add(statename,fsa);
+ /* add this state to the state combination list (it will be attached to the
+ * automaton later) */
+ state_buildlist(&list,&listsize,&count,(int)state->value);
+ } while (matchtoken(','));
needtoken('>');
if (count>0) {
- assert(automaton!=NULL);
- assert(fsa>=0);
- state_id=state_addlist(list,count,fsa);
- assert(state_id>0);
- } else {
- /* error is already given */
- state_id=0;
- } /* if */
+ assert(automaton!=NULL);
+ assert(fsa>=0);
+ state_id=state_addlist(list,count,fsa);
+ assert(state_id>0);
+ } else {
+ /* error is already given */
+ state_id=0;
+ } /* if */
if (list!=NULL)
- free(list);
+ free(list);
return state_id;
}
-static void attachstatelist(symbol *sym, int state_id)
+static void attachstatelist(symbol *sym, int state_id)
{
assert(sym!=NULL);
- if ((sym->usage & uDEFINE)!=0 && (sym->states==NULL || state_id==0))
- error(21,sym->name); /* function already defined, either without states or the current definition has no states */
+ if ((sym->usage & uDEFINE)!=0 && (sym->states==NULL || state_id==0))
+ error(21,sym->name); /* function already defined, either without states or the current definition has no states */
if (state_id!=0) {
- /* add the state list id */
- constvalue *stateptr;
- if (sym->states==NULL) {
- if ((sym->states=(constvalue*)malloc(sizeof(constvalue)))==NULL)
- error(103); /* insufficient memory (fatal error) */
- memset(sym->states,0,sizeof(constvalue));
- } /* if */
- /* see whether the id already exists (add new state only if it does not
- * yet exist
- */
- assert(sym->states!=NULL);
- for (stateptr=sym->states->next; stateptr!=NULL && stateptr->index!=state_id; stateptr=stateptr->next)
- /* nothing */;
- assert(state_id<=SHRT_MAX);
- if (stateptr==NULL)
- append_constval(sym->states,"",code_idx,(short)state_id);
- else if (stateptr->value==0)
- stateptr->value=code_idx;
- else
- error(84,sym->name);
- /* also check for another conflicting situation: a fallback function
- * without any states
- */
- if (state_id==-1 && sc_status!=statFIRST) {
- /* in the second round, all states should have been accumulated */
- assert(sym->states!=NULL);
- for (stateptr=sym->states->next; stateptr!=NULL && stateptr->index==-1; stateptr=stateptr->next)
- /* nothing */;
- if (stateptr==NULL)
- error(85,sym->name); /* no states are defined for this function */
- } /* if */
- } /* if */
+ /* add the state list id */
+ constvalue *stateptr;
+ if (sym->states==NULL) {
+ if ((sym->states=(constvalue*)malloc(sizeof(constvalue)))==NULL)
+ error(103); /* insufficient memory (fatal error) */
+ memset(sym->states,0,sizeof(constvalue));
+ } /* if */
+ /* see whether the id already exists (add new state only if it does not
+ * yet exist
+ */
+ assert(sym->states!=NULL);
+ for (stateptr=sym->states->next; stateptr!=NULL && stateptr->index!=state_id; stateptr=stateptr->next)
+ /* nothing */;
+ assert(state_id<=SHRT_MAX);
+ if (stateptr==NULL)
+ append_constval(sym->states,"",code_idx,(short)state_id);
+ else if (stateptr->value==0)
+ stateptr->value=code_idx;
+ else
+ error(84,sym->name);
+ /* also check for another conflicting situation: a fallback function
+ * without any states
+ */
+ if (state_id==-1 && sc_status!=statFIRST) {
+ /* in the second round, all states should have been accumulated */
+ assert(sym->states!=NULL);
+ for (stateptr=sym->states->next; stateptr!=NULL && stateptr->index==-1; stateptr=stateptr->next)
+ /* nothing */;
+ if (stateptr==NULL)
+ error(85,sym->name); /* no states are defined for this function */
+ } /* if */
+ } /* if */
}
/*
- * Finds a function in the global symbol table or creates a new entry.
- * It does some basic processing and error checking.
+ * Finds a function in the global symbol table or creates a new entry.
+ * It does some basic processing and error checking.
*/
-SC_FUNC symbol *fetchfunc(char *name,int tag)
+SC_FUNC symbol *fetchfunc(char *name,int tag)
{
symbol *sym;
- if ((sym=findglb(name))!=0) { /* already in symbol table? */
- if (sym->ident!=iFUNCTN) {
- error(21,name); /* yes, but not as a function */
- return NULL; /* make sure the old symbol is not damaged */
- } else if ((sym->usage & uNATIVE)!=0) {
- error(21,name); /* yes, and it is a native */
- } /* if */
- assert(sym->vclass==sGLOBAL);
- if ((sym->usage & uPROTOTYPED)!=0 && sym->tag!=tag)
- error(25); /* mismatch from earlier prototype */
- if ((sym->usage & uDEFINE)==0) {
- /* as long as the function stays undefined, update the address and the tag */
- if (sym->states==NULL)
- sym->addr=code_idx;
- sym->tag=tag;
- } /* if */
- } else {
- /* don't set the "uDEFINE" flag; it may be a prototype */
- sym=addsym(name,code_idx,iFUNCTN,sGLOBAL,tag,0);
- assert(sym!=NULL); /* fatal error 103 must be given on error */
- /* assume no arguments */
- sym->dim.arglist=(arginfo*)malloc(1*sizeof(arginfo));
- sym->dim.arglist[0].ident=0;
- /* set library ID to NULL (only for native functions) */
- sym->x.lib=NULL;
- /* set the required stack size to zero (only for non-native functions) */
- sym->x.stacksize=1; /* 1 for PROC opcode */
- } /* if */
+ if ((sym=findglb(name))!=0) { /* already in symbol table? */
+ if (sym->ident!=iFUNCTN) {
+ error(21,name); /* yes, but not as a function */
+ return NULL; /* make sure the old symbol is not damaged */
+ } else if ((sym->usage & uNATIVE)!=0) {
+ error(21,name); /* yes, and it is a native */
+ } /* if */
+ assert(sym->vclass==sGLOBAL);
+ if ((sym->usage & uPROTOTYPED)!=0 && sym->tag!=tag)
+ error(25); /* mismatch from earlier prototype */
+ if ((sym->usage & uDEFINE)==0) {
+ /* as long as the function stays undefined, update the address and the tag */
+ if (sym->states==NULL)
+ sym->addr=code_idx;
+ sym->tag=tag;
+ } /* if */
+ } else {
+ /* don't set the "uDEFINE" flag; it may be a prototype */
+ sym=addsym(name,code_idx,iFUNCTN,sGLOBAL,tag,0);
+ assert(sym!=NULL); /* fatal error 103 must be given on error */
+ /* assume no arguments */
+ sym->dim.arglist=(arginfo*)malloc(1*sizeof(arginfo));
+ sym->dim.arglist[0].ident=0;
+ /* set library ID to NULL (only for native functions) */
+ sym->x.lib=NULL;
+ /* set the required stack size to zero (only for non-native functions) */
+ sym->x.stacksize=1; /* 1 for PROC opcode */
+ } /* if */
return sym;
}
-/* This routine adds symbolic information for each argument.
+/* This routine adds symbolic information for each argument.
*/
-static void define_args(void)
+static void define_args(void)
{
symbol *sym;
- /* At this point, no local variables have been declared. All
- * local symbols are function arguments.
+ /* At this point, no local variables have been declared. All
+ * local symbols are function arguments.
*/
sym=loctab.next;
- while (sym!=NULL) {
- assert(sym->ident!=iLABEL);
- assert(sym->vclass==sLOCAL);
- markexpr(sLDECL,sym->name,sym->addr); /* mark for better optimization */
- sym=sym->next;
- } /* while */
+ while (sym!=NULL) {
+ assert(sym->ident!=iLABEL);
+ assert(sym->vclass==sLOCAL);
+ markexpr(sLDECL,sym->name,sym->addr); /* mark for better optimization */
+ sym=sym->next;
+ } /* while */
}
static int operatorname(char *name)
@@ -2736,7 +2736,7 @@ static int operatorname(char *name)
assert(name!=NULL);
- /* check the operator */
+ /* check the operator */
opertok=lex(&val,&str);
switch (opertok) {
case '+':
@@ -2749,32 +2749,32 @@ static int operatorname(char *name)
case '!':
case '~':
case '=':
- name[0]=(char)opertok;
- name[1]='\0';
- break;
+ name[0]=(char)opertok;
+ name[1]='\0';
+ break;
case tINC:
- strcpy(name,"++");
- break;
+ strcpy(name,"++");
+ break;
case tDEC:
- strcpy(name,"--");
- break;
+ strcpy(name,"--");
+ break;
case tlEQ:
- strcpy(name,"==");
- break;
+ strcpy(name,"==");
+ break;
case tlNE:
- strcpy(name,"!=");
- break;
+ strcpy(name,"!=");
+ break;
case tlLE:
- strcpy(name,"<=");
- break;
+ strcpy(name,"<=");
+ break;
case tlGE:
- strcpy(name,">=");
- break;
+ strcpy(name,">=");
+ break;
default:
- name[0]='\0';
- error(7); /* operator cannot be redefined (or bad operator name) */
- return 0;
- } /* switch */
+ name[0]='\0';
+ error(7); /* operator cannot be redefined (or bad operator name) */
+ return 0;
+ } /* switch */
return opertok;
}
@@ -2788,83 +2788,83 @@ static int operatoradjust(int opertok,symbol *sym,char *opername,int resulttag)
symbol *oldsym;
if (opertok==0)
- return TRUE;
+ return TRUE;
assert(sym!=NULL && sym->ident==iFUNCTN && sym->dim.arglist!=NULL);
/* count arguments and save (first two) tags */
- while (arg=&sym->dim.arglist[count], arg->ident!=0) {
- if (count<2) {
- if (arg->numtags>1)
- error(65,count+1); /* function argument may only have a single tag */
- else if (arg->numtags==1)
- tags[count]=arg->tags[0];
- } /* if */
- if (opertok=='~' && count==0) {
- if (arg->ident!=iREFARRAY)
- error(73,arg->name);/* must be an array argument */
- } else {
- if (arg->ident!=iVARIABLE)
- error(66,arg->name);/* must be non-reference argument */
- } /* if */
- if (arg->hasdefault)
- error(59,arg->name); /* arguments of an operator may not have a default value */
- count++;
- } /* while */
+ while (arg=&sym->dim.arglist[count], arg->ident!=0) {
+ if (count<2) {
+ if (arg->numtags>1)
+ error(65,count+1); /* function argument may only have a single tag */
+ else if (arg->numtags==1)
+ tags[count]=arg->tags[0];
+ } /* if */
+ if (opertok=='~' && count==0) {
+ if (arg->ident!=iREFARRAY)
+ error(73,arg->name);/* must be an array argument */
+ } else {
+ if (arg->ident!=iVARIABLE)
+ error(66,arg->name);/* must be non-reference argument */
+ } /* if */
+ if (arg->hasdefault)
+ error(59,arg->name); /* arguments of an operator may not have a default value */
+ count++;
+ } /* while */
- /* for '!', '++' and '--', count must be 1
- * for '-', count may be 1 or 2
- * for '=', count must be 1, and the resulttag is also important
- * for all other (binary) operators and the special '~' operator, count must be 2
+ /* for '!', '++' and '--', count must be 1
+ * for '-', count may be 1 or 2
+ * for '=', count must be 1, and the resulttag is also important
+ * for all other (binary) operators and the special '~' operator, count must be 2
*/
switch (opertok) {
case '!':
case '=':
case tINC:
case tDEC:
- if (count!=1)
- error(62); /* number or placement of the operands does not fit the operator */
- break;
+ if (count!=1)
+ error(62); /* number or placement of the operands does not fit the operator */
+ break;
case '-':
- if (count!=1 && count!=2)
- error(62); /* number or placement of the operands does not fit the operator */
- break;
+ if (count!=1 && count!=2)
+ error(62); /* number or placement of the operands does not fit the operator */
+ break;
default:
- if (count!=2)
- error(62); /* number or placement of the operands does not fit the operator */
- } /* switch */
+ if (count!=2)
+ error(62); /* number or placement of the operands does not fit the operator */
+ } /* switch */
- if (tags[0]==0 && (opertok!='=' && tags[1]==0 || opertok=='=' && resulttag==0))
- error(64); /* cannot change predefined operators */
+ if (tags[0]==0 && (opertok!='=' && tags[1]==0 || opertok=='=' && resulttag==0))
+ error(64); /* cannot change predefined operators */
- /* change the operator name */
+ /* change the operator name */
assert(strlen(opername)>0);
operator_symname(tmpname,opername,tags[0],tags[1],count,resulttag);
if ((oldsym=findglb(tmpname))!=NULL) {
- int i;
- if ((oldsym->usage & uDEFINE)!=0) {
- char errname[2*sNAMEMAX+16];
- funcdisplayname(errname,tmpname);
- error(21,errname); /* symbol already defined */
- } /* if */
- sym->usage|=oldsym->usage; /* copy flags from the previous definition */
- for (i=0; inumrefers; i++)
- if (oldsym->refer[i]!=NULL)
- refer_symbol(sym,oldsym->refer[i]);
- delete_symbol(&glbtab,oldsym);
- } /* if */
+ int i;
+ if ((oldsym->usage & uDEFINE)!=0) {
+ char errname[2*sNAMEMAX+16];
+ funcdisplayname(errname,tmpname);
+ error(21,errname); /* symbol already defined */
+ } /* if */
+ sym->usage|=oldsym->usage; /* copy flags from the previous definition */
+ for (i=0; inumrefers; i++)
+ if (oldsym->refer[i]!=NULL)
+ refer_symbol(sym,oldsym->refer[i]);
+ delete_symbol(&glbtab,oldsym);
+ } /* if */
strcpy(sym->name,tmpname);
sym->hash=namehash(sym->name);/* calculate new hash */
/* operators should return a value, except the '~' operator */
if (opertok!='~')
- sym->usage |= uRETVALUE;
+ sym->usage |= uRETVALUE;
return TRUE;
}
-static int check_operatortag(int opertok,int resulttag,char *opername)
+static int check_operatortag(int opertok,int resulttag,char *opername)
{
- assert(opername!=NULL && strlen(opername)>0);
+ assert(opername!=NULL && strlen(opername)>0);
switch (opertok) {
case '!':
case '<':
@@ -2873,65 +2873,65 @@ static int check_operatortag(int opertok,int resulttag,char *opername)
case tlNE:
case tlLE:
case tlGE:
- if (resulttag!=pc_addtag("bool")) {
- error(63,opername,"bool:"); /* operator X requires a "bool:" result tag */
- return FALSE;
- } /* if */
- break;
+ if (resulttag!=pc_addtag("bool")) {
+ error(63,opername,"bool:"); /* operator X requires a "bool:" result tag */
+ return FALSE;
+ } /* if */
+ break;
case '~':
- if (resulttag!=0) {
- error(63,opername,"_:"); /* operator "~" requires a "_:" result tag */
- return FALSE;
- } /* if */
- break;
- } /* switch */
+ if (resulttag!=0) {
+ error(63,opername,"_:"); /* operator "~" requires a "_:" result tag */
+ return FALSE;
+ } /* if */
+ break;
+ } /* switch */
return TRUE;
}
-static char *tag2str(char *dest,int tag)
+static char *tag2str(char *dest,int tag)
{
tag &= TAGMASK;
assert(tag>=0);
sprintf(dest,"0%x",tag);
- return isdigit(dest[1]) ? &dest[1] : dest;
+ return isdigit(dest[1]) ? &dest[1] : dest;
}
-SC_FUNC char *operator_symname(char *symname,char *opername,int tag1,int tag2,int numtags,int resulttag)
+SC_FUNC char *operator_symname(char *symname,char *opername,int tag1,int tag2,int numtags,int resulttag)
{
- char tagstr1[10], tagstr2[10];
+ char tagstr1[10], tagstr2[10];
int opertok;
- assert(numtags>=1 && numtags<=2);
+ assert(numtags>=1 && numtags<=2);
opertok= (opername[1]=='\0') ? opername[0] : 0;
if (opertok=='=')
- sprintf(symname,"%s%s%s",tag2str(tagstr1,resulttag),opername,tag2str(tagstr2,tag1));
+ sprintf(symname,"%s%s%s",tag2str(tagstr1,resulttag),opername,tag2str(tagstr2,tag1));
else if (numtags==1 || opertok=='~')
- sprintf(symname,"%s%s",opername,tag2str(tagstr1,tag1));
+ sprintf(symname,"%s%s",opername,tag2str(tagstr1,tag1));
else
- sprintf(symname,"%s%s%s",tag2str(tagstr1,tag1),opername,tag2str(tagstr2,tag2));
+ sprintf(symname,"%s%s%s",tag2str(tagstr1,tag1),opername,tag2str(tagstr2,tag2));
return symname;
}
-static int parse_funcname(char *fname,int *tag1,int *tag2,char *opname)
+static int parse_funcname(char *fname,int *tag1,int *tag2,char *opname)
{
char *ptr,*name;
int unary;
- /* tags are only positive, so if the function name starts with a '-',
- * the operator is an unary '-' or '--' operator.
+ /* tags are only positive, so if the function name starts with a '-',
+ * the operator is an unary '-' or '--' operator.
*/
if (*fname=='-') {
- *tag1=0;
- unary=TRUE;
- ptr=fname;
- } else {
- *tag1=(int)strtol(fname,&ptr,16);
- unary= ptr==fname; /* unary operator if it doesn't start with a tag name */
- } /* if */
- assert(!unary || *tag1==0);
+ *tag1=0;
+ unary=TRUE;
+ ptr=fname;
+ } else {
+ *tag1=(int)strtol(fname,&ptr,16);
+ unary= ptr==fname; /* unary operator if it doesn't start with a tag name */
+ } /* if */
+ assert(!unary || *tag1==0);
assert(*ptr!='\0');
- for (name=opname; !isdigit(*ptr); )
- *name++ = *ptr++;
+ for (name=opname; !isdigit(*ptr); )
+ *name++ = *ptr++;
*name='\0';
*tag2=(int)strtol(ptr,NULL,16);
return unary;
@@ -2940,43 +2940,43 @@ static int parse_funcname(char *fname,int *tag1,int *tag2,char *opname)
static constvalue *find_tag_byval(int tag)
{
constvalue *tagsym;
- tagsym=find_constval_byval(&tagname_tab,tag & ~PUBLICTAG);
+ tagsym=find_constval_byval(&tagname_tab,tag & ~PUBLICTAG);
if (tagsym==NULL)
- tagsym=find_constval_byval(&tagname_tab,tag | PUBLICTAG);
+ tagsym=find_constval_byval(&tagname_tab,tag | PUBLICTAG);
return tagsym;
}
-SC_FUNC char *funcdisplayname(char *dest,char *funcname)
+SC_FUNC char *funcdisplayname(char *dest,char *funcname)
{
int tags[2];
char opname[10];
constvalue *tagsym[2];
int unary;
- if (isalpha(*funcname) || *funcname=='_' || *funcname==PUBLIC_CHAR || *funcname=='\0') {
- if (dest!=funcname)
- strcpy(dest,funcname);
- return dest;
- } /* if */
+ if (isalpha(*funcname) || *funcname=='_' || *funcname==PUBLIC_CHAR || *funcname=='\0') {
+ if (dest!=funcname)
+ strcpy(dest,funcname);
+ return dest;
+ } /* if */
unary=parse_funcname(funcname,&tags[0],&tags[1],opname);
tagsym[1]=find_tag_byval(tags[1]);
assert(tagsym[1]!=NULL);
if (unary) {
- sprintf(dest,"operator%s(%s:)",opname,tagsym[1]->name);
- } else {
- tagsym[0]=find_tag_byval(tags[0]);
- assert(tagsym[0]!=NULL);
- /* special case: the assignment operator has the return value as the 2nd tag */
- if (opname[0]=='=' && opname[1]=='\0')
- sprintf(dest,"%s:operator%s(%s:)",tagsym[0]->name,opname,tagsym[1]->name);
- else
- sprintf(dest,"operator%s(%s:,%s:)",opname,tagsym[0]->name,tagsym[1]->name);
- } /* if */
+ sprintf(dest,"operator%s(%s:)",opname,tagsym[1]->name);
+ } else {
+ tagsym[0]=find_tag_byval(tags[0]);
+ assert(tagsym[0]!=NULL);
+ /* special case: the assignment operator has the return value as the 2nd tag */
+ if (opname[0]=='=' && opname[1]=='\0')
+ sprintf(dest,"%s:operator%s(%s:)",tagsym[0]->name,opname,tagsym[1]->name);
+ else
+ sprintf(dest,"operator%s(%s:,%s:)",opname,tagsym[0]->name,tagsym[1]->name);
+ } /* if */
return dest;
}
-static void funcstub(int native)
+static void funcstub(int native)
{
int tok,tag;
char *str;
@@ -2990,125 +2990,125 @@ static void funcstub(int native)
opertok=0;
lastst=0;
- litidx=0; /* clear the literal pool */
- assert(loctab.next==NULL); /* local symbol table should be empty */
+ litidx=0; /* clear the literal pool */
+ assert(loctab.next==NULL); /* local symbol table should be empty */
tag=pc_addtag(NULL); /* get the tag of the return value */
numdim=0;
- while (matchtoken('[')) {
- /* the function returns an array, get this tag for the index and the array
- * dimensions
- */
- if (numdim == sDIMEN_MAX) {
- error(53); /* exceeding maximum number of dimensions */
- return;
- } /* if */
- size=needsub(&idxtag[numdim],NULL); /* get size; size==0 for "var[]" */
- if (size==0)
- error(9); /* invalid array size */
- #if INT_MAX < LONG_MAX
- if (size > INT_MAX)
- error(105); /* overflow, exceeding capacity */
- #endif
- dim[numdim++]=(int)size;
- } /* while */
+ while (matchtoken('[')) {
+ /* the function returns an array, get this tag for the index and the array
+ * dimensions
+ */
+ if (numdim == sDIMEN_MAX) {
+ error(53); /* exceeding maximum number of dimensions */
+ return;
+ } /* if */
+ size=needsub(&idxtag[numdim],NULL); /* get size; size==0 for "var[]" */
+ if (size==0)
+ error(9); /* invalid array size */
+ #if INT_MAX < LONG_MAX
+ if (size > INT_MAX)
+ error(105); /* overflow, exceeding capacity */
+ #endif
+ dim[numdim++]=(int)size;
+ } /* while */
tok=lex(&val,&str);
if (native) {
- if (tok==tPUBLIC || tok==tSTOCK || tok==tSTATIC || tok==tSYMBOL && *str==PUBLIC_CHAR)
- error(42); /* invalid combination of class specifiers */
- } else {
- if (tok==tPUBLIC || tok==tSTOCK || tok==tSTATIC)
- tok=lex(&val,&str);
- } /* if */
+ if (tok==tPUBLIC || tok==tSTOCK || tok==tSTATIC || tok==tSYMBOL && *str==PUBLIC_CHAR)
+ error(42); /* invalid combination of class specifiers */
+ } else {
+ if (tok==tPUBLIC || tok==tSTOCK || tok==tSTATIC)
+ tok=lex(&val,&str);
+ } /* if */
if (tok==tOPERATOR) {
- opertok=operatorname(symbolname);
- if (opertok==0)
- return; /* error message already given */
- check_operatortag(opertok,tag,symbolname);
- } else {
- if (tok!=tSYMBOL && freading) {
- error(10); /* illegal function or declaration */
- return;
- } /* if */
- strcpy(symbolname,str);
- } /* if */
- needtoken('('); /* only functions may be native/forward */
+ opertok=operatorname(symbolname);
+ if (opertok==0)
+ return; /* error message already given */
+ check_operatortag(opertok,tag,symbolname);
+ } else {
+ if (tok!=tSYMBOL && freading) {
+ error(10); /* illegal function or declaration */
+ return;
+ } /* if */
+ strcpy(symbolname,str);
+ } /* if */
+ needtoken('('); /* only functions may be native/forward */
- sym=fetchfunc(symbolname,tag);/* get a pointer to the function entry */
+ sym=fetchfunc(symbolname,tag);/* get a pointer to the function entry */
if (sym==NULL)
- return;
+ return;
if (native) {
- sym->usage=(char)(uNATIVE | uRETVALUE | uDEFINE | (sym->usage & uPROTOTYPED));
- sym->x.lib=curlibrary;
- } /* if */
+ sym->usage=(char)(uNATIVE | uRETVALUE | uDEFINE | (sym->usage & uPROTOTYPED));
+ sym->x.lib=curlibrary;
+ } /* if */
declargs(sym);
- /* "declargs()" found the ")" */
- sc_attachdocumentation(sym); /* attach any documenation to the function */
+ /* "declargs()" found the ")" */
+ sc_attachdocumentation(sym); /* attach any documenation to the function */
if (!operatoradjust(opertok,sym,symbolname,tag))
- sym->usage &= ~uDEFINE;
+ sym->usage &= ~uDEFINE;
- if (getstates(symbolname)!=0) {
- if (native || opertok!=0)
- error(82); /* native functions and operators may not have states */
- else
- error(231); /* ignoring state specifications on forward declarations */
- } /* if */
+ if (getstates(symbolname)!=0) {
+ if (native || opertok!=0)
+ error(82); /* native functions and operators may not have states */
+ else
+ error(231); /* ignoring state specifications on forward declarations */
+ } /* if */
- /* for a native operator, also need to specify an "exported" function name;
- * for a native function, this is optional
+ /* for a native operator, also need to specify an "exported" function name;
+ * for a native function, this is optional
*/
if (native) {
- if (opertok!=0) {
- needtoken('=');
- lexpush(); /* push back, for matchtoken() to retrieve again */
- } /* if */
- if (matchtoken('=')) {
- /* allow number or symbol */
- if (matchtoken(tSYMBOL)) {
- tokeninfo(&val,&str);
- insert_alias(sym->name,str);
- } else {
- constexpr(&val,NULL,NULL);
- sym->addr=val;
- /* At the moment, I have assumed that this syntax is only valid if
- * val < 0. To properly mix "normal" native functions and indexed
- * native functions, one should use negative indices anyway.
- * Special code for a negative index in sym->addr exists in SC4.C
- * (ffcall()) and in SC6.C (the loops for counting the number of native
- * variables and for writing them).
- */
- } /* if */
- } /* if */
- } /* if */
+ if (opertok!=0) {
+ needtoken('=');
+ lexpush(); /* push back, for matchtoken() to retrieve again */
+ } /* if */
+ if (matchtoken('=')) {
+ /* allow number or symbol */
+ if (matchtoken(tSYMBOL)) {
+ tokeninfo(&val,&str);
+ insert_alias(sym->name,str);
+ } else {
+ constexpr(&val,NULL,NULL);
+ sym->addr=val;
+ /* At the moment, I have assumed that this syntax is only valid if
+ * val < 0. To properly mix "normal" native functions and indexed
+ * native functions, one should use negative indices anyway.
+ * Special code for a negative index in sym->addr exists in SC4.C
+ * (ffcall()) and in SC6.C (the loops for counting the number of native
+ * variables and for writing them).
+ */
+ } /* if */
+ } /* if */
+ } /* if */
needtoken(tTERM);
- /* attach the array to the function symbol */
- if (numdim>0) {
- assert(sym!=NULL);
- sub=addvariable(symbolname,0,iARRAY,sGLOBAL,tag,dim,numdim,idxtag);
- sub->parent=sym;
- } /* if */
+ /* attach the array to the function symbol */
+ if (numdim>0) {
+ assert(sym!=NULL);
+ sub=addvariable(symbolname,0,iARRAY,sGLOBAL,tag,dim,numdim,idxtag);
+ sub->parent=sym;
+ } /* if */
- litidx=0; /* clear the literal pool */
+ litidx=0; /* clear the literal pool */
delete_symbols(&loctab,0,TRUE,TRUE);/* clear local variables queue */
}
-/* newfunc - begin a function
+/* newfunc - begin a function
*
- * This routine is called from "parse" and tries to make a function
- * out of the following text
+ * This routine is called from "parse" and tries to make a function
+ * out of the following text
*
- * Global references: funcstatus,lastst,litidx
- * rettype (altered)
- * curfunc (altered)
- * declared (altered)
- * glb_declared (altered)
- * sc_alignnext (altered)
+ * Global references: funcstatus,lastst,litidx
+ * rettype (altered)
+ * curfunc (altered)
+ * declared (altered)
+ * glb_declared (altered)
+ * sc_alignnext (altered)
*/
-static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stock)
+static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stock)
{
symbol *sym;
int argcnt,tok,tag,funcline;
@@ -3116,183 +3116,183 @@ static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stoc
char symbolname[sNAMEMAX+1];
char *str;
cell val,cidx,glbdecl;
- short filenum;
+ short filenum;
int state_id;
- assert(litidx==0); /* literal queue should be empty */
- litidx=0; /* clear the literal pool (should already be empty) */
+ assert(litidx==0); /* literal queue should be empty */
+ litidx=0; /* clear the literal pool (should already be empty) */
opertok=0;
- lastst=0; /* no statement yet */
- cidx=0; /* just to avoid compiler warnings */
+ lastst=0; /* no statement yet */
+ cidx=0; /* just to avoid compiler warnings */
glbdecl=0;
- assert(loctab.next==NULL); /* local symbol table should be empty */
- filenum=fcurrent; /* save file number at the start of the declaration */
+ assert(loctab.next==NULL); /* local symbol table should be empty */
+ filenum=fcurrent; /* save file number at the start of the declaration */
if (firstname!=NULL) {
- assert(strlen(firstname)<=sNAMEMAX);
- strcpy(symbolname,firstname); /* save symbol name */
- tag=firsttag;
- } else {
- tag= (firsttag>=0) ? firsttag : pc_addtag(NULL);
- tok=lex(&val,&str);
- assert(!fpublic);
- if (tok==tNATIVE || tok==tPUBLIC && stock)
- error(42); /* invalid combination of class specifiers */
- if (tok==tOPERATOR) {
- opertok=operatorname(symbolname);
- if (opertok==0)
- return TRUE; /* error message already given */
- check_operatortag(opertok,tag,symbolname);
- } else {
- if (tok!=tSYMBOL && freading) {
- error(20,str); /* invalid symbol name */
- return FALSE;
- } /* if */
- assert(strlen(str)<=sNAMEMAX);
- strcpy(symbolname,str);
- } /* if */
- } /* if */
- /* check whether this is a function or a variable declaration */
+ assert(strlen(firstname)<=sNAMEMAX);
+ strcpy(symbolname,firstname); /* save symbol name */
+ tag=firsttag;
+ } else {
+ tag= (firsttag>=0) ? firsttag : pc_addtag(NULL);
+ tok=lex(&val,&str);
+ assert(!fpublic);
+ if (tok==tNATIVE || tok==tPUBLIC && stock)
+ error(42); /* invalid combination of class specifiers */
+ if (tok==tOPERATOR) {
+ opertok=operatorname(symbolname);
+ if (opertok==0)
+ return TRUE; /* error message already given */
+ check_operatortag(opertok,tag,symbolname);
+ } else {
+ if (tok!=tSYMBOL && freading) {
+ error(20,str); /* invalid symbol name */
+ return FALSE;
+ } /* if */
+ assert(strlen(str)<=sNAMEMAX);
+ strcpy(symbolname,str);
+ } /* if */
+ } /* if */
+ /* check whether this is a function or a variable declaration */
if (!matchtoken('('))
- return FALSE;
- /* so it is a function, proceed */
- funcline=fline; /* save line at which the function is defined */
+ return FALSE;
+ /* so it is a function, proceed */
+ funcline=fline; /* save line at which the function is defined */
if (symbolname[0]==PUBLIC_CHAR) {
- fpublic=TRUE; /* implicitly public function */
- if (stock)
- error(42); /* invalid combination of class specifiers */
- } /* if */
- sym=fetchfunc(symbolname,tag);/* get a pointer to the function entry */
- if (sym==NULL || (sym->usage & uNATIVE)!=0)
- return TRUE; /* it was recognized as a function declaration, but not as a valid one */
+ fpublic=TRUE; /* implicitly public function */
+ if (stock)
+ error(42); /* invalid combination of class specifiers */
+ } /* if */
+ sym=fetchfunc(symbolname,tag);/* get a pointer to the function entry */
+ if (sym==NULL || (sym->usage & uNATIVE)!=0)
+ return TRUE; /* it was recognized as a function declaration, but not as a valid one */
if (fpublic)
- sym->usage|=uPUBLIC;
+ sym->usage|=uPUBLIC;
if (fstatic)
- sym->fnumber=filenum;
- /* if the function was used before being declared, and it has a tag for the
- * result, add a third pass (as second "skimming" parse) because the function
- * result may have been used with user-defined operators, which have now
- * been incorrectly flagged (as the return tag was unknown at the time of
+ sym->fnumber=filenum;
+ /* if the function was used before being declared, and it has a tag for the
+ * result, add a third pass (as second "skimming" parse) because the function
+ * result may have been used with user-defined operators, which have now
+ * been incorrectly flagged (as the return tag was unknown at the time of
* the call)
*/
- if ((sym->usage & (uPROTOTYPED | uREAD))==uREAD && sym->tag!=0) {
- int curstatus=sc_status;
- sc_status=statWRITE; /* temporarily set status to WRITE, so the warning isn't blocked */
- //error(208); //this is silly, it should be caught the first pass
- sc_status=curstatus;
- sc_reparse=TRUE; /* must add another pass to "initial scan" phase */
- } /* if */
+ if ((sym->usage & (uPROTOTYPED | uREAD))==uREAD && sym->tag!=0) {
+ int curstatus=sc_status;
+ sc_status=statWRITE; /* temporarily set status to WRITE, so the warning isn't blocked */
+ //error(208); //this is silly, it should be caught the first pass
+ sc_status=curstatus;
+ sc_reparse=TRUE; /* must add another pass to "initial scan" phase */
+ } /* if */
/* declare all arguments */
argcnt=declargs(sym);
opererror=!operatoradjust(opertok,sym,symbolname,tag);
if (strcmp(symbolname,uMAINFUNC)==0 || strcmp(symbolname,uENTRYFUNC)==0) {
- if (argcnt>0)
- error(5); /* "main()" and "entry()" functions may not have any arguments */
- sym->usage|=uREAD; /* "main()" is the program's entry point: always used */
- } /* if */
+ if (argcnt>0)
+ error(5); /* "main()" and "entry()" functions may not have any arguments */
+ sym->usage|=uREAD; /* "main()" is the program's entry point: always used */
+ } /* if */
state_id=getstates(symbolname);
- if (opertok!=0 && state_id>0)
- error(82); /* operators may not have states */
+ if (opertok!=0 && state_id>0)
+ error(82); /* operators may not have states */
attachstatelist(sym,state_id);
- /* "declargs()" found the ")"; if a ";" appears after this, it was a
+ /* "declargs()" found the ")"; if a ";" appears after this, it was a
* prototype */
if (matchtoken(';')) {
- if (!sc_needsemicolon)
- error(218); /* old style prototypes used with optional semicolumns */
- delete_symbols(&loctab,0,TRUE,TRUE); /* prototype is done; forget everything */
- return TRUE;
- } /* if */
- /* so it is not a prototype, proceed */
- /* if this is a function that is not referred to (this can only be detected
- * in the second stage), shut code generation off */
- if (sc_status==statWRITE && (sym->usage & uREAD)==0) {
- sc_status=statSKIP;
- cidx=code_idx;
- glbdecl=glb_declared;
- } /* if */
+ if (!sc_needsemicolon)
+ error(218); /* old style prototypes used with optional semicolumns */
+ delete_symbols(&loctab,0,TRUE,TRUE); /* prototype is done; forget everything */
+ return TRUE;
+ } /* if */
+ /* so it is not a prototype, proceed */
+ /* if this is a function that is not referred to (this can only be detected
+ * in the second stage), shut code generation off */
+ if (sc_status==statWRITE && (sym->usage & uREAD)==0) {
+ sc_status=statSKIP;
+ cidx=code_idx;
+ glbdecl=glb_declared;
+ } /* if */
begcseg();
- sym->usage|=uDEFINE; /* set the definition flag */
+ sym->usage|=uDEFINE; /* set the definition flag */
if (fpublic)
- sym->usage|=uREAD; /* public functions are always "used" */
+ sym->usage|=uREAD; /* public functions are always "used" */
if (stock)
- sym->usage|=uSTOCK;
- if (opertok!=0 && opererror)
- sym->usage &= ~uDEFINE;
- /* if the function has states, dump the label to the start of the function */
+ sym->usage|=uSTOCK;
+ if (opertok!=0 && opererror)
+ sym->usage &= ~uDEFINE;
+ /* if the function has states, dump the label to the start of the function */
if (state_id!=0) {
- constvalue *ptr=sym->states->next;
- while (ptr!=NULL) {
- assert(sc_status!=statWRITE || strlen(ptr->name)>0);
- if (ptr->index==state_id) {
- setlabel((int)strtol(ptr->name,NULL,16));
- break;
- } /* if */
- ptr=ptr->next;
- } /* while */
- } /* if */
- startfunc(sym->name); /* creates stack frame */
+ constvalue *ptr=sym->states->next;
+ while (ptr!=NULL) {
+ assert(sc_status!=statWRITE || strlen(ptr->name)>0);
+ if (ptr->index==state_id) {
+ setlabel((int)strtol(ptr->name,NULL,16));
+ break;
+ } /* if */
+ ptr=ptr->next;
+ } /* while */
+ } /* if */
+ startfunc(sym->name); /* creates stack frame */
insert_dbgline(funcline);
setline(FALSE);
- if (sc_alignnext) {
- alignframe(sc_dataalign);
- sc_alignnext=FALSE;
- } /* if */
- declared=0; /* number of local cells */
- rettype=(sym->usage & uRETVALUE); /* set "return type" variable */
+ if (sc_alignnext) {
+ alignframe(sc_dataalign);
+ sc_alignnext=FALSE;
+ } /* if */
+ declared=0; /* number of local cells */
+ rettype=(sym->usage & uRETVALUE); /* set "return type" variable */
curfunc=sym;
- define_args(); /* add the symbolic info for the function arguments */
+ define_args(); /* add the symbolic info for the function arguments */
#if !defined SC_LIGHT
- if (matchtoken('{')) {
- lexpush();
- } else {
- /* Insert a separator so that comments following the statement will not
- * be attached to this function; they should be attached to the next
- * function. This is not a problem for functions having a compound block,
- * because the closing brace is an explicit "end token" for the function.
- * With single statement functions, the preprocessor may overread the
- * source code before the parser determines an "end of statement".
- */
- insert_docstring_separator();
- } /* if */
+ if (matchtoken('{')) {
+ lexpush();
+ } else {
+ /* Insert a separator so that comments following the statement will not
+ * be attached to this function; they should be attached to the next
+ * function. This is not a problem for functions having a compound block,
+ * because the closing brace is an explicit "end token" for the function.
+ * With single statement functions, the preprocessor may overread the
+ * source code before the parser determines an "end of statement".
+ */
+ insert_docstring_separator();
+ } /* if */
#endif
statement(NULL,FALSE);
if ((rettype & uRETVALUE)!=0)
- sym->usage|=uRETVALUE;
+ sym->usage|=uRETVALUE;
if (declared!=0) {
- /* This happens only in a very special (and useless) case, where a function
- * has only a single statement in its body (no compound block) and that
- * statement declares a new variable
- */
- modstk((int)declared*sizeof(cell)); /* remove all local variables */
- declared=0;
- } /* if */
- if ((lastst!=tRETURN) && (lastst!=tGOTO)){
- ldconst(0,sPRI);
- ffret();
- if ((sym->usage & uRETVALUE)!=0) {
- char symname[2*sNAMEMAX+16]; /* allow space for user defined operators */
- funcdisplayname(symname,sym->name);
- error(209,symname); /* function should return a value */
- } /* if */
- } /* if */
+ /* This happens only in a very special (and useless) case, where a function
+ * has only a single statement in its body (no compound block) and that
+ * statement declares a new variable
+ */
+ modstk((int)declared*sizeof(cell)); /* remove all local variables */
+ declared=0;
+ } /* if */
+ if ((lastst!=tRETURN) && (lastst!=tGOTO)){
+ ldconst(0,sPRI);
+ ffret();
+ if ((sym->usage & uRETVALUE)!=0) {
+ char symname[2*sNAMEMAX+16]; /* allow space for user defined operators */
+ funcdisplayname(symname,sym->name);
+ error(209,symname); /* function should return a value */
+ } /* if */
+ } /* if */
endfunc();
sym->codeaddr=code_idx;
- sc_attachdocumentation(sym); /* attach collected documenation to the function */
- if (litidx) { /* if there are literals defined */
- glb_declared+=litidx;
- begdseg(); /* flip to DATA segment */
- dumplits(); /* dump literal strings */
- litidx=0;
- } /* if */
- testsymbols(&loctab,0,TRUE,TRUE); /* test for unused arguments and labels */
- delete_symbols(&loctab,0,TRUE,TRUE); /* clear local variables queue */
+ sc_attachdocumentation(sym); /* attach collected documenation to the function */
+ if (litidx) { /* if there are literals defined */
+ glb_declared+=litidx;
+ begdseg(); /* flip to DATA segment */
+ dumplits(); /* dump literal strings */
+ litidx=0;
+ } /* if */
+ testsymbols(&loctab,0,TRUE,TRUE); /* test for unused arguments and labels */
+ delete_symbols(&loctab,0,TRUE,TRUE); /* clear local variables queue */
assert(loctab.next==NULL);
curfunc=NULL;
if (sc_status==statSKIP) {
- sc_status=statWRITE;
- code_idx=cidx;
- glb_declared=glbdecl;
- } /* if */
+ sc_status=statWRITE;
+ code_idx=cidx;
+ glb_declared=glbdecl;
+ } /* if */
return TRUE;
}
@@ -3300,52 +3300,52 @@ static int argcompare(arginfo *a1,arginfo *a2)
{
int result,level,i;
- result= strcmp(a1->name,a2->name)==0; /* name */
+ result= strcmp(a1->name,a2->name)==0; /* name */
if (result)
- result= a1->ident==a2->ident; /* type/class */
+ result= a1->ident==a2->ident; /* type/class */
if (result)
- result= a1->usage==a2->usage; /* "const" flag */
+ result= a1->usage==a2->usage; /* "const" flag */
if (result)
- result= a1->numtags==a2->numtags; /* tags (number and names) */
- for (i=0; result && inumtags; i++)
- result= a1->tags[i]==a2->tags[i];
+ result= a1->numtags==a2->numtags; /* tags (number and names) */
+ for (i=0; result && inumtags; i++)
+ result= a1->tags[i]==a2->tags[i];
if (result)
- result= a1->numdim==a2->numdim; /* array dimensions & index tags */
- for (level=0; result && levelnumdim; level++)
- result= a1->dim[level]==a2->dim[level];
- for (level=0; result && levelnumdim; level++)
- result= a1->idxtag[level]==a2->idxtag[level];
+ result= a1->numdim==a2->numdim; /* array dimensions & index tags */
+ for (level=0; result && levelnumdim; level++)
+ result= a1->dim[level]==a2->dim[level];
+ for (level=0; result && levelnumdim; level++)
+ result= a1->idxtag[level]==a2->idxtag[level];
if (result)
- result= a1->hasdefault==a2->hasdefault; /* availability of default value */
+ result= a1->hasdefault==a2->hasdefault; /* availability of default value */
if (a1->hasdefault) {
- if (a1->ident==iREFARRAY) {
- if (result)
- result= a1->defvalue.array.size==a2->defvalue.array.size;
- if (result)
- result= a1->defvalue.array.arraysize==a2->defvalue.array.arraysize;
- /* ??? should also check contents of the default array (these troubles
- * go away in a 2-pass compiler that forbids double declarations, but
- * Pawn currently does not forbid them) */
- } else {
- if (result) {
- if ((a1->hasdefault & uSIZEOF)!=0 || (a1->hasdefault & uTAGOF)!=0)
- result= a1->hasdefault==a2->hasdefault
- && strcmp(a1->defvalue.size.symname,a2->defvalue.size.symname)==0
- && a1->defvalue.size.level==a2->defvalue.size.level;
- else
- result= a1->defvalue.val==a2->defvalue.val;
- } /* if */
- } /* if */
- if (result)
- result= a1->defvalue_tag==a2->defvalue_tag;
- } /* if */
+ if (a1->ident==iREFARRAY) {
+ if (result)
+ result= a1->defvalue.array.size==a2->defvalue.array.size;
+ if (result)
+ result= a1->defvalue.array.arraysize==a2->defvalue.array.arraysize;
+ /* ??? should also check contents of the default array (these troubles
+ * go away in a 2-pass compiler that forbids double declarations, but
+ * Pawn currently does not forbid them) */
+ } else {
+ if (result) {
+ if ((a1->hasdefault & uSIZEOF)!=0 || (a1->hasdefault & uTAGOF)!=0)
+ result= a1->hasdefault==a2->hasdefault
+ && strcmp(a1->defvalue.size.symname,a2->defvalue.size.symname)==0
+ && a1->defvalue.size.level==a2->defvalue.size.level;
+ else
+ result= a1->defvalue.val==a2->defvalue.val;
+ } /* if */
+ } /* if */
+ if (result)
+ result= a1->defvalue_tag==a2->defvalue_tag;
+ } /* if */
return result;
}
-/* declargs()
+/* declargs()
*
- * This routine adds an entry in the local symbol table for each argument
- * found in the argument list. It returns the number of arguments.
+ * This routine adds an entry in the local symbol table for each argument
+ * found in the argument list. It returns the number of arguments.
*/
static int declargs(symbol *sym)
{
@@ -3358,305 +3358,305 @@ static int declargs(symbol *sym)
int ident,fpublic,fconst;
int idx;
- /* if the function is already defined earlier, get the number of arguments
- * of the existing definition
+ /* if the function is already defined earlier, get the number of arguments
+ * of the existing definition
*/
oldargcnt=0;
- if ((sym->usage & uPROTOTYPED)!=0)
- while (sym->dim.arglist[oldargcnt].ident!=0)
- oldargcnt++;
- argcnt=0; /* zero aruments up to now */
+ if ((sym->usage & uPROTOTYPED)!=0)
+ while (sym->dim.arglist[oldargcnt].ident!=0)
+ oldargcnt++;
+ argcnt=0; /* zero aruments up to now */
ident=iVARIABLE;
numtags=0;
fconst=FALSE;
fpublic= (sym->usage & uPUBLIC)!=0;
/* the '(' parantheses has already been parsed */
if (!matchtoken(')')){
- do { /* there are arguments; process them */
- /* any legal name increases argument count (and stack offset) */
- tok=lex(&val,&ptr);
- switch (tok) {
- case 0:
- /* nothing */
- break;
- case '&':
- if (ident!=iVARIABLE || numtags>0)
- error(1,"-identifier-","&");
- ident=iREFERENCE;
- break;
- case tCONST:
- if (ident!=iVARIABLE || numtags>0)
- error(1,"-identifier-","const");
- fconst=TRUE;
- break;
- case tLABEL:
- if (numtags>0)
- error(1,"-identifier-","-tagname-");
- tags[0]=pc_addtag(ptr);
- numtags=1;
- break;
- case '{':
- if (numtags>0)
- error(1,"-identifier-","-tagname-");
- numtags=0;
- while (numtags=sMAXARGS)
- error(45); /* too many function arguments */
- strcpy(name,ptr); /* save symbol name */
- if (name[0]==PUBLIC_CHAR)
- error(56,name); /* function arguments cannot be public */
- if (numtags==0)
- tags[numtags++]=0; /* default tag */
- /* Stack layout:
- * base + 0*sizeof(cell) == previous "base"
- * base + 1*sizeof(cell) == function return address
- * base + 2*sizeof(cell) == number of arguments
- * base + 3*sizeof(cell) == first argument of the function
- * So the offset of each argument is "(argcnt+3) * sizeof(cell)".
- */
- doarg(name,ident,(argcnt+3)*sizeof(cell),tags,numtags,fpublic,fconst,&arg);
- if (fpublic && arg.hasdefault)
- error(59,name); /* arguments of a public function may not have a default value */
- if ((sym->usage & uPROTOTYPED)==0) {
- /* redimension the argument list, add the entry */
- sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo));
- if (sym->dim.arglist==0)
- error(103); /* insufficient memory */
- memset(&sym->dim.arglist[argcnt+1],0,sizeof(arginfo)); /* keep the list terminated */
- sym->dim.arglist[argcnt]=arg;
- } else {
- /* check the argument with the earlier definition */
- if (argcnt>oldargcnt || !argcompare(&sym->dim.arglist[argcnt],&arg))
- error(25); /* function definition does not match prototype */
- /* may need to free default array argument and the tag list */
- if (arg.ident==iREFARRAY && arg.hasdefault)
- free(arg.defvalue.array.data);
- else if (arg.ident==iVARIABLE
- && ((arg.hasdefault & uSIZEOF)!=0 || (arg.hasdefault & uTAGOF)!=0))
- free(arg.defvalue.size.symname);
- free(arg.tags);
- } /* if */
- argcnt++;
- ident=iVARIABLE;
- numtags=0;
- fconst=FALSE;
- break;
- case tELLIPS:
- if (ident!=iVARIABLE)
- error(10); /* illegal function or declaration */
- if (numtags==0)
- tags[numtags++]=0; /* default tag */
- if ((sym->usage & uPROTOTYPED)==0) {
- /* redimension the argument list, add the entry iVARARGS */
- sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo));
- if (sym->dim.arglist==0)
- error(103); /* insufficient memory */
- memset(&sym->dim.arglist[argcnt+1],0,sizeof(arginfo)); /* keep the list terminated */
- sym->dim.arglist[argcnt].ident=iVARARGS;
- sym->dim.arglist[argcnt].hasdefault=FALSE;
- sym->dim.arglist[argcnt].defvalue.val=0;
- sym->dim.arglist[argcnt].defvalue_tag=0;
- sym->dim.arglist[argcnt].numtags=numtags;
- sym->dim.arglist[argcnt].tags=(int*)malloc(numtags*sizeof tags[0]);
- if (sym->dim.arglist[argcnt].tags==NULL)
- error(103); /* insufficient memory */
- memcpy(sym->dim.arglist[argcnt].tags,tags,numtags*sizeof tags[0]);
- } else {
- if (argcnt>oldargcnt || sym->dim.arglist[argcnt].ident!=iVARARGS)
- error(25); /* function definition does not match prototype */
- } /* if */
- argcnt++;
- break;
- default:
- error(10); /* illegal function or declaration */
- } /* switch */
- } while (tok=='&' || tok==tLABEL || tok==tCONST
- || tok!=tELLIPS && matchtoken(',')); /* more? */
- /* if the next token is not ",", it should be ")" */
- needtoken(')');
- } /* if */
- /* resolve any "sizeof" arguments (now that all arguments are known) */
+ do { /* there are arguments; process them */
+ /* any legal name increases argument count (and stack offset) */
+ tok=lex(&val,&ptr);
+ switch (tok) {
+ case 0:
+ /* nothing */
+ break;
+ case '&':
+ if (ident!=iVARIABLE || numtags>0)
+ error(1,"-identifier-","&");
+ ident=iREFERENCE;
+ break;
+ case tCONST:
+ if (ident!=iVARIABLE || numtags>0)
+ error(1,"-identifier-","const");
+ fconst=TRUE;
+ break;
+ case tLABEL:
+ if (numtags>0)
+ error(1,"-identifier-","-tagname-");
+ tags[0]=pc_addtag(ptr);
+ numtags=1;
+ break;
+ case '{':
+ if (numtags>0)
+ error(1,"-identifier-","-tagname-");
+ numtags=0;
+ while (numtags=sMAXARGS)
+ error(45); /* too many function arguments */
+ strcpy(name,ptr); /* save symbol name */
+ if (name[0]==PUBLIC_CHAR)
+ error(56,name); /* function arguments cannot be public */
+ if (numtags==0)
+ tags[numtags++]=0; /* default tag */
+ /* Stack layout:
+ * base + 0*sizeof(cell) == previous "base"
+ * base + 1*sizeof(cell) == function return address
+ * base + 2*sizeof(cell) == number of arguments
+ * base + 3*sizeof(cell) == first argument of the function
+ * So the offset of each argument is "(argcnt+3) * sizeof(cell)".
+ */
+ doarg(name,ident,(argcnt+3)*sizeof(cell),tags,numtags,fpublic,fconst,&arg);
+ if (fpublic && arg.hasdefault)
+ error(59,name); /* arguments of a public function may not have a default value */
+ if ((sym->usage & uPROTOTYPED)==0) {
+ /* redimension the argument list, add the entry */
+ sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo));
+ if (sym->dim.arglist==0)
+ error(103); /* insufficient memory */
+ memset(&sym->dim.arglist[argcnt+1],0,sizeof(arginfo)); /* keep the list terminated */
+ sym->dim.arglist[argcnt]=arg;
+ } else {
+ /* check the argument with the earlier definition */
+ if (argcnt>oldargcnt || !argcompare(&sym->dim.arglist[argcnt],&arg))
+ error(25); /* function definition does not match prototype */
+ /* may need to free default array argument and the tag list */
+ if (arg.ident==iREFARRAY && arg.hasdefault)
+ free(arg.defvalue.array.data);
+ else if (arg.ident==iVARIABLE
+ && ((arg.hasdefault & uSIZEOF)!=0 || (arg.hasdefault & uTAGOF)!=0))
+ free(arg.defvalue.size.symname);
+ free(arg.tags);
+ } /* if */
+ argcnt++;
+ ident=iVARIABLE;
+ numtags=0;
+ fconst=FALSE;
+ break;
+ case tELLIPS:
+ if (ident!=iVARIABLE)
+ error(10); /* illegal function or declaration */
+ if (numtags==0)
+ tags[numtags++]=0; /* default tag */
+ if ((sym->usage & uPROTOTYPED)==0) {
+ /* redimension the argument list, add the entry iVARARGS */
+ sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo));
+ if (sym->dim.arglist==0)
+ error(103); /* insufficient memory */
+ memset(&sym->dim.arglist[argcnt+1],0,sizeof(arginfo)); /* keep the list terminated */
+ sym->dim.arglist[argcnt].ident=iVARARGS;
+ sym->dim.arglist[argcnt].hasdefault=FALSE;
+ sym->dim.arglist[argcnt].defvalue.val=0;
+ sym->dim.arglist[argcnt].defvalue_tag=0;
+ sym->dim.arglist[argcnt].numtags=numtags;
+ sym->dim.arglist[argcnt].tags=(int*)malloc(numtags*sizeof tags[0]);
+ if (sym->dim.arglist[argcnt].tags==NULL)
+ error(103); /* insufficient memory */
+ memcpy(sym->dim.arglist[argcnt].tags,tags,numtags*sizeof tags[0]);
+ } else {
+ if (argcnt>oldargcnt || sym->dim.arglist[argcnt].ident!=iVARARGS)
+ error(25); /* function definition does not match prototype */
+ } /* if */
+ argcnt++;
+ break;
+ default:
+ error(10); /* illegal function or declaration */
+ } /* switch */
+ } while (tok=='&' || tok==tLABEL || tok==tCONST
+ || tok!=tELLIPS && matchtoken(',')); /* more? */
+ /* if the next token is not ",", it should be ")" */
+ needtoken(')');
+ } /* if */
+ /* resolve any "sizeof" arguments (now that all arguments are known) */
assert(sym->dim.arglist!=NULL);
arglist=sym->dim.arglist;
- for (idx=0; idx=argcnt) {
- error(17,ptr); /* undefined symbol */
- } else {
- assert(arglist[idx].defvalue.size.symname!=NULL);
- /* check the level against the number of dimensions */
- if (arglist[idx].defvalue.size.level>0
- && arglist[idx].defvalue.size.level>=arglist[altidx].numdim)
- error(28,arglist[idx].name); /* invalid subscript */
- /* check the type of the argument whose size to take; for a iVARIABLE
- * or a iREFERENCE, this is always 1 (so the code is redundant)
- */
- assert(arglist[altidx].ident!=iVARARGS);
- if (arglist[altidx].ident!=iREFARRAY && (arglist[idx].hasdefault & uSIZEOF)!=0) {
- if ((arglist[idx].hasdefault & uTAGOF)!=0) {
- error(81,arglist[idx].name); /* cannot take "tagof" an indexed array */
- } else {
- assert(arglist[altidx].ident==iVARIABLE || arglist[altidx].ident==iREFERENCE);
- error(223,ptr); /* redundant sizeof */
- } /* if */
- } /* if */
- } /* if */
- } /* if */
- } /* for */
+ for (idx=0; idx=argcnt) {
+ error(17,ptr); /* undefined symbol */
+ } else {
+ assert(arglist[idx].defvalue.size.symname!=NULL);
+ /* check the level against the number of dimensions */
+ if (arglist[idx].defvalue.size.level>0
+ && arglist[idx].defvalue.size.level>=arglist[altidx].numdim)
+ error(28,arglist[idx].name); /* invalid subscript */
+ /* check the type of the argument whose size to take; for a iVARIABLE
+ * or a iREFERENCE, this is always 1 (so the code is redundant)
+ */
+ assert(arglist[altidx].ident!=iVARARGS);
+ if (arglist[altidx].ident!=iREFARRAY && (arglist[idx].hasdefault & uSIZEOF)!=0) {
+ if ((arglist[idx].hasdefault & uTAGOF)!=0) {
+ error(81,arglist[idx].name); /* cannot take "tagof" an indexed array */
+ } else {
+ assert(arglist[altidx].ident==iVARIABLE || arglist[altidx].ident==iREFERENCE);
+ error(223,ptr); /* redundant sizeof */
+ } /* if */
+ } /* if */
+ } /* if */
+ } /* if */
+ } /* for */
sym->usage|=uPROTOTYPED;
- errorset(sRESET); /* reset error flag (clear the "panic mode")*/
+ errorset(sRESET); /* reset error flag (clear the "panic mode")*/
return argcnt;
}
-/* doarg - declare one argument type
+/* doarg - declare one argument type
*
- * this routine is called from "declargs()" and adds an entry in the local
- * symbol table for one argument.
+ * this routine is called from "declargs()" and adds an entry in the local
+ * symbol table for one argument.
*
- * "fpublic" indicates whether the function for this argument list is public.
- * The arguments themselves are never public.
+ * "fpublic" indicates whether the function for this argument list is public.
+ * The arguments themselves are never public.
*/
-static void doarg(char *name,int ident,int offset,int tags[],int numtags,
- int fpublic,int fconst,arginfo *arg)
+static void doarg(char *name,int ident,int offset,int tags[],int numtags,
+ int fpublic,int fconst,arginfo *arg)
{
symbol *argsym;
constvalue *enumroot;
cell size;
strcpy(arg->name,name);
- arg->hasdefault=FALSE; /* preset (most common case) */
- arg->defvalue.val=0; /* clear */
+ arg->hasdefault=FALSE; /* preset (most common case) */
+ arg->defvalue.val=0; /* clear */
arg->defvalue_tag=0;
arg->numdim=0;
if (matchtoken('[')) {
- if (ident==iREFERENCE)
- error(67,name); /* illegal declaration ("&name[]" is unsupported) */
- do {
- if (arg->numdim == sDIMEN_MAX) {
- error(53); /* exceeding maximum number of dimensions */
- return;
- } /* if */
- size=needsub(&arg->idxtag[arg->numdim],&enumroot);/* may be zero here, it is a pointer anyway */
- #if INT_MAX < LONG_MAX
- if (size > INT_MAX)
- error(105); /* overflow, exceeding capacity */
- #endif
- arg->dim[arg->numdim]=(int)size;
- arg->numdim+=1;
- } while (matchtoken('['));
- ident=iREFARRAY; /* "reference to array" (is a pointer) */
- if (matchtoken('=')) {
- lexpush(); /* initials() needs the "=" token again */
- assert(litidx==0); /* at the start of a function, this is reset */
- assert(numtags>0);
- initials(ident,tags[0],&size,arg->dim,arg->numdim,enumroot);
- assert(size>=litidx);
- /* allocate memory to hold the initial values */
- arg->defvalue.array.data=(cell *)malloc(litidx*sizeof(cell));
- if (arg->defvalue.array.data!=NULL) {
- int i;
- memcpy(arg->defvalue.array.data,litq,litidx*sizeof(cell));
- arg->hasdefault=TRUE; /* argument has default value */
- arg->defvalue.array.size=litidx;
- arg->defvalue.array.addr=-1;
- /* calulate size to reserve on the heap */
- arg->defvalue.array.arraysize=1;
- for (i=0; inumdim; i++)
- arg->defvalue.array.arraysize*=arg->dim[i];
- if (arg->defvalue.array.arraysize < arg->defvalue.array.size)
- arg->defvalue.array.arraysize = arg->defvalue.array.size;
- } /* if */
- litidx=0; /* reset */
- } /* if */
- } else {
- if (matchtoken('=')) {
- unsigned char size_tag_token;
- assert(ident==iVARIABLE || ident==iREFERENCE);
- arg->hasdefault=TRUE; /* argument has a default value */
- size_tag_token=(unsigned char)(matchtoken(tSIZEOF) ? uSIZEOF : 0);
- if (size_tag_token==0)
- size_tag_token=(unsigned char)(matchtoken(tTAGOF) ? uTAGOF : 0);
- if (size_tag_token!=0) {
- int paranthese;
- if (ident==iREFERENCE)
- error(66,name); /* argument may not be a reference */
- paranthese=0;
- while (matchtoken('('))
- paranthese++;
- if (needtoken(tSYMBOL)) {
- /* save the name of the argument whose size id to take */
- char *name;
- cell val;
- tokeninfo(&val,&name);
- if ((arg->defvalue.size.symname=duplicatestring(name)) == NULL)
- error(103); /* insufficient memory */
- arg->defvalue.size.level=0;
- if (size_tag_token==uSIZEOF) {
- while (matchtoken('[')) {
- arg->defvalue.size.level+=(short)1;
- needtoken(']');
- } /* while */
- } /* if */
- if (ident==iVARIABLE) /* make sure we set this only if not a reference */
- arg->hasdefault |= size_tag_token; /* uSIZEOF or uTAGOF */
- } /* if */
- while (paranthese--)
- needtoken(')');
- } else {
- constexpr(&arg->defvalue.val,&arg->defvalue_tag,NULL);
- assert(numtags>0);
- if (!matchtag(tags[0],arg->defvalue_tag,TRUE))
- error(213); /* tagname mismatch */
- } /* if */
- } /* if */
- } /* if */
+ if (ident==iREFERENCE)
+ error(67,name); /* illegal declaration ("&name[]" is unsupported) */
+ do {
+ if (arg->numdim == sDIMEN_MAX) {
+ error(53); /* exceeding maximum number of dimensions */
+ return;
+ } /* if */
+ size=needsub(&arg->idxtag[arg->numdim],&enumroot);/* may be zero here, it is a pointer anyway */
+ #if INT_MAX < LONG_MAX
+ if (size > INT_MAX)
+ error(105); /* overflow, exceeding capacity */
+ #endif
+ arg->dim[arg->numdim]=(int)size;
+ arg->numdim+=1;
+ } while (matchtoken('['));
+ ident=iREFARRAY; /* "reference to array" (is a pointer) */
+ if (matchtoken('=')) {
+ lexpush(); /* initials() needs the "=" token again */
+ assert(litidx==0); /* at the start of a function, this is reset */
+ assert(numtags>0);
+ initials(ident,tags[0],&size,arg->dim,arg->numdim,enumroot);
+ assert(size>=litidx);
+ /* allocate memory to hold the initial values */
+ arg->defvalue.array.data=(cell *)malloc(litidx*sizeof(cell));
+ if (arg->defvalue.array.data!=NULL) {
+ int i;
+ memcpy(arg->defvalue.array.data,litq,litidx*sizeof(cell));
+ arg->hasdefault=TRUE; /* argument has default value */
+ arg->defvalue.array.size=litidx;
+ arg->defvalue.array.addr=-1;
+ /* calulate size to reserve on the heap */
+ arg->defvalue.array.arraysize=1;
+ for (i=0; inumdim; i++)
+ arg->defvalue.array.arraysize*=arg->dim[i];
+ if (arg->defvalue.array.arraysize < arg->defvalue.array.size)
+ arg->defvalue.array.arraysize = arg->defvalue.array.size;
+ } /* if */
+ litidx=0; /* reset */
+ } /* if */
+ } else {
+ if (matchtoken('=')) {
+ unsigned char size_tag_token;
+ assert(ident==iVARIABLE || ident==iREFERENCE);
+ arg->hasdefault=TRUE; /* argument has a default value */
+ size_tag_token=(unsigned char)(matchtoken(tSIZEOF) ? uSIZEOF : 0);
+ if (size_tag_token==0)
+ size_tag_token=(unsigned char)(matchtoken(tTAGOF) ? uTAGOF : 0);
+ if (size_tag_token!=0) {
+ int paranthese;
+ if (ident==iREFERENCE)
+ error(66,name); /* argument may not be a reference */
+ paranthese=0;
+ while (matchtoken('('))
+ paranthese++;
+ if (needtoken(tSYMBOL)) {
+ /* save the name of the argument whose size id to take */
+ char *name;
+ cell val;
+ tokeninfo(&val,&name);
+ if ((arg->defvalue.size.symname=duplicatestring(name)) == NULL)
+ error(103); /* insufficient memory */
+ arg->defvalue.size.level=0;
+ if (size_tag_token==uSIZEOF) {
+ while (matchtoken('[')) {
+ arg->defvalue.size.level+=(short)1;
+ needtoken(']');
+ } /* while */
+ } /* if */
+ if (ident==iVARIABLE) /* make sure we set this only if not a reference */
+ arg->hasdefault |= size_tag_token; /* uSIZEOF or uTAGOF */
+ } /* if */
+ while (paranthese--)
+ needtoken(')');
+ } else {
+ constexpr(&arg->defvalue.val,&arg->defvalue_tag,NULL);
+ assert(numtags>0);
+ if (!matchtag(tags[0],arg->defvalue_tag,TRUE))
+ error(213); /* tagname mismatch */
+ } /* if */
+ } /* if */
+ } /* if */
arg->ident=(char)ident;
- arg->usage=(char)(fconst ? uCONST : 0);
+ arg->usage=(char)(fconst ? uCONST : 0);
arg->numtags=numtags;
- arg->tags=(int*)malloc(numtags*sizeof tags[0]);
+ arg->tags=(int*)malloc(numtags*sizeof tags[0]);
if (arg->tags==NULL)
- error(103); /* insufficient memory */
+ error(103); /* insufficient memory */
memcpy(arg->tags,tags,numtags*sizeof tags[0]);
argsym=findloc(name);
- if (argsym!=NULL) {
- error(21,name); /* symbol already defined */
- } else {
- if ((argsym=findglb(name))!=NULL && argsym->ident!=iFUNCTN)
- error(219,name); /* variable shadows another symbol */
- /* add details of type and address */
- assert(numtags>0);
- argsym=addvariable(name,offset,ident,sLOCAL,tags[0],
- arg->dim,arg->numdim,arg->idxtag);
- argsym->compound=0;
- if (ident==iREFERENCE)
- argsym->usage|=uREAD; /* because references are passed back */
- if (fpublic)
- argsym->usage|=uREAD; /* arguments of public functions are always "used" */
- if (fconst)
- argsym->usage|=uCONST;
- } /* if */
+ if (argsym!=NULL) {
+ error(21,name); /* symbol already defined */
+ } else {
+ if ((argsym=findglb(name))!=NULL && argsym->ident!=iFUNCTN)
+ error(219,name); /* variable shadows another symbol */
+ /* add details of type and address */
+ assert(numtags>0);
+ argsym=addvariable(name,offset,ident,sLOCAL,tags[0],
+ arg->dim,arg->numdim,arg->idxtag);
+ argsym->compound=0;
+ if (ident==iREFERENCE)
+ argsym->usage|=uREAD; /* because references are passed back */
+ if (fpublic)
+ argsym->usage|=uREAD; /* arguments of public functions are always "used" */
+ if (fconst)
+ argsym->usage|=uCONST;
+ } /* if */
}
static int count_referrers(symbol *entry)
@@ -3664,16 +3664,16 @@ static int count_referrers(symbol *entry)
int i,count;
count=0;
- for (i=0; inumrefers; i++)
- if (entry->refer[i]!=NULL)
- count++;
+ for (i=0; inumrefers; i++)
+ if (entry->refer[i]!=NULL)
+ count++;
return count;
}
-#if !defined SC_LIGHT
-static int find_xmltag(char *source,char *xmltag,char *xmlparam,char *xmlvalue,
- char **outer_start,int *outer_length,
- char **inner_start,int *inner_length)
+#if !defined SC_LIGHT
+static int find_xmltag(char *source,char *xmltag,char *xmlparam,char *xmlvalue,
+ char **outer_start,int *outer_length,
+ char **inner_start,int *inner_length)
{
char *ptr,*inner_end;
int xmltag_len,xmlparam_len,xmlvalue_len;
@@ -3686,122 +3686,122 @@ static int find_xmltag(char *source,char *xmltag,char *xmlparam,char *xmlvalue,
assert(inner_start!=NULL);
assert(inner_length!=NULL);
- /* both NULL or both non-NULL */
- assert(xmlvalue!=NULL && xmlparam!=NULL || xmlvalue==NULL && xmlparam==NULL);
+ /* both NULL or both non-NULL */
+ assert(xmlvalue!=NULL && xmlparam!=NULL || xmlvalue==NULL && xmlparam==NULL);
xmltag_len=strlen(xmltag);
- xmlparam_len= (xmlparam!=NULL) ? strlen(xmlparam) : 0;
- xmlvalue_len= (xmlvalue!=NULL) ? strlen(xmlvalue) : 0;
+ xmlparam_len= (xmlparam!=NULL) ? strlen(xmlparam) : 0;
+ xmlvalue_len= (xmlvalue!=NULL) ? strlen(xmlvalue) : 0;
ptr=source;
/* find an opening '<' */
- while ((ptr=strchr(ptr,'<'))!=NULL) {
- *outer_start=ptr; /* be optimistic... */
- match=FALSE; /* ...and pessimistic at the same time */
- ptr++; /* skip '<' */
- while (*ptr!='\0' && *ptr<=' ')
- ptr++; /* skip white space */
- if (strncmp(ptr,xmltag,xmltag_len)==0 && (*(ptr+xmltag_len)<=' ' || *(ptr+xmltag_len)=='>')) {
- /* xml tag found, optionally check the parameter */
- ptr+=xmltag_len;
- while (*ptr!='\0' && *ptr<=' ')
- ptr++; /* skip white space */
- if (xmlparam!=NULL) {
- if (strncmp(ptr,xmlparam,xmlparam_len)==0 && (*(ptr+xmlparam_len)<=' ' || *(ptr+xmlparam_len)=='=')) {
- ptr+=xmlparam_len;
- while (*ptr!='\0' && *ptr<=' ')
- ptr++; /* skip white space */
- if (*ptr=='=') {
- ptr++; /* skip '=' */
- while (*ptr!='\0' && *ptr<=' ')
- ptr++; /* skip white space */
- if (*ptr=='"' || *ptr=='\'')
- ptr++; /* skip " or ' */
- assert(xmlvalue!=NULL);
- if (strncmp(ptr,xmlvalue,xmlvalue_len)==0
- && (*(ptr+xmlvalue_len)<=' '
- || *(ptr+xmlvalue_len)=='>'
- || *(ptr+xmlvalue_len)=='"'
- || *(ptr+xmlvalue_len)=='\''))
- match=TRUE; /* found it */
- } /* if */
- } /* if */
- } else {
- match=TRUE; /* don't check the parameter */
- } /* if */
- } /* if */
- if (match) {
- /* now find the end of the opening tag */
- while (*ptr!='\0' && *ptr!='>')
- ptr++;
- if (*ptr=='>')
- ptr++;
- while (*ptr!='\0' && *ptr<=' ')
- ptr++; /* skip white space */
- *inner_start=ptr;
- /* find the start of the closing tag (assume no nesting) */
- while ((ptr=strchr(ptr,'<'))!=NULL) {
- inner_end=ptr;
- ptr++; /* skip '<' */
- while (*ptr!='\0' && *ptr<=' ')
- ptr++; /* skip white space */
- if (*ptr=='/') {
- ptr++; /* skip / */
- while (*ptr!='\0' && *ptr<=' ')
- ptr++; /* skip white space */
- if (strncmp(ptr,xmltag,xmltag_len)==0 && (*(ptr+xmltag_len)<=' ' || *(ptr+xmltag_len)=='>')) {
- /* find the end of the closing tag */
- while (*ptr!='\0' && *ptr!='>')
- ptr++;
- if (*ptr=='>')
- ptr++;
- /* set the lengths of the inner and outer segment */
- assert(*inner_start!=NULL);
- *inner_length=(int)(inner_end-*inner_start);
- assert(*outer_start!=NULL);
- *outer_length=(int)(ptr-*outer_start);
- break; /* break out of the loop */
- } /* if */
- } /* if */
- } /* while */
- return TRUE;
- } /* if */
- } /* while */
- return FALSE; /* not found */
+ while ((ptr=strchr(ptr,'<'))!=NULL) {
+ *outer_start=ptr; /* be optimistic... */
+ match=FALSE; /* ...and pessimistic at the same time */
+ ptr++; /* skip '<' */
+ while (*ptr!='\0' && *ptr<=' ')
+ ptr++; /* skip white space */
+ if (strncmp(ptr,xmltag,xmltag_len)==0 && (*(ptr+xmltag_len)<=' ' || *(ptr+xmltag_len)=='>')) {
+ /* xml tag found, optionally check the parameter */
+ ptr+=xmltag_len;
+ while (*ptr!='\0' && *ptr<=' ')
+ ptr++; /* skip white space */
+ if (xmlparam!=NULL) {
+ if (strncmp(ptr,xmlparam,xmlparam_len)==0 && (*(ptr+xmlparam_len)<=' ' || *(ptr+xmlparam_len)=='=')) {
+ ptr+=xmlparam_len;
+ while (*ptr!='\0' && *ptr<=' ')
+ ptr++; /* skip white space */
+ if (*ptr=='=') {
+ ptr++; /* skip '=' */
+ while (*ptr!='\0' && *ptr<=' ')
+ ptr++; /* skip white space */
+ if (*ptr=='"' || *ptr=='\'')
+ ptr++; /* skip " or ' */
+ assert(xmlvalue!=NULL);
+ if (strncmp(ptr,xmlvalue,xmlvalue_len)==0
+ && (*(ptr+xmlvalue_len)<=' '
+ || *(ptr+xmlvalue_len)=='>'
+ || *(ptr+xmlvalue_len)=='"'
+ || *(ptr+xmlvalue_len)=='\''))
+ match=TRUE; /* found it */
+ } /* if */
+ } /* if */
+ } else {
+ match=TRUE; /* don't check the parameter */
+ } /* if */
+ } /* if */
+ if (match) {
+ /* now find the end of the opening tag */
+ while (*ptr!='\0' && *ptr!='>')
+ ptr++;
+ if (*ptr=='>')
+ ptr++;
+ while (*ptr!='\0' && *ptr<=' ')
+ ptr++; /* skip white space */
+ *inner_start=ptr;
+ /* find the start of the closing tag (assume no nesting) */
+ while ((ptr=strchr(ptr,'<'))!=NULL) {
+ inner_end=ptr;
+ ptr++; /* skip '<' */
+ while (*ptr!='\0' && *ptr<=' ')
+ ptr++; /* skip white space */
+ if (*ptr=='/') {
+ ptr++; /* skip / */
+ while (*ptr!='\0' && *ptr<=' ')
+ ptr++; /* skip white space */
+ if (strncmp(ptr,xmltag,xmltag_len)==0 && (*(ptr+xmltag_len)<=' ' || *(ptr+xmltag_len)=='>')) {
+ /* find the end of the closing tag */
+ while (*ptr!='\0' && *ptr!='>')
+ ptr++;
+ if (*ptr=='>')
+ ptr++;
+ /* set the lengths of the inner and outer segment */
+ assert(*inner_start!=NULL);
+ *inner_length=(int)(inner_end-*inner_start);
+ assert(*outer_start!=NULL);
+ *outer_length=(int)(ptr-*outer_start);
+ break; /* break out of the loop */
+ } /* if */
+ } /* if */
+ } /* while */
+ return TRUE;
+ } /* if */
+ } /* while */
+ return FALSE; /* not found */
}
-static char *xmlencode(char *dest,char *source)
+static char *xmlencode(char *dest,char *source)
{
char temp[2*sNAMEMAX+20],*ptr;
- /* replace < by < and such; normally, such a symbol occurs at most once in
+ /* replace < by < and such; normally, such a symbol occurs at most once in
* a symbol name (e.g. "operator<")
*/
ptr=temp;
- while (*source!='\0') {
- switch (*source) {
- case '<':
- strcpy(ptr,"<");
- ptr+=4;
- break;
- case '>':
- strcpy(ptr,">");
- ptr+=4;
- break;
- case '&':
- strcpy(ptr,"&");
- ptr+=5;
- break;
- default:
- *ptr++=*source;
- } /* switch */
- source++;
- } /* while */
+ while (*source!='\0') {
+ switch (*source) {
+ case '<':
+ strcpy(ptr,"<");
+ ptr+=4;
+ break;
+ case '>':
+ strcpy(ptr,">");
+ ptr+=4;
+ break;
+ case '&':
+ strcpy(ptr,"&");
+ ptr+=5;
+ break;
+ default:
+ *ptr++=*source;
+ } /* switch */
+ source++;
+ } /* while */
*ptr='\0';
strcpy(dest,temp);
return dest;
}
-static void make_report(symbol *root,FILE *log,char *sourcefile)
+static void make_report(symbol *root,FILE *log,char *sourcefile)
{
char symname[2*sNAMEMAX+20];
int i,arg;
@@ -3810,324 +3810,324 @@ static void make_report(symbol *root,FILE *log,char *sourcefile)
constvalue *enumroot;
char *ptr;
- /* the XML header */
+ /* the XML header */
fprintf(log,"\n");
- fprintf(log,"\n");
- fprintf(log,"\n",sourcefile);
+ fprintf(log,"\n");
+ fprintf(log,"\n",sourcefile);
ptr=strrchr(sourcefile,DIRSEP_CHAR);
if (ptr!=NULL)
- ptr++;
+ ptr++;
else
- ptr=sourcefile;
+ ptr=sourcefile;
fprintf(log,"\t\n\t\t%s\n\t\n",ptr);
- /* attach the global documentation, if any */
+ /* attach the global documentation, if any */
if (sc_documentation!=NULL) {
- fprintf(log,"\n\t\n");
- fprintf(log,"\t\n\t\t");
- fputs(sc_documentation,log);
- fprintf(log,"\n\t\n\n");
- } /* if */
+ fprintf(log,"\n\t\n");
+ fprintf(log,"\t\n\t\t");
+ fputs(sc_documentation,log);
+ fprintf(log,"\n\t\n\n");
+ } /* if */
- /* use multiple passes to print constants variables and functions in
+ /* use multiple passes to print constants variables and functions in
* separate sections
*/
fprintf(log,"\t\n");
fprintf(log,"\n\t\t\n");
for (sym=root->next; sym!=NULL; sym=sym->next) {
- if (sym->parent!=NULL)
- continue; /* hierarchical data type */
- assert(sym->ident==iCONSTEXPR || sym->ident==iVARIABLE
- || sym->ident==iARRAY || sym->ident==iFUNCTN);
- if (sym->ident!=iCONSTEXPR || (sym->usage & uENUMROOT)==0)
- continue;
- if ((sym->usage & uREAD)==0)
- continue;
- fprintf(log,"\t\t\n",funcdisplayname(symname,sym->name),sym->addr);
- if (sym->tag!=0) {
- tagsym=find_tag_byval(sym->tag);
- assert(tagsym!=NULL);
- fprintf(log,"\t\t\t\n",tagsym->name);
- } /* if */
- /* browse through all fields */
- if ((enumroot=sym->dim.enumlist)!=NULL) {
- enumroot=enumroot->next; /* skip root */
- while (enumroot!=NULL) {
- fprintf(log,"\t\t\t\n",funcdisplayname(symname,enumroot->name),enumroot->value);
- /* find the constant with this name and get the tag */
- ref=findglb(enumroot->name);
- if (ref!=NULL) {
- if (ref->x.idxtag!=0) {
- tagsym=find_tag_byval(ref->x.idxtag);
- assert(tagsym!=NULL);
- fprintf(log,"\t\t\t\t\n",tagsym->name);
- } /* if */
- if (ref->dim.array.length!=1)
- fprintf(log,"\t\t\t\t\n",(long)ref->dim.array.length);
- } /* if */
- fprintf(log,"\t\t\t\n");
- enumroot=enumroot->next;
- } /* while */
- } /* if */
- assert(sym->refer!=NULL);
- for (i=0; inumrefers; i++) {
- if ((ref=sym->refer[i])!=NULL)
- fprintf(log,"\t\t\t\n",xmlencode(symname,funcdisplayname(symname,ref->name)));
- } /* for */
- if (sym->documentation!=NULL)
- fprintf(log,"\t\t\t%s\n",sym->documentation);
- fprintf(log,"\t\t\n");
- } /* for */
+ if (sym->parent!=NULL)
+ continue; /* hierarchical data type */
+ assert(sym->ident==iCONSTEXPR || sym->ident==iVARIABLE
+ || sym->ident==iARRAY || sym->ident==iFUNCTN);
+ if (sym->ident!=iCONSTEXPR || (sym->usage & uENUMROOT)==0)
+ continue;
+ if ((sym->usage & uREAD)==0)
+ continue;
+ fprintf(log,"\t\t\n",funcdisplayname(symname,sym->name),sym->addr);
+ if (sym->tag!=0) {
+ tagsym=find_tag_byval(sym->tag);
+ assert(tagsym!=NULL);
+ fprintf(log,"\t\t\t\n",tagsym->name);
+ } /* if */
+ /* browse through all fields */
+ if ((enumroot=sym->dim.enumlist)!=NULL) {
+ enumroot=enumroot->next; /* skip root */
+ while (enumroot!=NULL) {
+ fprintf(log,"\t\t\t\n",funcdisplayname(symname,enumroot->name),enumroot->value);
+ /* find the constant with this name and get the tag */
+ ref=findglb(enumroot->name);
+ if (ref!=NULL) {
+ if (ref->x.idxtag!=0) {
+ tagsym=find_tag_byval(ref->x.idxtag);
+ assert(tagsym!=NULL);
+ fprintf(log,"\t\t\t\t\n",tagsym->name);
+ } /* if */
+ if (ref->dim.array.length!=1)
+ fprintf(log,"\t\t\t\t\n",(long)ref->dim.array.length);
+ } /* if */
+ fprintf(log,"\t\t\t\n");
+ enumroot=enumroot->next;
+ } /* while */
+ } /* if */
+ assert(sym->refer!=NULL);
+ for (i=0; inumrefers; i++) {
+ if ((ref=sym->refer[i])!=NULL)
+ fprintf(log,"\t\t\t\n",xmlencode(symname,funcdisplayname(symname,ref->name)));
+ } /* for */
+ if (sym->documentation!=NULL)
+ fprintf(log,"\t\t\t%s\n",sym->documentation);
+ fprintf(log,"\t\t\n");
+ } /* for */
- fprintf(log,"\n\t\t\n");
+ fprintf(log,"\n\t\t\n");
for (sym=root->next; sym!=NULL; sym=sym->next) {
- if (sym->parent!=NULL)
- continue; /* hierarchical data type */
- assert(sym->ident==iCONSTEXPR || sym->ident==iVARIABLE
- || sym->ident==iARRAY || sym->ident==iFUNCTN);
- if (sym->ident!=iCONSTEXPR)
- continue;
- if ((sym->usage & uREAD)==0 || (sym->usage & (uENUMFIELD | uENUMROOT))!=0)
- continue;
- fprintf(log,"\t\t\n",funcdisplayname(symname,sym->name),sym->addr);
- if (sym->tag!=0) {
- tagsym=find_tag_byval(sym->tag);
- assert(tagsym!=NULL);
- fprintf(log,"\t\t\t\n",tagsym->name);
- } /* if */
- assert(sym->refer!=NULL);
- for (i=0; inumrefers; i++) {
- if ((ref=sym->refer[i])!=NULL)
- fprintf(log,"\t\t\t\n",xmlencode(symname,funcdisplayname(symname,ref->name)));
- } /* for */
- if (sym->documentation!=NULL)
- fprintf(log,"\t\t\t%s\n",sym->documentation);
- fprintf(log,"\t\t\n");
- } /* for */
+ if (sym->parent!=NULL)
+ continue; /* hierarchical data type */
+ assert(sym->ident==iCONSTEXPR || sym->ident==iVARIABLE
+ || sym->ident==iARRAY || sym->ident==iFUNCTN);
+ if (sym->ident!=iCONSTEXPR)
+ continue;
+ if ((sym->usage & uREAD)==0 || (sym->usage & (uENUMFIELD | uENUMROOT))!=0)
+ continue;
+ fprintf(log,"\t\t\n",funcdisplayname(symname,sym->name),sym->addr);
+ if (sym->tag!=0) {
+ tagsym=find_tag_byval(sym->tag);
+ assert(tagsym!=NULL);
+ fprintf(log,"\t\t\t\n",tagsym->name);
+ } /* if */
+ assert(sym->refer!=NULL);
+ for (i=0; inumrefers; i++) {
+ if ((ref=sym->refer[i])!=NULL)
+ fprintf(log,"\t\t\t\n",xmlencode(symname,funcdisplayname(symname,ref->name)));
+ } /* for */
+ if (sym->documentation!=NULL)
+ fprintf(log,"\t\t\t%s\n",sym->documentation);
+ fprintf(log,"\t\t\n");
+ } /* for */
- fprintf(log,"\n\t\t\n");
+ fprintf(log,"\n\t\t\n");
for (sym=root->next; sym!=NULL; sym=sym->next) {
- if (sym->parent!=NULL)
- continue; /* hierarchical data type */
- if (sym->ident!=iVARIABLE && sym->ident!=iARRAY)
- continue;
- fprintf(log,"\t\t\n",funcdisplayname(symname,sym->name));
- if (sym->tag!=0) {
- tagsym=find_tag_byval(sym->tag);
- assert(tagsym!=NULL);
- fprintf(log,"\t\t\t\n",tagsym->name);
- } /* if */
- assert(sym->refer!=NULL);
- if ((sym->usage & uPUBLIC)!=0)
- fprintf(log,"\t\t\t\n");
- for (i=0; inumrefers; i++) {
- if ((ref=sym->refer[i])!=NULL)
- fprintf(log,"\t\t\t\n",xmlencode(symname,funcdisplayname(symname,ref->name)));
- } /* for */
- if (sym->documentation!=NULL)
- fprintf(log,"\t\t\t%s\n",sym->documentation);
- fprintf(log,"\t\t\n");
- } /* for */
+ if (sym->parent!=NULL)
+ continue; /* hierarchical data type */
+ if (sym->ident!=iVARIABLE && sym->ident!=iARRAY)
+ continue;
+ fprintf(log,"\t\t\n",funcdisplayname(symname,sym->name));
+ if (sym->tag!=0) {
+ tagsym=find_tag_byval(sym->tag);
+ assert(tagsym!=NULL);
+ fprintf(log,"\t\t\t\n",tagsym->name);
+ } /* if */
+ assert(sym->refer!=NULL);
+ if ((sym->usage & uPUBLIC)!=0)
+ fprintf(log,"\t\t\t\n");
+ for (i=0; inumrefers; i++) {
+ if ((ref=sym->refer[i])!=NULL)
+ fprintf(log,"\t\t\t\n",xmlencode(symname,funcdisplayname(symname,ref->name)));
+ } /* for */
+ if (sym->documentation!=NULL)
+ fprintf(log,"\t\t\t%s\n",sym->documentation);
+ fprintf(log,"\t\t\n");
+ } /* for */
- fprintf(log,"\n\t\t\n");
+ fprintf(log,"\n\t\t\n");
for (sym=root->next; sym!=NULL; sym=sym->next) {
- if (sym->parent!=NULL)
- continue; /* hierarchical data type */
- if (sym->ident!=iFUNCTN)
- continue;
- if ((sym->usage & (uREAD | uNATIVE))==uNATIVE)
- continue; /* unused native function */
- funcdisplayname(symname,sym->name);
- xmlencode(symname,symname);
- fprintf(log,"\t\tdim.arglist!=NULL);
- for (arg=0; sym->dim.arglist[arg].ident!=0; arg++) {
- int dim;
- if (arg>0)
- fprintf(log,", ");
- switch (sym->dim.arglist[arg].ident) {
- case iVARIABLE:
- fprintf(log,"%s",sym->dim.arglist[arg].name);
- break;
- case iREFERENCE:
- fprintf(log,"&%s",sym->dim.arglist[arg].name);
- break;
- case iREFARRAY:
- fprintf(log,"%s",sym->dim.arglist[arg].name);
- for (dim=0; dimdim.arglist[arg].numdim;dim++)
- fprintf(log,"[]");
- break;
- case iVARARGS:
- fprintf(log,"...");
- break;
- } /* switch */
- } /* for */
- /* ??? should also print an "array return" size */
- fprintf(log,")\">\n");
- if (sym->tag!=0) {
- tagsym=find_tag_byval(sym->tag);
- assert(tagsym!=NULL);
- fprintf(log,"\t\t\t\n",tagsym->name);
- } /* if */
- /* check whether this function is called from the outside */
- if ((sym->usage & uNATIVE)!=0)
- fprintf(log,"\t\t\t\n");
- if ((sym->usage & uPUBLIC)!=0)
- fprintf(log,"\t\t\t\n");
- if (strcmp(sym->name,uMAINFUNC)==0 || strcmp(sym->name,uENTRYFUNC)==0)
- fprintf(log,"\t\t\t\n");
- if ((sym->usage & uNATIVE)==0)
- fprintf(log,"\t\t\t\n",(long)sym->x.stacksize);
- if (sym->states!=NULL) {
- constvalue *stlist=sym->states->next;
- assert(stlist!=NULL); /* there should be at least one state item */
- while (stlist!=NULL && stlist->index==-1)
- stlist=stlist->next;
- assert(stlist!=NULL); /* state id should be found */
- i=state_getfsa(stlist->index);
- assert(i>=0); /* automaton 0 exists */
- stlist=automaton_findid(i);
- assert(stlist!=NULL); /* automaton should be found */
- fprintf(log,"\t\t\t\n", strlen(stlist->name)>0 ? stlist->name : "(anonymous)");
- //??? dump state decision table
- } /* if */
- assert(sym->refer!=NULL);
- for (i=0; inumrefers; i++)
- if ((ref=sym->refer[i])!=NULL)
- fprintf(log,"\t\t\t\n",xmlencode(symname,funcdisplayname(symname,ref->name)));
- /* print all symbols that are required for this function to compile */
- for (ref=root->next; ref!=NULL; ref=ref->next) {
- if (ref==sym)
- continue;
- for (i=0; inumrefers; i++)
- if (ref->refer[i]==sym)
- fprintf(log,"\t\t\t\n",xmlencode(symname,funcdisplayname(symname,ref->name)));
- } /* for */
- /* print parameter list, with tag & const information, plus descriptions */
- assert(sym->dim.arglist!=NULL);
- for (arg=0; sym->dim.arglist[arg].ident!=0; arg++) {
- int dim,paraminfo;
- char *outer_start,*inner_start;
- int outer_length,inner_length;
- if (sym->dim.arglist[arg].ident==iVARARGS)
- fprintf(log,"\t\t\t\n");
- else
- fprintf(log,"\t\t\t\n",sym->dim.arglist[arg].name);
- /* print the tag name(s) for each parameter */
- assert(sym->dim.arglist[arg].numtags>0);
- assert(sym->dim.arglist[arg].tags!=NULL);
- paraminfo=(sym->dim.arglist[arg].numtags>1 || sym->dim.arglist[arg].tags[0]!=0)
- || sym->dim.arglist[arg].ident==iREFERENCE
- || sym->dim.arglist[arg].ident==iREFARRAY;
- if (paraminfo)
- fprintf(log,"\t\t\t\t");
- if (sym->dim.arglist[arg].numtags>1 || sym->dim.arglist[arg].tags[0]!=0) {
- assert(paraminfo);
- if (sym->dim.arglist[arg].numtags>1)
- fprintf(log," {");
- for (i=0; idim.arglist[arg].numtags; i++) {
- if (i>0)
- fprintf(log,",");
- tagsym=find_tag_byval(sym->dim.arglist[arg].tags[i]);
- assert(tagsym!=NULL);
- fprintf(log,"%s",tagsym->name);
- } /* for */
- if (sym->dim.arglist[arg].numtags>1)
- fprintf(log,"}");
- } /* if */
- switch (sym->dim.arglist[arg].ident) {
- case iREFERENCE:
- fprintf(log," &");
- break;
- case iREFARRAY:
- fprintf(log," ");
- for (dim=0; dimdim.arglist[arg].numdim; dim++) {
- if (sym->dim.arglist[arg].dim[dim]==0) {
- fprintf(log,"[]");
- } else {
- //??? find index tag
- fprintf(log,"[%d]",sym->dim.arglist[arg].dim[dim]);
- } /* if */
- } /* for */
- break;
- } /* switch */
- if (paraminfo)
- fprintf(log," \n");
- /* print the user description of the parameter (parse through
- * sym->documentation)
- */
- if (sym->documentation!=NULL
- && find_xmltag(sym->documentation, "param", "name", sym->dim.arglist[arg].name,
- &outer_start, &outer_length, &inner_start, &inner_length))
- {
- char *tail;
- fprintf(log,"\t\t\t\t%.*s\n",inner_length,inner_start);
- /* delete from documentation string */
- tail=outer_start+outer_length;
- memmove(outer_start,tail,strlen(tail)+1);
- } /* if */
- fprintf(log,"\t\t\t\n");
- } /* for */
- if (sym->documentation!=NULL)
- fprintf(log,"\t\t\t%s\n",sym->documentation);
- fprintf(log,"\t\t\n");
- } /* for */
+ if (sym->parent!=NULL)
+ continue; /* hierarchical data type */
+ if (sym->ident!=iFUNCTN)
+ continue;
+ if ((sym->usage & (uREAD | uNATIVE))==uNATIVE)
+ continue; /* unused native function */
+ funcdisplayname(symname,sym->name);
+ xmlencode(symname,symname);
+ fprintf(log,"\t\tdim.arglist!=NULL);
+ for (arg=0; sym->dim.arglist[arg].ident!=0; arg++) {
+ int dim;
+ if (arg>0)
+ fprintf(log,", ");
+ switch (sym->dim.arglist[arg].ident) {
+ case iVARIABLE:
+ fprintf(log,"%s",sym->dim.arglist[arg].name);
+ break;
+ case iREFERENCE:
+ fprintf(log,"&%s",sym->dim.arglist[arg].name);
+ break;
+ case iREFARRAY:
+ fprintf(log,"%s",sym->dim.arglist[arg].name);
+ for (dim=0; dimdim.arglist[arg].numdim;dim++)
+ fprintf(log,"[]");
+ break;
+ case iVARARGS:
+ fprintf(log,"...");
+ break;
+ } /* switch */
+ } /* for */
+ /* ??? should also print an "array return" size */
+ fprintf(log,")\">\n");
+ if (sym->tag!=0) {
+ tagsym=find_tag_byval(sym->tag);
+ assert(tagsym!=NULL);
+ fprintf(log,"\t\t\t\n",tagsym->name);
+ } /* if */
+ /* check whether this function is called from the outside */
+ if ((sym->usage & uNATIVE)!=0)
+ fprintf(log,"\t\t\t\n");
+ if ((sym->usage & uPUBLIC)!=0)
+ fprintf(log,"\t\t\t\n");
+ if (strcmp(sym->name,uMAINFUNC)==0 || strcmp(sym->name,uENTRYFUNC)==0)
+ fprintf(log,"\t\t\t\n");
+ if ((sym->usage & uNATIVE)==0)
+ fprintf(log,"\t\t\t\n",(long)sym->x.stacksize);
+ if (sym->states!=NULL) {
+ constvalue *stlist=sym->states->next;
+ assert(stlist!=NULL); /* there should be at least one state item */
+ while (stlist!=NULL && stlist->index==-1)
+ stlist=stlist->next;
+ assert(stlist!=NULL); /* state id should be found */
+ i=state_getfsa(stlist->index);
+ assert(i>=0); /* automaton 0 exists */
+ stlist=automaton_findid(i);
+ assert(stlist!=NULL); /* automaton should be found */
+ fprintf(log,"\t\t\t\n", strlen(stlist->name)>0 ? stlist->name : "(anonymous)");
+ //??? dump state decision table
+ } /* if */
+ assert(sym->refer!=NULL);
+ for (i=0; inumrefers; i++)
+ if ((ref=sym->refer[i])!=NULL)
+ fprintf(log,"\t\t\t\n",xmlencode(symname,funcdisplayname(symname,ref->name)));
+ /* print all symbols that are required for this function to compile */
+ for (ref=root->next; ref!=NULL; ref=ref->next) {
+ if (ref==sym)
+ continue;
+ for (i=0; inumrefers; i++)
+ if (ref->refer[i]==sym)
+ fprintf(log,"\t\t\t\n",xmlencode(symname,funcdisplayname(symname,ref->name)));
+ } /* for */
+ /* print parameter list, with tag & const information, plus descriptions */
+ assert(sym->dim.arglist!=NULL);
+ for (arg=0; sym->dim.arglist[arg].ident!=0; arg++) {
+ int dim,paraminfo;
+ char *outer_start,*inner_start;
+ int outer_length,inner_length;
+ if (sym->dim.arglist[arg].ident==iVARARGS)
+ fprintf(log,"\t\t\t\n");
+ else
+ fprintf(log,"\t\t\t\n",sym->dim.arglist[arg].name);
+ /* print the tag name(s) for each parameter */
+ assert(sym->dim.arglist[arg].numtags>0);
+ assert(sym->dim.arglist[arg].tags!=NULL);
+ paraminfo=(sym->dim.arglist[arg].numtags>1 || sym->dim.arglist[arg].tags[0]!=0)
+ || sym->dim.arglist[arg].ident==iREFERENCE
+ || sym->dim.arglist[arg].ident==iREFARRAY;
+ if (paraminfo)
+ fprintf(log,"\t\t\t\t");
+ if (sym->dim.arglist[arg].numtags>1 || sym->dim.arglist[arg].tags[0]!=0) {
+ assert(paraminfo);
+ if (sym->dim.arglist[arg].numtags>1)
+ fprintf(log," {");
+ for (i=0; idim.arglist[arg].numtags; i++) {
+ if (i>0)
+ fprintf(log,",");
+ tagsym=find_tag_byval(sym->dim.arglist[arg].tags[i]);
+ assert(tagsym!=NULL);
+ fprintf(log,"%s",tagsym->name);
+ } /* for */
+ if (sym->dim.arglist[arg].numtags>1)
+ fprintf(log,"}");
+ } /* if */
+ switch (sym->dim.arglist[arg].ident) {
+ case iREFERENCE:
+ fprintf(log," &");
+ break;
+ case iREFARRAY:
+ fprintf(log," ");
+ for (dim=0; dimdim.arglist[arg].numdim; dim++) {
+ if (sym->dim.arglist[arg].dim[dim]==0) {
+ fprintf(log,"[]");
+ } else {
+ //??? find index tag
+ fprintf(log,"[%d]",sym->dim.arglist[arg].dim[dim]);
+ } /* if */
+ } /* for */
+ break;
+ } /* switch */
+ if (paraminfo)
+ fprintf(log," \n");
+ /* print the user description of the parameter (parse through
+ * sym->documentation)
+ */
+ if (sym->documentation!=NULL
+ && find_xmltag(sym->documentation, "param", "name", sym->dim.arglist[arg].name,
+ &outer_start, &outer_length, &inner_start, &inner_length))
+ {
+ char *tail;
+ fprintf(log,"\t\t\t\t%.*s\n",inner_length,inner_start);
+ /* delete from documentation string */
+ tail=outer_start+outer_length;
+ memmove(outer_start,tail,strlen(tail)+1);
+ } /* if */
+ fprintf(log,"\t\t\t\n");
+ } /* for */
+ if (sym->documentation!=NULL)
+ fprintf(log,"\t\t\t%s\n",sym->documentation);
+ fprintf(log,"\t\t\n");
+ } /* for */
fprintf(log,"\n\t\n");
fprintf(log,"\n");
}
#endif
-/* Every symbol has a referrer list, that contains the functions that use
- * the symbol. Now, if function "apple" is accessed by functions "banana" and
- * "citron", but neither function "banana" nor "citron" are used by anyone
+/* Every symbol has a referrer list, that contains the functions that use
+ * the symbol. Now, if function "apple" is accessed by functions "banana" and
+ * "citron", but neither function "banana" nor "citron" are used by anyone
* else, then, by inference, function "apple" is not used either.
*/
-static void reduce_referrers(symbol *root)
+static void reduce_referrers(symbol *root)
{
int i,restart;
symbol *sym,*ref;
do {
- restart=0;
- for (sym=root->next; sym!=NULL; sym=sym->next) {
- if (sym->parent!=NULL)
- continue; /* hierarchical data type */
- if (sym->ident==iFUNCTN
- && (sym->usage & uNATIVE)==0
- && (sym->usage & uPUBLIC)==0 && strcmp(sym->name,uMAINFUNC)!=0 && strcmp(sym->name,uENTRYFUNC)!=0
- && count_referrers(sym)==0)
- {
- sym->usage&=~(uREAD | uWRITTEN); /* erase usage bits if there is no referrer */
- /* find all symbols that are referred by this symbol */
- for (ref=root->next; ref!=NULL; ref=ref->next) {
- if (ref->parent!=NULL)
- continue; /* hierarchical data type */
- assert(ref->refer!=NULL);
- for (i=0; inumrefers && ref->refer[i]!=sym; i++)
- /* nothing */;
- if (inumrefers) {
- assert(ref->refer[i]==sym);
- ref->refer[i]=NULL;
- restart++;
- } /* if */
- } /* for */
- } else if ((sym->ident==iVARIABLE || sym->ident==iARRAY)
- && (sym->usage & uPUBLIC)==0
- && sym->parent==NULL
- && count_referrers(sym)==0)
- {
- sym->usage&=~(uREAD | uWRITTEN); /* erase usage bits if there is no referrer */
- } /* if */
- } /* for */
- /* after removing a symbol, check whether more can be removed */
- } while (restart>0);
+ restart=0;
+ for (sym=root->next; sym!=NULL; sym=sym->next) {
+ if (sym->parent!=NULL)
+ continue; /* hierarchical data type */
+ if (sym->ident==iFUNCTN
+ && (sym->usage & uNATIVE)==0
+ && (sym->usage & uPUBLIC)==0 && strcmp(sym->name,uMAINFUNC)!=0 && strcmp(sym->name,uENTRYFUNC)!=0
+ && count_referrers(sym)==0)
+ {
+ sym->usage&=~(uREAD | uWRITTEN); /* erase usage bits if there is no referrer */
+ /* find all symbols that are referred by this symbol */
+ for (ref=root->next; ref!=NULL; ref=ref->next) {
+ if (ref->parent!=NULL)
+ continue; /* hierarchical data type */
+ assert(ref->refer!=NULL);
+ for (i=0; inumrefers && ref->refer[i]!=sym; i++)
+ /* nothing */;
+ if (inumrefers) {
+ assert(ref->refer[i]==sym);
+ ref->refer[i]=NULL;
+ restart++;
+ } /* if */
+ } /* for */
+ } else if ((sym->ident==iVARIABLE || sym->ident==iARRAY)
+ && (sym->usage & uPUBLIC)==0
+ && sym->parent==NULL
+ && count_referrers(sym)==0)
+ {
+ sym->usage&=~(uREAD | uWRITTEN); /* erase usage bits if there is no referrer */
+ } /* if */
+ } /* for */
+ /* after removing a symbol, check whether more can be removed */
+ } while (restart>0);
}
-#if !defined SC_LIGHT
-static long max_stacksize_recurse(symbol *sym,long basesize,int *pubfuncparams)
+#if !defined SC_LIGHT
+static long max_stacksize_recurse(symbol *sym,long basesize,int *pubfuncparams)
{
long size,maxsize;
int i;
@@ -4137,246 +4137,246 @@ static long max_stacksize_recurse(symbol *sym,long basesize,int *pubfuncparams)
assert((sym->usage & uNATIVE)==0);
/* recursion detection */
if (sym->compound==0)
- return -1; /* this function was processed already -> recursion */
+ return -1; /* this function was processed already -> recursion */
sym->compound=0;
maxsize=sym->x.stacksize;
- for (i=0; inumrefers; i++) {
- if (sym->refer[i]!=NULL) {
- assert(sym->refer[i]->ident==iFUNCTN);
- assert((sym->refer[i]->usage & uNATIVE)==0); /* a native function cannot refer to a user-function */
- size=max_stacksize_recurse(sym->refer[i],sym->x.stacksize,pubfuncparams);
- if (size<0)
- return size; /* recursion was detected, quit */
- if (maxsizenumrefers; i++) {
+ if (sym->refer[i]!=NULL) {
+ assert(sym->refer[i]->ident==iFUNCTN);
+ assert((sym->refer[i]->usage & uNATIVE)==0); /* a native function cannot refer to a user-function */
+ size=max_stacksize_recurse(sym->refer[i],sym->x.stacksize,pubfuncparams);
+ if (size<0)
+ return size; /* recursion was detected, quit */
+ if (maxsizeusage & uPUBLIC)!=0) {
- /* Find out how many parameters a public function has, then see if this
- * is bigger than some maximum
- */
- arginfo *arg=sym->dim.arglist;
- int count=0;
- assert(arg!=0);
- while (arg->ident!=0) {
- count++;
- arg++;
- } /* while */
- assert(pubfuncparams!=0);
- if (count>*pubfuncparams)
- *pubfuncparams=count;
- } /* if */
+ if ((sym->usage & uPUBLIC)!=0) {
+ /* Find out how many parameters a public function has, then see if this
+ * is bigger than some maximum
+ */
+ arginfo *arg=sym->dim.arglist;
+ int count=0;
+ assert(arg!=0);
+ while (arg->ident!=0) {
+ count++;
+ arg++;
+ } /* while */
+ assert(pubfuncparams!=0);
+ if (count>*pubfuncparams)
+ *pubfuncparams=count;
+ } /* if */
return maxsize+basesize;
}
-static long max_stacksize(symbol *root)
+static long max_stacksize(symbol *root)
{
- /* Loop over all non-native functions. For each function, loop
- * over all of its referrers, accumulating the stack requirements.
- * Detect (indirect) recursion with a "mark-and-sweep" algorithm.
- * I (mis-)use the "compound" field of the symbol structure for
- * the marker, as this field is unused for functions.
+ /* Loop over all non-native functions. For each function, loop
+ * over all of its referrers, accumulating the stack requirements.
+ * Detect (indirect) recursion with a "mark-and-sweep" algorithm.
+ * I (mis-)use the "compound" field of the symbol structure for
+ * the marker, as this field is unused for functions.
*
- * Note that the stack is shared with the heap. A host application
- * may "eat" cells from the heap as well, through amx_Allot(). The
- * stack requirements are thus only an estimate.
+ * Note that the stack is shared with the heap. A host application
+ * may "eat" cells from the heap as well, through amx_Allot(). The
+ * stack requirements are thus only an estimate.
*/
long size,maxsize;
int maxparams;
symbol *sym;
#if !defined NDEBUG
- for (sym=root->next; sym!=NULL; sym=sym->next)
- if (sym->ident==iFUNCTN)
- assert(sym->compound==0);
+ for (sym=root->next; sym!=NULL; sym=sym->next)
+ if (sym->ident==iFUNCTN)
+ assert(sym->compound==0);
#endif
maxsize=0;
maxparams=0;
for (sym=root->next; sym!=NULL; sym=sym->next) {
- symbol *tmpsym;
- /* drop out if this is not a user-implemented function */
- if (sym->ident!=iFUNCTN || (sym->usage & uNATIVE)!=0)
- continue;
- /* set a "mark" on all functions */
- for (tmpsym=root->next; tmpsym!=NULL; tmpsym=tmpsym->next)
- if (tmpsym->ident==iFUNCTN)
- tmpsym->compound=1;
- /* accumulate stack size for this symbol */
- size=max_stacksize_recurse(sym,0L,&maxparams);
- if (size<0)
- return size; /* recursion was detected */
- if (maxsizeident!=iFUNCTN || (sym->usage & uNATIVE)!=0)
+ continue;
+ /* set a "mark" on all functions */
+ for (tmpsym=root->next; tmpsym!=NULL; tmpsym=tmpsym->next)
+ if (tmpsym->ident==iFUNCTN)
+ tmpsym->compound=1;
+ /* accumulate stack size for this symbol */
+ size=max_stacksize_recurse(sym,0L,&maxparams);
+ if (size<0)
+ return size; /* recursion was detected */
+ if (maxsizenext; sym!=NULL; sym=sym->next)
- if (sym->ident==iFUNCTN)
- sym->compound=0;
+ if (sym->ident==iFUNCTN)
+ sym->compound=0;
- maxsize++; /* +1 because a zero cell is always pushed on top
- * of the stack to catch stack overwrites */
- return maxsize+(maxparams+1);/* +1 because # of parameters is always pushed on entry */
+ maxsize++; /* +1 because a zero cell is always pushed on top
+ * of the stack to catch stack overwrites */
+ return maxsize+(maxparams+1);/* +1 because # of parameters is always pushed on entry */
}
#endif
-/* testsymbols - test for unused local or global variables
+/* testsymbols - test for unused local or global variables
*
- * "Public" functions are excluded from the check, since these
- * may be exported to other object modules.
- * Labels are excluded from the check if the argument 'testlabs'
- * is 0. Thus, labels are not tested until the end of the function.
- * Constants may also be excluded (convenient for global constants).
+ * "Public" functions are excluded from the check, since these
+ * may be exported to other object modules.
+ * Labels are excluded from the check if the argument 'testlabs'
+ * is 0. Thus, labels are not tested until the end of the function.
+ * Constants may also be excluded (convenient for global constants).
*
- * When the nesting level drops below "level", the check stops.
+ * When the nesting level drops below "level", the check stops.
*
- * The function returns whether there is an "entry" point for the file.
- * This flag will only be 1 when browsing the global symbol table.
+ * The function returns whether there is an "entry" point for the file.
+ * This flag will only be 1 when browsing the global symbol table.
*/
-static int testsymbols(symbol *root,int level,int testlabs,int testconst)
+static int testsymbols(symbol *root,int level,int testlabs,int testconst)
{
char symname[2*sNAMEMAX+16];
int entry=FALSE;
symbol *sym=root->next;
- while (sym!=NULL && sym->compound>=level) {
- switch (sym->ident) {
- case iLABEL:
- if (testlabs) {
- if ((sym->usage & uDEFINE)==0)
- error(19,sym->name); /* not a label: ... */
- else if ((sym->usage & uREAD)==0)
- error(203,sym->name); /* symbol isn't used: ... */
- } /* if */
- break;
- case iFUNCTN:
- if ((sym->usage & (uDEFINE | uREAD | uNATIVE | uSTOCK))==uDEFINE) {
- funcdisplayname(symname,sym->name);
- if (strlen(symname)>0)
- error(203,symname); /* symbol isn't used ... (and not native/stock) */
- } /* if */
- if ((sym->usage & uPUBLIC)!=0 || strcmp(sym->name,uMAINFUNC)==0)
- entry=TRUE; /* there is an entry point */
- /* also mark the function to the debug information */
- if ((sym->usage & uREAD)!=0 && (sym->usage & uNATIVE)==0)
- insert_dbgsymbol(sym);
- break;
- case iCONSTEXPR:
- if (testconst && (sym->usage & uREAD)==0)
- error(203,sym->name); /* symbol isn't used: ... */
- break;
- default:
- /* a variable */
- if (sym->parent!=NULL)
- break; /* hierarchical data type */
- if ((sym->usage & (uWRITTEN | uREAD | uSTOCK))==0)
- error(203,sym->name); /* symbol isn't used (and not stock) */
- else if ((sym->usage & (uREAD | uSTOCK | uPUBLIC))==0)
- error(204,sym->name); /* value assigned to symbol is never used */
-#if 0 // ??? not sure whether it is a good idea to force people use "const"
- else if ((sym->usage & (uWRITTEN | uPUBLIC | uCONST))==0 && sym->ident==iREFARRAY)
- error(214,sym->name); /* make array argument "const" */
+ while (sym!=NULL && sym->compound>=level) {
+ switch (sym->ident) {
+ case iLABEL:
+ if (testlabs) {
+ if ((sym->usage & uDEFINE)==0)
+ error(19,sym->name); /* not a label: ... */
+ else if ((sym->usage & uREAD)==0)
+ error(203,sym->name); /* symbol isn't used: ... */
+ } /* if */
+ break;
+ case iFUNCTN:
+ if ((sym->usage & (uDEFINE | uREAD | uNATIVE | uSTOCK))==uDEFINE) {
+ funcdisplayname(symname,sym->name);
+ if (strlen(symname)>0)
+ error(203,symname); /* symbol isn't used ... (and not native/stock) */
+ } /* if */
+ if ((sym->usage & uPUBLIC)!=0 || strcmp(sym->name,uMAINFUNC)==0)
+ entry=TRUE; /* there is an entry point */
+ /* also mark the function to the debug information */
+ if ((sym->usage & uREAD)!=0 && (sym->usage & uNATIVE)==0)
+ insert_dbgsymbol(sym);
+ break;
+ case iCONSTEXPR:
+ if (testconst && (sym->usage & uREAD)==0)
+ error(203,sym->name); /* symbol isn't used: ... */
+ break;
+ default:
+ /* a variable */
+ if (sym->parent!=NULL)
+ break; /* hierarchical data type */
+ if ((sym->usage & (uWRITTEN | uREAD | uSTOCK))==0)
+ error(203,sym->name); /* symbol isn't used (and not stock) */
+ else if ((sym->usage & (uREAD | uSTOCK | uPUBLIC))==0)
+ error(204,sym->name); /* value assigned to symbol is never used */
+#if 0 // ??? not sure whether it is a good idea to force people use "const"
+ else if ((sym->usage & (uWRITTEN | uPUBLIC | uCONST))==0 && sym->ident==iREFARRAY)
+ error(214,sym->name); /* make array argument "const" */
#endif
- /* also mark the variable (local or global) to the debug information */
- if ((sym->usage & (uWRITTEN | uREAD))!=0 && (sym->usage & uNATIVE)==0)
- insert_dbgsymbol(sym);
- } /* if */
- sym=sym->next;
- } /* while */
+ /* also mark the variable (local or global) to the debug information */
+ if ((sym->usage & (uWRITTEN | uREAD))!=0 && (sym->usage & uNATIVE)==0)
+ insert_dbgsymbol(sym);
+ } /* if */
+ sym=sym->next;
+ } /* while */
return entry;
}
-static cell calc_array_datasize(symbol *sym, cell *offset)
+static cell calc_array_datasize(symbol *sym, cell *offset)
{
cell length;
assert(sym!=NULL);
- assert(sym->ident==iARRAY || sym->ident==iREFARRAY);
+ assert(sym->ident==iARRAY || sym->ident==iREFARRAY);
length=sym->dim.array.length;
- if (sym->dim.array.level > 0) {
- cell sublength=calc_array_datasize(finddepend(sym),offset);
- if (offset!=NULL)
- *offset=length*(*offset+sizeof(cell));
- if (sublength>0)
- length*=length*sublength;
- else
- length=0;
- } else {
- if (offset!=NULL)
- *offset=0;
- } /* if */
+ if (sym->dim.array.level > 0) {
+ cell sublength=calc_array_datasize(finddepend(sym),offset);
+ if (offset!=NULL)
+ *offset=length*(*offset+sizeof(cell));
+ if (sublength>0)
+ length*=length*sublength;
+ else
+ length=0;
+ } else {
+ if (offset!=NULL)
+ *offset=0;
+ } /* if */
return length;
}
-static void destructsymbols(symbol *root,int level)
+static void destructsymbols(symbol *root,int level)
{
cell offset=0;
int savepri=FALSE;
symbol *sym=root->next;
- while (sym!=NULL && sym->compound>=level) {
- if (sym->ident==iVARIABLE || sym->ident==iARRAY) {
- char symbolname[16];
- symbol *opsym;
- cell elements;
- /* check that the '~' operator is defined for this tag */
- operator_symname(symbolname,"~",sym->tag,0,1,0);
- if ((opsym=findglb(symbolname))!=NULL) {
- /* save PRI, in case of a return statment */
- if (!savepri) {
- pushreg(sPRI); /* right-hand operand is in PRI */
- savepri=TRUE;
- } /* if */
- /* if the variable is an array, get the number of elements */
- if (sym->ident==iARRAY) {
- elements=calc_array_datasize(sym,&offset);
- /* "elements" can be zero when the variable is declared like
- * new mytag: myvar[2][] = { {1, 2}, {3, 4} }
- * one should declare all dimensions!
- */
- if (elements==0)
- error(46,sym->name); /* array size is unknown */
- } else {
- elements=1;
- offset=0;
- } /* if */
- pushval(elements);
- /* call the '~' operator */
- address(sym,sPRI);
- addconst(offset); /* add offset to array data to the address */
- pushreg(sPRI);
- pushval(2*sizeof(cell));/* 2 parameters */
- assert(opsym->ident==iFUNCTN);
- ffcall(opsym,NULL,1);
- if (sc_status!=statSKIP)
- markusage(opsym,uREAD); /* do not mark as "used" when this call itself is skipped */
- if ((opsym->usage & uNATIVE)!=0 && opsym->x.lib!=NULL)
- opsym->x.lib->value += 1; /* increment "usage count" of the library */
- } /* if */
- } /* if */
- sym=sym->next;
- } /* while */
- /* restore PRI, if it was saved */
+ while (sym!=NULL && sym->compound>=level) {
+ if (sym->ident==iVARIABLE || sym->ident==iARRAY) {
+ char symbolname[16];
+ symbol *opsym;
+ cell elements;
+ /* check that the '~' operator is defined for this tag */
+ operator_symname(symbolname,"~",sym->tag,0,1,0);
+ if ((opsym=findglb(symbolname))!=NULL) {
+ /* save PRI, in case of a return statment */
+ if (!savepri) {
+ pushreg(sPRI); /* right-hand operand is in PRI */
+ savepri=TRUE;
+ } /* if */
+ /* if the variable is an array, get the number of elements */
+ if (sym->ident==iARRAY) {
+ elements=calc_array_datasize(sym,&offset);
+ /* "elements" can be zero when the variable is declared like
+ * new mytag: myvar[2][] = { {1, 2}, {3, 4} }
+ * one should declare all dimensions!
+ */
+ if (elements==0)
+ error(46,sym->name); /* array size is unknown */
+ } else {
+ elements=1;
+ offset=0;
+ } /* if */
+ pushval(elements);
+ /* call the '~' operator */
+ address(sym,sPRI);
+ addconst(offset); /* add offset to array data to the address */
+ pushreg(sPRI);
+ pushval(2*sizeof(cell));/* 2 parameters */
+ assert(opsym->ident==iFUNCTN);
+ ffcall(opsym,NULL,1);
+ if (sc_status!=statSKIP)
+ markusage(opsym,uREAD); /* do not mark as "used" when this call itself is skipped */
+ if ((opsym->usage & uNATIVE)!=0 && opsym->x.lib!=NULL)
+ opsym->x.lib->value += 1; /* increment "usage count" of the library */
+ } /* if */
+ } /* if */
+ sym=sym->next;
+ } /* while */
+ /* restore PRI, if it was saved */
if (savepri)
- popreg(sPRI);
+ popreg(sPRI);
}
-static constvalue *insert_constval(constvalue *prev,constvalue *next,const char *name,cell val,
- short index)
+static constvalue *insert_constval(constvalue *prev,constvalue *next,const char *name,cell val,
+ short index)
{
constvalue *cur;
if ((cur=(constvalue*)malloc(sizeof(constvalue)))==NULL)
- error(103); /* insufficient memory (fatal error) */
+ error(103); /* insufficient memory (fatal error) */
memset(cur,0,sizeof(constvalue));
if (name!=NULL) {
- assert(strlen(name)name,name);
- } /* if */
+ assert(strlen(name)name,name);
+ } /* if */
cur->value=val;
cur->index=index;
cur->next=next;
@@ -4384,369 +4384,369 @@ static constvalue *insert_constval(constvalue *prev,constvalue *next,const char
return cur;
}
-SC_FUNC constvalue *append_constval(constvalue *table,const char *name,cell val,short index)
+SC_FUNC constvalue *append_constval(constvalue *table,const char *name,cell val,short index)
{
constvalue *cur,*prev;
- /* find the end of the constant table */
- for (prev=table, cur=table->next; cur!=NULL; prev=cur, cur=cur->next)
- /* nothing */;
+ /* find the end of the constant table */
+ for (prev=table, cur=table->next; cur!=NULL; prev=cur, cur=cur->next)
+ /* nothing */;
return insert_constval(prev,NULL,name,val,index);
}
-SC_FUNC constvalue *find_constval(constvalue *table,char *name,short index)
+SC_FUNC constvalue *find_constval(constvalue *table,char *name,short index)
{
- constvalue *ptr = table->next;
+ constvalue *ptr = table->next;
- while (ptr!=NULL) {
- if (strcmp(name,ptr->name)==0 && ptr->index==index)
- return ptr;
- ptr=ptr->next;
- } /* while */
+ while (ptr!=NULL) {
+ if (strcmp(name,ptr->name)==0 && ptr->index==index)
+ return ptr;
+ ptr=ptr->next;
+ } /* while */
return NULL;
}
static constvalue *find_constval_byval(constvalue *table,cell val)
{
- constvalue *ptr = table->next;
+ constvalue *ptr = table->next;
- while (ptr!=NULL) {
- if (ptr->value==val)
- return ptr;
- ptr=ptr->next;
- } /* while */
+ while (ptr!=NULL) {
+ if (ptr->value==val)
+ return ptr;
+ ptr=ptr->next;
+ } /* while */
return NULL;
}
-#if 0 /* never used */
+#if 0 /* never used */
static int delete_constval(constvalue *table,char *name)
{
constvalue *prev = table;
- constvalue *cur = prev->next;
+ constvalue *cur = prev->next;
- while (cur!=NULL) {
- if (strcmp(name,cur->name)==0) {
- prev->next=cur->next;
- free(cur);
- return TRUE;
- } /* if */
- prev=cur;
- cur=cur->next;
- } /* while */
+ while (cur!=NULL) {
+ if (strcmp(name,cur->name)==0) {
+ prev->next=cur->next;
+ free(cur);
+ return TRUE;
+ } /* if */
+ prev=cur;
+ cur=cur->next;
+ } /* while */
return FALSE;
}
#endif
-SC_FUNC void delete_consttable(constvalue *table)
+SC_FUNC void delete_consttable(constvalue *table)
{
constvalue *cur=table->next, *next;
- while (cur!=NULL) {
- next=cur->next;
- free(cur);
- cur=next;
- } /* while */
+ while (cur!=NULL) {
+ next=cur->next;
+ free(cur);
+ cur=next;
+ } /* while */
memset(table,0,sizeof(constvalue));
}
-/* add_constant
+/* add_constant
*
- * Adds a symbol to the #define symbol table. Returns NULL on failure.
+ * Adds a symbol to the #define symbol table. Returns NULL on failure.
*/
-SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag)
+SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag)
{
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. */
+ /* 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);
if (!sym)
- sym=findloc(name);
+ sym=findloc(name);
if (sym) {
- /* silently ignore redefinitions of constants with the same value */
- if (sym->ident==iCONSTEXPR) {
- if (sym->addr!=val)
- error(201,name); /* redefinition of constant (different value) */
- } else {
- error(21,name); /* symbol already defined */
- return NULL;
- } /* if */
- return sym;
- } /* if */
+ /* silently ignore redefinitions of constants with the same value */
+ if (sym->ident==iCONSTEXPR) {
+ if (sym->addr!=val)
+ error(201,name); /* redefinition of constant (different value) */
+ } else {
+ error(21,name); /* symbol already defined */
+ return NULL;
+ } /* if */
+ return sym;
+ } /* if */
- /* constant doesn't exist yet, an entry must be created */
+ /* constant doesn't exist yet, an entry must be created */
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;
+ assert(sym!=NULL); /* fatal error 103 must be given on error */
+ if (sc_status == statIDLE)
+ sym->usage |= uPREDEF;
return sym;
}
-/* statement - The Statement Parser
+/* statement - The Statement Parser
*
- * This routine is called whenever the parser needs to know what statement
- * it encounters (i.e. whenever program syntax requires a statement).
+ * This routine is called whenever the parser needs to know what statement
+ * it encounters (i.e. whenever program syntax requires a statement).
*/
-static void statement(int *lastindent,int allow_decl)
+static void statement(int *lastindent,int allow_decl)
{
int tok;
cell val;
char *st;
if (!freading) {
- error(36); /* empty statement */
- return;
- } /* if */
+ error(36); /* empty statement */
+ return;
+ } /* if */
errorset(sRESET);
tok=lex(&val,&st);
- if (tok!='{') {
- insert_dbgline(fline);
- setline(TRUE);
- } /* if */
+ if (tok!='{') {
+ insert_dbgline(fline);
+ setline(TRUE);
+ } /* if */
/* lex() has set stmtindent */
if (lastindent!=NULL && tok!=tLABEL) {
- if (*lastindent>=0 && *lastindent!=stmtindent && !indent_nowarn && sc_tabsize>0)
- error(217); /* loose indentation */
- *lastindent=stmtindent;
- indent_nowarn=FALSE; /* if warning was blocked, re-enable it */
- } /* if */
+ if (*lastindent>=0 && *lastindent!=stmtindent && !indent_nowarn && sc_tabsize>0)
+ error(217); /* loose indentation */
+ *lastindent=stmtindent;
+ indent_nowarn=FALSE; /* if warning was blocked, re-enable it */
+ } /* if */
switch (tok) {
case 0:
- /* nothing */
- break;
+ /* nothing */
+ break;
case tNEW:
- if (allow_decl) {
- declloc(FALSE);
- lastst=tNEW;
- } else {
- error(3); /* declaration only valid in a block */
- } /* if */
- break;
+ if (allow_decl) {
+ declloc(FALSE);
+ lastst=tNEW;
+ } else {
+ error(3); /* declaration only valid in a block */
+ } /* if */
+ break;
case tSTATIC:
- if (allow_decl) {
- declloc(TRUE);
- lastst=tNEW;
- } else {
- error(3); /* declaration only valid in a block */
- } /* if */
- break;
+ if (allow_decl) {
+ declloc(TRUE);
+ lastst=tNEW;
+ } else {
+ error(3); /* declaration only valid in a block */
+ } /* if */
+ break;
case '{':
- tok=fline;
- if (!matchtoken('}')) /* {} is the empty statement */
- compound(tok==fline);
- /* lastst (for "last statement") does not change */
- break;
+ tok=fline;
+ if (!matchtoken('}')) /* {} is the empty statement */
+ compound(tok==fline);
+ /* lastst (for "last statement") does not change */
+ break;
case ';':
- error(36); /* empty statement */
- break;
+ error(36); /* empty statement */
+ break;
case tIF:
- doif();
- lastst=tIF;
- break;
+ doif();
+ lastst=tIF;
+ break;
case tWHILE:
- dowhile();
- lastst=tWHILE;
- break;
+ dowhile();
+ lastst=tWHILE;
+ break;
case tDO:
- dodo();
- lastst=tDO;
- break;
+ dodo();
+ lastst=tDO;
+ break;
case tFOR:
- dofor();
- lastst=tFOR;
- break;
+ dofor();
+ lastst=tFOR;
+ break;
case tSWITCH:
- doswitch();
- lastst=tSWITCH;
- break;
+ doswitch();
+ lastst=tSWITCH;
+ break;
case tCASE:
case tDEFAULT:
- error(14); /* not in switch */
- break;
+ error(14); /* not in switch */
+ break;
case tGOTO:
- dogoto();
- lastst=tGOTO;
- break;
+ dogoto();
+ lastst=tGOTO;
+ break;
case tLABEL:
- dolabel();
- lastst=tLABEL;
- break;
+ dolabel();
+ lastst=tLABEL;
+ break;
case tRETURN:
- doreturn();
- lastst=tRETURN;
- break;
+ doreturn();
+ lastst=tRETURN;
+ break;
case tBREAK:
- dobreak();
- lastst=tBREAK;
- break;
+ dobreak();
+ lastst=tBREAK;
+ break;
case tCONTINUE:
- docont();
- lastst=tCONTINUE;
- break;
+ docont();
+ lastst=tCONTINUE;
+ break;
case tEXIT:
- doexit();
- lastst=tEXIT;
- break;
+ doexit();
+ lastst=tEXIT;
+ break;
case tASSERT:
- doassert();
- lastst=tASSERT;
- break;
+ doassert();
+ lastst=tASSERT;
+ break;
case tSLEEP:
- dosleep();
- lastst=tSLEEP;
- break;
+ dosleep();
+ lastst=tSLEEP;
+ break;
case tSTATE:
- dostate();
- lastst=tSTATE;
- break;
+ dostate();
+ lastst=tSTATE;
+ break;
case tCONST:
- decl_const(sLOCAL);
- break;
+ decl_const(sLOCAL);
+ break;
case tENUM:
- decl_enum(sLOCAL);
- break;
- default: /* non-empty expression */
- sc_allowproccall=optproccall;
- lexpush(); /* analyze token later */
- doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE);
- needtoken(tTERM);
- lastst=tEXPR;
- sc_allowproccall=FALSE;
- } /* switch */
+ decl_enum(sLOCAL);
+ break;
+ default: /* non-empty expression */
+ sc_allowproccall=optproccall;
+ lexpush(); /* analyze token later */
+ doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE);
+ needtoken(tTERM);
+ lastst=tEXPR;
+ sc_allowproccall=FALSE;
+ } /* switch */
}
-static void compound(int stmt_sameline)
+static void compound(int stmt_sameline)
{
int indent=-1;
cell save_decl=declared;
int count_stmt=0;
- /* if there is more text on this line, we should adjust the statement indent */
+ /* if there is more text on this line, we should adjust the statement indent */
if (stmt_sameline) {
- int i;
- const unsigned char *p=lptr;
- /* go back to the opening brace */
- while (*p!='{') {
- assert(p>pline);
- p--;
- } /* while */
- assert(*p=='{'); /* it should be found */
- /* go forward, skipping white-space */
- p++;
- while (*p<=' ' && *p!='\0')
- p++;
- assert(*p!='\0'); /* a token should be found */
- stmtindent=0;
- for (i=0; i<(int)(p-pline); i++)
- if (pline[i]=='\t' && sc_tabsize>0)
- stmtindent += (int)(sc_tabsize - (stmtindent+sc_tabsize) % sc_tabsize);
- else
- stmtindent++;
- } /* if */
+ int i;
+ const unsigned char *p=lptr;
+ /* go back to the opening brace */
+ while (*p!='{') {
+ assert(p>pline);
+ p--;
+ } /* while */
+ assert(*p=='{'); /* it should be found */
+ /* go forward, skipping white-space */
+ p++;
+ while (*p<=' ' && *p!='\0')
+ p++;
+ assert(*p!='\0'); /* a token should be found */
+ stmtindent=0;
+ for (i=0; i<(int)(p-pline); i++)
+ if (pline[i]=='\t' && sc_tabsize>0)
+ stmtindent += (int)(sc_tabsize - (stmtindent+sc_tabsize) % sc_tabsize);
+ else
+ stmtindent++;
+ } /* if */
- nestlevel+=1; /* increase compound statement level */
- while (matchtoken('}')==0){ /* repeat until compound statement is closed */
- if (!freading){
- needtoken('}'); /* gives error: "expected token }" */
- break;
- } else {
- if (count_stmt>0 && (lastst==tRETURN || lastst==tBREAK || lastst==tCONTINUE))
- error(225); /* unreachable code */
- statement(&indent,TRUE); /* do a statement */
- count_stmt++;
- } /* if */
- } /* while */
+ nestlevel+=1; /* increase compound statement level */
+ while (matchtoken('}')==0){ /* repeat until compound statement is closed */
+ if (!freading){
+ needtoken('}'); /* gives error: "expected token }" */
+ break;
+ } else {
+ if (count_stmt>0 && (lastst==tRETURN || lastst==tBREAK || lastst==tCONTINUE))
+ error(225); /* unreachable code */
+ statement(&indent,TRUE); /* do a statement */
+ count_stmt++;
+ } /* if */
+ } /* while */
if (lastst!=tRETURN)
- destructsymbols(&loctab,nestlevel);
+ destructsymbols(&loctab,nestlevel);
if (lastst!=tRETURN && lastst!=tGOTO)
- modstk((int)(declared-save_decl)*sizeof(cell)); /* delete local variable space */
- testsymbols(&loctab,nestlevel,FALSE,TRUE); /* look for unused block locals */
+ modstk((int)(declared-save_decl)*sizeof(cell)); /* delete local variable space */
+ testsymbols(&loctab,nestlevel,FALSE,TRUE); /* look for unused block locals */
declared=save_decl;
- delete_symbols(&loctab,nestlevel,FALSE,TRUE); /* erase local symbols, but
- * retain block local labels
- * (within the function) */
- nestlevel-=1; /* decrease compound statement level */
+ delete_symbols(&loctab,nestlevel,FALSE,TRUE); /* erase local symbols, but
+ * retain block local labels
+ * (within the function) */
+ nestlevel-=1; /* decrease compound statement level */
}
-/* doexpr
+/* doexpr
*
- * Global references: stgidx (referred to only)
+ * Global references: stgidx (referred to only)
*/
-static int doexpr(int comma,int chkeffect,int allowarray,int mark_endexpr,
- int *tag,symbol **symptr,int chkfuncresult)
+static int doexpr(int comma,int chkeffect,int allowarray,int mark_endexpr,
+ int *tag,symbol **symptr,int chkfuncresult)
{
int index,ident;
int localstaging=FALSE;
cell val;
- if (!staging) {
- stgset(TRUE); /* start stage-buffering */
- localstaging=TRUE;
- assert(stgidx==0);
- } /* if */
+ if (!staging) {
+ stgset(TRUE); /* start stage-buffering */
+ localstaging=TRUE;
+ assert(stgidx==0);
+ } /* if */
index=stgidx;
errorset(sEXPRMARK);
do {
- /* on second round through, mark the end of the previous expression */
- if (index!=stgidx)
- markexpr(sEXPR,NULL,0);
- sideeffect=FALSE;
- ident=expression(&val,tag,symptr,chkfuncresult);
- if (!allowarray && (ident==iARRAY || ident==iREFARRAY))
- error(33,"-unknown-"); /* array must be indexed */
- if (chkeffect && !sideeffect)
- error(215); /* expression has no effect */
- sc_allowproccall=FALSE; /* cannot use "procedure call" syntax anymore */
- } while (comma && matchtoken(',')); /* more? */
+ /* on second round through, mark the end of the previous expression */
+ if (index!=stgidx)
+ markexpr(sEXPR,NULL,0);
+ sideeffect=FALSE;
+ ident=expression(&val,tag,symptr,chkfuncresult);
+ if (!allowarray && (ident==iARRAY || ident==iREFARRAY))
+ error(33,"-unknown-"); /* array must be indexed */
+ if (chkeffect && !sideeffect)
+ error(215); /* expression has no effect */
+ sc_allowproccall=FALSE; /* cannot use "procedure call" syntax anymore */
+ } while (comma && matchtoken(',')); /* more? */
if (mark_endexpr)
- markexpr(sEXPR,NULL,0); /* optionally, mark the end of the expression */
+ markexpr(sEXPR,NULL,0); /* optionally, mark the end of the expression */
errorset(sEXPRRELEASE);
- if (localstaging) {
- stgout(index);
- stgset(FALSE); /* stop staging */
- } /* if */
+ if (localstaging) {
+ stgout(index);
+ stgset(FALSE); /* stop staging */
+ } /* if */
return ident;
}
-/* constexpr
+/* constexpr
*/
-SC_FUNC int constexpr(cell *val,int *tag,symbol **symptr)
+SC_FUNC int constexpr(cell *val,int *tag,symbol **symptr)
{
int ident,index;
cell cidx;
- stgset(TRUE); /* start stage-buffering */
- stgget(&index,&cidx); /* mark position in code generator */
+ stgset(TRUE); /* start stage-buffering */
+ stgget(&index,&cidx); /* mark position in code generator */
errorset(sEXPRMARK);
ident=expression(val,tag,symptr,FALSE);
- stgdel(index,cidx); /* scratch generated code */
- stgset(FALSE); /* stop stage-buffering */
+ stgdel(index,cidx); /* scratch generated code */
+ stgset(FALSE); /* stop stage-buffering */
if (ident!=iCONSTEXPR) {
- error(8); /* must be constant expression */
- if (val!=NULL)
- *val=0;
- if (tag!=NULL)
- *tag=0;
- if (symptr!=NULL)
- *symptr=NULL;
- } /* if */
+ error(8); /* must be constant expression */
+ if (val!=NULL)
+ *val=0;
+ if (tag!=NULL)
+ *tag=0;
+ if (symptr!=NULL)
+ *symptr=NULL;
+ } /* if */
errorset(sEXPRRELEASE);
return (ident==iCONSTEXPR);
}
-/* test
+/* test
*
- * In the case a "simple assignment" operator ("=") is used within a test,
- * the warning "possibly unintended assignment" is displayed. This routine
- * sets the global variable "sc_intest" to true, it is restored upon termination.
- * In the case the assignment was intended, use parantheses around the
- * expression to avoid the warning; primary() sets "sc_intest" to 0.
+ * In the case a "simple assignment" operator ("=") is used within a test,
+ * the warning "possibly unintended assignment" is displayed. This routine
+ * sets the global variable "sc_intest" to true, it is restored upon termination.
+ * In the case the assignment was intended, use parantheses around the
+ * expression to avoid the warning; primary() sets "sc_intest" to 0.
*
- * Global references: sc_intest (altered, but restored upon termination)
+ * Global references: sc_intest (altered, but restored upon termination)
*/
-static void test(int label,int parens,int invert)
+static void test(int label,int parens,int invert)
{
int index,tok;
cell cidx;
@@ -4755,121 +4755,121 @@ static void test(int label,int parens,int invert)
symbol *sym;
int localstaging=FALSE;
- if (!staging) {
- stgset(TRUE); /* start staging */
- localstaging=TRUE;
- #if !defined NDEBUG
- stgget(&index,&cidx); /* should start at zero if started locally */
- assert(index==0);
- #endif
- } /* if */
+ if (!staging) {
+ stgset(TRUE); /* start staging */
+ localstaging=TRUE;
+ #if !defined NDEBUG
+ stgget(&index,&cidx); /* should start at zero if started locally */
+ assert(index==0);
+ #endif
+ } /* if */
PUSHSTK_I(sc_intest);
sc_intest=TRUE;
if (parens)
- needtoken('(');
+ needtoken('(');
do {
- stgget(&index,&cidx); /* mark position (of last expression) in
- * code generator */
- ident=expression(&constval,&tag,&sym,TRUE);
- tok=matchtoken(',');
- if (tok)
- markexpr(sEXPR,NULL,0);
- } while (tok); /* do */
+ stgget(&index,&cidx); /* mark position (of last expression) in
+ * code generator */
+ ident=expression(&constval,&tag,&sym,TRUE);
+ tok=matchtoken(',');
+ if (tok)
+ markexpr(sEXPR,NULL,0);
+ } while (tok); /* do */
if (parens)
- needtoken(')');
- if (ident==iARRAY || ident==iREFARRAY) {
- char *ptr=(sym->name!=NULL) ? sym->name : "-unknown-";
- error(33,ptr); /* array must be indexed */
- } /* if */
- if (ident==iCONSTEXPR) { /* constant expression */
- sc_intest=(short)POPSTK_I();/* restore stack */
- stgdel(index,cidx);
- if (constval) { /* code always executed */
- error(206); /* redundant test: always non-zero */
- } else {
- error(205); /* redundant code: never executed */
- jumplabel(label);
- } /* if */
- if (localstaging) {
- stgout(0); /* write "jumplabel" code */
- stgset(FALSE); /* stop staging */
- } /* if */
- return;
- } /* if */
- if (tag!=0 && tag!=pc_addtag("bool"))
- if (check_userop(lneg,tag,0,1,NULL,&tag))
- invert= !invert; /* user-defined ! operator inverted result */
+ needtoken(')');
+ if (ident==iARRAY || ident==iREFARRAY) {
+ char *ptr=(sym->name!=NULL) ? sym->name : "-unknown-";
+ error(33,ptr); /* array must be indexed */
+ } /* if */
+ if (ident==iCONSTEXPR) { /* constant expression */
+ sc_intest=(short)POPSTK_I();/* restore stack */
+ stgdel(index,cidx);
+ if (constval) { /* code always executed */
+ error(206); /* redundant test: always non-zero */
+ } else {
+ error(205); /* redundant code: never executed */
+ jumplabel(label);
+ } /* if */
+ if (localstaging) {
+ stgout(0); /* write "jumplabel" code */
+ stgset(FALSE); /* stop staging */
+ } /* if */
+ return;
+ } /* if */
+ if (tag!=0 && tag!=pc_addtag("bool"))
+ if (check_userop(lneg,tag,0,1,NULL,&tag))
+ invert= !invert; /* user-defined ! operator inverted result */
if (invert)
- jmp_ne0(label); /* jump to label if true (different from 0) */
+ jmp_ne0(label); /* jump to label if true (different from 0) */
else
- jmp_eq0(label); /* jump to label if false (equal to 0) */
- markexpr(sEXPR,NULL,0); /* end expression (give optimizer a chance) */
- sc_intest=(short)POPSTK_I(); /* double typecast to avoid warning with Microsoft C */
- if (localstaging) {
- stgout(0); /* output queue from the very beginning (see
- * assert() when localstaging is set to TRUE) */
- stgset(FALSE); /* stop staging */
- } /* if */
+ jmp_eq0(label); /* jump to label if false (equal to 0) */
+ markexpr(sEXPR,NULL,0); /* end expression (give optimizer a chance) */
+ sc_intest=(short)POPSTK_I(); /* double typecast to avoid warning with Microsoft C */
+ if (localstaging) {
+ stgout(0); /* output queue from the very beginning (see
+ * assert() when localstaging is set to TRUE) */
+ stgset(FALSE); /* stop staging */
+ } /* if */
}
-static void doif(void)
+static void doif(void)
{
int flab1,flab2;
int ifindent;
- ifindent=stmtindent; /* save the indent of the "if" instruction */
- flab1=getlabel(); /* get label number for false branch */
- test(flab1,TRUE,FALSE); /* get expression, branch to flab1 if false */
- statement(NULL,FALSE); /* if true, do a statement */
- if (matchtoken(tELSE)==0){ /* if...else ? */
- setlabel(flab1); /* no, simple if..., print false label */
- } else {
- /* to avoid the "dangling else" error, we want a warning if the "else"
- * has a lower indent than the matching "if" */
- if (stmtindent0)
- error(217); /* loose indentation */
- flab2=getlabel();
- if ((lastst!=tRETURN) && (lastst!=tGOTO))
- jumplabel(flab2);
- setlabel(flab1); /* print false label */
- statement(NULL,FALSE); /* do "else" clause */
- setlabel(flab2); /* print true label */
- } /* endif */
+ ifindent=stmtindent; /* save the indent of the "if" instruction */
+ flab1=getlabel(); /* get label number for false branch */
+ test(flab1,TRUE,FALSE); /* get expression, branch to flab1 if false */
+ statement(NULL,FALSE); /* if true, do a statement */
+ if (matchtoken(tELSE)==0){ /* if...else ? */
+ setlabel(flab1); /* no, simple if..., print false label */
+ } else {
+ /* to avoid the "dangling else" error, we want a warning if the "else"
+ * has a lower indent than the matching "if" */
+ if (stmtindent0)
+ error(217); /* loose indentation */
+ flab2=getlabel();
+ if ((lastst!=tRETURN) && (lastst!=tGOTO))
+ jumplabel(flab2);
+ setlabel(flab1); /* print false label */
+ statement(NULL,FALSE); /* do "else" clause */
+ setlabel(flab2); /* print true label */
+ } /* endif */
}
-static void dowhile(void)
+static void dowhile(void)
{
- int wq[wqSIZE]; /* allocate local queue */
+ int wq[wqSIZE]; /* allocate local queue */
- addwhile(wq); /* add entry to queue for "break" */
- setlabel(wq[wqLOOP]); /* loop label */
- /* The debugger uses the "line" opcode to be able to "break" out of
- * a loop. To make sure that each loop has a line opcode, even for the
- * tiniest loop, set it below the top of the loop
+ addwhile(wq); /* add entry to queue for "break" */
+ setlabel(wq[wqLOOP]); /* loop label */
+ /* The debugger uses the "line" opcode to be able to "break" out of
+ * a loop. To make sure that each loop has a line opcode, even for the
+ * tiniest loop, set it below the top of the loop
*/
setline(TRUE);
- test(wq[wqEXIT],TRUE,FALSE); /* branch to wq[wqEXIT] if false */
- statement(NULL,FALSE); /* if so, do a statement */
- jumplabel(wq[wqLOOP]); /* and loop to "while" start */
- setlabel(wq[wqEXIT]); /* exit label */
- delwhile(); /* delete queue entry */
+ test(wq[wqEXIT],TRUE,FALSE); /* branch to wq[wqEXIT] if false */
+ statement(NULL,FALSE); /* if so, do a statement */
+ jumplabel(wq[wqLOOP]); /* and loop to "while" start */
+ setlabel(wq[wqEXIT]); /* exit label */
+ delwhile(); /* delete queue entry */
}
/*
- * Note that "continue" will in this case not jump to the top of the loop, but
- * to the end: just before the TRUE-or-FALSE testing code.
+ * Note that "continue" will in this case not jump to the top of the loop, but
+ * to the end: just before the TRUE-or-FALSE testing code.
*/
-static void dodo(void)
+static void dodo(void)
{
int wq[wqSIZE],top;
- addwhile(wq); /* see "dowhile" for more info */
- top=getlabel(); /* make a label first */
- setlabel(top); /* loop label */
+ addwhile(wq); /* see "dowhile" for more info */
+ top=getlabel(); /* make a label first */
+ setlabel(top); /* loop label */
statement(NULL,FALSE);
needtoken(tWHILE);
- setlabel(wq[wqLOOP]); /* "continue" always jumps to WQLOOP. */
+ setlabel(wq[wqLOOP]); /* "continue" always jumps to WQLOOP. */
setline(TRUE);
test(wq[wqEXIT],TRUE,FALSE);
jumplabel(top);
@@ -4878,7 +4878,7 @@ static void dodo(void)
needtoken(tTERM);
}
-static void dofor(void)
+static void dofor(void)
{
int wq[wqSIZE],skiplab;
cell save_decl;
@@ -4892,504 +4892,504 @@ static void dofor(void)
skiplab=getlabel();
needtoken('(');
if (matchtoken(';')==0) {
- /* new variable declarations are allowed here */
- if (matchtoken(tNEW)) {
- /* The variable in expr1 of the for loop is at a
- * 'compound statement' level of it own.
- */
- nestlevel++;
- declloc(FALSE); /* declare local variable */
- } else {
- doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE); /* expression 1 */
- needtoken(';');
- } /* if */
- } /* if */
- /* Adjust the "declared" field in the "while queue", in case that
- * local variables were declared in the first expression of the
- * "for" loop. These are deleted in separately, so a "break" or a "continue"
+ /* new variable declarations are allowed here */
+ if (matchtoken(tNEW)) {
+ /* The variable in expr1 of the for loop is at a
+ * 'compound statement' level of it own.
+ */
+ nestlevel++;
+ declloc(FALSE); /* declare local variable */
+ } else {
+ doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE); /* expression 1 */
+ needtoken(';');
+ } /* if */
+ } /* if */
+ /* Adjust the "declared" field in the "while queue", in case that
+ * local variables were declared in the first expression of the
+ * "for" loop. These are deleted in separately, so a "break" or a "continue"
* must ignore these fields.
*/
ptr=readwhile();
assert(ptr!=NULL);
ptr[wqBRK]=(int)declared;
ptr[wqCONT]=(int)declared;
- jumplabel(skiplab); /* skip expression 3 1st time */
- setlabel(wq[wqLOOP]); /* "continue" goes to this label: expr3 */
+ jumplabel(skiplab); /* skip expression 3 1st time */
+ setlabel(wq[wqLOOP]); /* "continue" goes to this label: expr3 */
setline(TRUE);
- /* Expressions 2 and 3 are reversed in the generated code: expression 3
- * precedes expression 2. When parsing, the code is buffered and marks for
- * the start of each expression are insterted in the buffer.
+ /* Expressions 2 and 3 are reversed in the generated code: expression 3
+ * precedes expression 2. When parsing, the code is buffered and marks for
+ * the start of each expression are insterted in the buffer.
*/
assert(!staging);
- stgset(TRUE); /* start staging */
+ stgset(TRUE); /* start staging */
assert(stgidx==0);
index=stgidx;
stgmark(sSTARTREORDER);
- stgmark((char)(sEXPRSTART+0)); /* mark start of 2nd expression in stage */
- setlabel(skiplab); /* jump to this point after 1st expression */
+ stgmark((char)(sEXPRSTART+0)); /* mark start of 2nd expression in stage */
+ setlabel(skiplab); /* jump to this point after 1st expression */
if (matchtoken(';')==0) {
- test(wq[wqEXIT],FALSE,FALSE); /* expression 2 (jump to wq[wqEXIT] if false) */
- needtoken(';');
- } /* if */
- stgmark((char)(sEXPRSTART+1)); /* mark start of 3th expression in stage */
+ test(wq[wqEXIT],FALSE,FALSE); /* expression 2 (jump to wq[wqEXIT] if false) */
+ needtoken(';');
+ } /* if */
+ stgmark((char)(sEXPRSTART+1)); /* mark start of 3th expression in stage */
if (matchtoken(')')==0) {
- doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE); /* expression 3 */
- needtoken(')');
- } /* if */
- stgmark(sENDREORDER); /* mark end of reversed evaluation */
+ doexpr(TRUE,TRUE,TRUE,TRUE,NULL,NULL,FALSE); /* expression 3 */
+ needtoken(')');
+ } /* if */
+ stgmark(sENDREORDER); /* mark end of reversed evaluation */
stgout(index);
- stgset(FALSE); /* stop staging */
+ stgset(FALSE); /* stop staging */
statement(NULL,FALSE);
jumplabel(wq[wqLOOP]);
setlabel(wq[wqEXIT]);
delwhile();
assert(nestlevel>=save_nestlevel);
- if (nestlevel>save_nestlevel) {
- /* Clean up the space and the symbol table for the local
- * variable in "expr1".
- */
- destructsymbols(&loctab,nestlevel);
- modstk((int)(declared-save_decl)*sizeof(cell));
- testsymbols(&loctab,nestlevel,FALSE,TRUE); /* look for unused block locals */
- declared=save_decl;
- delete_symbols(&loctab,nestlevel,FALSE,TRUE);
- nestlevel=save_nestlevel; /* reset 'compound statement' nesting level */
- } /* if */
+ if (nestlevel>save_nestlevel) {
+ /* Clean up the space and the symbol table for the local
+ * variable in "expr1".
+ */
+ destructsymbols(&loctab,nestlevel);
+ modstk((int)(declared-save_decl)*sizeof(cell));
+ testsymbols(&loctab,nestlevel,FALSE,TRUE); /* look for unused block locals */
+ declared=save_decl;
+ delete_symbols(&loctab,nestlevel,FALSE,TRUE);
+ nestlevel=save_nestlevel; /* reset 'compound statement' nesting level */
+ } /* if */
}
-/* The switch statement is incompatible with its C sibling:
- * 1. the cases are not drop through
- * 2. only one instruction may appear below each case, use a compound
- * instruction to execute multiple instructions
- * 3. the "case" keyword accepts a comma separated list of values to
- * match, it also accepts a range using the syntax "1 .. 4"
+/* The switch statement is incompatible with its C sibling:
+ * 1. the cases are not drop through
+ * 2. only one instruction may appear below each case, use a compound
+ * instruction to execute multiple instructions
+ * 3. the "case" keyword accepts a comma separated list of values to
+ * match, it also accepts a range using the syntax "1 .. 4"
*
* SWITCH param
- * PRI = expression result
- * param = table offset (code segment)
+ * PRI = expression result
+ * param = table offset (code segment)
*
*/
-static void doswitch(void)
+static void doswitch(void)
{
int lbl_table,lbl_exit,lbl_case;
int tok,swdefault,casecount;
cell val;
char *str;
- constvalue caselist = { NULL, "", 0, 0}; /* case list starts empty */
+ constvalue caselist = { NULL, "", 0, 0}; /* case list starts empty */
constvalue *cse,*csp;
char labelname[sNAMEMAX+1];
needtoken('(');
- doexpr(TRUE,FALSE,FALSE,FALSE,NULL,NULL,TRUE);/* evaluate switch expression */
+ doexpr(TRUE,FALSE,FALSE,FALSE,NULL,NULL,TRUE);/* evaluate switch expression */
needtoken(')');
/* generate the code for the switch statement, the label is the address
- * of the case table (to be generated later).
+ * of the case table (to be generated later).
*/
lbl_table=getlabel();
- lbl_case=0; /* just to avoid a compiler warning */
+ lbl_case=0; /* just to avoid a compiler warning */
ffswitch(lbl_table);
needtoken('{');
- lbl_exit=getlabel(); /* get label number for jumping out of switch */
+ lbl_exit=getlabel(); /* get label number for jumping out of switch */
swdefault=FALSE;
casecount=0;
do {
- tok=lex(&val,&str); /* read in (new) token */
- switch (tok) {
- case tCASE:
- if (swdefault!=FALSE)
- error(15); /* "default" case must be last in switch statement */
- lbl_case=getlabel();
- PUSHSTK_I(sc_allowtags);
- sc_allowtags=FALSE; /* do not allow tagnames here */
- do {
- casecount++;
+ tok=lex(&val,&str); /* read in (new) token */
+ switch (tok) {
+ case tCASE:
+ if (swdefault!=FALSE)
+ error(15); /* "default" case must be last in switch statement */
+ lbl_case=getlabel();
+ PUSHSTK_I(sc_allowtags);
+ sc_allowtags=FALSE; /* do not allow tagnames here */
+ do {
+ casecount++;
- /* ??? enforce/document that, in a switch, a statement cannot start
- * with a label. Then, you can search for:
- * * the first semicolon (marks the end of a statement)
- * * an opening brace (marks the start of a compound statement)
- * and search for the right-most colon before that statement
- * Now, by replacing the ':' by a special COLON token, you can
- * parse all expressions until that special token.
- */
+ /* ??? enforce/document that, in a switch, a statement cannot start
+ * with a label. Then, you can search for:
+ * * the first semicolon (marks the end of a statement)
+ * * an opening brace (marks the start of a compound statement)
+ * and search for the right-most colon before that statement
+ * Now, by replacing the ':' by a special COLON token, you can
+ * parse all expressions until that special token.
+ */
- constexpr(&val,NULL,NULL);
- /* Search the insertion point (the table is kept in sorted order, so
- * that advanced abstract machines can sift the case table with a
- * binary search). Check for duplicate case values at the same time.
- */
- for (csp=&caselist, cse=caselist.next;
- cse!=NULL && cse->valuenext)
- /* nothing */;
- if (cse!=NULL && cse->value==val)
- error(40,val); /* duplicate "case" label */
- /* Since the label is stored as a string in the "constvalue", the
- * size of an identifier must be at least 8, as there are 8
- * hexadecimal digits in a 32-bit number.
- */
- #if sNAMEMAX < 8
- #error Length of identifier (sNAMEMAX) too small.
- #endif
- assert(csp!=NULL);
- assert(csp->next==cse);
- insert_constval(csp,cse,itoh(lbl_case),val,0);
- if (matchtoken(tDBLDOT)) {
- cell end;
- constexpr(&end,NULL,NULL);
- if (end<=val)
- error(50); /* invalid range */
- while (++val<=end) {
- casecount++;
- /* find the new insertion point */
- for (csp=&caselist, cse=caselist.next;
- cse!=NULL && cse->valuenext)
- /* nothing */;
- if (cse!=NULL && cse->value==val)
- error(40,val); /* duplicate "case" label */
- assert(csp!=NULL);
- assert(csp->next==cse);
- insert_constval(csp,cse,itoh(lbl_case),val,0);
- } /* if */
- } /* if */
- } while (matchtoken(','));
- needtoken(':'); /* ':' ends the case */
- sc_allowtags=(short)POPSTK_I(); /* reset */
- setlabel(lbl_case);
- statement(NULL,FALSE);
- jumplabel(lbl_exit);
- break;
- case tDEFAULT:
- if (swdefault!=FALSE)
- error(16); /* multiple defaults in switch */
- lbl_case=getlabel();
- setlabel(lbl_case);
- needtoken(':');
- swdefault=TRUE;
- statement(NULL,FALSE);
- /* Jump to lbl_exit, even thouh this is the last clause in the
- * switch, because the jump table is generated between the last
- * clause of the switch and the exit label.
- */
- jumplabel(lbl_exit);
- break;
- case '}':
- /* nothing, but avoid dropping into "default" */
- break;
- default:
- error(2);
- indent_nowarn=TRUE; /* disable this check */
- tok='}'; /* break out of the loop after an error */
- } /* switch */
- } while (tok!='}');
+ constexpr(&val,NULL,NULL);
+ /* Search the insertion point (the table is kept in sorted order, so
+ * that advanced abstract machines can sift the case table with a
+ * binary search). Check for duplicate case values at the same time.
+ */
+ for (csp=&caselist, cse=caselist.next;
+ cse!=NULL && cse->valuenext)
+ /* nothing */;
+ if (cse!=NULL && cse->value==val)
+ error(40,val); /* duplicate "case" label */
+ /* Since the label is stored as a string in the "constvalue", the
+ * size of an identifier must be at least 8, as there are 8
+ * hexadecimal digits in a 32-bit number.
+ */
+ #if sNAMEMAX < 8
+ #error Length of identifier (sNAMEMAX) too small.
+ #endif
+ assert(csp!=NULL);
+ assert(csp->next==cse);
+ insert_constval(csp,cse,itoh(lbl_case),val,0);
+ if (matchtoken(tDBLDOT)) {
+ cell end;
+ constexpr(&end,NULL,NULL);
+ if (end<=val)
+ error(50); /* invalid range */
+ while (++val<=end) {
+ casecount++;
+ /* find the new insertion point */
+ for (csp=&caselist, cse=caselist.next;
+ cse!=NULL && cse->valuenext)
+ /* nothing */;
+ if (cse!=NULL && cse->value==val)
+ error(40,val); /* duplicate "case" label */
+ assert(csp!=NULL);
+ assert(csp->next==cse);
+ insert_constval(csp,cse,itoh(lbl_case),val,0);
+ } /* if */
+ } /* if */
+ } while (matchtoken(','));
+ needtoken(':'); /* ':' ends the case */
+ sc_allowtags=(short)POPSTK_I(); /* reset */
+ setlabel(lbl_case);
+ statement(NULL,FALSE);
+ jumplabel(lbl_exit);
+ break;
+ case tDEFAULT:
+ if (swdefault!=FALSE)
+ error(16); /* multiple defaults in switch */
+ lbl_case=getlabel();
+ setlabel(lbl_case);
+ needtoken(':');
+ swdefault=TRUE;
+ statement(NULL,FALSE);
+ /* Jump to lbl_exit, even thouh this is the last clause in the
+ * switch, because the jump table is generated between the last
+ * clause of the switch and the exit label.
+ */
+ jumplabel(lbl_exit);
+ break;
+ case '}':
+ /* nothing, but avoid dropping into "default" */
+ break;
+ default:
+ error(2);
+ indent_nowarn=TRUE; /* disable this check */
+ tok='}'; /* break out of the loop after an error */
+ } /* switch */
+ } while (tok!='}');
#if !defined NDEBUG
- /* verify that the case table is sorted (unfortunatly, duplicates can
- * occur; there really shouldn't be duplicate cases, but the compiler
- * may not crash or drop into an assertion for a user error). */
- for (cse=caselist.next; cse!=NULL && cse->next!=NULL; cse=cse->next)
- assert(cse->value <= cse->next->value);
+ /* verify that the case table is sorted (unfortunatly, duplicates can
+ * occur; there really shouldn't be duplicate cases, but the compiler
+ * may not crash or drop into an assertion for a user error). */
+ for (cse=caselist.next; cse!=NULL && cse->next!=NULL; cse=cse->next)
+ assert(cse->value <= cse->next->value);
#endif
- /* generate the table here, before lbl_exit (general jump target) */
+ /* generate the table here, before lbl_exit (general jump target) */
setlabel(lbl_table);
assert(swdefault==FALSE || swdefault==TRUE);
- if (swdefault==FALSE) {
- /* store lbl_exit as the "none-matched" label in the switch table */
- strcpy(labelname,itoh(lbl_exit));
- } else {
- /* lbl_case holds the label of the "default" clause */
- strcpy(labelname,itoh(lbl_case));
- } /* if */
+ if (swdefault==FALSE) {
+ /* store lbl_exit as the "none-matched" label in the switch table */
+ strcpy(labelname,itoh(lbl_exit));
+ } else {
+ /* lbl_case holds the label of the "default" clause */
+ strcpy(labelname,itoh(lbl_case));
+ } /* if */
ffcase(casecount,labelname,TRUE);
- /* generate the rest of the table */
+ /* generate the rest of the table */
for (cse=caselist.next; cse!=NULL; cse=cse->next)
- ffcase(cse->value,cse->name,FALSE);
+ ffcase(cse->value,cse->name,FALSE);
setlabel(lbl_exit);
- delete_consttable(&caselist); /* clear list of case labels */
+ delete_consttable(&caselist); /* clear list of case labels */
}
-static void doassert(void)
+static void doassert(void)
{
int flab1,index;
cell cidx;
- if ((sc_debug & sCHKBOUNDS)!=0) {
- flab1=getlabel(); /* get label number for "OK" branch */
- test(flab1,FALSE,TRUE); /* get expression and branch to flab1 if true */
- insert_dbgline(fline); /* make sure we can find the correct line number */
- ffabort(xASSERTION);
- setlabel(flab1);
- } else {
- stgset(TRUE); /* start staging */
- stgget(&index,&cidx); /* mark position in code generator */
- do {
- expression(NULL,NULL,NULL,FALSE);
- stgdel(index,cidx); /* just scrap the code */
- } while (matchtoken(','));
- stgset(FALSE); /* stop staging */
- } /* if */
+ if ((sc_debug & sCHKBOUNDS)!=0) {
+ flab1=getlabel(); /* get label number for "OK" branch */
+ test(flab1,FALSE,TRUE); /* get expression and branch to flab1 if true */
+ insert_dbgline(fline); /* make sure we can find the correct line number */
+ ffabort(xASSERTION);
+ setlabel(flab1);
+ } else {
+ stgset(TRUE); /* start staging */
+ stgget(&index,&cidx); /* mark position in code generator */
+ do {
+ expression(NULL,NULL,NULL,FALSE);
+ stgdel(index,cidx); /* just scrap the code */
+ } while (matchtoken(','));
+ stgset(FALSE); /* stop staging */
+ } /* if */
needtoken(tTERM);
}
-static void dogoto(void)
+static void dogoto(void)
{
char *st;
cell val;
symbol *sym;
if (lex(&val,&st)==tSYMBOL) {
- sym=fetchlab(st);
- jumplabel((int)sym->addr);
- sym->usage|=uREAD; /* set "uREAD" bit */
- // ??? if the label is defined (check sym->usage & uDEFINE), check
- // sym->compound (nesting level of the label) against nestlevel;
- // if sym->compound < nestlevel, call the destructor operator
- } else {
- error(20,st); /* illegal symbol name */
- } /* if */
+ sym=fetchlab(st);
+ jumplabel((int)sym->addr);
+ sym->usage|=uREAD; /* set "uREAD" bit */
+ // ??? if the label is defined (check sym->usage & uDEFINE), check
+ // sym->compound (nesting level of the label) against nestlevel;
+ // if sym->compound < nestlevel, call the destructor operator
+ } else {
+ error(20,st); /* illegal symbol name */
+ } /* if */
needtoken(tTERM);
}
-static void dolabel(void)
+static void dolabel(void)
{
char *st;
cell val;
symbol *sym;
- tokeninfo(&val,&st); /* retrieve label name again */
+ tokeninfo(&val,&st); /* retrieve label name again */
if (find_constval(&tagname_tab,st,0)!=NULL)
- error(221,st); /* label name shadows tagname */
+ error(221,st); /* label name shadows tagname */
sym=fetchlab(st);
setlabel((int)sym->addr);
- /* since one can jump around variable declarations or out of compound
- * blocks, the stack must be manually adjusted
+ /* since one can jump around variable declarations or out of compound
+ * blocks, the stack must be manually adjusted
*/
setstk(-declared*sizeof(cell));
- sym->usage|=uDEFINE; /* label is now defined */
+ sym->usage|=uDEFINE; /* label is now defined */
}
-/* fetchlab
+/* fetchlab
*
- * Finds a label from the (local) symbol table or adds one to it.
- * Labels are local in scope.
+ * Finds a label from the (local) symbol table or adds one to it.
+ * Labels are local in scope.
*
- * Note: The "_usage" bit is set to zero. The routines that call "fetchlab()"
- * must set this bit accordingly.
+ * Note: The "_usage" bit is set to zero. The routines that call "fetchlab()"
+ * must set this bit accordingly.
*/
static symbol *fetchlab(char *name)
{
symbol *sym;
- sym=findloc(name); /* labels are local in scope */
+ sym=findloc(name); /* labels are local in scope */
if (sym){
- if (sym->ident!=iLABEL)
- error(19,sym->name); /* not a label: ... */
- } else {
- sym=addsym(name,getlabel(),iLABEL,sLOCAL,0,0);
- assert(sym!=NULL); /* fatal error 103 must be given on error */
- sym->x.declared=(int)declared;
- sym->compound=nestlevel;
- } /* if */
+ if (sym->ident!=iLABEL)
+ error(19,sym->name); /* not a label: ... */
+ } else {
+ sym=addsym(name,getlabel(),iLABEL,sLOCAL,0,0);
+ assert(sym!=NULL); /* fatal error 103 must be given on error */
+ sym->x.declared=(int)declared;
+ sym->compound=nestlevel;
+ } /* if */
return sym;
}
-/* doreturn
+/* doreturn
*
- * Global references: rettype (altered)
+ * Global references: rettype (altered)
*/
-static void doreturn(void)
+static void doreturn(void)
{
int tag,ident;
int level;
symbol *sym,*sub;
if (!matchtoken(tTERM)) {
- /* "return " */
- if ((rettype & uRETNONE)!=0)
- error(78); /* mix "return;" and "return value;" */
- ident=doexpr(TRUE,FALSE,TRUE,TRUE,&tag,&sym,TRUE);
- needtoken(tTERM);
- /* see if this function already has a sub type (an array attached) */
- sub=finddepend(curfunc);
- assert(sub==NULL || sub->ident==iREFARRAY);
- if ((rettype & uRETVALUE)!=0) {
- int retarray=(ident==iARRAY || ident==iREFARRAY);
- /* there was an earlier "return" statement in this function */
- if (sub==NULL && retarray || sub!=NULL && !retarray)
- error(79); /* mixing "return array;" and "return value;" */
- } /* if */
- rettype|=uRETVALUE; /* function returns a value */
- /* check tagname with function tagname */
- assert(curfunc!=NULL);
- if (!matchtag(curfunc->tag,tag,TRUE))
- error(213); /* tagname mismatch */
- if (ident==iARRAY || ident==iREFARRAY) {
- int dim[sDIMEN_MAX],numdim;
- cell arraysize;
- assert(sym!=NULL);
- if (sub!=NULL) {
- assert(sub->ident==iREFARRAY);
- /* this function has an array attached already; check that the current
- * "return" statement returns exactly the same array
- */
- level=sym->dim.array.level;
- if (sub->dim.array.level!=level) {
- error(48); /* array dimensions must match */
- } else {
- for (numdim=0; numdim<=level; numdim++) {
- dim[numdim]=(int)sub->dim.array.length;
- if (sym->dim.array.length!=dim[numdim])
- error(47); /* array sizes must match */
- if (numdimdim.array.level;
- for (numdim=0; numdim<=level; numdim++) {
- dim[numdim]=(int)sub->dim.array.length;
- idxtag[numdim]=sub->x.idxtag;
- if (numdimname);
- } /* for */
- /* the address of the array is stored in a hidden parameter; the address
- * of this parameter is 1 + the number of parameters (times the size of
- * a cell) + the size of the stack frame and the return address
- * base + 0*sizeof(cell) == previous "base"
- * base + 1*sizeof(cell) == function return address
- * base + 2*sizeof(cell) == number of arguments
- * base + 3*sizeof(cell) == first argument of the function
- * ...
- * base + ((n-1)+3)*sizeof(cell) == last argument of the function
- * base + (n+3)*sizeof(cell) == hidden parameter with array address
- */
- assert(curfunc!=NULL);
- assert(curfunc->dim.arglist!=NULL);
- for (argcount=0; curfunc->dim.arglist[argcount].ident!=0; argcount++)
- /* nothing */;
- sub=addvariable(curfunc->name,(argcount+3)*sizeof(cell),iREFARRAY,sGLOBAL,curfunc->tag,dim,numdim,idxtag);
- sub->parent=curfunc;
- } /* if */
- /* get the hidden parameter, copy the array (the array is on the heap;
- * it stays on the heap for the moment, and it is removed -usually- at
- * the end of the expression/statement, see expression() in SC3.C)
- */
- address(sub,sALT); /* ALT = destination */
- arraysize=calc_arraysize(dim,numdim,0);
- memcopy(arraysize*sizeof(cell)); /* source already in PRI */
- /* moveto1(); is not necessary, callfunction() does a popreg() */
- } /* if */
- } else {
- /* this return statement contains no expression */
- ldconst(0,sPRI);
- if ((rettype & uRETVALUE)!=0) {
- char symname[2*sNAMEMAX+16]; /* allow space for user defined operators */
- assert(curfunc!=NULL);
- funcdisplayname(symname,curfunc->name);
- error(209,symname); /* function should return a value */
- } /* if */
- rettype|=uRETNONE; /* function does not return anything */
- } /* if */
- destructsymbols(&loctab,0); /* call destructor for *all* locals */
- modstk((int)declared*sizeof(cell)); /* end of function, remove *all*
- * local variables */
+ /* "return " */
+ if ((rettype & uRETNONE)!=0)
+ error(78); /* mix "return;" and "return value;" */
+ ident=doexpr(TRUE,FALSE,TRUE,TRUE,&tag,&sym,TRUE);
+ needtoken(tTERM);
+ /* see if this function already has a sub type (an array attached) */
+ sub=finddepend(curfunc);
+ assert(sub==NULL || sub->ident==iREFARRAY);
+ if ((rettype & uRETVALUE)!=0) {
+ int retarray=(ident==iARRAY || ident==iREFARRAY);
+ /* there was an earlier "return" statement in this function */
+ if (sub==NULL && retarray || sub!=NULL && !retarray)
+ error(79); /* mixing "return array;" and "return value;" */
+ } /* if */
+ rettype|=uRETVALUE; /* function returns a value */
+ /* check tagname with function tagname */
+ assert(curfunc!=NULL);
+ if (!matchtag(curfunc->tag,tag,TRUE))
+ error(213); /* tagname mismatch */
+ if (ident==iARRAY || ident==iREFARRAY) {
+ int dim[sDIMEN_MAX],numdim;
+ cell arraysize;
+ assert(sym!=NULL);
+ if (sub!=NULL) {
+ assert(sub->ident==iREFARRAY);
+ /* this function has an array attached already; check that the current
+ * "return" statement returns exactly the same array
+ */
+ level=sym->dim.array.level;
+ if (sub->dim.array.level!=level) {
+ error(48); /* array dimensions must match */
+ } else {
+ for (numdim=0; numdim<=level; numdim++) {
+ dim[numdim]=(int)sub->dim.array.length;
+ if (sym->dim.array.length!=dim[numdim])
+ error(47); /* array sizes must match */
+ if (numdimdim.array.level;
+ for (numdim=0; numdim<=level; numdim++) {
+ dim[numdim]=(int)sub->dim.array.length;
+ idxtag[numdim]=sub->x.idxtag;
+ if (numdimname);
+ } /* for */
+ /* the address of the array is stored in a hidden parameter; the address
+ * of this parameter is 1 + the number of parameters (times the size of
+ * a cell) + the size of the stack frame and the return address
+ * base + 0*sizeof(cell) == previous "base"
+ * base + 1*sizeof(cell) == function return address
+ * base + 2*sizeof(cell) == number of arguments
+ * base + 3*sizeof(cell) == first argument of the function
+ * ...
+ * base + ((n-1)+3)*sizeof(cell) == last argument of the function
+ * base + (n+3)*sizeof(cell) == hidden parameter with array address
+ */
+ assert(curfunc!=NULL);
+ assert(curfunc->dim.arglist!=NULL);
+ for (argcount=0; curfunc->dim.arglist[argcount].ident!=0; argcount++)
+ /* nothing */;
+ sub=addvariable(curfunc->name,(argcount+3)*sizeof(cell),iREFARRAY,sGLOBAL,curfunc->tag,dim,numdim,idxtag);
+ sub->parent=curfunc;
+ } /* if */
+ /* get the hidden parameter, copy the array (the array is on the heap;
+ * it stays on the heap for the moment, and it is removed -usually- at
+ * the end of the expression/statement, see expression() in SC3.C)
+ */
+ address(sub,sALT); /* ALT = destination */
+ arraysize=calc_arraysize(dim,numdim,0);
+ memcopy(arraysize*sizeof(cell)); /* source already in PRI */
+ /* moveto1(); is not necessary, callfunction() does a popreg() */
+ } /* if */
+ } else {
+ /* this return statement contains no expression */
+ ldconst(0,sPRI);
+ if ((rettype & uRETVALUE)!=0) {
+ char symname[2*sNAMEMAX+16]; /* allow space for user defined operators */
+ assert(curfunc!=NULL);
+ funcdisplayname(symname,curfunc->name);
+ error(209,symname); /* function should return a value */
+ } /* if */
+ rettype|=uRETNONE; /* function does not return anything */
+ } /* if */
+ destructsymbols(&loctab,0); /* call destructor for *all* locals */
+ modstk((int)declared*sizeof(cell)); /* end of function, remove *all*
+ * local variables */
ffret();
}
-static void dobreak(void)
+static void dobreak(void)
{
int *ptr;
- ptr=readwhile(); /* readwhile() gives an error if not in loop */
+ ptr=readwhile(); /* readwhile() gives an error if not in loop */
needtoken(tTERM);
if (ptr==NULL)
- return;
+ return;
destructsymbols(&loctab,nestlevel);
modstk(((int)declared-ptr[wqBRK])*sizeof(cell));
jumplabel(ptr[wqEXIT]);
}
-static void docont(void)
+static void docont(void)
{
int *ptr;
- ptr=readwhile(); /* readwhile() gives an error if not in loop */
+ ptr=readwhile(); /* readwhile() gives an error if not in loop */
needtoken(tTERM);
if (ptr==NULL)
- return;
+ return;
destructsymbols(&loctab,nestlevel);
modstk(((int)declared-ptr[wqCONT])*sizeof(cell));
jumplabel(ptr[wqLOOP]);
}
-SC_FUNC void exporttag(int tag)
+SC_FUNC void exporttag(int tag)
{
/* find the tag by value in the table, then set the top bit to mark it
* "public"
*/
- if (tag!=0 && (tag & PUBLICTAG)==0) {
- constvalue *ptr;
- for (ptr=tagname_tab.next; ptr!=NULL && tag!=(int)(ptr->value & TAGMASK); ptr=ptr->next)
- /* nothing */;
- if (ptr!=NULL)
- ptr->value |= PUBLICTAG;
- } /* if */
+ if (tag!=0 && (tag & PUBLICTAG)==0) {
+ constvalue *ptr;
+ for (ptr=tagname_tab.next; ptr!=NULL && tag!=(int)(ptr->value & TAGMASK); ptr=ptr->next)
+ /* nothing */;
+ if (ptr!=NULL)
+ ptr->value |= PUBLICTAG;
+ } /* if */
}
-static void doexit(void)
+static void doexit(void)
{
int tag=0;
if (matchtoken(tTERM)==0){
- doexpr(TRUE,FALSE,FALSE,TRUE,&tag,NULL,TRUE);
- needtoken(tTERM);
- } else {
- ldconst(0,sPRI);
- } /* if */
+ doexpr(TRUE,FALSE,FALSE,TRUE,&tag,NULL,TRUE);
+ needtoken(tTERM);
+ } else {
+ ldconst(0,sPRI);
+ } /* if */
ldconst(tag,sALT);
exporttag(tag);
- destructsymbols(&loctab,0); /* call destructor for *all* locals */
+ destructsymbols(&loctab,0); /* call destructor for *all* locals */
ffabort(xEXIT);
}
-static void dosleep(void)
+static void dosleep(void)
{
int tag=0;
if (matchtoken(tTERM)==0){
- doexpr(TRUE,FALSE,FALSE,TRUE,&tag,NULL,TRUE);
- needtoken(tTERM);
- } else {
- ldconst(0,sPRI);
- } /* if */
+ doexpr(TRUE,FALSE,FALSE,TRUE,&tag,NULL,TRUE);
+ needtoken(tTERM);
+ } else {
+ ldconst(0,sPRI);
+ } /* if */
ldconst(tag,sALT);
exporttag(tag);
ffabort(xSLEEP);
}
-static void dostate(void)
+static void dostate(void)
{
char name[sNAMEMAX+1];
cell val;
@@ -5401,161 +5401,161 @@ static void dostate(void)
int islabel;
symbol *sym;
#if !defined SC_LIGHT
- int length,index,listid,listindex,stateindex;
- char *doc;
+ int length,index,listid,listindex,stateindex;
+ char *doc;
#endif
/* check for an optional condition */
if (matchtoken('(')) {
- flabel=getlabel(); /* get label number for "false" branch */
- pc_docexpr=TRUE; /* attach expression as a documentation string */
- test(flabel,FALSE,FALSE); /* get expression, branch to flabel if false */
- pc_docexpr=FALSE;
- needtoken(')');
- } else {
- flabel=-1;
- } /* if */
+ flabel=getlabel(); /* get label number for "false" branch */
+ pc_docexpr=TRUE; /* attach expression as a documentation string */
+ test(flabel,FALSE,FALSE); /* get expression, branch to flabel if false */
+ pc_docexpr=FALSE;
+ needtoken(')');
+ } else {
+ flabel=-1;
+ } /* if */
fsa=0;
- if (!(islabel=matchtoken(tLABEL)) && !needtoken(tSYMBOL)) {
- delete_autolisttable();
- return;
- } /* if */
+ if (!(islabel=matchtoken(tLABEL)) && !needtoken(tSYMBOL)) {
+ delete_autolisttable();
+ return;
+ } /* if */
tokeninfo(&val,&str);
- assert(strlen(str)index;
- if (!needtoken(tSYMBOL)) {
- delete_autolisttable();
- return;
- } /* if */
- tokeninfo(&val,&str);
- assert(strlen(str)index;
+ if (!needtoken(tSYMBOL)) {
+ delete_autolisttable();
+ return;
+ } /* if */
+ tokeninfo(&val,&str);
+ assert(strlen(str)name;
- if (*fsaname=='\0')
- fsaname="";
- error(87,name,fsaname); /* unknown state for automaton */
- } else {
- ldconst(state->value,sPRI);
- storereg(automaton->value,sPRI);
- /* find the optional entry() function for the state */
- sym=findglb(uENTRYFUNC);
- if (sc_status==statWRITE && sym!=NULL && sym->ident==iFUNCTN && sym->states!=NULL) {
- for (stlist=sym->states->next; stlist!=NULL; stlist=stlist->next) {
- assert(strlen(stlist->name)!=0);
- if (state_getfsa(stlist->index)==fsa && state_inlist(stlist->index,(int)state->value))
- break; /* found! */
- } /* for */
- assert(stlist==NULL || state_inlist(stlist->index,state->value));
- if (stlist!=NULL) {
- /* the label to jump to is in stlist->name */
- ffcall(sym,stlist->name,0);
- } /* if */
- } /* if */
- } /* if */
- } /* if */
+ state=state_find(name,fsa);
+ if (state==NULL) {
+ char *fsaname=automaton->name;
+ if (*fsaname=='\0')
+ fsaname="";
+ error(87,name,fsaname); /* unknown state for automaton */
+ } else {
+ ldconst(state->value,sPRI);
+ storereg(automaton->value,sPRI);
+ /* find the optional entry() function for the state */
+ sym=findglb(uENTRYFUNC);
+ if (sc_status==statWRITE && sym!=NULL && sym->ident==iFUNCTN && sym->states!=NULL) {
+ for (stlist=sym->states->next; stlist!=NULL; stlist=stlist->next) {
+ assert(strlen(stlist->name)!=0);
+ if (state_getfsa(stlist->index)==fsa && state_inlist(stlist->index,(int)state->value))
+ break; /* found! */
+ } /* for */
+ assert(stlist==NULL || state_inlist(stlist->index,state->value));
+ if (stlist!=NULL) {
+ /* the label to jump to is in stlist->name */
+ ffcall(sym,stlist->name,0);
+ } /* if */
+ } /* if */
+ } /* if */
+ } /* if */
needtoken(tTERM);
if (flabel>=0)
- setlabel(flabel); /* condition was false, jump around the state switch */
+ setlabel(flabel); /* condition was false, jump around the state switch */
#if !defined SC_LIGHT
- /* mark for documentation */
- if (sc_status==statFIRST) {
- /* get the last list id attached to the function, this contains the source states */
- assert(curfunc!=NULL);
- if (curfunc->states!=NULL) {
- stlist=curfunc->states->next;
- assert(stlist!=NULL);
- while (stlist->next!=NULL)
- stlist=stlist->next;
- listid=stlist->index;
- } else {
- listid=-1;
- } /* if */
- listindex=0;
- length=strlen(name)+70; /* +70 for the fixed part "\n" */
- /* see if there are any condition strings to attach */
- for (index=0; (str=get_autolist(index))!=NULL; index++)
- length+=strlen(str);
- if ((doc=(char*)malloc(length*sizeof(char)))!=NULL) {
- do {
- sprintf(doc,"=0) {
- /* get the source state */
- stateindex=state_listitem(listid,listindex);
- state=state_findid(stateindex);
- assert(state!=NULL);
- sprintf(doc+strlen(doc)," source=\"%s\"",state->name);
- } /* if */
- if (get_autolist(0)!=NULL) {
- /* add the condition */
- strcat(doc," condition=\"");
- for (index=0; (str=get_autolist(index))!=NULL; index++) {
- /* remove the ')' token that may be appended before detecting that the expression has ended */
- if (*str!=')' || *(str+1)!='\0' || get_autolist(index+1)!=NULL)
- strcat(doc,str);
- } /* for */
- strcat(doc,"\"");
- } /* if */
- strcat(doc,"/>\n");
- insert_docstring(doc);
- } while (listid>=0 && ++listindexstates!=NULL) {
+ stlist=curfunc->states->next;
+ assert(stlist!=NULL);
+ while (stlist->next!=NULL)
+ stlist=stlist->next;
+ listid=stlist->index;
+ } else {
+ listid=-1;
+ } /* if */
+ listindex=0;
+ length=strlen(name)+70; /* +70 for the fixed part "\n" */
+ /* see if there are any condition strings to attach */
+ for (index=0; (str=get_autolist(index))!=NULL; index++)
+ length+=strlen(str);
+ if ((doc=(char*)malloc(length*sizeof(char)))!=NULL) {
+ do {
+ sprintf(doc,"=0) {
+ /* get the source state */
+ stateindex=state_listitem(listid,listindex);
+ state=state_findid(stateindex);
+ assert(state!=NULL);
+ sprintf(doc+strlen(doc)," source=\"%s\"",state->name);
+ } /* if */
+ if (get_autolist(0)!=NULL) {
+ /* add the condition */
+ strcat(doc," condition=\"");
+ for (index=0; (str=get_autolist(index))!=NULL; index++) {
+ /* remove the ')' token that may be appended before detecting that the expression has ended */
+ if (*str!=')' || *(str+1)!='\0' || get_autolist(index+1)!=NULL)
+ strcat(doc,str);
+ } /* for */
+ strcat(doc,"\"");
+ } /* if */
+ strcat(doc,"/>\n");
+ insert_docstring(doc);
+ } while (listid>=0 && ++listindex=(wq+wqTABSZ-wqSIZE))
- error(102,"loop table"); /* loop table overflow (too many active loops)*/
+ error(102,"loop table"); /* loop table overflow (too many active loops)*/
k=0;
- while (kwq)
- wqptr-=wqSIZE;
+ wqptr-=wqSIZE;
}
static int *readwhile(void)
{
if (wqptr<=wq){
- error(24); /* out of context */
- return NULL;
- } else {
- return (wqptr-wqSIZE);
- } /* if */
+ error(24); /* out of context */
+ return NULL;
+ } else {
+ return (wqptr-wqSIZE);
+ } /* if */
}
diff --git a/compiler/libpc300/sc2.c b/compiler/libpc300/sc2.c
index 2fc52a32..b703b81a 100755
--- a/compiler/libpc300/sc2.c
+++ b/compiler/libpc300/sc2.c
@@ -715,18 +715,6 @@ static int ftoi(cell *val,const unsigned char *curptr)
#endif
#elif PAWN_CELL_SIZE==64
*val=*((cell *)&fnum);
- #if !defined NDEBUG
- /* I assume that the C/C++ compiler stores "double" values in IEEE 754
- * format (as mandated in the ANSI standard).
- */
- { float test1 = 0.0, test2 = 50.0, test3 = -50.0;
- uint64_t bit = 1;
- /* test 0.0 == all bits 0 */
- assert(*(uint64_t*)&test1==0x00000000L);
- /* test sign & magnitude format */
- assert(((*(uint64_t*)&test2) ^ (*(uint64_t*)&test3)) == (bit << (PAWN_CELL_SIZE-1)));
- }
- #endif
#else
#error Unsupported cell size
#endif
@@ -1578,7 +1566,7 @@ static void substallpatterns(unsigned char *line,int buffersize)
if (*start=='\0')
break; /* abort loop on error */
/* if matching the operator "defined", skip it plus the symbol behind it */
- if (strncmp((char*)start,"defined",7)==0 && *(start+7)<=' ') {
+ if (strncmp((char*)start,"defined",7)==0 && !isalpha((char)*(start+7))) {
start+=7; /* skip "defined" */
/* skip white space & parantheses */
while (*start<=' ' && *start!='\0' || *start=='(')