indirect constants for m32-script alongside with other changes

git-svn-id: https://svn.eduke32.com/eduke32@1496 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2009-09-14 22:11:37 +00:00
parent 174dbe472e
commit 3be58d63d0
6 changed files with 276 additions and 181 deletions

View file

@ -65,6 +65,9 @@ extern void SetWATERPalette(void);
extern void SetSLIMEPalette(void); extern void SetSLIMEPalette(void);
extern void SetBOSS1Palette(void); extern void SetBOSS1Palette(void);
extern int32_t *constants, constants_allocsize;
extern int32_t g_numSavedConstants;
extern instype *script ,*insptr; extern instype *script ,*insptr;
extern int32_t *labelval; extern int32_t *labelval;
extern uint8_t *labeltype; extern uint8_t *labeltype;

View file

@ -4583,7 +4583,7 @@ static void Keys3d(void)
if (keystatus[KEYSC_QUOTE] && keystatus[KEYSC_DELETE]) // ' del if (keystatus[KEYSC_QUOTE] && keystatus[KEYSC_DELETE]) // ' del
{ {
keystatus[KEYSC_BS] = 0; keystatus[KEYSC_DELETE] = 0;
switch (searchstat) switch (searchstat)
{ {
case 0: case 0:
@ -8866,7 +8866,8 @@ static int32_t osdcmd_do(const osdfuncparm_t *parm)
{ {
intptr_t tscrofs; intptr_t tscrofs;
char *tp; char *tp;
int32_t slen; int32_t i, j, slen;
int32_t onumconstants=g_numSavedConstants;
if (parm->numparms < 1) if (parm->numparms < 1)
return OSDCMD_SHOWHELP; return OSDCMD_SHOWHELP;
@ -8885,17 +8886,34 @@ static int32_t osdcmd_do(const osdfuncparm_t *parm)
tp[slen] = '\n'; tp[slen] = '\n';
tp[slen+1] = '\0'; tp[slen+1] = '\0';
g_didDefineSomething = 0;
C_Compile(tp, 0); C_Compile(tp, 0);
Bfree(tp); Bfree(tp);
if (g_numCompilerErrors == 0)
if (g_numCompilerErrors)
{ {
// g_scriptPtr = script + tscrofs; // handled in C_Compile()
return OSDCMD_OK;
}
for (i=0,j=0; i<MAXEVENTS; i++)
if (aEventOffsets[i]>=0)
j++;
if (g_didDefineSomething == 0)
{
g_numSavedConstants = onumconstants;
*g_scriptPtr = CON_RETURN + (g_lineNumber<<12); *g_scriptPtr = CON_RETURN + (g_lineNumber<<12);
g_scriptPtr = script + tscrofs;
insptr = script + tscrofs; insptr = script + tscrofs;
Bmemcpy(&vm, &vm_default, sizeof(vmstate_t)); Bmemcpy(&vm, &vm_default, sizeof(vmstate_t));
X_DoExecute(0); X_DoExecute(0);
// asksave = 1; // handled in Access(Sprite|Sector|Wall) // asksave = 1; // handled in Access(Sprite|Sector|Wall)
} }
g_scriptPtr = script + tscrofs;
return OSDCMD_OK; return OSDCMD_OK;
} }

View file

@ -31,22 +31,42 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
char g_szScriptFileName[BMAX_PATH] = "(none)"; // file we're currently compiling char g_szScriptFileName[BMAX_PATH] = "(none)"; // file we're currently compiling
static char g_szCurrentBlockName[256] = "(none)", g_szLastBlockName[256] = "NULL"; static char g_szCurrentBlockName[256] = "(none)", g_szLastBlockName[256] = "NULL";
////// compiler state vvv
static const char *textptr;
int32_t g_totalLines, g_lineNumber; int32_t g_totalLines, g_lineNumber;
static int32_t g_checkingIfElse, g_currentStateIdx = -1; int32_t g_numCompilerErrors, g_numCompilerWarnings;
static instype *g_caseScriptPtr = NULL; // the pointer to the start of the case table in a switch statement int32_t g_didDefineSomething;
typedef struct
{
int32_t currentStateIdx;
ofstype currentStateOfs; // the offset to the start of the currently parsed states' code
int32_t currentEvent;
ofstype parsingEventOfs;
int32_t checkingSwitch;
int32_t numCases;
instype *caseScriptPtr; // the pointer to the start of the case table in a switch statement
// first entry is 'default' code. // first entry is 'default' code.
static instype *g_caseCodePtr = NULL; // the pointer to the start of the different cases' code instype *caseCodePtr; // the pointer to the start of the different cases' code
static ofstype g_currentStateOfs = -1; // the offset to the start of the currently parsed states' code int32_t labelsOnly;
static int32_t g_numCases = 0; int32_t numBraces;
static int32_t g_checkingSwitch = 0, g_currentEvent = -1; int32_t checkingIfElse, ifElseAborted;
static int32_t g_labelsOnly = 0; } compilerstate_t;
static int32_t g_numBraces = 0;
static compilerstate_t cs;
static compilerstate_t cs_default = {-1, -1, -1, -1, 0, 0, NULL, NULL, 0, 0, 0, 0};
////// -------------------
instype *script = NULL; instype *script = NULL;
instype *g_scriptPtr; instype *g_scriptPtr;
int32_t g_scriptSize = 65536; int32_t g_scriptSize = 65536;
int32_t *constants, constants_allocsize=1024;
int32_t g_numSavedConstants=0;
static int32_t g_tooBigConstant=0;
char *label; char *label;
int32_t *labelval; int32_t *labelval;
uint8_t *labeltype; uint8_t *labeltype;
@ -76,20 +96,15 @@ int32_t g_numQuoteRedefinitions = 0;
ofstype aEventOffsets[MAXEVENTS]; ofstype aEventOffsets[MAXEVENTS];
static int32_t aEventSizes[MAXEVENTS]; static int32_t aEventSizes[MAXEVENTS];
static ofstype g_parsingEventOfs = -1;
gamevar_t aGameVars[MAXGAMEVARS]; gamevar_t aGameVars[MAXGAMEVARS];
gamearray_t aGameArrays[MAXGAMEARRAYS]; gamearray_t aGameArrays[MAXGAMEARRAYS];
int32_t g_gameVarCount=0, g_systemVarCount=0; int32_t g_gameVarCount=0, g_systemVarCount=0;
int32_t g_gameArrayCount=0, g_systemArrayCount=0; int32_t g_gameArrayCount=0, g_systemArrayCount=0;
static const char *textptr;
int32_t g_numCompilerErrors, g_numCompilerWarnings;
static int32_t g_noConstBitwidthWarning=0;
// "magic" number for { and }, overrides line number in compiled code for later detection // "magic" number for { and }, overrides line number in compiled code for later detection
#define IFELSE_MAGIC 31337 #define IFELSE_MAGIC 31337
static int32_t g_ifElseAborted;
void C_ReportError(int32_t iError); void C_ReportError(int32_t iError);
@ -509,8 +524,8 @@ static void C_InitHashes()
static int32_t C_SetScriptSize(int32_t size) static int32_t C_SetScriptSize(int32_t size)
{ {
ofstype oscriptOfs = (unsigned)(g_scriptPtr-script); ofstype oscriptOfs = (unsigned)(g_scriptPtr-script);
ofstype ocaseScriptOfs = (unsigned)(g_caseScriptPtr-script); ofstype ocaseScriptOfs = (unsigned)(cs.caseScriptPtr-script);
ofstype ocaseCodeOfs = (unsigned)(g_caseCodePtr-script); ofstype ocaseCodeOfs = (unsigned)(cs.caseCodePtr-script);
instype *newscript; instype *newscript;
int32_t osize = g_scriptSize; int32_t osize = g_scriptSize;
@ -545,10 +560,10 @@ static int32_t C_SetScriptSize(int32_t size)
g_scriptPtr = (instype *)(script+oscriptOfs); g_scriptPtr = (instype *)(script+oscriptOfs);
// initprintf("script: %d, \n",script); initprintf("offset: %d\n",(unsigned)(g_scriptPtr-script)); // initprintf("script: %d, \n",script); initprintf("offset: %d\n",(unsigned)(g_scriptPtr-script));
if (g_caseScriptPtr != NULL) if (cs.caseScriptPtr != NULL)
g_caseScriptPtr = (instype *)(script+ocaseScriptOfs); cs.caseScriptPtr = (instype *)(script+ocaseScriptOfs);
if (g_caseCodePtr != NULL) if (cs.caseCodePtr != NULL)
g_caseCodePtr = (instype *)(script+ocaseCodeOfs); cs.caseCodePtr = (instype *)(script+ocaseCodeOfs);
return 0; return 0;
} }
@ -595,8 +610,8 @@ static int32_t C_SkipComments(void)
// initprintf("%s:%d: debug: EOF in comment!\n",g_szScriptFileName,g_lineNumber); // initprintf("%s:%d: debug: EOF in comment!\n",g_szScriptFileName,g_lineNumber);
C_ReportError(-1); C_ReportError(-1);
initprintf("%s:%d: error: found `/*' with no `*/'.\n",g_szScriptFileName,g_lineNumber); initprintf("%s:%d: error: found `/*' with no `*/'.\n",g_szScriptFileName,g_lineNumber);
g_numBraces = 0; cs.numBraces = 0;
g_currentStateIdx = -1; cs.currentStateIdx = -1;
g_numCompilerErrors++; g_numCompilerErrors++;
break; break;
} }
@ -777,12 +792,12 @@ static int32_t C_GetNextKeyword(void) //Returns its code #
static void C_GetNextVarType(int32_t type) static void C_GetNextVarType(int32_t type)
{ {
int32_t id=0, flags=0, num; int32_t i, id=0, flags=0, num, indirect=0;
C_SkipComments(); C_SkipComments();
// constant where gamevar expected // constant where gamevar expected
if ((type==0 || type==GAMEVAR_SPECIAL) && !g_labelsOnly && if ((type==0 || type==GAMEVAR_SPECIAL) && !cs.labelsOnly &&
(isdigit(*textptr) || ((*textptr == '-') && isdigit(*(textptr+1))))) (isdigit(*textptr) || ((*textptr == '-') && isdigit(*(textptr+1)))))
{ {
// if (!(g_numCompilerErrors || g_numCompilerWarnings) && g_scriptDebug) // if (!(g_numCompilerErrors || g_numCompilerWarnings) && g_scriptDebug)
@ -793,21 +808,44 @@ static void C_GetNextVarType(int32_t type)
else else
num = atoi(textptr); num = atoi(textptr);
if (type==GAMEVAR_SPECIAL && (int16_t)num < 0) if (type==GAMEVAR_SPECIAL && (num<0 || num>=65536))
{ {
C_ReportError(-1); C_ReportError(-1);
initprintf("%s:%d: error: negative array index.\n",g_szScriptFileName,g_lineNumber); initprintf("%s:%d: error: array index %d out of bounds. (max: 65535)\n",g_szScriptFileName,g_lineNumber, num);
g_numCompilerErrors++; g_numCompilerErrors++;
} }
if (num != (int16_t)num) if (g_numCompilerErrors==0 && type!=GAMEVAR_SPECIAL && num != (int16_t)num)
{ {
if (!g_noConstBitwidthWarning) g_tooBigConstant = 1;
C_ReportError(WARNING_CONSTANTBITSIZE); indirect = 1;
g_numCompilerWarnings++;
for (i=g_numSavedConstants-1; i>=0; i--)
if (constants[i] == num)
break;
if (i<0)
{
i = g_numSavedConstants;
if (i>=constants_allocsize)
{
constants_allocsize *= 2;
constants = Brealloc(constants, constants_allocsize * sizeof(constants[0]));
if (!constants)
{
initprintf("C_GetNextVarType(): ERROR: out of memory!\n");
g_numCompilerErrors++;
return;
}
} }
*g_scriptPtr++ = MAXGAMEVARS | (num<<16); constants[i] = num;
num = i;
g_numSavedConstants++;
}
}
*g_scriptPtr++ = MAXGAMEVARS | (num<<16) | indirect;
while (!ispecial(*textptr) && *textptr != ']') textptr++; while (!ispecial(*textptr) && *textptr != ']') textptr++;
@ -941,7 +979,7 @@ static void C_GetNextVarType(int32_t type)
id = GetGamevarID(tlabel); id = GetGamevarID(tlabel);
if (id < 0) //gamevar not found if (id < 0) //gamevar not found
{ {
if (!type && !g_labelsOnly) if (!type && !cs.labelsOnly)
{ {
//try looking for a define instead //try looking for a define instead
id = hash_find(&labelH, tlabel); id = hash_find(&labelH, tlabel);
@ -949,20 +987,24 @@ static void C_GetNextVarType(int32_t type)
{ {
// if (!(g_numCompilerErrors || g_numCompilerWarnings) && g_scriptDebug) // if (!(g_numCompilerErrors || g_numCompilerWarnings) && g_scriptDebug)
// initprintf("%s:%d: debug: accepted defined label `%s' instead of gamevar.\n",g_szScriptFileName,g_lineNumber,label+(id*MAXLABELLEN)); // initprintf("%s:%d: debug: accepted defined label `%s' instead of gamevar.\n",g_szScriptFileName,g_lineNumber,label+(id*MAXLABELLEN));
num = labelval[id];
*g_scriptPtr++ = MAXGAMEVARS | (labelval[id]<<16); if (type==GAMEVAR_SPECIAL && (num<0 || num>=65536))
if (labelval[id] != (int16_t)labelval[id])
{ {
if (!g_noConstBitwidthWarning) C_ReportError(-1);
C_ReportError(WARNING_CONSTANTBITSIZE); initprintf("%s:%d: error: label %s=%d not suitable as array index. (max: 65535)\n",g_szScriptFileName,g_lineNumber, label+(id*MAXLABELLEN), num);
g_numCompilerWarnings++; g_numCompilerErrors++;
}
else if (num != (int16_t)num)
{
g_tooBigConstant = 1;
indirect = 2;
num = id;
} }
*g_scriptPtr++ = MAXGAMEVARS | (num<<16) | indirect;
return; return;
} }
g_numCompilerErrors++;
C_ReportError(ERROR_NOTAGAMEVAR);
return;
} }
g_numCompilerErrors++; g_numCompilerErrors++;
C_ReportError(ERROR_NOTAGAMEVAR); C_ReportError(ERROR_NOTAGAMEVAR);
@ -1054,7 +1096,7 @@ static int32_t C_GetNextValue(int32_t type)
gl = (char *)C_GetLabelType(labeltype[i]); gl = (char *)C_GetLabelType(labeltype[i]);
C_ReportError(-1); C_ReportError(-1);
initprintf("%s:%d: error: expected %s, found %s.\n",g_szScriptFileName,g_lineNumber,el,gl); initprintf("%s:%d: error: expected %s, found %s.\n",g_szScriptFileName,g_lineNumber,el,gl);
initprintf("i=%d, %s!!! lt:%d t:%d\n", i, label+(i*MAXLABELLEN), labeltype[i], type); // initprintf("i=%d, %s!!! lt:%d t:%d\n", i, label+(i*MAXLABELLEN), labeltype[i], type);
g_numCompilerErrors++; g_numCompilerErrors++;
Bfree(el); Bfree(el);
Bfree(gl); Bfree(gl);
@ -1071,7 +1113,7 @@ static int32_t C_GetNextValue(int32_t type)
return -1; // error! return -1; // error!
} }
if (isdigit(*textptr) && g_labelsOnly) if (isdigit(*textptr) && cs.labelsOnly)
{ {
C_ReportError(WARNING_LABELSONLY); C_ReportError(WARNING_LABELSONLY);
g_numCompilerWarnings++; g_numCompilerWarnings++;
@ -1135,7 +1177,7 @@ static int32_t C_CheckMalformedBranch(ofstype lastScriptOfs)
case CON_ENDS: case CON_ENDS:
case CON_ELSE: case CON_ELSE:
g_scriptPtr = script + lastScriptOfs; g_scriptPtr = script + lastScriptOfs;
g_ifElseAborted = 1; cs.ifElseAborted = 1;
C_ReportError(-1); C_ReportError(-1);
g_numCompilerWarnings++; g_numCompilerWarnings++;
initprintf("%s:%d: warning: malformed `%s' branch\n", g_szScriptFileName, g_lineNumber, initprintf("%s:%d: warning: malformed `%s' branch\n", g_szScriptFileName, g_lineNumber,
@ -1150,14 +1192,14 @@ static int32_t C_CheckEmptyBranch(int32_t tw, ofstype lastScriptOfs)
// ifrnd actually does something when the condition is executed // ifrnd actually does something when the condition is executed
if ((Bstrncmp(keyw[tw], "if", 2) && tw != CON_ELSE) || tw == CON_IFRND) if ((Bstrncmp(keyw[tw], "if", 2) && tw != CON_ELSE) || tw == CON_IFRND)
{ {
g_ifElseAborted = 0; cs.ifElseAborted = 0;
return 0; return 0;
} }
if ((*(g_scriptPtr) & 0xFFF) != CON_NULLOP || *(g_scriptPtr)>>12 != IFELSE_MAGIC) if ((*(g_scriptPtr) & 0xFFF) != CON_NULLOP || *(g_scriptPtr)>>12 != IFELSE_MAGIC)
g_ifElseAborted = 0; cs.ifElseAborted = 0;
if (g_ifElseAborted) if (cs.ifElseAborted)
{ {
C_ReportError(-1); C_ReportError(-1);
g_numCompilerWarnings++; g_numCompilerWarnings++;
@ -1178,27 +1220,27 @@ static int32_t C_CountCaseStatements()
const char *temptextptr = textptr; const char *temptextptr = textptr;
int32_t temp_ScriptLineNumber = g_lineNumber; int32_t temp_ScriptLineNumber = g_lineNumber;
ofstype scriptoffset = (unsigned)(g_scriptPtr-script); ofstype scriptoffset = (unsigned)(g_scriptPtr-script);
ofstype caseoffset = (unsigned)(g_caseScriptPtr-script); ofstype caseoffset = (unsigned)(cs.caseScriptPtr-script);
g_numCases=0; cs.numCases=0;
g_caseScriptPtr=NULL; cs.caseScriptPtr=NULL;
//Bsprintf(g_szBuf,"CSS: %.12s",textptr); AddLog(g_szBuf); //Bsprintf(g_szBuf,"CSS: %.12s",textptr); AddLog(g_szBuf);
while (C_ParseCommand() == 0) while (C_ParseCommand() == 0)
{ {
//Bsprintf(g_szBuf,"CSSL: %.20s",textptr); AddLog(g_szBuf); //Bsprintf(g_szBuf,"CSSL: %.20s",textptr); AddLog(g_szBuf);
; ;
} }
// since we processed the endswitch, we need to re-increment g_checkingSwitch // since we processed the endswitch, we need to re-increment cs.checkingSwitch
g_checkingSwitch++; cs.checkingSwitch++;
textptr = temptextptr; textptr = temptextptr;
g_scriptPtr = (instype *)(script+scriptoffset); g_scriptPtr = (instype *)(script+scriptoffset);
g_lineNumber = temp_ScriptLineNumber; g_lineNumber = temp_ScriptLineNumber;
lCount = g_numCases; lCount = cs.numCases;
g_numCases = 0; cs.numCases = 0;
g_caseScriptPtr = (instype *)(script+caseoffset); cs.caseScriptPtr = (instype *)(script+caseoffset);
return lCount; return lCount;
} }
@ -1220,7 +1262,7 @@ static int32_t C_ParseCommand(void)
// if (g_scriptDebug) // if (g_scriptDebug)
// C_ReportError(-1); // C_ReportError(-1);
/// if (g_checkingSwitch > 0) /// if (cs.checkingSwitch > 0)
/// Bsprintf(g_szBuf,"PC(): '%.25s'",textptr); AddLog(g_szBuf); /// Bsprintf(g_szBuf,"PC(): '%.25s'",textptr); AddLog(g_szBuf);
tw = C_GetNextKeyword(); tw = C_GetNextKeyword();
@ -1243,7 +1285,7 @@ static int32_t C_ParseCommand(void)
g_numCompilerWarnings++; g_numCompilerWarnings++;
initprintf("%s:%d: warning: `nullop' found without `else'\n",g_szScriptFileName,g_lineNumber); initprintf("%s:%d: warning: `nullop' found without `else'\n",g_szScriptFileName,g_lineNumber);
g_scriptPtr--; g_scriptPtr--;
g_ifElseAborted = 1; cs.ifElseAborted = 1;
} }
return 0; return 0;
@ -1353,8 +1395,8 @@ static int32_t C_ParseCommand(void)
Bstrcpy(g_szScriptFileName, tempbuf); Bstrcpy(g_szScriptFileName, tempbuf);
temp_ScriptLineNumber = g_lineNumber; temp_ScriptLineNumber = g_lineNumber;
g_lineNumber = 1; g_lineNumber = 1;
temp_ifelse_check = g_checkingIfElse; temp_ifelse_check = cs.checkingIfElse;
g_checkingIfElse = 0; cs.checkingIfElse = 0;
textptr = mptr; textptr = mptr;
do done = C_ParseCommand(); do done = C_ParseCommand();
@ -1363,7 +1405,7 @@ static int32_t C_ParseCommand(void)
Bstrcpy(g_szScriptFileName, parentScriptFileName); Bstrcpy(g_szScriptFileName, parentScriptFileName);
g_totalLines += g_lineNumber; g_totalLines += g_lineNumber;
g_lineNumber = temp_ScriptLineNumber; g_lineNumber = temp_ScriptLineNumber;
g_checkingIfElse = temp_ifelse_check; cs.checkingIfElse = temp_ifelse_check;
textptr = origtptr; textptr = origtptr;
@ -1373,7 +1415,7 @@ static int32_t C_ParseCommand(void)
case CON_DEFSTATE: case CON_DEFSTATE:
g_scriptPtr--; g_scriptPtr--;
if (g_parsingEventOfs < 0 && g_currentStateIdx < 0) if (cs.parsingEventOfs < 0 && cs.currentStateIdx < 0)
{ {
C_GetNextLabelName(); C_GetNextLabelName();
@ -1401,20 +1443,20 @@ static int32_t C_ParseCommand(void)
j = hash_find(&stateH, tlabel); j = hash_find(&stateH, tlabel);
if (j>=0) // only redefining if (j>=0) // only redefining
{ {
g_currentStateIdx = j; cs.currentStateIdx = j;
g_currentStateOfs = (g_scriptPtr-script); cs.currentStateOfs = (g_scriptPtr-script);
Bsprintf(g_szCurrentBlockName, "%s", statesinfo[j].name); Bsprintf(g_szCurrentBlockName, "%s", statesinfo[j].name);
} }
else // new state definition else // new state definition
{ {
g_currentStateIdx = j = g_stateCount; cs.currentStateIdx = j = g_stateCount;
g_currentStateOfs = (g_scriptPtr-script); cs.currentStateOfs = (g_scriptPtr-script);
if (g_stateCount >= statesinfo_allocsize) if (g_stateCount >= statesinfo_allocsize)
{ {
statesinfo_allocsize *= 2; statesinfo_allocsize *= 2;
statesinfo = Brealloc(statesinfo, statesinfo_allocsize); statesinfo = Brealloc(statesinfo, statesinfo_allocsize * sizeof(statesinfo[0]));
if (!statesinfo) if (!statesinfo)
{ {
initprintf("C_ParseCommand(): ERROR: out of memory!\n"); initprintf("C_ParseCommand(): ERROR: out of memory!\n");
@ -1436,7 +1478,7 @@ static int32_t C_ParseCommand(void)
return 1; return 1;
case CON_ENDS: case CON_ENDS:
if (g_currentStateIdx < 0) if (cs.currentStateIdx < 0)
{ {
C_ReportError(-1); C_ReportError(-1);
initprintf("%s:%d: error: found `ends' without open `state'.\n",g_szScriptFileName,g_lineNumber); initprintf("%s:%d: error: found `ends' without open `state'.\n",g_szScriptFileName,g_lineNumber);
@ -1445,37 +1487,37 @@ static int32_t C_ParseCommand(void)
} }
else else
{ {
if (g_numBraces > 0) if (cs.numBraces > 0)
{ {
C_ReportError(ERROR_OPENBRACKET); C_ReportError(ERROR_OPENBRACKET);
g_numCompilerErrors++; g_numCompilerErrors++;
} }
if (g_numBraces < 0) if (cs.numBraces < 0)
{ {
C_ReportError(ERROR_CLOSEBRACKET); C_ReportError(ERROR_CLOSEBRACKET);
g_numCompilerErrors++; g_numCompilerErrors++;
} }
if (g_checkingSwitch > 0) if (cs.checkingSwitch > 0)
{ {
C_ReportError(ERROR_NOENDSWITCH); C_ReportError(ERROR_NOENDSWITCH);
g_numCompilerErrors++; g_numCompilerErrors++;
g_checkingSwitch = 0; // can't be checking anymore... cs.checkingSwitch = 0; // can't be checking anymore...
} }
if (g_numCompilerErrors) if (g_numCompilerErrors)
{ {
g_currentStateOfs = -1; cs.currentStateOfs = -1;
g_currentStateIdx = -1; cs.currentStateIdx = -1;
Bsprintf(g_szCurrentBlockName,"(none)"); Bsprintf(g_szCurrentBlockName,"(none)");
return 0; return 0;
} }
j = g_currentStateIdx; j = cs.currentStateIdx;
if (g_currentStateIdx == g_stateCount) // we were defining a new state if (cs.currentStateIdx == g_stateCount) // we were defining a new state
{ {
statesinfo[j].ofs = g_currentStateOfs; statesinfo[j].ofs = cs.currentStateOfs;
statesinfo[j].codesize = (g_scriptPtr-script) - g_currentStateOfs; statesinfo[j].codesize = (g_scriptPtr-script) - cs.currentStateOfs;
g_stateCount++; g_stateCount++;
@ -1484,7 +1526,7 @@ static int32_t C_ParseCommand(void)
else // we were redefining a state else // we were redefining a state
{ {
int32_t oofs = statesinfo[j].ofs; int32_t oofs = statesinfo[j].ofs;
int32_t nofs = g_currentStateOfs; int32_t nofs = cs.currentStateOfs;
int32_t osize = statesinfo[j].codesize; int32_t osize = statesinfo[j].codesize;
int32_t nsize = (g_scriptPtr-script) - nofs; int32_t nsize = (g_scriptPtr-script) - nofs;
@ -1529,8 +1571,10 @@ static int32_t C_ParseCommand(void)
g_scriptPtr -= osize; g_scriptPtr -= osize;
} }
g_currentStateOfs = -1; g_didDefineSomething = 1;
g_currentStateIdx = -1;
cs.currentStateOfs = -1;
cs.currentStateIdx = -1;
Bsprintf(g_szCurrentBlockName,"(none)"); Bsprintf(g_szCurrentBlockName,"(none)");
} }
@ -1568,14 +1612,14 @@ static int32_t C_ParseCommand(void)
return 0; return 0;
case CON_ONEVENT: case CON_ONEVENT:
if (g_currentStateIdx >= 0 || g_parsingEventOfs >= 0) if (cs.currentStateIdx >= 0 || cs.parsingEventOfs >= 0)
{ {
C_ReportError(ERROR_FOUNDWITHIN); C_ReportError(ERROR_FOUNDWITHIN);
g_numCompilerErrors++; g_numCompilerErrors++;
} }
g_scriptPtr--; g_scriptPtr--;
g_numBraces = 0; cs.numBraces = 0;
C_SkipComments(); C_SkipComments();
j = 0; j = 0;
@ -1586,15 +1630,15 @@ static int32_t C_ParseCommand(void)
} }
g_szCurrentBlockName[j] = 0; g_szCurrentBlockName[j] = 0;
g_labelsOnly = 1; cs.labelsOnly = 1;
C_GetNextValue(LABEL_EVENT); C_GetNextValue(LABEL_EVENT);
g_labelsOnly = 0; cs.labelsOnly = 0;
g_scriptPtr--; g_scriptPtr--;
j = *g_scriptPtr; // event number j = *g_scriptPtr; // event number
g_currentEvent = j; cs.currentEvent = j;
g_parsingEventOfs = g_scriptPtr-script; cs.parsingEventOfs = g_scriptPtr-script;
//Bsprintf(g_szBuf,"Adding Event for %d at %lX",j, g_parsingEventPtr); AddLog(g_szBuf); //Bsprintf(g_szBuf,"Adding Event for %d at %lX",j, g_parsingEventPtr); AddLog(g_szBuf);
if (j<0 || j >= MAXEVENTS) if (j<0 || j >= MAXEVENTS)
{ {
@ -1603,39 +1647,39 @@ static int32_t C_ParseCommand(void)
return 0; return 0;
} }
g_checkingIfElse = 0; cs.checkingIfElse = 0;
return 0; return 0;
case CON_ENDEVENT: case CON_ENDEVENT:
if (g_parsingEventOfs < 0) if (cs.parsingEventOfs < 0)
{ {
C_ReportError(-1); C_ReportError(-1);
initprintf("%s:%d: error: found `endevent' without open `onevent'.\n",g_szScriptFileName,g_lineNumber); initprintf("%s:%d: error: found `endevent' without open `onevent'.\n",g_szScriptFileName,g_lineNumber);
g_numCompilerErrors++; g_numCompilerErrors++;
return 1; return 1;
} }
if (g_numBraces > 0) if (cs.numBraces > 0)
{ {
C_ReportError(ERROR_OPENBRACKET); C_ReportError(ERROR_OPENBRACKET);
g_numCompilerErrors++; g_numCompilerErrors++;
} }
if (g_numBraces < 0) if (cs.numBraces < 0)
{ {
C_ReportError(ERROR_CLOSEBRACKET); C_ReportError(ERROR_CLOSEBRACKET);
g_numCompilerErrors++; g_numCompilerErrors++;
} }
if (g_numCompilerErrors) if (g_numCompilerErrors)
{ {
g_parsingEventOfs = -1; cs.parsingEventOfs = -1;
g_currentEvent = -1; cs.currentEvent = -1;
Bsprintf(g_szCurrentBlockName,"(none)"); Bsprintf(g_szCurrentBlockName,"(none)");
return 0; return 0;
} }
j = g_currentEvent; j = cs.currentEvent;
if (aEventOffsets[j] >= 0) // if event was previously declared, overwrite it if (aEventOffsets[j] >= 0) // if event was previously declared, overwrite it
{ {
int32_t oofs = aEventOffsets[j], nofs = g_parsingEventOfs; int32_t oofs = aEventOffsets[j], nofs = cs.parsingEventOfs;
int32_t osize = aEventSizes[j], nsize = (g_scriptPtr-script) - nofs; int32_t osize = aEventSizes[j], nsize = (g_scriptPtr-script) - nofs;
if (osize == nsize) if (osize == nsize)
@ -1680,28 +1724,30 @@ static int32_t C_ParseCommand(void)
} }
else // event defined for the first time else // event defined for the first time
{ {
aEventOffsets[j] = g_parsingEventOfs; aEventOffsets[j] = cs.parsingEventOfs;
aEventSizes[j] = (g_scriptPtr-script) - g_parsingEventOfs; aEventSizes[j] = (g_scriptPtr-script) - cs.parsingEventOfs;
initprintf(" Defined event `%s' (index %d).\n", g_szCurrentBlockName, j); initprintf(" Defined event `%s' (index %d).\n", g_szCurrentBlockName, j);
} }
g_parsingEventOfs = -1; g_didDefineSomething = 1;
g_currentEvent = -1;
cs.parsingEventOfs = -1;
cs.currentEvent = -1;
Bsprintf(g_szCurrentBlockName,"(none)"); Bsprintf(g_szCurrentBlockName,"(none)");
return 0; return 0;
// *** control flow // *** control flow
case CON_ELSE: case CON_ELSE:
if (g_checkingIfElse) if (cs.checkingIfElse)
{ {
ofstype offset; ofstype offset;
ofstype lastScriptOfs = (g_scriptPtr-script) - 1; ofstype lastScriptOfs = (g_scriptPtr-script) - 1;
instype *tscrptr; instype *tscrptr;
g_ifElseAborted = 0; cs.ifElseAborted = 0;
g_checkingIfElse--; cs.checkingIfElse--;
if (C_CheckMalformedBranch(lastScriptOfs)) if (C_CheckMalformedBranch(lastScriptOfs))
return 0; return 0;
@ -1731,7 +1777,7 @@ static int32_t C_ParseCommand(void)
if (C_GetKeyword() == CON_LEFTBRACE) if (C_GetKeyword() == CON_LEFTBRACE)
{ {
C_GetNextKeyword(); C_GetNextKeyword();
g_numBraces++; cs.numBraces++;
do do
done = C_ParseCommand(); done = C_ParseCommand();
@ -1745,7 +1791,7 @@ static int32_t C_ParseCommand(void)
case CON_RETURN: case CON_RETURN:
case CON_BREAK: case CON_BREAK:
if (g_checkingSwitch) if (cs.checkingSwitch)
{ {
//Bsprintf(g_szBuf," * (L%d) case Break statement.\n",g_lineNumber); AddLog(g_szBuf); //Bsprintf(g_szBuf," * (L%d) case Break statement.\n",g_lineNumber); AddLog(g_szBuf);
return 1; return 1;
@ -1757,8 +1803,8 @@ static int32_t C_ParseCommand(void)
ofstype tempoffset; ofstype tempoffset;
//AddLog("Got Switch statement"); //AddLog("Got Switch statement");
// if (g_checkingSwitch) Bsprintf(g_szBuf,"ERROR::%s %d: g_checkingSwitch=",__FILE__,__LINE__, g_checkingSwitch); AddLog(g_szBuf); // if (cs.checkingSwitch) Bsprintf(g_szBuf,"ERROR::%s %d: cs.checkingSwitch=",__FILE__,__LINE__, cs.checkingSwitch); AddLog(g_szBuf);
g_checkingSwitch++; // allow nesting (if other things work) cs.checkingSwitch++; // allow nesting (if other things work)
C_GetNextVar(); // Get The ID of the DEF C_GetNextVar(); // Get The ID of the DEF
@ -1767,21 +1813,21 @@ static int32_t C_ParseCommand(void)
*g_scriptPtr++ = 0; // leave spot for end location (for after processing) *g_scriptPtr++ = 0; // leave spot for end location (for after processing)
*g_scriptPtr++ = 0; // count of case statements *g_scriptPtr++ = 0; // count of case statements
g_caseScriptPtr = g_scriptPtr; // the first case's pointer. cs.caseScriptPtr = g_scriptPtr; // the first case's pointer.
*g_scriptPtr++ = -1; // leave spot for 'default' offset to cases' code (-1 if none) *g_scriptPtr++ = -1; // leave spot for 'default' offset to cases' code (-1 if none)
temptextptr = textptr; temptextptr = textptr;
// probably does not allow nesting... // probably does not allow nesting...
//AddLog("Counting Case Statements..."); //AddLog("Counting Case Statements...");
j = C_CountCaseStatements(); j = C_CountCaseStatements();
// initprintf("Done Counting Case Statements for switch %d: found %d.\n", g_checkingSwitch,j); // initprintf("Done Counting Case Statements for switch %d: found %d.\n", cs.checkingSwitch,j);
g_scriptPtr += j*2; g_scriptPtr += j*2;
g_caseCodePtr = g_scriptPtr; cs.caseCodePtr = g_scriptPtr;
C_SkipComments(); C_SkipComments();
g_scriptPtr -= j*2; // allocate buffer for the table g_scriptPtr -= j*2; // allocate buffer for the table
tempscrptr = (instype *)(script+tempoffset); tempscrptr = (instype *)(script+tempoffset);
// if (g_checkingSwitch>1) Bsprintf(g_szBuf,"ERROR::%s %d: g_checkingSwitch=",__FILE__,__LINE__, g_checkingSwitch); AddLog(g_szBuf); // if (cs.checkingSwitch>1) Bsprintf(g_szBuf,"ERROR::%s %d: cs.checkingSwitch=",__FILE__,__LINE__, cs.checkingSwitch); AddLog(g_szBuf);
if (j<0) if (j<0)
return 1; return 1;
@ -1798,7 +1844,7 @@ static int32_t C_ParseCommand(void)
C_SkipComments(); C_SkipComments();
} }
//Bsprintf(g_szBuf,"SWITCH1: '%.22s'",textptr); AddLog(g_szBuf); //Bsprintf(g_szBuf,"SWITCH1: '%.22s'",textptr); AddLog(g_szBuf);
g_numCases = 0; cs.numCases = 0;
while (C_ParseCommand() == 0) while (C_ParseCommand() == 0)
{ {
//Bsprintf(g_szBuf,"SWITCH2: '%.22s'",textptr); AddLog(g_szBuf); //Bsprintf(g_szBuf,"SWITCH2: '%.22s'",textptr); AddLog(g_szBuf);
@ -1807,7 +1853,7 @@ static int32_t C_ParseCommand(void)
tempscrptr = (instype *)(script+tempoffset); tempscrptr = (instype *)(script+tempoffset);
//Bsprintf(g_szBuf,"SWITCHXX: '%.22s'",textptr); AddLog(g_szBuf); //Bsprintf(g_szBuf,"SWITCHXX: '%.22s'",textptr); AddLog(g_szBuf);
// done processing switch. clean up. // done processing switch. clean up.
// if (g_checkingSwitch < 1) Bsprintf(g_szBuf,"ERROR::%s %d: g_checkingSwitch=%d",__FILE__,__LINE__, g_checkingSwitch); AddLog(g_szBuf); // if (cs.checkingSwitch < 1) Bsprintf(g_szBuf,"ERROR::%s %d: cs.checkingSwitch=%d",__FILE__,__LINE__, cs.checkingSwitch); AddLog(g_szBuf);
if (tempscrptr) if (tempscrptr)
{ {
int32_t t,n; // !!! int32_t t,n; // !!!
@ -1829,16 +1875,16 @@ static int32_t C_ParseCommand(void)
} }
} }
// for (j=3;j<3+tempscrptr[1]*2;j+=2)initprintf("%5d %8x\n",tempscrptr[j],tempscrptr[j+1]); // for (j=3;j<3+tempscrptr[1]*2;j+=2)initprintf("%5d %8x\n",tempscrptr[j],tempscrptr[j+1]);
tempscrptr[0] = (ofstype)(g_scriptPtr-g_caseCodePtr); // save 'end' location as offset from code-place tempscrptr[0] = (ofstype)(g_scriptPtr-cs.caseCodePtr); // save 'end' location as offset from code-place
} }
// else Bsprintf(g_szBuf,"ERROR::%s %d",__FILE__,__LINE__); AddLog(g_szBuf); // else Bsprintf(g_szBuf,"ERROR::%s %d",__FILE__,__LINE__); AddLog(g_szBuf);
g_numCases = 0; cs.numCases = 0;
g_caseScriptPtr = NULL; cs.caseScriptPtr = NULL;
g_caseCodePtr = NULL; cs.caseCodePtr = NULL;
// decremented in endswitch. Don't decrement here... // decremented in endswitch. Don't decrement here...
// g_checkingSwitch--; // allow nesting (maybe if other things work) // cs.checkingSwitch--; // allow nesting (maybe if other things work)
tempscrptr = NULL; tempscrptr = NULL;
// if (g_checkingSwitch) Bsprintf(g_szBuf,"ERROR::%s %d: g_checkingSwitch=%d",__FILE__,__LINE__, g_checkingSwitch); AddLog(g_szBuf); // if (cs.checkingSwitch) Bsprintf(g_szBuf,"ERROR::%s %d: cs.checkingSwitch=%d",__FILE__,__LINE__, cs.checkingSwitch); AddLog(g_szBuf);
//AddLog("End of Switch statement"); //AddLog("End of Switch statement");
} }
break; break;
@ -1849,7 +1895,7 @@ static int32_t C_ParseCommand(void)
//AddLog("Found Case"); //AddLog("Found Case");
repeatcase: repeatcase:
g_scriptPtr--; // don't save in code g_scriptPtr--; // don't save in code
if (g_checkingSwitch < 1) if (cs.checkingSwitch < 1)
{ {
g_numCompilerErrors++; g_numCompilerErrors++;
C_ReportError(-1); C_ReportError(-1);
@ -1857,26 +1903,26 @@ repeatcase:
return 1; return 1;
} }
g_numCases++; cs.numCases++;
//Bsprintf(g_szBuf,"case1: %.12s",textptr); AddLog(g_szBuf); //Bsprintf(g_szBuf,"case1: %.12s",textptr); AddLog(g_szBuf);
C_GetNextValue(LABEL_DEFINE); C_GetNextValue(LABEL_DEFINE);
if (*textptr == ':') if (*textptr == ':')
textptr++; textptr++;
//Bsprintf(g_szBuf,"case2: %.12s",textptr); AddLog(g_szBuf); //Bsprintf(g_szBuf,"case2: %.12s",textptr); AddLog(g_szBuf);
j = *(--g_scriptPtr); // get value j = *(--g_scriptPtr); // get value
//Bsprintf(g_szBuf,"case: Value of case %d is %d",(int32_t)g_numCases,(int32_t)j); AddLog(g_szBuf); //Bsprintf(g_szBuf,"case: Value of case %d is %d",(int32_t)cs.numCases,(int32_t)j); AddLog(g_szBuf);
if (g_caseScriptPtr) if (cs.caseScriptPtr)
{ {
for (i=(g_numCases/2)-1; i>=0; i--) for (i=(cs.numCases/2)-1; i>=0; i--)
if (g_caseScriptPtr[i*2+1] == j) if (cs.caseScriptPtr[i*2+1] == j)
{ {
g_numCompilerWarnings++; g_numCompilerWarnings++;
C_ReportError(WARNING_DUPLICATECASE); C_ReportError(WARNING_DUPLICATECASE);
break; break;
} }
//AddLog("Adding value to script"); //AddLog("Adding value to script");
g_caseScriptPtr[g_numCases++] = j; // save value cs.caseScriptPtr[cs.numCases++] = j; // save value
g_caseScriptPtr[g_numCases] = (ofstype)(g_scriptPtr - g_caseCodePtr); // offset from beginning of cases' code cs.caseScriptPtr[cs.numCases] = (ofstype)(g_scriptPtr - cs.caseCodePtr); // offset from beginning of cases' code
} }
//Bsprintf(g_szBuf,"case3: %.12s",textptr); AddLog(g_szBuf); //Bsprintf(g_szBuf,"case3: %.12s",textptr); AddLog(g_szBuf);
j = C_GetKeyword(); j = C_GetKeyword();
@ -1908,22 +1954,22 @@ repeatcase:
case CON_DEFAULT: case CON_DEFAULT:
g_scriptPtr--; // don't save g_scriptPtr--; // don't save
if (g_checkingSwitch < 1) if (cs.checkingSwitch < 1)
{ {
g_numCompilerErrors++; g_numCompilerErrors++;
C_ReportError(-1); C_ReportError(-1);
initprintf("%s:%d: error: found `default' statement when not in switch\n",g_szScriptFileName,g_lineNumber); initprintf("%s:%d: error: found `default' statement when not in switch\n",g_szScriptFileName,g_lineNumber);
return 1; return 1;
} }
if (g_caseScriptPtr && g_caseScriptPtr[0]!=0) if (cs.caseScriptPtr && cs.caseScriptPtr[0]!=0)
{ {
// duplicate default statement // duplicate default statement
g_numCompilerErrors++; g_numCompilerErrors++;
C_ReportError(-1); C_ReportError(-1);
initprintf("%s:%d: error: multiple `default' statements found in switch\n",g_szScriptFileName,g_lineNumber); initprintf("%s:%d: error: multiple `default' statements found in switch\n",g_szScriptFileName,g_lineNumber);
} }
if (g_caseScriptPtr) if (cs.caseScriptPtr)
g_caseScriptPtr[0] = (ofstype)(g_scriptPtr-g_caseCodePtr); // save offset from cases' code cs.caseScriptPtr[0] = (ofstype)(g_scriptPtr-cs.caseCodePtr); // save offset from cases' code
//Bsprintf(g_szBuf,"default: '%.22s'",textptr); AddLog(g_szBuf); //Bsprintf(g_szBuf,"default: '%.22s'",textptr); AddLog(g_szBuf);
while (C_ParseCommand() == 0) while (C_ParseCommand() == 0)
{ {
@ -1934,8 +1980,8 @@ repeatcase:
case CON_ENDSWITCH: case CON_ENDSWITCH:
//AddLog("End Switch"); //AddLog("End Switch");
g_checkingSwitch--; cs.checkingSwitch--;
if (g_checkingSwitch < 0) if (cs.checkingSwitch < 0)
{ {
g_numCompilerErrors++; g_numCompilerErrors++;
C_ReportError(-1); C_ReportError(-1);
@ -1952,13 +1998,13 @@ repeatcase:
return 0; return 0;
case CON_LEFTBRACE: case CON_LEFTBRACE:
// if (!(g_currentStateIdx >= 0 || g_parsingEventOfs >= 0)) // if (!(cs.currentStateIdx >= 0 || cs.parsingEventOfs >= 0))
// { // {
// g_numCompilerErrors++; // g_numCompilerErrors++;
// C_ReportError(ERROR_SYNTAXERROR); // C_ReportError(ERROR_SYNTAXERROR);
// } // }
g_numBraces++; cs.numBraces++;
do do
done = C_ParseCommand(); done = C_ParseCommand();
@ -1966,7 +2012,7 @@ repeatcase:
return 0; return 0;
case CON_RIGHTBRACE: case CON_RIGHTBRACE:
g_numBraces--; cs.numBraces--;
// rewrite "{ }" into "nullop" // rewrite "{ }" into "nullop"
if (*(g_scriptPtr-2) == CON_LEFTBRACE + (IFELSE_MAGIC<<12)) if (*(g_scriptPtr-2) == CON_LEFTBRACE + (IFELSE_MAGIC<<12))
@ -1976,28 +2022,28 @@ repeatcase:
g_scriptPtr -= 2; g_scriptPtr -= 2;
if (C_GetKeyword() != CON_ELSE && (*(g_scriptPtr-2)&0xFFF) != CON_ELSE) if (C_GetKeyword() != CON_ELSE && (*(g_scriptPtr-2)&0xFFF) != CON_ELSE)
g_ifElseAborted = 1; cs.ifElseAborted = 1;
else g_ifElseAborted = 0; else cs.ifElseAborted = 0;
j = C_GetKeyword(); j = C_GetKeyword();
if (g_checkingIfElse && j != CON_ELSE) if (cs.checkingIfElse && j != CON_ELSE)
g_checkingIfElse--; cs.checkingIfElse--;
return 1; return 1;
} }
if (g_numBraces < 0) if (cs.numBraces < 0)
{ {
if (g_checkingSwitch) if (cs.checkingSwitch)
C_ReportError(ERROR_NOENDSWITCH); C_ReportError(ERROR_NOENDSWITCH);
C_ReportError(-1); C_ReportError(-1);
initprintf("%s:%d: error: found more `}' than `{'.\n",g_szScriptFileName,g_lineNumber); initprintf("%s:%d: error: found more `}' than `{'.\n",g_szScriptFileName,g_lineNumber);
g_numCompilerErrors++; g_numCompilerErrors++;
} }
if (g_checkingIfElse && j != CON_ELSE) if (cs.checkingIfElse && j != CON_ELSE)
g_checkingIfElse--; cs.checkingIfElse--;
return 1; return 1;
@ -2016,7 +2062,7 @@ repeatcase:
// syntax getsector[<var>].x <VAR> // syntax getsector[<var>].x <VAR>
// gets the value of sector[<var>].xxx into <VAR> // gets the value of sector[<var>].xxx into <VAR>
if ((tw==CON_GETTSPR || tw==CON_SETTSPR) && g_currentEvent != EVENT_ANALYZESPRITES) if ((tw==CON_GETTSPR || tw==CON_SETTSPR) && cs.currentEvent != EVENT_ANALYZESPRITES)
{ {
C_ReportError(-1); C_ReportError(-1);
initprintf("%s:%d: warning: found `%s' outside of EVENT_ANALYZESPRITES\n",g_szScriptFileName,g_lineNumber,tempbuf); initprintf("%s:%d: warning: found `%s' outside of EVENT_ANALYZESPRITES\n",g_szScriptFileName,g_lineNumber,tempbuf);
@ -2032,9 +2078,9 @@ repeatcase:
textptr++; textptr++;
// get the ID of the DEF // get the ID of the DEF
g_labelsOnly = 1; cs.labelsOnly = 1;
C_GetNextVar(); C_GetNextVar();
g_labelsOnly = 0; cs.labelsOnly = 0;
// now get name of .xxx // now get name of .xxx
while (*textptr != '.') while (*textptr != '.')
{ {
@ -2321,20 +2367,16 @@ repeatcase:
{ {
instype *inst = (g_scriptPtr-1); instype *inst = (g_scriptPtr-1);
const char *otextptr; const char *otextptr;
int32_t ow, oe;
C_GetNextVarType(GAMEVAR_READONLY); C_GetNextVarType(GAMEVAR_READONLY);
ow = g_numCompilerWarnings;
oe = g_numCompilerErrors;
otextptr = textptr; otextptr = textptr;
g_noConstBitwidthWarning = 1; g_tooBigConstant = 0;
C_GetNextVar(); C_GetNextVar();
g_noConstBitwidthWarning = 0;
if (!g_numCompilerErrors && g_numCompilerWarnings > ow) if (!g_numCompilerErrors && g_tooBigConstant)
{ {
g_numCompilerWarnings--;
textptr = otextptr; textptr = otextptr;
g_scriptPtr--; g_scriptPtr--;
*inst -= (CON_SETVARVAR - CON_SETVAR); *inst -= (CON_SETVARVAR - CON_SETVAR);
@ -2475,7 +2517,7 @@ repeatcase:
ofstype offset; ofstype offset;
ofstype lastScriptOfs = (g_scriptPtr-script-1); ofstype lastScriptOfs = (g_scriptPtr-script-1);
instype *tscrptr; instype *tscrptr;
g_ifElseAborted = 0; cs.ifElseAborted = 0;
if (tw<=CON_WHILEVARL) // careful! check this against order in m32def.h! if (tw<=CON_WHILEVARL) // careful! check this against order in m32def.h!
{ {
@ -2486,20 +2528,16 @@ repeatcase:
{ {
instype *inst = (g_scriptPtr-1); instype *inst = (g_scriptPtr-1);
const char *otextptr; const char *otextptr;
int32_t ow, oe;
C_GetNextVar(); C_GetNextVar();
ow = g_numCompilerWarnings;
oe = g_numCompilerErrors;
otextptr = textptr; otextptr = textptr;
g_noConstBitwidthWarning = 1; g_tooBigConstant = 0;
C_GetNextVar(); C_GetNextVar();
g_noConstBitwidthWarning = 0;
if (!g_numCompilerErrors && g_numCompilerWarnings > ow) if (!g_numCompilerErrors && g_tooBigConstant)
{ {
g_numCompilerWarnings--;
textptr = otextptr; textptr = otextptr;
g_scriptPtr--; g_scriptPtr--;
*inst -= (CON_IFVARVARL - CON_IFVARL); *inst -= (CON_IFVARVARL - CON_IFVARL);
@ -2532,7 +2570,7 @@ repeatcase:
j = C_GetKeyword(); j = C_GetKeyword();
if (j == CON_ELSE || j == CON_LEFTBRACE) if (j == CON_ELSE || j == CON_LEFTBRACE)
g_checkingIfElse++; cs.checkingIfElse++;
} }
return 0; return 0;
@ -2854,7 +2892,7 @@ repeatcase:
case CON_ROTATESPRITE16: case CON_ROTATESPRITE16:
case CON_ROTATESPRITE: case CON_ROTATESPRITE:
if (g_parsingEventOfs < 0 && g_currentStateIdx < 0) if (cs.parsingEventOfs < 0 && cs.currentStateIdx < 0)
{ {
C_ReportError(ERROR_EVENTONLY); C_ReportError(ERROR_EVENTONLY);
g_numCompilerErrors++; g_numCompilerErrors++;
@ -2910,8 +2948,10 @@ void C_CompilationInfo(void)
int32_t j, k=0; int32_t j, k=0;
initprintf("Compiled code info: (size=%ld*%d bytes)\n", initprintf("Compiled code info: (size=%ld*%d bytes)\n",
(unsigned)(g_scriptPtr-script), sizeof(instype)); (unsigned)(g_scriptPtr-script), sizeof(instype));
initprintf(" %d user labels, %d/%d user variables, %d/%d user arrays\n", initprintf(" %d/%d user labels, %d/65536 indirect constants,\n",
g_numLabels-g_numDefaultLabels, g_numLabels-g_numDefaultLabels, 65536-g_numDefaultLabels,
g_numSavedConstants);
initprintf(" %d/%d user variables, %d/%d user arrays\n",
g_gameVarCount-g_systemVarCount, MAXGAMEVARS-g_systemVarCount, g_gameVarCount-g_systemVarCount, MAXGAMEVARS-g_systemVarCount,
g_gameArrayCount-g_systemArrayCount, MAXGAMEARRAYS-g_systemArrayCount); g_gameArrayCount-g_systemArrayCount, MAXGAMEARRAYS-g_systemArrayCount);
for (j=0; j<MAXEVENTS; j++) for (j=0; j<MAXEVENTS; j++)
@ -2919,11 +2959,11 @@ void C_CompilationInfo(void)
k++; k++;
initprintf(" %d states, %d/%d defined events\n", g_stateCount, k,MAXEVENTS); initprintf(" %d states, %d/%d defined events\n", g_stateCount, k,MAXEVENTS);
for (j=MAXQUOTES-1, k=0; j>=0; j--) for (k=0, j=MAXQUOTES-1; j>=0; j--)
if (ScriptQuotes[j]) if (ScriptQuotes[j])
k++; k++;
if (k | g_numQuoteRedefinitions) if (k || g_numQuoteRedefinitions)
initprintf(" %d/%d quotes, %d quote redefinitions\n",k,MAXQUOTES,g_numQuoteRedefinitions); initprintf(" %d/%d quotes, %d/%d quote redefinitions\n", k,MAXQUOTES, g_numQuoteRedefinitions,MAXQUOTES);
} }
void C_Compile(const char *filenameortext, int32_t isfilename) void C_Compile(const char *filenameortext, int32_t isfilename)
@ -2942,6 +2982,8 @@ void C_Compile(const char *filenameortext, int32_t isfilename)
labelval = Bmalloc(label_allocsize * sizeof(int32_t)); labelval = Bmalloc(label_allocsize * sizeof(int32_t));
labeltype = Bmalloc(label_allocsize * sizeof(uint8_t)); labeltype = Bmalloc(label_allocsize * sizeof(uint8_t));
constants = Bmalloc(constants_allocsize * sizeof(int32_t));
statesinfo = Bmalloc(statesinfo_allocsize * sizeof(statesinfo_t)); statesinfo = Bmalloc(statesinfo_allocsize * sizeof(statesinfo_t));
for (i=0; i<MAXEVENTS; i++) for (i=0; i<MAXEVENTS; i++)
@ -2956,7 +2998,7 @@ void C_Compile(const char *filenameortext, int32_t isfilename)
script = Bcalloc(g_scriptSize, sizeof(instype)); script = Bcalloc(g_scriptSize, sizeof(instype));
// initprintf("script: %d\n",script); // initprintf("script: %d\n",script);
if (!script || !label) if (!script || !label || !labelval || !labeltype || !constants)
{ {
initprintf("C_Compile(): ERROR: out of memory!\n"); initprintf("C_Compile(): ERROR: out of memory!\n");
g_numCompilerErrors++; g_numCompilerErrors++;
@ -3031,12 +3073,17 @@ void C_Compile(const char *filenameortext, int32_t isfilename)
else else
textptr = filenameortext; textptr = filenameortext;
g_numCompilerWarnings = 0; //////
g_numCompilerErrors = 0; g_numCompilerWarnings = g_numCompilerErrors = 0;
g_lineNumber = 1; g_lineNumber = 1;
g_totalLines = 0; g_totalLines = 0;
//////
oscriptPtr = g_scriptPtr; oscriptPtr = g_scriptPtr;
g_didDefineSomething = 0;
Bmemcpy(&cs, &cs_default, sizeof(compilerstate_t));
while (C_ParseCommand() == 0); while (C_ParseCommand() == 0);
@ -3071,7 +3118,10 @@ void C_Compile(const char *filenameortext, int32_t isfilename)
} }
if (g_numCompilerErrors) if (g_numCompilerErrors)
{
if (!g_didDefineSomething)
g_scriptPtr = oscriptPtr; g_scriptPtr = oscriptPtr;
}
else else
{ {
g_totalLines += g_lineNumber; g_totalLines += g_lineNumber;
@ -3102,9 +3152,9 @@ void C_ReportError(int32_t iError)
{ {
if (Bstrcmp(g_szCurrentBlockName, g_szLastBlockName)) if (Bstrcmp(g_szCurrentBlockName, g_szLastBlockName))
{ {
if (g_parsingEventOfs >= 0 || g_currentStateIdx >= 0) if (cs.parsingEventOfs >= 0 || cs.currentStateIdx >= 0)
initprintf("%s: In %s `%s':\n",g_szScriptFileName, initprintf("%s: In %s `%s':\n",g_szScriptFileName,
g_parsingEventOfs >= 0 ? "event":"state", g_szCurrentBlockName); cs.parsingEventOfs >= 0 ? "event":"state", g_szCurrentBlockName);
else initprintf("%s: At top level:\n", g_szScriptFileName); else initprintf("%s: At top level:\n", g_szScriptFileName);
Bstrcpy(g_szLastBlockName, g_szCurrentBlockName); Bstrcpy(g_szLastBlockName, g_szCurrentBlockName);
} }
@ -3128,7 +3178,7 @@ void C_ReportError(int32_t iError)
break; break;
case ERROR_FOUNDWITHIN: case ERROR_FOUNDWITHIN:
initprintf("%s:%d: error: found `%s' within %s.\n", initprintf("%s:%d: error: found `%s' within %s.\n",
g_szScriptFileName, g_lineNumber, tempbuf, (g_parsingEventOfs >= 0)?"an event":"a state"); g_szScriptFileName, g_lineNumber, tempbuf, (cs.parsingEventOfs >= 0)?"an event":"a state");
break; break;
case ERROR_ISAKEYWORD: case ERROR_ISAKEYWORD:
initprintf("%s:%d: error: symbol `%s' is a keyword.\n", initprintf("%s:%d: error: symbol `%s' is a keyword.\n",

View file

@ -43,6 +43,8 @@ extern char g_szScriptFileName[BMAX_PATH];
extern int32_t g_totalLines,g_lineNumber; extern int32_t g_totalLines,g_lineNumber;
extern int32_t g_numCompilerErrors,g_numCompilerWarnings; extern int32_t g_numCompilerErrors,g_numCompilerWarnings;
extern int32_t g_didDefineSomething;
extern instype *g_scriptPtr; extern instype *g_scriptPtr;
void C_Compile(const char *filenameortext, int32_t isfilename); void C_Compile(const char *filenameortext, int32_t isfilename);

View file

@ -1791,8 +1791,16 @@ badindex:
aGameVars[(code>>16)&(MAXGAMEVARS-1)].szLabel:"???"); aGameVars[(code>>16)&(MAXGAMEVARS-1)].szLabel:"???");
} }
if ((code&0x0000FFFF) == MAXGAMEVARS) // addlogvar for a constant.. why not? :P if ((code&0x0000FFFC) == MAXGAMEVARS) // addlogvar for a constant.. why not? :P
Bsprintf(buf, "(constant)"); {
switch (code&3)
{
case 0: Bsprintf(buf, "(immediate constant)"); break;
case 1: Bsprintf(buf, "(indirect constant)"); break;
case 2: Bsprintf(buf, "(label constant)"); break;
default: Bsprintf(buf, "(??? constant)"); break;
}
}
else if (code&(MAXGAMEVARS<<2)) else if (code&(MAXGAMEVARS<<2))
Bsprintf(buf, "(array) %s[%s]", aGameArrays[code&(MAXGAMEARRAYS-1)].szLabel? Bsprintf(buf, "(array) %s[%s]", aGameArrays[code&(MAXGAMEARRAYS-1)].szLabel?
aGameArrays[code&(MAXGAMEARRAYS-1)].szLabel:"???", buf2); aGameArrays[code&(MAXGAMEARRAYS-1)].szLabel:"???", buf2);

View file

@ -249,8 +249,22 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
if (id == g_iThisActorID) if (id == g_iThisActorID)
return vm.g_i; return vm.g_i;
if ((id & 0x0000FFFF) == MAXGAMEVARS) if ((id & 0x0000FFFC) == MAXGAMEVARS)
{
switch (id&3)
{
case 0:
return ((int16_t)(id>>16)); return ((int16_t)(id>>16));
case 1:
return constants[(id>>16)&0xffff];
case 2:
return labelval[(id>>16)&0xffff];
default:
OSD_Printf(CON_ERROR "Gv_GetVarX() (constant): WTF??\n",g_errorLineNum,keyw[g_tw]);
vm.g_errorFlag = 1;
return -1;
}
}
{ {
register int32_t negateResult = id&(MAXGAMEVARS<<1); register int32_t negateResult = id&(MAXGAMEVARS<<1);