private bool Visit(TaskStatement stmt) { AssertNotConstant(stmt); if (stmt is PrintTaskStatement print) { Machine.Print(FormatString(print.Text, Locals)); } else if (stmt is ShowTaskStatement show) { Machine.Print(Visit(show.Value).ToString()); } else if (stmt is UpdateTaskStatement) { if (Machine is not IUpdatableMachine upd) { throw new InterpreterException("This machine cannot queue updates", stmt.Span); } upd.QueueUpdate(); } else { throw new InterpreterException("Unknown task", stmt.Span); } return(false); string FormatString(string str, IDictionary <string, BitsValue> locals) { return(Regex.Replace(str, @"\$([a-zA-Z_][a-zA-Z0-9_]*)(:(?<base>b|x))?", m => { if (!locals.TryGetValue(m.Groups[1].Value, out var value)) { throw new InterpreterException($"Local variable ${m.Value} not found in string interpolation", stmt.Span); } var nBase = m.Groups["base"].Success ? m.Groups["base"].Value : null; return nBase == "x" ? value.ToStringHex() : nBase == "b" ? value.ToStringBinary() : value.ToString(); })); } }
private void Visit(TaskStatement stmt) { switch (stmt) { case ShowTaskStatement show: LoadMachine(); Visit(show.Value); IL.Box(typeof(BitsValue)); IL.Call(typeof(object).GetMethod(nameof(object.ToString))); IL.Call(typeof(IMachine).GetMethod(nameof(IMachine.Print))); break; case PrintTaskStatement print: LoadMachine(); IL.Ldstr(print.Text); IL.Call(typeof(IMachine).GetMethod(nameof(IMachine.Print))); break; } }