diff --git a/CPUModel.Using.CSharp.Rec/Program.cs b/CPUModel.Using.CSharp.Rec/Program.cs index bf35325..e1cafa2 100644 --- a/CPUModel.Using.CSharp.Rec/Program.cs +++ b/CPUModel.Using.CSharp.Rec/Program.cs @@ -1,4 +1,6 @@ int[] registers = new int[2]; + +#region While // int i = 0; // while (i < 10) // { @@ -6,6 +8,35 @@ // i++; // } +//var declarations = new ICommand[] +//{ +// new PutConstantToRegisterCommand(0, 0), +// new WriteCommand("i", 0), +//}; + +//var condition = new ICommand[] +//{ +// new PutConstantToRegisterCommand(1, 10), +// new ReadCommand("i", 0), +// new LtCommand(0) +//}; + +//var body = new ICommand[] +//{ +// new OutputCommand("#StopRussianAgression") +//}.Concat(new IncrementCommand("i", 1).Compile()).ToArray(); + +//var commands = declarations.Concat(new WhileCommand(condition, body) +// .Compile()).ToArray(); +#endregion + +#region For +//int i = 0; +//for (; i < 10; i+=2) +//{ +// Console.WriteLine("#Stand with Ukraine!!!"); +//} + var declarations = new ICommand[] { new PutConstantToRegisterCommand(0, 0), @@ -21,11 +52,14 @@ var body = new ICommand[] { - new OutputCommand("#StopRussianAgression") -}.Concat(new IncrementCommand("i").Compile()).ToArray(); + new OutputCommand("#Stand with Ukraine!!!") +}; + +var increment = new IncrementCommand("i", 2).Compile().ToArray(); -var commands = declarations.Concat(new WhileCommand(condition, body) +var commands = declarations.Concat(new ForCommand(condition, body, increment) .Compile()).ToArray(); +#endregion for (int i = 0; i < commands.Length;) { @@ -43,6 +77,35 @@ Console.ReadLine(); +class ForCommand +{ + private readonly ICommand[] _condition; + private readonly ICommand[] _increment; + private readonly ICommand[] _body; + + public ForCommand(ICommand[] condition, ICommand[] body, ICommand[] increment) + { + _condition = condition; + _body = body; + _increment = increment; + } + + public IEnumerable Compile() + { + var realBody = _body.Concat(_increment.Concat(new ICommand[] + { + new PutConstantToRegisterCommand(0, int.MaxValue), // Stub + new JumpCommand() + })).ToArray(); + + var ifCommandsCount = new IfCommand(_condition, realBody, Array.Empty()) + .Compile().Count() - 3; + realBody[^2] = new PutConstantToRegisterCommand(0, -ifCommandsCount); + + return new IfCommand(_condition, realBody, Array.Empty()).Compile(); + } +} + class WhileCommand { private readonly ICommand[] _condition; @@ -72,16 +135,18 @@ public IEnumerable Compile() class IncrementCommand { private readonly string _address; + private readonly int _incrementingValue; - public IncrementCommand(string address) + public IncrementCommand(string address, int incrementingValue) { _address = address; + _incrementingValue = incrementingValue; } public IEnumerable Compile() { yield return new ReadCommand(_address, 0); - yield return new PutConstantToRegisterCommand(1, 1); + yield return new PutConstantToRegisterCommand(1, _incrementingValue); yield return new AddCommand(0); yield return new WriteCommand(_address, 0); }