diff --git a/CPUModel.Using.CSharp.Rec/Commands/ForCommand.cs b/CPUModel.Using.CSharp.Rec/Commands/ForCommand.cs new file mode 100644 index 0000000..9d19cb8 --- /dev/null +++ b/CPUModel.Using.CSharp.Rec/Commands/ForCommand.cs @@ -0,0 +1,40 @@ +class ForCommand +{ + private readonly ICommand[] _preCondition; + private readonly ICommand[] _condition; + private readonly ICommand[] _postCondition; + private readonly ICommand[] _body; + + public ForCommand( + ICommand[] preCondition, + ICommand[] condition, + ICommand[] postCondition, + ICommand[] body) + { + _preCondition = preCondition; + _condition = condition; + _postCondition = postCondition; + _body = body; + } + + public IEnumerable Compile() + { + var realBody = _body + .Concat(_postCondition) + .Concat(new ICommand[] + { + new PutConstantToRegisterCommand(0, int.MaxValue), // Stub + new JumpCommand() + }) + .ToArray(); + var ifCommandsCount = new IfCommand(_condition, realBody.ToArray(), Array.Empty()).Compile().Count() - 3; + realBody[^2] = new PutConstantToRegisterCommand(0, -ifCommandsCount); + + + return _preCondition + .Concat(new IfCommand( + _condition, + realBody, + Array.Empty()).Compile()); + } +} \ No newline at end of file diff --git a/CPUModel.Using.CSharp.Rec/Commands/IfCommand.cs b/CPUModel.Using.CSharp.Rec/Commands/IfCommand.cs new file mode 100644 index 0000000..260527d --- /dev/null +++ b/CPUModel.Using.CSharp.Rec/Commands/IfCommand.cs @@ -0,0 +1,35 @@ +class IfCommand +{ + private readonly ICommand[] _condition, _ifClause, _elseClause; + + public IfCommand(ICommand[] condition, ICommand[] ifClause, ICommand[] elseClause) + { + _condition = condition; + _ifClause = ifClause; + _elseClause = elseClause; + } + + public IEnumerable Compile() + { + foreach (var command in _condition) + yield return command; + + yield return new PutConstantToRegisterCommand(1, 1); + yield return new AddCommand(0); + yield return new JumpCommand(); + + yield return new PutConstantToRegisterCommand(1, _ifClause.Length + 3); + yield return new PutConstantToRegisterCommand(0, 0); + yield return new AddCommand(0); + yield return new JumpCommand(); + + foreach (var command in _ifClause) + yield return command; + + yield return new PutConstantToRegisterCommand(0, _elseClause.Length + 1); + yield return new JumpCommand(); + + foreach (var command in _elseClause) + yield return command; + } +} \ No newline at end of file diff --git a/CPUModel.Using.CSharp.Rec/Commands/IncrementCommand.cs b/CPUModel.Using.CSharp.Rec/Commands/IncrementCommand.cs new file mode 100644 index 0000000..3bd0632 --- /dev/null +++ b/CPUModel.Using.CSharp.Rec/Commands/IncrementCommand.cs @@ -0,0 +1,17 @@ +class IncrementCommand +{ + private readonly string _address; + + public IncrementCommand(string address) + { + _address = address; + } + + public IEnumerable Compile() + { + yield return new ReadCommand(_address, 0); + yield return new PutConstantToRegisterCommand(1, 1); + yield return new AddCommand(0); + yield return new WriteCommand(_address, 0); + } +} \ No newline at end of file diff --git a/CPUModel.Using.CSharp.Rec/Commands/WhileCommand.cs b/CPUModel.Using.CSharp.Rec/Commands/WhileCommand.cs new file mode 100644 index 0000000..95045e6 --- /dev/null +++ b/CPUModel.Using.CSharp.Rec/Commands/WhileCommand.cs @@ -0,0 +1,16 @@ +class WhileCommand +{ + private readonly ICommand[] _condition; + private readonly ICommand[] _body; + + public WhileCommand(ICommand[] condition, ICommand[] body) + { + _condition = condition; + _body = body; + } + + public IEnumerable Compile() + { + return new ForCommand(Array.Empty(), _condition, Array.Empty(), _body).Compile(); + } +} \ No newline at end of file diff --git a/CPUModel.Using.CSharp.Rec/Program.cs b/CPUModel.Using.CSharp.Rec/Program.cs index bf35325..9dd070e 100644 --- a/CPUModel.Using.CSharp.Rec/Program.cs +++ b/CPUModel.Using.CSharp.Rec/Program.cs @@ -1,6 +1,6 @@ int[] registers = new int[2]; -// int i = 0; -// while (i < 10) +// +// for (int i = 0; i < 10; i++) // { // Console.WriteLine("#StopRussianAgression"); // i++; @@ -22,10 +22,15 @@ var body = new ICommand[] { new OutputCommand("#StopRussianAgression") -}.Concat(new IncrementCommand("i").Compile()).ToArray(); +}; -var commands = declarations.Concat(new WhileCommand(condition, body) - .Compile()).ToArray(); +var commands = new ForCommand( + preCondition: declarations, + condition: condition, + postCondition: new IncrementCommand("i").Compile().ToArray(), + body: body) + .Compile() + .ToArray(); for (int i = 0; i < commands.Length;) { @@ -41,84 +46,4 @@ Console.WriteLine(); } -Console.ReadLine(); - -class WhileCommand -{ - private readonly ICommand[] _condition; - private readonly ICommand[] _body; - - public WhileCommand(ICommand[] condition, ICommand[] body) - { - _condition = condition; - _body = body; - } - - public IEnumerable Compile() - { - var realBody = _body.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 IncrementCommand -{ - private readonly string _address; - - public IncrementCommand(string address) - { - _address = address; - } - - public IEnumerable Compile() - { - yield return new ReadCommand(_address, 0); - yield return new PutConstantToRegisterCommand(1, 1); - yield return new AddCommand(0); - yield return new WriteCommand(_address, 0); - } -} - -class IfCommand -{ - private readonly ICommand[] _condition, _ifClause, _elseClause; - - public IfCommand(ICommand[] condition, ICommand[] ifClause, ICommand[] elseClause) - { - _condition = condition; - _ifClause = ifClause; - _elseClause = elseClause; - } - - public IEnumerable Compile() - { - foreach (var command in _condition) - yield return command; - - yield return new PutConstantToRegisterCommand(1, 1); - yield return new AddCommand(0); - yield return new JumpCommand(); - - yield return new PutConstantToRegisterCommand(1, _ifClause.Length + 3); - yield return new PutConstantToRegisterCommand(0, 0); - yield return new AddCommand(0); - yield return new JumpCommand(); - - foreach (var command in _ifClause) - yield return command; - - yield return new PutConstantToRegisterCommand(0, _elseClause.Length + 1); - yield return new JumpCommand(); - - foreach (var command in _elseClause) - yield return command; - } -} \ No newline at end of file +Console.ReadLine(); \ No newline at end of file