I got feedback The this[] property should use property initialization to set its default value.
for this source, but I don’t know how to handle.
Source code that caused feedback
using System;
using System.Collections.Generic;
using System.Linq;
internal class Interpreter
{
private readonly Stack<int> stack = new();
private readonly IEnumerator<string> tokens;
private readonly Dictionary<string, Action?> words;
internal Interpreter(IEnumerable<string> t)
{
tokens = t.GetEnumerator();
words = new() {
["+"] = () => {
var b = stack.Pop();
var a = stack.Pop();
stack.Push(a + b);
},
["-"] = () => {
var b = stack.Pop();
var a = stack.Pop();
stack.Push(a - b);
},
["*"] = () => {
var b = stack.Pop();
var a = stack.Pop();
stack.Push(a * b);
},
["/"] = () => {
var b = stack.Pop();
var a = stack.Pop();
stack.Push(a / b);
},
["DUP"] = () => {
var a = stack.Pop();
stack.Push(a);
stack.Push(a);
},
["DROP"] = () => stack.Pop(),
["SWAP"] = () => {
var b = stack.Pop();
var a = stack.Pop();
stack.Push(b);
stack.Push(a);
},
["OVER"] = () => {
var b = stack.Pop();
var a = stack.Pop();
stack.Push(a);
stack.Push(b);
stack.Push(a);
},
};
}
internal void DefineWord()
{
tokens.MoveNext();
var name = tokens.Current;
if (name == ":" || name == ";" || int.TryParse(name, out _)) throw new InvalidOperationException();
Action? r = null;
for (tokens.MoveNext(); tokens.Current != ";"; tokens.MoveNext())
{
r += tokens.Current switch
{
var t when int.TryParse(t, out int v) => () => stack.Push(v),
var t when words.ContainsKey(t) => words[t],
_ => throw new InvalidOperationException(),
};
}
words[name] = r;
}
internal string Eval()
{
while (tokens.MoveNext())
{
var t = tokens.Current;
switch (t)
{
case var _ when int.TryParse(t, out int v):
stack.Push(v);
break;
case ":":
DefineWord();
break;
case var _ when words.ContainsKey(t):
words[t]?.Invoke();
break;
default:
throw new InvalidOperationException();
}
}
var r = stack.ToArray();
Array.Reverse(r);
return string.Join(" ", r);
}
}
public static class Forth
{
public static string Evaluate(string[] instructions)
{
var tokens = instructions.SelectMany(s => s.ToUpper().Split(' ', StringSplitOptions.RemoveEmptyEntries));
return new Interpreter(tokens).Eval();
}
}
I can’t write private readonly Dictionary<string, Action?> words = new() { /* blah blah */ }
, because the language doesn’t allow to use field stack
inside initializer.