From 3be58d63d0722c55e8ece93a54bbcb3866664213 Mon Sep 17 00:00:00 2001 From: helixhorned Date: Mon, 14 Sep 2009 22:11:37 +0000 Subject: [PATCH] indirect constants for m32-script alongside with other changes git-svn-id: https://svn.eduke32.com/eduke32@1496 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/build/include/m32script.h | 3 + polymer/eduke32/source/astub.c | 26 +- polymer/eduke32/source/m32def.c | 396 ++++++++++++---------- polymer/eduke32/source/m32def.h | 2 + polymer/eduke32/source/m32exec.c | 12 +- polymer/eduke32/source/m32vars.c | 18 +- 6 files changed, 276 insertions(+), 181 deletions(-) diff --git a/polymer/eduke32/build/include/m32script.h b/polymer/eduke32/build/include/m32script.h index 27e3eb24f..15fbac750 100644 --- a/polymer/eduke32/build/include/m32script.h +++ b/polymer/eduke32/build/include/m32script.h @@ -65,6 +65,9 @@ extern void SetWATERPalette(void); extern void SetSLIMEPalette(void); extern void SetBOSS1Palette(void); +extern int32_t *constants, constants_allocsize; +extern int32_t g_numSavedConstants; + extern instype *script ,*insptr; extern int32_t *labelval; extern uint8_t *labeltype; diff --git a/polymer/eduke32/source/astub.c b/polymer/eduke32/source/astub.c index bf0352af8..9f5e01066 100644 --- a/polymer/eduke32/source/astub.c +++ b/polymer/eduke32/source/astub.c @@ -4583,7 +4583,7 @@ static void Keys3d(void) if (keystatus[KEYSC_QUOTE] && keystatus[KEYSC_DELETE]) // ' del { - keystatus[KEYSC_BS] = 0; + keystatus[KEYSC_DELETE] = 0; switch (searchstat) { case 0: @@ -8866,7 +8866,8 @@ static int32_t osdcmd_do(const osdfuncparm_t *parm) { intptr_t tscrofs; char *tp; - int32_t slen; + int32_t i, j, slen; + int32_t onumconstants=g_numSavedConstants; if (parm->numparms < 1) return OSDCMD_SHOWHELP; @@ -8885,17 +8886,34 @@ static int32_t osdcmd_do(const osdfuncparm_t *parm) tp[slen] = '\n'; tp[slen+1] = '\0'; + g_didDefineSomething = 0; + C_Compile(tp, 0); 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=0) + j++; + + if (g_didDefineSomething == 0) + { + g_numSavedConstants = onumconstants; + *g_scriptPtr = CON_RETURN + (g_lineNumber<<12); + g_scriptPtr = script + tscrofs; + insptr = script + tscrofs; Bmemcpy(&vm, &vm_default, sizeof(vmstate_t)); X_DoExecute(0); // asksave = 1; // handled in Access(Sprite|Sector|Wall) } - g_scriptPtr = script + tscrofs; + return OSDCMD_OK; } diff --git a/polymer/eduke32/source/m32def.c b/polymer/eduke32/source/m32def.c index 482f20d2e..1a00bceab 100644 --- a/polymer/eduke32/source/m32def.c +++ b/polymer/eduke32/source/m32def.c @@ -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 static char g_szCurrentBlockName[256] = "(none)", g_szLastBlockName[256] = "NULL"; +////// compiler state vvv +static const char *textptr; 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 -// first entry is 'default' code. -static instype *g_caseCodePtr = NULL; // 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 -static int32_t g_numCases = 0; -static int32_t g_checkingSwitch = 0, g_currentEvent = -1; -static int32_t g_labelsOnly = 0; -static int32_t g_numBraces = 0; +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. + instype *caseCodePtr; // the pointer to the start of the different cases' code + int32_t labelsOnly; + int32_t numBraces; + int32_t checkingIfElse, ifElseAborted; +} compilerstate_t; + +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 *g_scriptPtr; int32_t g_scriptSize = 65536; +int32_t *constants, constants_allocsize=1024; +int32_t g_numSavedConstants=0; +static int32_t g_tooBigConstant=0; + char *label; int32_t *labelval; uint8_t *labeltype; @@ -76,20 +96,15 @@ int32_t g_numQuoteRedefinitions = 0; ofstype aEventOffsets[MAXEVENTS]; static int32_t aEventSizes[MAXEVENTS]; -static ofstype g_parsingEventOfs = -1; gamevar_t aGameVars[MAXGAMEVARS]; gamearray_t aGameArrays[MAXGAMEARRAYS]; int32_t g_gameVarCount=0, g_systemVarCount=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 #define IFELSE_MAGIC 31337 -static int32_t g_ifElseAborted; void C_ReportError(int32_t iError); @@ -509,8 +524,8 @@ static void C_InitHashes() static int32_t C_SetScriptSize(int32_t size) { ofstype oscriptOfs = (unsigned)(g_scriptPtr-script); - ofstype ocaseScriptOfs = (unsigned)(g_caseScriptPtr-script); - ofstype ocaseCodeOfs = (unsigned)(g_caseCodePtr-script); + ofstype ocaseScriptOfs = (unsigned)(cs.caseScriptPtr-script); + ofstype ocaseCodeOfs = (unsigned)(cs.caseCodePtr-script); instype *newscript; int32_t osize = g_scriptSize; @@ -545,10 +560,10 @@ static int32_t C_SetScriptSize(int32_t size) g_scriptPtr = (instype *)(script+oscriptOfs); // initprintf("script: %d, \n",script); initprintf("offset: %d\n",(unsigned)(g_scriptPtr-script)); - if (g_caseScriptPtr != NULL) - g_caseScriptPtr = (instype *)(script+ocaseScriptOfs); - if (g_caseCodePtr != NULL) - g_caseCodePtr = (instype *)(script+ocaseCodeOfs); + if (cs.caseScriptPtr != NULL) + cs.caseScriptPtr = (instype *)(script+ocaseScriptOfs); + if (cs.caseCodePtr != NULL) + cs.caseCodePtr = (instype *)(script+ocaseCodeOfs); return 0; } @@ -595,8 +610,8 @@ static int32_t C_SkipComments(void) // initprintf("%s:%d: debug: EOF in comment!\n",g_szScriptFileName,g_lineNumber); C_ReportError(-1); initprintf("%s:%d: error: found `/*' with no `*/'.\n",g_szScriptFileName,g_lineNumber); - g_numBraces = 0; - g_currentStateIdx = -1; + cs.numBraces = 0; + cs.currentStateIdx = -1; g_numCompilerErrors++; break; } @@ -777,12 +792,12 @@ static int32_t C_GetNextKeyword(void) //Returns its code # 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(); // 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))))) { // if (!(g_numCompilerErrors || g_numCompilerWarnings) && g_scriptDebug) @@ -793,21 +808,44 @@ static void C_GetNextVarType(int32_t type) else num = atoi(textptr); - if (type==GAMEVAR_SPECIAL && (int16_t)num < 0) + if (type==GAMEVAR_SPECIAL && (num<0 || num>=65536)) { 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++; } - if (num != (int16_t)num) + if (g_numCompilerErrors==0 && type!=GAMEVAR_SPECIAL && num != (int16_t)num) { - if (!g_noConstBitwidthWarning) - C_ReportError(WARNING_CONSTANTBITSIZE); - g_numCompilerWarnings++; + g_tooBigConstant = 1; + indirect = 1; + + 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; + } + } + + constants[i] = num; + num = i; + g_numSavedConstants++; + } } - *g_scriptPtr++ = MAXGAMEVARS | (num<<16); + *g_scriptPtr++ = MAXGAMEVARS | (num<<16) | indirect; while (!ispecial(*textptr) && *textptr != ']') textptr++; @@ -941,7 +979,7 @@ static void C_GetNextVarType(int32_t type) id = GetGamevarID(tlabel); if (id < 0) //gamevar not found { - if (!type && !g_labelsOnly) + if (!type && !cs.labelsOnly) { //try looking for a define instead id = hash_find(&labelH, tlabel); @@ -949,20 +987,24 @@ static void C_GetNextVarType(int32_t type) { // 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)); + num = labelval[id]; - *g_scriptPtr++ = MAXGAMEVARS | (labelval[id]<<16); - if (labelval[id] != (int16_t)labelval[id]) + if (type==GAMEVAR_SPECIAL && (num<0 || num>=65536)) { - if (!g_noConstBitwidthWarning) - C_ReportError(WARNING_CONSTANTBITSIZE); - g_numCompilerWarnings++; + C_ReportError(-1); + initprintf("%s:%d: error: label %s=%d not suitable as array index. (max: 65535)\n",g_szScriptFileName,g_lineNumber, label+(id*MAXLABELLEN), num); + g_numCompilerErrors++; + } + else if (num != (int16_t)num) + { + g_tooBigConstant = 1; + indirect = 2; + num = id; } + *g_scriptPtr++ = MAXGAMEVARS | (num<<16) | indirect; return; } - g_numCompilerErrors++; - C_ReportError(ERROR_NOTAGAMEVAR); - return; } g_numCompilerErrors++; C_ReportError(ERROR_NOTAGAMEVAR); @@ -1054,7 +1096,7 @@ static int32_t C_GetNextValue(int32_t type) gl = (char *)C_GetLabelType(labeltype[i]); C_ReportError(-1); 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++; Bfree(el); Bfree(gl); @@ -1071,7 +1113,7 @@ static int32_t C_GetNextValue(int32_t type) return -1; // error! } - if (isdigit(*textptr) && g_labelsOnly) + if (isdigit(*textptr) && cs.labelsOnly) { C_ReportError(WARNING_LABELSONLY); g_numCompilerWarnings++; @@ -1135,7 +1177,7 @@ static int32_t C_CheckMalformedBranch(ofstype lastScriptOfs) case CON_ENDS: case CON_ELSE: g_scriptPtr = script + lastScriptOfs; - g_ifElseAborted = 1; + cs.ifElseAborted = 1; C_ReportError(-1); g_numCompilerWarnings++; 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 if ((Bstrncmp(keyw[tw], "if", 2) && tw != CON_ELSE) || tw == CON_IFRND) { - g_ifElseAborted = 0; + cs.ifElseAborted = 0; return 0; } 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); g_numCompilerWarnings++; @@ -1178,27 +1220,27 @@ static int32_t C_CountCaseStatements() const char *temptextptr = textptr; int32_t temp_ScriptLineNumber = g_lineNumber; ofstype scriptoffset = (unsigned)(g_scriptPtr-script); - ofstype caseoffset = (unsigned)(g_caseScriptPtr-script); + ofstype caseoffset = (unsigned)(cs.caseScriptPtr-script); - g_numCases=0; - g_caseScriptPtr=NULL; + cs.numCases=0; + cs.caseScriptPtr=NULL; //Bsprintf(g_szBuf,"CSS: %.12s",textptr); AddLog(g_szBuf); while (C_ParseCommand() == 0) { //Bsprintf(g_szBuf,"CSSL: %.20s",textptr); AddLog(g_szBuf); ; } - // since we processed the endswitch, we need to re-increment g_checkingSwitch - g_checkingSwitch++; + // since we processed the endswitch, we need to re-increment cs.checkingSwitch + cs.checkingSwitch++; textptr = temptextptr; g_scriptPtr = (instype *)(script+scriptoffset); g_lineNumber = temp_ScriptLineNumber; - lCount = g_numCases; - g_numCases = 0; - g_caseScriptPtr = (instype *)(script+caseoffset); + lCount = cs.numCases; + cs.numCases = 0; + cs.caseScriptPtr = (instype *)(script+caseoffset); return lCount; } @@ -1220,7 +1262,7 @@ static int32_t C_ParseCommand(void) // if (g_scriptDebug) // C_ReportError(-1); -/// if (g_checkingSwitch > 0) +/// if (cs.checkingSwitch > 0) /// Bsprintf(g_szBuf,"PC(): '%.25s'",textptr); AddLog(g_szBuf); tw = C_GetNextKeyword(); @@ -1243,7 +1285,7 @@ static int32_t C_ParseCommand(void) g_numCompilerWarnings++; initprintf("%s:%d: warning: `nullop' found without `else'\n",g_szScriptFileName,g_lineNumber); g_scriptPtr--; - g_ifElseAborted = 1; + cs.ifElseAborted = 1; } return 0; @@ -1353,8 +1395,8 @@ static int32_t C_ParseCommand(void) Bstrcpy(g_szScriptFileName, tempbuf); temp_ScriptLineNumber = g_lineNumber; g_lineNumber = 1; - temp_ifelse_check = g_checkingIfElse; - g_checkingIfElse = 0; + temp_ifelse_check = cs.checkingIfElse; + cs.checkingIfElse = 0; textptr = mptr; do done = C_ParseCommand(); @@ -1363,7 +1405,7 @@ static int32_t C_ParseCommand(void) Bstrcpy(g_szScriptFileName, parentScriptFileName); g_totalLines += g_lineNumber; g_lineNumber = temp_ScriptLineNumber; - g_checkingIfElse = temp_ifelse_check; + cs.checkingIfElse = temp_ifelse_check; textptr = origtptr; @@ -1373,7 +1415,7 @@ static int32_t C_ParseCommand(void) case CON_DEFSTATE: g_scriptPtr--; - if (g_parsingEventOfs < 0 && g_currentStateIdx < 0) + if (cs.parsingEventOfs < 0 && cs.currentStateIdx < 0) { C_GetNextLabelName(); @@ -1401,20 +1443,20 @@ static int32_t C_ParseCommand(void) j = hash_find(&stateH, tlabel); if (j>=0) // only redefining { - g_currentStateIdx = j; - g_currentStateOfs = (g_scriptPtr-script); + cs.currentStateIdx = j; + cs.currentStateOfs = (g_scriptPtr-script); Bsprintf(g_szCurrentBlockName, "%s", statesinfo[j].name); } else // new state definition { - g_currentStateIdx = j = g_stateCount; - g_currentStateOfs = (g_scriptPtr-script); + cs.currentStateIdx = j = g_stateCount; + cs.currentStateOfs = (g_scriptPtr-script); if (g_stateCount >= statesinfo_allocsize) { statesinfo_allocsize *= 2; - statesinfo = Brealloc(statesinfo, statesinfo_allocsize); + statesinfo = Brealloc(statesinfo, statesinfo_allocsize * sizeof(statesinfo[0])); if (!statesinfo) { initprintf("C_ParseCommand(): ERROR: out of memory!\n"); @@ -1436,7 +1478,7 @@ static int32_t C_ParseCommand(void) return 1; case CON_ENDS: - if (g_currentStateIdx < 0) + if (cs.currentStateIdx < 0) { C_ReportError(-1); 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 { - if (g_numBraces > 0) + if (cs.numBraces > 0) { C_ReportError(ERROR_OPENBRACKET); g_numCompilerErrors++; } - if (g_numBraces < 0) + if (cs.numBraces < 0) { C_ReportError(ERROR_CLOSEBRACKET); g_numCompilerErrors++; } - if (g_checkingSwitch > 0) + if (cs.checkingSwitch > 0) { C_ReportError(ERROR_NOENDSWITCH); g_numCompilerErrors++; - g_checkingSwitch = 0; // can't be checking anymore... + cs.checkingSwitch = 0; // can't be checking anymore... } if (g_numCompilerErrors) { - g_currentStateOfs = -1; - g_currentStateIdx = -1; + cs.currentStateOfs = -1; + cs.currentStateIdx = -1; Bsprintf(g_szCurrentBlockName,"(none)"); 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].codesize = (g_scriptPtr-script) - g_currentStateOfs; + statesinfo[j].ofs = cs.currentStateOfs; + statesinfo[j].codesize = (g_scriptPtr-script) - cs.currentStateOfs; g_stateCount++; @@ -1484,7 +1526,7 @@ static int32_t C_ParseCommand(void) else // we were redefining a state { int32_t oofs = statesinfo[j].ofs; - int32_t nofs = g_currentStateOfs; + int32_t nofs = cs.currentStateOfs; int32_t osize = statesinfo[j].codesize; int32_t nsize = (g_scriptPtr-script) - nofs; @@ -1529,8 +1571,10 @@ static int32_t C_ParseCommand(void) g_scriptPtr -= osize; } - g_currentStateOfs = -1; - g_currentStateIdx = -1; + g_didDefineSomething = 1; + + cs.currentStateOfs = -1; + cs.currentStateIdx = -1; Bsprintf(g_szCurrentBlockName,"(none)"); } @@ -1568,14 +1612,14 @@ static int32_t C_ParseCommand(void) return 0; case CON_ONEVENT: - if (g_currentStateIdx >= 0 || g_parsingEventOfs >= 0) + if (cs.currentStateIdx >= 0 || cs.parsingEventOfs >= 0) { C_ReportError(ERROR_FOUNDWITHIN); g_numCompilerErrors++; } g_scriptPtr--; - g_numBraces = 0; + cs.numBraces = 0; C_SkipComments(); j = 0; @@ -1586,15 +1630,15 @@ static int32_t C_ParseCommand(void) } g_szCurrentBlockName[j] = 0; - g_labelsOnly = 1; + cs.labelsOnly = 1; C_GetNextValue(LABEL_EVENT); - g_labelsOnly = 0; + cs.labelsOnly = 0; g_scriptPtr--; j = *g_scriptPtr; // event number - g_currentEvent = j; - g_parsingEventOfs = g_scriptPtr-script; + cs.currentEvent = j; + cs.parsingEventOfs = g_scriptPtr-script; //Bsprintf(g_szBuf,"Adding Event for %d at %lX",j, g_parsingEventPtr); AddLog(g_szBuf); if (j<0 || j >= MAXEVENTS) { @@ -1603,39 +1647,39 @@ static int32_t C_ParseCommand(void) return 0; } - g_checkingIfElse = 0; + cs.checkingIfElse = 0; return 0; case CON_ENDEVENT: - if (g_parsingEventOfs < 0) + if (cs.parsingEventOfs < 0) { C_ReportError(-1); initprintf("%s:%d: error: found `endevent' without open `onevent'.\n",g_szScriptFileName,g_lineNumber); g_numCompilerErrors++; return 1; } - if (g_numBraces > 0) + if (cs.numBraces > 0) { C_ReportError(ERROR_OPENBRACKET); g_numCompilerErrors++; } - if (g_numBraces < 0) + if (cs.numBraces < 0) { C_ReportError(ERROR_CLOSEBRACKET); g_numCompilerErrors++; } if (g_numCompilerErrors) { - g_parsingEventOfs = -1; - g_currentEvent = -1; + cs.parsingEventOfs = -1; + cs.currentEvent = -1; Bsprintf(g_szCurrentBlockName,"(none)"); return 0; } - j = g_currentEvent; + j = cs.currentEvent; 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; if (osize == nsize) @@ -1680,28 +1724,30 @@ static int32_t C_ParseCommand(void) } else // event defined for the first time { - aEventOffsets[j] = g_parsingEventOfs; - aEventSizes[j] = (g_scriptPtr-script) - g_parsingEventOfs; + aEventOffsets[j] = cs.parsingEventOfs; + aEventSizes[j] = (g_scriptPtr-script) - cs.parsingEventOfs; initprintf(" Defined event `%s' (index %d).\n", g_szCurrentBlockName, j); } - g_parsingEventOfs = -1; - g_currentEvent = -1; + g_didDefineSomething = 1; + + cs.parsingEventOfs = -1; + cs.currentEvent = -1; Bsprintf(g_szCurrentBlockName,"(none)"); return 0; // *** control flow case CON_ELSE: - if (g_checkingIfElse) + if (cs.checkingIfElse) { ofstype offset; ofstype lastScriptOfs = (g_scriptPtr-script) - 1; instype *tscrptr; - g_ifElseAborted = 0; - g_checkingIfElse--; + cs.ifElseAborted = 0; + cs.checkingIfElse--; if (C_CheckMalformedBranch(lastScriptOfs)) return 0; @@ -1731,7 +1777,7 @@ static int32_t C_ParseCommand(void) if (C_GetKeyword() == CON_LEFTBRACE) { C_GetNextKeyword(); - g_numBraces++; + cs.numBraces++; do done = C_ParseCommand(); @@ -1745,7 +1791,7 @@ static int32_t C_ParseCommand(void) case CON_RETURN: case CON_BREAK: - if (g_checkingSwitch) + if (cs.checkingSwitch) { //Bsprintf(g_szBuf," * (L%d) case Break statement.\n",g_lineNumber); AddLog(g_szBuf); return 1; @@ -1757,8 +1803,8 @@ static int32_t C_ParseCommand(void) ofstype tempoffset; //AddLog("Got Switch statement"); - // if (g_checkingSwitch) Bsprintf(g_szBuf,"ERROR::%s %d: g_checkingSwitch=",__FILE__,__LINE__, g_checkingSwitch); AddLog(g_szBuf); - g_checkingSwitch++; // allow nesting (if other things work) + // if (cs.checkingSwitch) Bsprintf(g_szBuf,"ERROR::%s %d: cs.checkingSwitch=",__FILE__,__LINE__, cs.checkingSwitch); AddLog(g_szBuf); + cs.checkingSwitch++; // allow nesting (if other things work) 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; // 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) temptextptr = textptr; // probably does not allow nesting... //AddLog("Counting Case Statements..."); 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_caseCodePtr = g_scriptPtr; + cs.caseCodePtr = g_scriptPtr; C_SkipComments(); g_scriptPtr -= j*2; // allocate buffer for the table 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) return 1; @@ -1798,7 +1844,7 @@ static int32_t C_ParseCommand(void) C_SkipComments(); } //Bsprintf(g_szBuf,"SWITCH1: '%.22s'",textptr); AddLog(g_szBuf); - g_numCases = 0; + cs.numCases = 0; while (C_ParseCommand() == 0) { //Bsprintf(g_szBuf,"SWITCH2: '%.22s'",textptr); AddLog(g_szBuf); @@ -1807,7 +1853,7 @@ static int32_t C_ParseCommand(void) tempscrptr = (instype *)(script+tempoffset); //Bsprintf(g_szBuf,"SWITCHXX: '%.22s'",textptr); AddLog(g_szBuf); // 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) { 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]); - 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); - g_numCases = 0; - g_caseScriptPtr = NULL; - g_caseCodePtr = NULL; + cs.numCases = 0; + cs.caseScriptPtr = NULL; + cs.caseCodePtr = NULL; // 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; - // 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"); } break; @@ -1849,7 +1895,7 @@ static int32_t C_ParseCommand(void) //AddLog("Found Case"); repeatcase: g_scriptPtr--; // don't save in code - if (g_checkingSwitch < 1) + if (cs.checkingSwitch < 1) { g_numCompilerErrors++; C_ReportError(-1); @@ -1857,26 +1903,26 @@ repeatcase: return 1; } - g_numCases++; + cs.numCases++; //Bsprintf(g_szBuf,"case1: %.12s",textptr); AddLog(g_szBuf); C_GetNextValue(LABEL_DEFINE); if (*textptr == ':') textptr++; //Bsprintf(g_szBuf,"case2: %.12s",textptr); AddLog(g_szBuf); 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); - if (g_caseScriptPtr) + //Bsprintf(g_szBuf,"case: Value of case %d is %d",(int32_t)cs.numCases,(int32_t)j); AddLog(g_szBuf); + if (cs.caseScriptPtr) { - for (i=(g_numCases/2)-1; i>=0; i--) - if (g_caseScriptPtr[i*2+1] == j) + for (i=(cs.numCases/2)-1; i>=0; i--) + if (cs.caseScriptPtr[i*2+1] == j) { g_numCompilerWarnings++; C_ReportError(WARNING_DUPLICATECASE); break; } //AddLog("Adding value to script"); - g_caseScriptPtr[g_numCases++] = j; // save value - g_caseScriptPtr[g_numCases] = (ofstype)(g_scriptPtr - g_caseCodePtr); // offset from beginning of cases' code + cs.caseScriptPtr[cs.numCases++] = j; // save value + cs.caseScriptPtr[cs.numCases] = (ofstype)(g_scriptPtr - cs.caseCodePtr); // offset from beginning of cases' code } //Bsprintf(g_szBuf,"case3: %.12s",textptr); AddLog(g_szBuf); j = C_GetKeyword(); @@ -1908,22 +1954,22 @@ repeatcase: case CON_DEFAULT: g_scriptPtr--; // don't save - if (g_checkingSwitch < 1) + if (cs.checkingSwitch < 1) { g_numCompilerErrors++; C_ReportError(-1); initprintf("%s:%d: error: found `default' statement when not in switch\n",g_szScriptFileName,g_lineNumber); return 1; } - if (g_caseScriptPtr && g_caseScriptPtr[0]!=0) + if (cs.caseScriptPtr && cs.caseScriptPtr[0]!=0) { // duplicate default statement g_numCompilerErrors++; C_ReportError(-1); initprintf("%s:%d: error: multiple `default' statements found in switch\n",g_szScriptFileName,g_lineNumber); } - if (g_caseScriptPtr) - g_caseScriptPtr[0] = (ofstype)(g_scriptPtr-g_caseCodePtr); // save offset from cases' code + if (cs.caseScriptPtr) + cs.caseScriptPtr[0] = (ofstype)(g_scriptPtr-cs.caseCodePtr); // save offset from cases' code //Bsprintf(g_szBuf,"default: '%.22s'",textptr); AddLog(g_szBuf); while (C_ParseCommand() == 0) { @@ -1934,8 +1980,8 @@ repeatcase: case CON_ENDSWITCH: //AddLog("End Switch"); - g_checkingSwitch--; - if (g_checkingSwitch < 0) + cs.checkingSwitch--; + if (cs.checkingSwitch < 0) { g_numCompilerErrors++; C_ReportError(-1); @@ -1952,13 +1998,13 @@ repeatcase: return 0; case CON_LEFTBRACE: -// if (!(g_currentStateIdx >= 0 || g_parsingEventOfs >= 0)) +// if (!(cs.currentStateIdx >= 0 || cs.parsingEventOfs >= 0)) // { // g_numCompilerErrors++; // C_ReportError(ERROR_SYNTAXERROR); // } - g_numBraces++; + cs.numBraces++; do done = C_ParseCommand(); @@ -1966,7 +2012,7 @@ repeatcase: return 0; case CON_RIGHTBRACE: - g_numBraces--; + cs.numBraces--; // rewrite "{ }" into "nullop" if (*(g_scriptPtr-2) == CON_LEFTBRACE + (IFELSE_MAGIC<<12)) @@ -1976,28 +2022,28 @@ repeatcase: g_scriptPtr -= 2; if (C_GetKeyword() != CON_ELSE && (*(g_scriptPtr-2)&0xFFF) != CON_ELSE) - g_ifElseAborted = 1; - else g_ifElseAborted = 0; + cs.ifElseAborted = 1; + else cs.ifElseAborted = 0; j = C_GetKeyword(); - if (g_checkingIfElse && j != CON_ELSE) - g_checkingIfElse--; + if (cs.checkingIfElse && j != CON_ELSE) + cs.checkingIfElse--; return 1; } - if (g_numBraces < 0) + if (cs.numBraces < 0) { - if (g_checkingSwitch) + if (cs.checkingSwitch) C_ReportError(ERROR_NOENDSWITCH); C_ReportError(-1); initprintf("%s:%d: error: found more `}' than `{'.\n",g_szScriptFileName,g_lineNumber); g_numCompilerErrors++; } - if (g_checkingIfElse && j != CON_ELSE) - g_checkingIfElse--; + if (cs.checkingIfElse && j != CON_ELSE) + cs.checkingIfElse--; return 1; @@ -2016,7 +2062,7 @@ repeatcase: // syntax getsector[].x // gets the value of sector[].xxx into - 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); initprintf("%s:%d: warning: found `%s' outside of EVENT_ANALYZESPRITES\n",g_szScriptFileName,g_lineNumber,tempbuf); @@ -2032,9 +2078,9 @@ repeatcase: textptr++; // get the ID of the DEF - g_labelsOnly = 1; + cs.labelsOnly = 1; C_GetNextVar(); - g_labelsOnly = 0; + cs.labelsOnly = 0; // now get name of .xxx while (*textptr != '.') { @@ -2321,20 +2367,16 @@ repeatcase: { instype *inst = (g_scriptPtr-1); const char *otextptr; - int32_t ow, oe; C_GetNextVarType(GAMEVAR_READONLY); - ow = g_numCompilerWarnings; - oe = g_numCompilerErrors; otextptr = textptr; - g_noConstBitwidthWarning = 1; + g_tooBigConstant = 0; C_GetNextVar(); - g_noConstBitwidthWarning = 0; - if (!g_numCompilerErrors && g_numCompilerWarnings > ow) + + if (!g_numCompilerErrors && g_tooBigConstant) { - g_numCompilerWarnings--; textptr = otextptr; g_scriptPtr--; *inst -= (CON_SETVARVAR - CON_SETVAR); @@ -2475,7 +2517,7 @@ repeatcase: ofstype offset; ofstype lastScriptOfs = (g_scriptPtr-script-1); instype *tscrptr; - g_ifElseAborted = 0; + cs.ifElseAborted = 0; if (tw<=CON_WHILEVARL) // careful! check this against order in m32def.h! { @@ -2486,20 +2528,16 @@ repeatcase: { instype *inst = (g_scriptPtr-1); const char *otextptr; - int32_t ow, oe; C_GetNextVar(); - ow = g_numCompilerWarnings; - oe = g_numCompilerErrors; otextptr = textptr; - g_noConstBitwidthWarning = 1; + g_tooBigConstant = 0; C_GetNextVar(); - g_noConstBitwidthWarning = 0; - if (!g_numCompilerErrors && g_numCompilerWarnings > ow) + + if (!g_numCompilerErrors && g_tooBigConstant) { - g_numCompilerWarnings--; textptr = otextptr; g_scriptPtr--; *inst -= (CON_IFVARVARL - CON_IFVARL); @@ -2532,7 +2570,7 @@ repeatcase: j = C_GetKeyword(); if (j == CON_ELSE || j == CON_LEFTBRACE) - g_checkingIfElse++; + cs.checkingIfElse++; } return 0; @@ -2854,7 +2892,7 @@ repeatcase: case CON_ROTATESPRITE16: case CON_ROTATESPRITE: - if (g_parsingEventOfs < 0 && g_currentStateIdx < 0) + if (cs.parsingEventOfs < 0 && cs.currentStateIdx < 0) { C_ReportError(ERROR_EVENTONLY); g_numCompilerErrors++; @@ -2910,8 +2948,10 @@ void C_CompilationInfo(void) int32_t j, k=0; initprintf("Compiled code info: (size=%ld*%d bytes)\n", (unsigned)(g_scriptPtr-script), sizeof(instype)); - initprintf(" %d user labels, %d/%d user variables, %d/%d user arrays\n", - g_numLabels-g_numDefaultLabels, + initprintf(" %d/%d user labels, %d/65536 indirect constants,\n", + 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_gameArrayCount-g_systemArrayCount, MAXGAMEARRAYS-g_systemArrayCount); for (j=0; j=0; j--) + for (k=0, j=MAXQUOTES-1; j>=0; j--) if (ScriptQuotes[j]) k++; - if (k | g_numQuoteRedefinitions) - initprintf(" %d/%d quotes, %d quote redefinitions\n",k,MAXQUOTES,g_numQuoteRedefinitions); + if (k || 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) @@ -2942,6 +2982,8 @@ void C_Compile(const char *filenameortext, int32_t isfilename) labelval = Bmalloc(label_allocsize * sizeof(int32_t)); labeltype = Bmalloc(label_allocsize * sizeof(uint8_t)); + constants = Bmalloc(constants_allocsize * sizeof(int32_t)); + statesinfo = Bmalloc(statesinfo_allocsize * sizeof(statesinfo_t)); for (i=0; i= 0 || g_currentStateIdx >= 0) + if (cs.parsingEventOfs >= 0 || cs.currentStateIdx >= 0) 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); Bstrcpy(g_szLastBlockName, g_szCurrentBlockName); } @@ -3128,7 +3178,7 @@ void C_ReportError(int32_t iError) break; case ERROR_FOUNDWITHIN: 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; case ERROR_ISAKEYWORD: initprintf("%s:%d: error: symbol `%s' is a keyword.\n", diff --git a/polymer/eduke32/source/m32def.h b/polymer/eduke32/source/m32def.h index 6e89d63f7..318af9396 100644 --- a/polymer/eduke32/source/m32def.h +++ b/polymer/eduke32/source/m32def.h @@ -43,6 +43,8 @@ extern char g_szScriptFileName[BMAX_PATH]; extern int32_t g_totalLines,g_lineNumber; extern int32_t g_numCompilerErrors,g_numCompilerWarnings; +extern int32_t g_didDefineSomething; + extern instype *g_scriptPtr; void C_Compile(const char *filenameortext, int32_t isfilename); diff --git a/polymer/eduke32/source/m32exec.c b/polymer/eduke32/source/m32exec.c index 1002f7bae..273ae8a03 100644 --- a/polymer/eduke32/source/m32exec.c +++ b/polymer/eduke32/source/m32exec.c @@ -1791,8 +1791,16 @@ badindex: aGameVars[(code>>16)&(MAXGAMEVARS-1)].szLabel:"???"); } - if ((code&0x0000FFFF) == MAXGAMEVARS) // addlogvar for a constant.. why not? :P - Bsprintf(buf, "(constant)"); + if ((code&0x0000FFFC) == MAXGAMEVARS) // addlogvar for a constant.. why not? :P + { + 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)) Bsprintf(buf, "(array) %s[%s]", aGameArrays[code&(MAXGAMEARRAYS-1)].szLabel? aGameArrays[code&(MAXGAMEARRAYS-1)].szLabel:"???", buf2); diff --git a/polymer/eduke32/source/m32vars.c b/polymer/eduke32/source/m32vars.c index 63c8bfb44..afef0ed6a 100644 --- a/polymer/eduke32/source/m32vars.c +++ b/polymer/eduke32/source/m32vars.c @@ -249,8 +249,22 @@ int32_t __fastcall Gv_GetVarX(register int32_t id) if (id == g_iThisActorID) return vm.g_i; - if ((id & 0x0000FFFF) == MAXGAMEVARS) - return ((int16_t)(id>>16)); + if ((id & 0x0000FFFC) == MAXGAMEVARS) + { + switch (id&3) + { + case 0: + 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);