Skip to content

Commit

Permalink
omg loops
Browse files Browse the repository at this point in the history
  • Loading branch information
maxattack committed Aug 2, 2011
1 parent 1b1af83 commit ba9c300
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 25 deletions.
20 changes: 20 additions & 0 deletions Lang/Block.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
namespace RoboLogo.Lang {

public class Block {
public int instructionIndex;

public Block(int index) {
instructionIndex = index;
}
}

public class WhileBlock : Block {
public BranchInstruction branch;

public WhileBlock(BranchInstruction branch, int index) : base(index) {
this.branch = branch;
}
}
}

28 changes: 14 additions & 14 deletions Lang/Instruction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ public abstract class Instruction {
}

/// <summary>
/// Implementation of a goto instruction
/// Implementation of a jump instruction
/// </summary>
public class GotoInstruction : Instruction {
int mIndex;
public class JumpInstruction : Instruction {
public int index;

public GotoInstruction(int index) {
mIndex = index;
public JumpInstruction(int index) {
this.index = index;
}

override public void Execute(Interpreter interp) {
interp.Goto(mIndex);
interp.Goto(index);
}
}

Expand All @@ -61,18 +61,18 @@ override public void Execute(Interpreter interp) {
/// Implemention of a branch instruciton, used to implement conditionals and loops
/// </summary>
public class BranchInstruction : Instruction {
Expression mCondition;
int mTrueIndex;
int mFalseIndex;
public Expression condition;
public int indexTrue;
public int indexFalse;

public BranchInstruction(Expression condition, int trueIndex, int falseIndex) {
mCondition = condition;
mTrueIndex = trueIndex;
mFalseIndex = falseIndex;
public BranchInstruction(Expression condition, int jumpTrue, int jumpFalse) {
this.condition = condition;
this.indexTrue = jumpTrue;
this.indexFalse = jumpFalse;
}

override public void Execute(Interpreter interp) {
interp.Goto(mCondition.Compute(interp) == 0 ? mFalseIndex : mTrueIndex);
interp.Goto(condition.Compute(interp) == 0 ? indexFalse : indexTrue);
}
}

Expand Down
83 changes: 81 additions & 2 deletions Lang/InstructionParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,20 @@ public class InstructionParser {
public Action<int> turnAction;

enum TokenType { Expression, Keyword }
enum BlockType { WhileLoop }

delegate State State(Token t);

struct Token {
public TokenType type;
public string data;
}

TextReader mReader;
StringBuilder mBuilder = new StringBuilder();
State mState;
List<Instruction> mScratchpad;
Stack<Block> mBlock = new Stack<Block>();
ExpressionParser mExpParser;
static readonly string[] sPalette = { "red", "green", "blue" };

Expand Down Expand Up @@ -57,6 +59,10 @@ public Instruction[] Parse(TextReader reader) {
var result = mScratchpad.ToArray();
mBuilder.Length = 0;
mScratchpad.Clear();
if (mBlock.Count > 0) {
mBlock.Clear();
return null;
}
return result;
}

Expand All @@ -81,8 +87,25 @@ State Idle(Token t) {
case "stop": return SawStop;
case "move": return SawMove;
case "turn": return SawTurn;
default: return null;
case "while": return SawWhile;
case "until": return SawUntil;
case "increment": return SawIncrement;
case "decrement": return SawDecrement;
}
if (t.data == "end") {
if (mBlock.Count == 0) {
return null;
}
var block = mBlock.Pop();
switch(block.GetType().Name) {
case "WhileBlock":
var wb = block as WhileBlock;
mScratchpad.Add(new JumpInstruction(wb.instructionIndex));
wb.branch.indexFalse = mScratchpad.Count;
return Idle;
}
}

}
return null;
}
Expand Down Expand Up @@ -214,7 +237,63 @@ State SawTurn(Token t) {
}
return null;
}

State SawWhile(Token t) {
if (t.type == TokenType.Expression) {
var exp = mExpParser.Parse(t.data);
if (exp == null) { return null; }
StartWhileLoop(exp);
return Idle;
}
return null;
}

State SawUntil(Token t) {
if (t.type == TokenType.Expression) {
var exp = mExpParser.Parse(t.data);
if (exp == null) { return null; }
StartWhileLoop(new UnaryOperationExpression(UnaryOperation.Complement, exp));
return Idle;
}
return null;
}

State SawIncrement(Token t) {
if (t.type == TokenType.Expression) {
var exp = mExpParser.Parse(t.data) as VariableExpression;
if (exp == null) { return null; }
mScratchpad.Add(
new SetInstruction(exp.name, new BinaryOperationExpression(BinaryOperation.Add, exp, new LiteralExpression(1)))
);
return Idle;
}
return null;
}

State SawDecrement(Token t) {
if (t.type == TokenType.Expression) {
var exp = mExpParser.Parse(t.data) as VariableExpression;
if (exp == null) { return null; }
mScratchpad.Add(
new SetInstruction(exp.name, new BinaryOperationExpression(BinaryOperation.Add, exp, new LiteralExpression(-1)))
);
return Idle;
}
return null;
}

//---------------------------------------------------------------------
// HELPERS
//---------------------------------------------------------------------

void StartWhileLoop(Expression exp) {
int branchIndex = mScratchpad.Count;
var branch = new BranchInstruction(exp, branchIndex+1, -1);
Block b = new WhileBlock(branch, branchIndex);
mScratchpad.Add(branch);
mBlock.Push(b);
}

//---------------------------------------------------------------------
// TOKENIZATION
//---------------------------------------------------------------------
Expand Down
22 changes: 13 additions & 9 deletions Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public static void Main (string[] args) {
set X 0
hello
set X X+1
branch (X<10) 1 4
branch (X<10) 1
"));
*/

Expand All @@ -42,13 +42,17 @@ set X X+1
};
var program = compiler.Parse(@"
X = (10+32)
set color to blue
set thickness to 10
start stroke
move forward X
turn left
move backward 5
stop stroke
LOOP = 0
until (LOOP=3)
set color to blue
set thickness to 10
start stroke
move forward X
turn left
move backward 5
stop stroke
increment LOOP
end
");
var interpreter = new Interpreter(program);
while(interpreter.ExecuteNextInstruction()) {}
Expand All @@ -74,7 +78,7 @@ static Instruction[] StupidCompiler(string src) {
buffer.Add(new ActionInstruction(arg=>Console.WriteLine("Hello, World"), new NullExpression()) );
break;
case "branch":
buffer.Add(new BranchInstruction(parser.Parse(tokens[1]), int.Parse(tokens[2]), int.Parse(tokens[3])) );
buffer.Add(new BranchInstruction(parser.Parse(tokens[1]), int.Parse(tokens[2]), int.Parse(tokens[3])));
break;
}
}
Expand Down
1 change: 1 addition & 0 deletions RoboLogo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<Compile Include="Lang\Expression.cs" />
<Compile Include="Lang\ExpressionParser.cs" />
<Compile Include="Lang\InstructionParser.cs" />
<Compile Include="Lang\Block.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
Expand Down

0 comments on commit ba9c300

Please sign in to comment.