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

Zilf: Changed ChtypeMethod attribute parsing to make Context optional.

Removed unused Context parameter from chtype methods.
Minor style cleanup.
parent 50348c10e92e
......@@ -469,6 +469,7 @@ System.Xml.Linq.*</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=IGRTR/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=INTBL/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=NEWTYPE/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=oblist/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=opcode/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=PICINF/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=PICSET/@EntryIndexedValue">True</s:Boolean>
......@@ -480,6 +481,7 @@ System.Xml.Linq.*</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=PROPSPEC/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=quux/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=RFATAL/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=spliceable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=SUBR/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Subrs/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=TYPEPRIM/@EntryIndexedValue">True</s:Boolean>
......
......@@ -26,8 +26,9 @@ namespace Zilf.Interpreter
/// </summary>
/// <remarks>
/// <para>If applied to a constructor, it must take a single value of the primitive type.</para>
/// <para>If applied to a static method, it must take two parameters, <see cref="Context"/>
/// and the primitive type, and return a type assignable to <see cref="Values.ZilObject"/>.</para>
/// <para>If applied to a static method, it must take either one or two parameters,
/// an optional <see cref="Context"/> followed by the primitive type, and return a type
/// assignable to <see cref="Values.ZilObject"/>.</para>
/// </remarks>
/// <seealso cref="BuiltinTypeAttribute"/>
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method)]
......
......@@ -798,12 +798,25 @@ namespace Zilf.Interpreter
throw new FileNotFoundException();
}
/// <summary>
/// Adapts a MethodInfo, describing a function that takes a
/// specific ZilObject type and returns a ZilObject, to ChtypeDelegate.
/// </summary>
[NotNull]
static ChtypeDelegate AdaptChtypeMethod1<T>([NotNull] MethodInfo mi)
where T : ZilObject
{
var rawDel = Delegate.CreateDelegate(typeof(Func<T, ZilObject>), mi);
var del = (Func<T, ZilObject>)rawDel;
return (_, zo) => del((T)zo);
}
/// <summary>
/// Adapts a MethodInfo, describing a function that takes a context and a
/// specific ZilObject type and returns a ZilObject, to ChtypeDelegate.
/// </summary>
[NotNull]
static ChtypeDelegate AdaptChtypeMethod<T>([NotNull] MethodInfo mi)
static ChtypeDelegate AdaptChtypeMethod2<T>([NotNull] MethodInfo mi)
where T : ZilObject
{
var rawDel = Delegate.CreateDelegate(typeof(Func<Context, T, ZilObject>), mi);
......@@ -813,7 +826,7 @@ namespace Zilf.Interpreter
/// <summary>
/// Adapts a ConstructorInfo, describing a constructor that creates a
/// given a specific ZilObject type, to ChtypeDelegate.
/// given specific ZilObject type, to ChtypeDelegate.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="ci"></param>
......@@ -844,44 +857,51 @@ namespace Zilf.Interpreter
from a in t.GetCustomAttributes<BuiltinTypeAttribute>(false)
select new { Type = t, Attr = a };
Type[] chtypeParamTypes = { typeof(Context), null };
Type primitiveClassType;
foreach (var r in query)
{
// look up chtype method
Func<MethodInfo, ChtypeDelegate> adaptChtypeMethod;
Func<MethodInfo, ChtypeDelegate> adaptChtypeMethod1;
Func<MethodInfo, ChtypeDelegate> adaptChtypeMethod2;
Func<ConstructorInfo, ChtypeDelegate> adaptChtypeCtor;
switch (r.Attr.PrimType)
{
case PrimType.ATOM:
chtypeParamTypes[1] = typeof(ZilAtom);
adaptChtypeMethod = AdaptChtypeMethod<ZilAtom>;
primitiveClassType = typeof(ZilAtom);
adaptChtypeMethod1 = AdaptChtypeMethod1<ZilAtom>;
adaptChtypeMethod2 = AdaptChtypeMethod2<ZilAtom>;
adaptChtypeCtor = AdaptChtypeCtor<ZilAtom>;
break;
case PrimType.FIX:
chtypeParamTypes[1] = typeof(ZilFix);
adaptChtypeMethod = AdaptChtypeMethod<ZilFix>;
primitiveClassType = typeof(ZilFix);
adaptChtypeMethod1 = AdaptChtypeMethod1<ZilFix>;
adaptChtypeMethod2 = AdaptChtypeMethod2<ZilFix>;
adaptChtypeCtor = AdaptChtypeCtor<ZilFix>;
break;
case PrimType.LIST:
chtypeParamTypes[1] = typeof(ZilListBase);
adaptChtypeMethod = AdaptChtypeMethod<ZilList>;
primitiveClassType = typeof(ZilListBase);
adaptChtypeMethod1 = AdaptChtypeMethod1<ZilList>;
adaptChtypeMethod2 = AdaptChtypeMethod2<ZilList>;
adaptChtypeCtor = AdaptChtypeCtor<ZilList>;
break;
case PrimType.STRING:
chtypeParamTypes[1] = typeof(ZilString);
adaptChtypeMethod = AdaptChtypeMethod<ZilString>;
primitiveClassType = typeof(ZilString);
adaptChtypeMethod1 = AdaptChtypeMethod1<ZilString>;
adaptChtypeMethod2 = AdaptChtypeMethod2<ZilString>;
adaptChtypeCtor = AdaptChtypeCtor<ZilString>;
break;
case PrimType.TABLE:
chtypeParamTypes[1] = typeof(ZilTable);
adaptChtypeMethod = AdaptChtypeMethod<ZilTable>;
primitiveClassType = typeof(ZilTable);
adaptChtypeMethod1 = AdaptChtypeMethod1<ZilTable>;
adaptChtypeMethod2 = AdaptChtypeMethod2<ZilTable>;
adaptChtypeCtor = AdaptChtypeCtor<ZilTable>;
break;
case PrimType.VECTOR:
chtypeParamTypes[1] = typeof(ZilVector);
adaptChtypeMethod = AdaptChtypeMethod<ZilVector>;
primitiveClassType = typeof(ZilVector);
adaptChtypeMethod1 = AdaptChtypeMethod1<ZilVector>;
adaptChtypeMethod2 = AdaptChtypeMethod2<ZilVector>;
adaptChtypeCtor = AdaptChtypeCtor<ZilVector>;
break;
default:
......@@ -901,17 +921,33 @@ namespace Zilf.Interpreter
{
// adapt the static method
var foundParamTypes = chtypeMethod.GetParameters().Select(pi => pi.ParameterType).ToArray();
if (foundParamTypes.Length != chtypeParamTypes.Length ||
foundParamTypes[0] != chtypeParamTypes[0] ||
!foundParamTypes[1].IsAssignableFrom(chtypeParamTypes[1]))
switch (foundParamTypes.Length)
{
throw new InvalidOperationException(
$"Wrong parameters for static ChtypeMethod {chtypeMethod.Name} on type {r.Type.Name}\n" +
$"Expected: ({string.Join(", ", chtypeParamTypes.Select(t => t.Name))})\n" +
$"Actual: ({string.Join(", ", chtypeMethod.GetParameters().Select(pi => pi.ParameterType.Name))})");
case 1:
if (!foundParamTypes[0].IsAssignableFrom(primitiveClassType))
{
goto default;
}
chtypeDelegate = adaptChtypeMethod1(chtypeMethod);
break;
case 2:
if (foundParamTypes[0] != typeof(Context) ||
!foundParamTypes[1].IsAssignableFrom(primitiveClassType))
{
goto default;
}
chtypeDelegate = adaptChtypeMethod2(chtypeMethod);
break;
default:
throw new InvalidOperationException(
$"Wrong parameters for static ChtypeMethod {chtypeMethod.Name} on type {r.Type.Name}\n" +
$"Expected: ({primitiveClassType.Name}) or ({typeof(Context).Name}, {primitiveClassType.Namespace})\n" +
$"Actual: ({string.Join(", ", foundParamTypes.Select(t => t.Name))})");
}
chtypeDelegate = adaptChtypeMethod(chtypeMethod);
}
else
{
......@@ -923,12 +959,16 @@ namespace Zilf.Interpreter
if (chtypeCtor != null)
{
var foundParamTypes = chtypeCtor.GetParameters().Select(pi => pi.ParameterType).ToArray();
// adapt the constructor
if (!chtypeCtor.GetParameters()
.Select(pi => pi.ParameterType)
.SequenceEqual(chtypeParamTypes.Skip(1)))
if (foundParamTypes.Length != 1 || !foundParamTypes[0].IsAssignableFrom(primitiveClassType))
{
throw new InvalidOperationException(
$"Wrong parameters for ChtypeMethod constructor on type {r.Type.Name}");
$"Wrong parameters for ChtypeMethod constructor on type {r.Type.Name}\n" +
$"Expected: ({primitiveClassType.Name})\n" +
$"Actual: ({string.Join(", ", foundParamTypes.Select(t => t.Name))})");
}
chtypeDelegate = adaptChtypeCtor(chtypeCtor);
}
......
......@@ -41,7 +41,7 @@ namespace Zilf.Interpreter.Values.Tied
return new TiedLayout(properties.ToArray());
}
public TiedLayout(PropertyInfo[] properties, [CanBeNull] PropertyInfo catchAll = null)
TiedLayout(IReadOnlyList<PropertyInfo> properties, [CanBeNull] PropertyInfo catchAll = null)
{
PropertyInfos = properties;
CatchAllPropertyInfo = catchAll;
......
......@@ -41,10 +41,8 @@ namespace Zilf.Interpreter.Values
/// <exception cref="InterpreterError">Always thrown.</exception>
[ChtypeMethod]
[ContractAnnotation("=> halt")]
public static ZilActivation FromAtom([NotNull] Context ctx, [NotNull] ZilAtom name)
{
public static ZilActivation FromAtom([NotNull] Context ctx, [NotNull] ZilAtom name) =>
throw new InterpreterError(InterpreterMessages.CHTYPE_To_0_Not_Supported, "ACTIVATION");
}
public override StdAtom StdTypeAtom => StdAtom.ACTIVATION;
......
......@@ -44,10 +44,8 @@ namespace Zilf.Interpreter.Values
/// <exception cref="InterpreterError">Always thrown.</exception>
[ChtypeMethod]
public static ZilAsoc FromList([NotNull] Context ctx, [NotNull] ZilListBase list)
{
public static ZilAsoc FromList([NotNull] Context ctx, [NotNull] ZilListBase list) =>
throw new InterpreterError(InterpreterMessages.CHTYPE_To_0_Not_Supported, "ASOC");
}
public ZilObject Item => results[index].Item;
public ZilObject Indicator => results[index].Indicator;
......
......@@ -44,11 +44,8 @@ namespace Zilf.Interpreter.Values
[NotNull]
[ChtypeMethod]
public static ZilAtom FromAtom([NotNull] Context ctx, [NotNull] ZilAtom other)
{
// we can't construct a new atom since it wouldn't be equal to the old one
return other;
}
// we can't construct a new atom since it wouldn't be equal to the old one
public static ZilAtom FromAtom([NotNull] ZilAtom other) => other;
[NotNull]
public string Text { get; }
......@@ -158,8 +155,10 @@ namespace Zilf.Interpreter.Values
// or (2) no atom by that name can be found in the path.
foreach (var oblist in obListPath.OfType<ObList>())
{
if (oblist.Contains(Text))
return oblist[Text] != this;
}
return true;
}
......@@ -247,9 +246,6 @@ namespace Zilf.Interpreter.Values
public override PrimType PrimType => PrimType.ATOM;
[NotNull]
public override ZilObject GetPrimitive(Context ctx)
{
return this;
}
public override ZilObject GetPrimitive(Context ctx) => this;
}
}
\ No newline at end of file
......@@ -35,10 +35,8 @@ namespace Zilf.Interpreter.Values
{
/// <exception cref="InterpreterError">Always thrown.</exception>
[ChtypeMethod]
public static ZilChannel FromVector([NotNull] Context ctx, [NotNull] ZilVector vector)
{
public static ZilChannel FromVector([NotNull] Context ctx, [NotNull] ZilVector vector) =>
throw new InterpreterError(InterpreterMessages.CHTYPE_To_0_Not_Supported, "CHANNEL");
}
public override StdAtom StdTypeAtom => StdAtom.CHANNEL;
......
......@@ -38,13 +38,11 @@ namespace Zilf.Interpreter.Values
[NotNull]
[ChtypeMethod]
public static ZilChar FromFix([NotNull] Context ctx, [NotNull] ZilFix fix)
{
return new ZilChar(fix.Value);
}
public static ZilChar FromFix([NotNull] ZilFix fix) => new ZilChar(fix.Value);
public char Char => (char)value;
[NotNull]
public override string ToString()
{
return "!\\" + Char;
......
......@@ -35,10 +35,7 @@ namespace Zilf.Interpreter.Values
[NotNull]
[ChtypeMethod]
public static ZilDecl FromList(Context ctx, [NotNull] ZilListBase list)
{
return new ZilDecl(list);
}
public static ZilDecl FromList([NotNull] ZilListBase list) => new ZilDecl(list);
public override StdAtom StdTypeAtom => StdAtom.DECL;
......
......@@ -30,10 +30,8 @@ namespace Zilf.Interpreter.Values
readonly WeakReference<LocalEnvironment> env;
[ChtypeMethod]
public static ZilEnvironment FromAtom([NotNull] Context ctx, [NotNull] ZilAtom atom)
{
public static ZilEnvironment FromAtom([NotNull] Context ctx, [NotNull] ZilAtom atom) =>
throw new InterpreterError(InterpreterMessages.CHTYPE_To_0_Not_Supported, "ENVIRONMENT");
}
public ZilEnvironment(LocalEnvironment env, ZilAtom name)
{
......
......@@ -40,17 +40,21 @@ namespace Zilf.Interpreter.Values
public static ZilEvalMacro FromList([NotNull] Context ctx, [NotNull] ZilListBase list)
{
if (list.First == null || list.Rest == null || list.Rest.First != null)
{
throw new InterpreterError(
InterpreterMessages._0_Must_Have_1_Element1s,
"list coerced to MACRO",
1);
}
if (!list.First.IsApplicable(ctx))
{
throw new InterpreterError(
InterpreterMessages.Element_0_Of_1_Must_Be_2,
1,
"list coerced to MACRO",
"applicable");
}
return new ZilEvalMacro(list.First);
}
......
......@@ -23,7 +23,7 @@ using JetBrains.Annotations;
namespace Zilf.Interpreter.Values
{
[BuiltinType(StdAtom.FSUBR, PrimType.STRING)]
class ZilFSubr : ZilSubr
sealed class ZilFSubr : ZilSubr
{
public ZilFSubr([NotNull] string name, [NotNull] SubrDelegate handler)
: base(name, handler)
......@@ -32,10 +32,8 @@ namespace Zilf.Interpreter.Values
[ChtypeMethod]
[NotNull]
public new static ZilFSubr FromString([NotNull] Context ctx, [NotNull] ZilString str)
{
return FromString(ctx, str.ToStringContext(ctx, true));
}
public new static ZilFSubr FromString([NotNull] Context ctx, [NotNull] ZilString str) =>
FromString(ctx, str.ToStringContext(ctx, true));
[NotNull]
public new static ZilFSubr FromString([NotNull] Context ctx, [NotNull] string name)
......@@ -48,16 +46,11 @@ namespace Zilf.Interpreter.Values
throw new InterpreterError(InterpreterMessages.Unrecognized_0_1, "FSUBR name", name);
}
public override string ToString()
{
return $"#FSUBR \"{name}\"";
}
[NotNull]
public override string ToString() => $"#FSUBR \"{name}\"";
public override StdAtom StdTypeAtom => StdAtom.FSUBR;
public override ZilResult Apply(Context ctx, ZilObject[] args)
{
return ApplyNoEval(ctx, args);
}
public override ZilResult Apply(Context ctx, ZilObject[] args) => ApplyNoEval(ctx, args);
}
}
\ No newline at end of file
......@@ -46,10 +46,7 @@ namespace Zilf.Interpreter.Values
[NotNull]
[ChtypeMethod]
public static ZilForm FromList([NotNull] Context ctx, [NotNull] ZilListBase list)
{
return new ZilForm(list.First, list.Rest);
}
public static ZilForm FromList([NotNull] ZilListBase list) => new ZilForm(list.First, list.Rest);
protected override string OpenBracket => "<";
......@@ -275,7 +272,7 @@ namespace Zilf.Interpreter.Values
return (IsLVAL(out var myAtom) && other.IsLVAL(out var theirAtom) ||
IsGVAL(out myAtom) && other.IsGVAL(out theirAtom)) &&
myAtom == theirAtom;
myAtom == theirAtom;
}
public override int GetHashCode()
......
......@@ -64,8 +64,7 @@ namespace Zilf.Interpreter.Values
protected override TiedLayout GetLayout()
{
return TiedLayout.Create<ZilFunction>(
x => x.ArgSpecAsList)
return TiedLayout.Create<ZilFunction>(x => x.ArgSpecAsList)
.WithCatchAll<ZilFunction>(x => x.BodyAsList);
}
......
......@@ -33,14 +33,10 @@ namespace Zilf.Interpreter.Values
public override StdAtom StdTypeAtom => StdAtom.LINK;
[ChtypeMethod]
public new static ZilLink FromAtom(Context ctx, ZilAtom atom)
{
public new static ZilLink FromAtom(ZilAtom atom) =>
throw new InterpreterError(InterpreterMessages.CHTYPE_To_0_Not_Supported, "LINK");
}
public override ZilObject GetPrimitive(Context ctx)
{
public override ZilObject GetPrimitive(Context ctx) =>
throw new InterpreterError(InterpreterMessages.CHTYPE_Away_From_0_Not_Supported, "LINK");
}
}
}
......@@ -35,10 +35,7 @@ namespace Zilf.Interpreter.Values
[NotNull]
[ChtypeMethod]
public static ZilList FromList([NotNull] Context ctx, [NotNull] ZilListBase list)
{
return new ZilList(list.First, list.Rest);
}
public static ZilList FromList([NotNull] ZilListBase list) => new ZilList(list.First, list.Rest);
public override StdAtom StdTypeAtom => StdAtom.LIST;
......
......@@ -42,7 +42,7 @@ namespace Zilf.Interpreter.Values
[NotNull]
[ChtypeMethod]
public static ZilSegment FromList([NotNull] Context ctx, [NotNull] ZilListBase list)
public static ZilSegment FromList([NotNull] ZilListBase list)
{
if (!(list is ZilForm form))
{
......@@ -55,6 +55,7 @@ namespace Zilf.Interpreter.Values
[NotNull]
public ZilForm Form => form;
[NotNull]
public override string ToString() => "!" + form;
public override StdAtom StdTypeAtom => StdAtom.SEGMENT;
......
......@@ -28,7 +28,7 @@ namespace Zilf.Interpreter.Values
bool spliceable;
[ChtypeMethod]
public ZilSplice([NotNull] ZilListBase other)
public ZilSplice([NotNull] ZilListoidBase other)
: base(other.First, other.Rest)
{
}
......
......@@ -23,6 +23,7 @@ using System.Text;
using Zilf.Language;
using Zilf.Diagnostics;
using JetBrains.Annotations;
// ReSharper disable StringLiteralTypo
namespace Zilf.Interpreter.Values
{
......@@ -34,21 +35,13 @@ namespace Zilf.Interpreter.Values
[NotNull]
[ChtypeMethod]
public static ZilString FromString([NotNull] Context ctx, [NotNull] ZilString other)
{
return new OriginalString(other.Text);
}
public static ZilString FromString([NotNull] ZilString other) => new OriginalString(other.Text);
[NotNull]
public static ZilString FromString([NotNull] string text)
{
return new OriginalString(text);
}
public static ZilString FromString([NotNull] string text) => new OriginalString(text);
public sealed override string ToString()
{
return Quote(Text);
}
[NotNull]
public sealed override string ToString() => Quote(Text);
[NotNull]
public static string Quote([NotNull] string text)
......@@ -76,20 +69,12 @@ namespace Zilf.Interpreter.Values
return sb.ToString();
}
protected sealed override string ToStringContextImpl(Context ctx, bool friendly)
{
return friendly ? Text : ToString();
}
protected sealed override string ToStringContextImpl(Context ctx, bool friendly) =>
friendly ? Text : ToString();
public override bool ExactlyEquals(ZilObject obj)
{
return (obj as ZilString)?.Text.Equals(Text) ?? false;
}
public override bool ExactlyEquals(ZilObject obj) => (obj as ZilString)?.Text.Equals(Text) ?? false;
public override int GetHashCode()
{
return Text.GetHashCode();
}
public override int GetHashCode() => Text.GetHashCode();
public sealed override StdAtom StdTypeAtom => StdAtom.STRING;
......@@ -98,10 +83,7 @@ namespace Zilf.Interpreter.Values
public abstract ZilObject this[int index] { get; set; }
[NotNull]
public sealed override ZilObject GetPrimitive(Context ctx)
{
return this;
}
public sealed override ZilObject GetPrimitive(Context ctx) => this;
public abstract ZilObject GetFirst();
public abstract IStructure GetRest(int skip);
......@@ -117,10 +99,7 @@ namespace Zilf.Interpreter.Values
throw new NotSupportedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
[BuiltinAlternate(typeof(ZilString))]
sealed class OriginalString : ZilString
......@@ -163,12 +142,18 @@ namespace Zilf.Interpreter.Values
set
{
if (!(value is ZilChar ch))
throw new InterpreterError(InterpreterMessages._0_In_1_Must_Be_2, "elements", "a STRING", "CHARACTERs");
if (index >= 0 && index < Text.Length)
Text = Text.Substring(0, index) + ch.Char +
Text.Substring(index + 1, Text.Length - index - 1);
else
{
throw new InterpreterError(InterpreterMessages._0_In_1_Must_Be_2,
"elements",
"a STRING",
"CHARACTERs");
}
if (index < 0 || index >= Text.Length)
throw new ArgumentOutOfRangeException(nameof(index));
Text = Text.Substring(0, index) + ch.Char +
Text.Substring(index + 1, Text.Length - index - 1);
}
}
......
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