Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating 'for cycle' command #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 70 additions & 5 deletions CPUModel.Using.CSharp.Rec/Program.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,42 @@
int[] registers = new int[2];

#region While
// int i = 0;
// while (i < 10)
// {
// Console.WriteLine("#StopRussianAgression");
// 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),
Expand All @@ -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;)
{
Expand All @@ -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)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For loop can be a bit more complex:
for(int i = 0, j = 10; i < 10 && j > -5; i++, j--) {
body
}

So there also should be a definition block that should be executed once, before loop.

{
_condition = condition;
_body = body;
_increment = increment;
}

public IEnumerable<ICommand> Compile()
{
var realBody = _body.Concat(_increment.Concat(new ICommand[]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use while class, not copy it

{
new PutConstantToRegisterCommand(0, int.MaxValue), // Stub
new JumpCommand()
})).ToArray();

var ifCommandsCount = new IfCommand(_condition, realBody, Array.Empty<ICommand>())
.Compile().Count() - 3;
realBody[^2] = new PutConstantToRegisterCommand(0, -ifCommandsCount);

return new IfCommand(_condition, realBody, Array.Empty<ICommand>()).Compile();
}
}

class WhileCommand
{
private readonly ICommand[] _condition;
Expand Down Expand Up @@ -72,16 +135,18 @@ public IEnumerable<ICommand> 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<ICommand> 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);
}
Expand Down