Skip to content
Open
Show file tree
Hide file tree
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
40 changes: 40 additions & 0 deletions CPUModel.Using.CSharp.Rec/Commands/ForCommand.cs
Original file line number Diff line number Diff line change
@@ -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<ICommand> 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<ICommand>()).Compile().Count() - 3;
Copy link
Owner

Choose a reason for hiding this comment

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

It's quite complex logic and you are duplicating it.
Let's reuse code from WhileCommand

realBody[^2] = new PutConstantToRegisterCommand(0, -ifCommandsCount);


return _preCondition
.Concat(new IfCommand(
_condition,
realBody,
Array.Empty<ICommand>()).Compile());
}
}
35 changes: 35 additions & 0 deletions CPUModel.Using.CSharp.Rec/Commands/IfCommand.cs
Original file line number Diff line number Diff line change
@@ -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<ICommand> 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;
}
}
17 changes: 17 additions & 0 deletions CPUModel.Using.CSharp.Rec/Commands/IncrementCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class IncrementCommand
{
private readonly string _address;

public IncrementCommand(string address)
{
_address = address;
}

public IEnumerable<ICommand> Compile()
{
yield return new ReadCommand(_address, 0);
yield return new PutConstantToRegisterCommand(1, 1);
yield return new AddCommand(0);
yield return new WriteCommand(_address, 0);
}
}
16 changes: 16 additions & 0 deletions CPUModel.Using.CSharp.Rec/Commands/WhileCommand.cs
Original file line number Diff line number Diff line change
@@ -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<ICommand> Compile()
{
return new ForCommand(Array.Empty<ICommand>(), _condition, Array.Empty<ICommand>(), _body).Compile();
}
}
97 changes: 11 additions & 86 deletions CPUModel.Using.CSharp.Rec/Program.cs
Original file line number Diff line number Diff line change
@@ -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++;
Expand All @@ -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;)
{
Expand All @@ -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<ICommand> Compile()
{
var realBody = _body.Concat(new ICommand[]
{
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 IncrementCommand
{
private readonly string _address;

public IncrementCommand(string address)
{
_address = address;
}

public IEnumerable<ICommand> 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<ICommand> 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;
}
}
Console.ReadLine();