Commit b7ab064e authored by Jesse McGrew's avatar Jesse McGrew
Browse files

Issue warning MDL0429 for suspicious quoted elements in a SYNONYM or ADJECTIVE

property, where the user probably forgot to escape an apostrophe. [ZILF-105]
parent ced622f71970
......@@ -267,6 +267,8 @@ namespace Zilf.Diagnostics
public const int _0_Routines_May_Not_Define_BIND_TUPLE_Or_ARGS_Arguments = 427;
[Warning("{0}: LEXV table initializer is not a multiple of 3 elements")]
public const int _0_LEXV_Table_Initializer_Is_Not_A_Multiple_Of_3_Elements = 428;
[Warning("{0}'{1} is parsed as two separate words, {0} and {1}; did you mean {0}\\'{1}?")]
public const int _0_1_Is_Parsed_As_Two_Separate_Words_0_And_1_Did_You_Mean_0_1 = 429;
// Modularity (package system, definitions sections) - 0500
......
......@@ -353,6 +353,7 @@ namespace Zilf.Interpreter
public static ZilObject OBJECT(Context ctx, ZilAtom name,
[Decl("<LIST [REST LIST]>")] ZilList[] props)
{
CheckObjectDefinitionForShadyQuotedAtoms(ctx);
return PerformObject(ctx, name, props, false);
}
......@@ -360,9 +361,55 @@ namespace Zilf.Interpreter
public static ZilObject ROOM(Context ctx, ZilAtom name,
[Decl("<LIST [REST LIST]>")] ZilList[] props)
{
CheckObjectDefinitionForShadyQuotedAtoms(ctx);
return PerformObject(ctx, name, props, true);
}
private static void CheckObjectDefinitionForShadyQuotedAtoms(Context ctx)
{
// OBJECT and ROOM are SUBRs, so quotes will have already been evaluated before the call,
// but we can use ctx.TopFrame to access the original calling form
if (ctx.TopFrame is CallFrame { SourceLine: var sourceLine, CallingForm: var objectForm })
{
foreach (var elem in objectForm)
{
// check property clauses for SYNONYM and ADJECTIVE
if (elem is ZilList { First: ZilAtom { StdAtom: StdAtom.SYNONYM or StdAtom.ADJECTIVE }, Rest: { } propValues })
{
ZilObject? prevWord = null;
foreach (var word in propValues)
{
switch (word)
{
// issue warning for each quoted atom-or-fix in the property value that
// follows another (optionally quoted) atom-or-fix
case ZilForm {
First: ZilAtom { StdAtom: StdAtom.QUOTE },
Rest: { First: { } quotedWord, Rest: { IsEmpty: true } }
} when prevWord != null && quotedWord is ZilAtom or ZilFix:
ctx.HandleError(new InterpreterError(
sourceLine,
InterpreterMessages._0_1_Is_Parsed_As_Two_Separate_Words_0_And_1_Did_You_Mean_0_1,
prevWord,
quotedWord));
prevWord = quotedWord;
break;
case ZilAtom or ZilFix:
prevWord = word;
break;
default:
prevWord = null;
break;
}
}
}
}
}
}
static ZilObject PerformObject(Context ctx, ZilAtom atom, ZilList[] props, bool isRoom)
{
string name = isRoom ? "ROOM" : "OBJECT";
......
......@@ -625,5 +625,17 @@ namespace Zilf.Tests.Integration
.WithoutWarnings()
.CompilesAsync();
}
[TestMethod]
public async Task Vocab_Properties_With_Apostrophes_Should_Warn()
{
await AssertGlobals("<OBJECT CATS-PAJAMAS (SYNONYM PAJAMAS) (ADJECTIVE CAT'S)>")
.WithWarnings("MDL0429")
.CompilesAsync();
await AssertGlobals("<OBJECT FOO (SYNONYM WOULDN'T'VE) (ADJECTIVE 90'S)>")
.WithWarnings("MDL0429")
.DoesNotCompileAsync(); // because 90 can't be an adjective
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment