- demoted the SWCustom parser to the primitive Hexen interface after finding out that this is all the Build parser can do.

This also meant I had to add symbol support to the old style number parsers.
This commit is contained in:
Christoph Oelckers 2020-09-12 10:23:47 +02:00
parent e0ae87e973
commit 89316aea33
4 changed files with 139 additions and 70 deletions

View file

@ -61,7 +61,7 @@ int32_t scriptfile_getnumber(scriptfile *sf, int32_t *num)
{
char *p = sf->textptr;
skipovertoken(sf);
Printf("Error on line %s:%d: expecting int32_t, got \"%s\"\n",sf->filename,scriptfile_getlinum(sf,sf->ltextptr),p);
Printf("Error on line %s:%d: expecting int, got \"%s\"\n",sf->filename,scriptfile_getlinum(sf,sf->ltextptr),p);
return -2;
}
return 0;

View file

@ -505,6 +505,7 @@ bool FScanner::ScanString (bool tokens)
const char *marker, *tok;
bool return_val;
ParseError = false;
CheckOpen();
if (AlreadyGot)
{
@ -545,7 +546,7 @@ bool FScanner::GetString ()
return ScanString (false);
}
//==========================================================================
//============================================ ==============================
//
// FScanner :: MustGetString
//
@ -723,7 +724,7 @@ bool FScanner::CheckToken (int token, bool evaluate)
//
//==========================================================================
bool FScanner::GetNumber ()
bool FScanner::GetNumber (bool evaluate)
{
char *stopper;
@ -740,6 +741,19 @@ bool FScanner::GetNumber ()
Number = (int)BigNumber;// clamp<int64_t>(BigNumber, 0, UINT_MAX);
if (*stopper != 0)
{
if (evaluate && symbols.CountUsed())
{
auto sym = symbols.CheckKey(String);
if (sym && sym->tokenType == TK_IntConst)
{
BigNumber = sym->Number;
Number = (int)sym->Number;
Float = sym->Float;
// String will retain the actual symbol name.
return true;
}
}
ScriptError ("SC_GetNumber: Bad numeric constant \"%s\".", String);
}
}
@ -758,9 +772,9 @@ bool FScanner::GetNumber ()
//
//==========================================================================
void FScanner::MustGetNumber ()
void FScanner::MustGetNumber (bool evaluate)
{
if (GetNumber() == false)
if (GetNumber(evaluate) == false)
{
ScriptError ("Missing integer (unexpected end of file).");
}
@ -775,7 +789,7 @@ void FScanner::MustGetNumber ()
//
//==========================================================================
bool FScanner::CheckNumber ()
bool FScanner::CheckNumber (bool evaluate)
{
char *stopper;
@ -797,6 +811,19 @@ bool FScanner::CheckNumber ()
Number = (int)BigNumber;// clamp<int64_t>(BigNumber, 0, UINT_MAX);
if (*stopper != 0)
{
if (evaluate && symbols.CountUsed())
{
auto sym = symbols.CheckKey(String);
if (sym && sym->tokenType == TK_IntConst)
{
BigNumber = sym->Number;
Number = (int)sym->Number;
Float = sym->Float;
// String will retain the actual symbol name.
return true;
}
}
UnGet();
return false;
}
@ -818,7 +845,7 @@ bool FScanner::CheckNumber ()
//
//==========================================================================
bool FScanner::CheckFloat ()
bool FScanner::CheckFloat (bool evaluate)
{
char *stopper;
@ -833,6 +860,20 @@ bool FScanner::CheckFloat ()
Float = strtod (String, &stopper);
if (*stopper != 0)
{
if (evaluate && symbols.CountUsed())
{
auto sym = symbols.CheckKey(String);
if (sym && sym->tokenType == TK_IntConst && sym->tokenType != TK_FloatConst)
{
BigNumber = sym->Number;
Number = (int)sym->Number;
Float = sym->Float;
// String will retain the actual symbol name.
return true;
}
}
UnGet();
return false;
}
@ -851,7 +892,7 @@ bool FScanner::CheckFloat ()
//
//==========================================================================
bool FScanner::GetFloat ()
bool FScanner::GetFloat (bool evaluate)
{
char *stopper;
@ -861,6 +902,19 @@ bool FScanner::GetFloat ()
Float = strtod (String, &stopper);
if (*stopper != 0)
{
if (evaluate && symbols.CountUsed())
{
auto sym = symbols.CheckKey(String);
if (sym && sym->tokenType == TK_IntConst && sym->tokenType != TK_FloatConst)
{
BigNumber = sym->Number;
Number = (int)sym->Number;
Float = sym->Float;
// String will retain the actual symbol name.
return true;
}
}
ScriptError ("SC_GetFloat: Bad numeric constant \"%s\".", String);
}
Number = (int)Float;
@ -878,9 +932,9 @@ bool FScanner::GetFloat ()
//
//==========================================================================
void FScanner::MustGetFloat ()
void FScanner::MustGetFloat (bool evaluate)
{
if (GetFloat() == false)
if (GetFloat(evaluate) == false)
{
ScriptError ("Missing floating-point number (unexpected end of file).");
}
@ -1115,6 +1169,12 @@ void FScanner::ScriptError (const char *message, ...)
va_end (arglist);
}
if (NoFatalErrors)
{
Printf(TEXTCOLOR_RED "Script error, \"%s\"" TEXTCOLOR_RED " line %d:\n" TEXTCOLOR_RED "%s\n", ScriptName.GetChars(),
AlreadyGot ? AlreadyGotLine : Line, composed.GetChars());
return;
}
I_Error ("Script error, \"%s\" line %d:\n%s\n", ScriptName.GetChars(),
AlreadyGot? AlreadyGotLine : Line, composed.GetChars());
}

View file

@ -82,6 +82,7 @@ public:
void SetCMode(bool cmode);
void SetNoOctals(bool cmode) { NoOctals = cmode; }
void SetNoFatalErrors(bool cmode) { NoFatalErrors = cmode; }
void SetEscape(bool esc);
void SetStateMode(bool stately);
void DisableStateOptions();
@ -108,13 +109,13 @@ public:
bool CheckToken(int token, bool evaluate = false);
bool CheckTokenId(ENamedName id);
bool GetNumber();
void MustGetNumber();
bool CheckNumber();
bool GetNumber(bool evaluate = false);
void MustGetNumber(bool evaluate = false);
bool CheckNumber(bool evaluate = false);
bool GetFloat();
void MustGetFloat();
bool CheckFloat();
bool GetFloat(bool evaluate = false);
void MustGetFloat(bool evaluate = false);
bool CheckFloat(bool evaluate = false);
double *LookupConstant(FName name)
{
@ -148,6 +149,7 @@ public:
double Float;
int Line;
bool End;
bool ParseError = false;
bool Crossed;
int LumpNum;
FString ScriptName;
@ -176,6 +178,7 @@ protected:
int LastGotLine;
bool CMode;
bool NoOctals = false;
bool NoFatalErrors = false;
uint8_t StateMode;
bool StateOptions;
bool Escape;

View file

@ -463,6 +463,8 @@ void LoadCustomInfoFromScript(const char *filename)
sc.OpenLumpNum(lump);
sc.SetNoOctals(true);
sc.SetCMode(true);
sc.SetNoFatalErrors(true);
// predefine constants for some stuff to give convenience and eliminate the need for a 'define' directive
sc.AddSymbol("INV_ARMOR", 1+InvDecl_Armor);
@ -484,61 +486,60 @@ void LoadCustomInfoFromScript(const char *filename)
}
MapRecord* curMap = nullptr;
while (sc.GetToken())
while (sc.GetString())
{
sc.TokenMustBe(TK_Identifier);
switch (cm_transtok(sc.String, cm_tokens, cm_numtokens))
{
case CM_MAP:
{
sc.MustGetValue(false, true);
int mapno = sc.Number;
sc.MustGetNumber(true);
int mapno = sc.ParseError? -1 : sc.Number;
curMap = FindMapByLevelNum(mapno);
if (!curMap)
{
curMap = AllocateMap();
curMap->levelNumber = mapno;
}
sc.MustGetToken('{');
if (sc.CheckString("{"))
while (!sc.CheckToken('}'))
while (!sc.CheckString("}"))
{
sc.MustGetToken(TK_Identifier);
sc.MustGetString();
switch (cm_transtok(sc.String, cm_map_tokens, cm_map_numtokens))
{
case CM_FILENAME:
{
sc.MustGetToken(TK_StringConst, true);
sc.MustGetString();
curMap->SetFileName(sc.String);
break;
}
case CM_SONG:
{
sc.MustGetToken(TK_StringConst, true);
sc.MustGetString();
curMap->music = sc.String;
break;
}
case CM_TITLE:
{
sc.MustGetToken(TK_StringConst, true);
sc.MustGetString();
curMap->SetName(sc.String);
break;
}
case CM_BESTTIME:
{
sc.MustGetValue(false);
sc.MustGetNumber();
curMap->designerTime = sc.Number;
break;
}
case CM_PARTIME:
{
sc.MustGetValue(false);
sc.MustGetNumber();
curMap->parTime = sc.Number;
break;
}
case CM_CDATRACK:
{
sc.MustGetValue(false);
sc.MustGetNumber();
curMap->cdSongId = sc.Number;
break;
}
@ -554,31 +555,32 @@ void LoadCustomInfoFromScript(const char *filename)
{
int curep;
sc.MustGetValue(false, true);
sc.MustGetNumber();
curep = sc.Number;
if ((unsigned)--curep >= 2u)
if (sc.ParseError) curep = -1;
else if ((unsigned)--curep >= 2u)
{
sc.ScriptMessage("Episode number %d not in range 1-2\n", curep + 1);
curep = -1;
break;
}
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
if (sc.CheckString("{"))
while (!sc.CheckString("}"))
{
sc.MustGetToken(TK_Identifier);
sc.MustGetString();
switch (cm_transtok(sc.String, cm_episode_tokens, cm_episode_numtokens))
{
case CM_TITLE:
{
sc.MustGetToken(TK_StringConst, true);
sc.MustGetString();
if (curep != -1) gVolumeNames[curep] = sc.String;
break;
}
case CM_SUBTITLE:
{
sc.MustGetToken(TK_StringConst, true);
sc.MustGetString();
if (curep != -1) gVolumeSubtitles[curep] = sc.String;
break;
}
@ -593,8 +595,9 @@ void LoadCustomInfoFromScript(const char *filename)
case CM_SKILL:
{
int curskill;
sc.MustGetValue(false, true);
sc.MustGetNumber();
curskill = sc.Number;
if (sc.ParseError) curskill = -1;
if ((unsigned)--curskill >= 4u)
{
sc.ScriptMessage("Skill number %d not in range 1-4 on line %s:%d\n", curskill + 1);
@ -602,15 +605,15 @@ void LoadCustomInfoFromScript(const char *filename)
break;
}
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
if (sc.CheckString("{"))
while (!sc.CheckString("}"))
{
sc.MustGetToken(TK_Identifier);
sc.MustGetString();
switch (cm_transtok(sc.String, cm_skill_tokens, cm_skill_numtokens))
{
case CM_TITLE:
{
sc.MustGetToken(TK_StringConst, true);
sc.MustGetString();
if (curskill != -1) gSkillNames[curskill] = sc.String;
break;
}
@ -625,10 +628,10 @@ void LoadCustomInfoFromScript(const char *filename)
case CM_COOKIE:
{
int fc = 0;
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
if (sc.CheckString("{"))
while (!sc.CheckString("}"))
{
sc.MustGetToken(TK_StringConst, true);
sc.MustGetString();
if (fc < MAX_FORTUNES)
{
quoteMgr.InitializeQuote(QUOTE_COOKIE + fc, sc.String);
@ -640,10 +643,10 @@ void LoadCustomInfoFromScript(const char *filename)
case CM_GOTKEY:
{
int fc = 0;
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
if (sc.CheckString("{"))
while (!sc.CheckString("}"))
{
sc.MustGetToken(TK_StringConst, true);
sc.MustGetString();
if (fc < MAX_KEYS)
{
quoteMgr.InitializeQuote(QUOTE_KEYMSG + fc, sc.String);
@ -655,10 +658,10 @@ void LoadCustomInfoFromScript(const char *filename)
case CM_NEEDKEY:
{
int fc = 0;
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
if (sc.CheckString("{"))
while (!sc.CheckString("}"))
{
sc.MustGetToken(TK_StringConst, true);
sc.MustGetString();
if (fc < MAX_KEYS)
{
quoteMgr.InitializeQuote(QUOTE_DOORMSG + fc, sc.String);
@ -673,9 +676,10 @@ void LoadCustomInfoFromScript(const char *filename)
FString name;
int amt = -1;
sc.MustGetValue(false, true);
sc.MustGetNumber();
in = sc.Number;
if (sc.ParseError) in = -1;
if ((unsigned)--in >= (unsigned)InvDecl_TOTAL)
{
sc.ScriptMessage("Inventory item number %d not in range 1-%d\n", in, InvDecl_TOTAL);
@ -683,10 +687,10 @@ void LoadCustomInfoFromScript(const char *filename)
break;
}
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
if (sc.CheckString("{"))
while (!sc.CheckString("}"))
{
sc.MustGetToken(TK_Identifier);
sc.MustGetString();
switch (cm_transtok(sc.String, cm_inventory_tokens, cm_inventory_numtokens))
{
case CM_TITLE:
@ -694,7 +698,7 @@ void LoadCustomInfoFromScript(const char *filename)
name = sc.String;
break;
case CM_AMOUNT:
sc.MustGetValue(false, true);
sc.MustGetNumber();
amt = sc.Number;
break;
default:
@ -720,9 +724,10 @@ void LoadCustomInfoFromScript(const char *filename)
int maxammo = -1, damagemin = -1, damagemax = -1, pickup = -1, wpickup = -1;
int in,id;
sc.MustGetValue(false, true);
sc.MustGetNumber();
in = sc.Number;
if (sc.ParseError) in = -1;
if ((unsigned)--in >= (unsigned)SIZ(weaponmap))
{
sc.ScriptMessage("Error: weapon number %d not in range 1-%d", in+1, (int)SIZ(weaponmap));
@ -730,10 +735,10 @@ void LoadCustomInfoFromScript(const char *filename)
break;
}
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
if (sc.CheckString("{"))
while (!sc.CheckString("}"))
{
sc.MustGetToken(TK_Identifier);
sc.MustGetString();
switch (cm_transtok(sc.String, cm_weapons_tokens, cm_weapons_numtokens))
{
case CM_TITLE:
@ -745,23 +750,23 @@ void LoadCustomInfoFromScript(const char *filename)
ammo = sc.String;
break;
case CM_MAXAMMO:
sc.MustGetValue(false, true);
sc.MustGetNumber();
maxammo = sc.Number;
break;
case CM_DAMAGEMIN:
sc.MustGetValue(false, true);
sc.MustGetNumber();
damagemin = sc.Number;
break;
case CM_DAMAGEMAX:
sc.MustGetValue(false, true);
sc.MustGetNumber();
damagemax = sc.Number;
break;
case CM_AMOUNT:
sc.MustGetValue(false, true);
sc.MustGetNumber();
pickup = sc.Number;
break;
case CM_WEAPON:
sc.MustGetValue(false, true);
sc.MustGetNumber();
wpickup = sc.Number;
break;
default:
@ -801,18 +806,19 @@ void LoadCustomInfoFromScript(const char *filename)
int trak = -1;
int curtheme;
sc.MustGetValue(false, true);
sc.MustGetNumber();
curtheme = sc.Number;
if ((unsigned)--curtheme >= 6u)
if (sc.ParseError) curtheme = -1;
if ((unsigned)--curtheme >= 6u)
{
sc.ScriptMessage("Theme number %d not in range 1-6", curtheme+1);
curtheme = -1;
}
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
if (sc.CheckString("{"))
while (!sc.CheckString("}"))
{
sc.MustGetToken(TK_Identifier);
sc.MustGetString();
switch (cm_transtok(sc.String, cm_theme_tokens, cm_theme_numtokens))
{
case CM_SONG:
@ -820,7 +826,7 @@ void LoadCustomInfoFromScript(const char *filename)
name = sc.String;
break;
case CM_CDATRACK:
sc.MustGetValue(false, true);
sc.MustGetNumber();
trak = sc.Number;
break;
default: