Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
maxattack committed Jul 30, 2011
0 parents commit 40b87c1
Show file tree
Hide file tree
Showing 8 changed files with 498 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
bin
*.pidb
*.userprefs
142 changes: 142 additions & 0 deletions Lang/Expression.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// ROBOLOGO
// Copyright (C) 2011 [email protected]
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

using System;
namespace RoboLogo.Lang {

/// <summary>
/// Interface for all instructions. Conditional expressions are treated as expr!=0 numeric expressions
/// </summary>
public abstract class Expression {
public abstract int Compute(Interpreter interp);
}

/// <summary>
/// Implemented Binary Operations
/// </summary>
public enum BinaryOperation { Add, Subtract, Multiply, Divide, And, Or, Equals, GreaterThan, LessThan }

/// <summary>
/// Implemented Unary Operations
/// </summary>
public enum UnaryOperation { Negate, Complement }

/// <summary>
/// Null expression just returns 0
/// </summary>
public class NullExpression : Expression {
override public int Compute(Interpreter interp) {
return 0;
}
}

/// <summary>
/// A literal expression evaluates to a constant
/// </summary>
public class LiteralExpression : Expression {
int mValue;

public LiteralExpression(int val) {
mValue = val;
}

override public int Compute(Interpreter interp) {
return mValue;
}
}

/// <summary>
/// A variable expression looks up a value in the current executing context
/// </summary>
public class VariableExpression : Expression {
string mName;

public VariableExpression(string name) {
mName = name;
}

override public int Compute(Interpreter interp) {
int result;
if (!interp.GetVariable(mName, out result)) {
Console.WriteLine("Undefined Variable Expression");
}
return result;
}
}

/// <summary>
/// Implementation of all binary operations
/// </summary>
public class BinaryOperationExpression : Expression {
BinaryOperation mOp;
Expression mLeft;
Expression mRight;

public BinaryOperationExpression(BinaryOperation op, Expression left, Expression right) {
mOp = op;
mLeft = left;
mRight = right;

}

override public int Compute(Interpreter interp) {
switch(mOp) {
case BinaryOperation.Add: return mLeft.Compute(interp) + mRight.Compute(interp);
case BinaryOperation.Subtract: return mLeft.Compute(interp) - mRight.Compute(interp);
case BinaryOperation.Multiply: return mLeft.Compute(interp) * mRight.Compute(interp);
case BinaryOperation.Divide:
int r = mRight.Compute(interp);
if (r == 0) {
Console.WriteLine("Divide By Zero");
return 0;
} else {
return mLeft.Compute(interp) / r;
}
case BinaryOperation.And: return (mLeft.Compute(interp) != 0) && (mRight.Compute(interp) != 0) ? 1 : 0;
case BinaryOperation.Or: return (mLeft.Compute(interp) != 0) || (mRight.Compute(interp) != 0) ? 1 : 0;
case BinaryOperation.Equals: return mLeft.Compute(interp) == mRight.Compute(interp) ? 1 : 0;
case BinaryOperation.GreaterThan: return mLeft.Compute(interp) > mRight.Compute(interp) ? 1 : 0;
case BinaryOperation.LessThan: return mLeft.Compute(interp) < mRight.Compute(interp) ? 1 : 0;
default: return 0;
}
}
}

/// <summary>
/// Implementation of all unary operations
/// </summary>
public class UnaryOperationExpression : Expression {
UnaryOperation mOp;
Expression mExpr;

public UnaryOperationExpression(UnaryOperation op, Expression exp) {
mOp = op;
mExpr = exp;
}

override public int Compute(Interpreter interp) {
switch(mOp) {
case UnaryOperation.Negate: return -mExpr.Compute(interp);
case UnaryOperation.Complement: return mExpr.Compute(interp) != 0 ? 0 : 1;
default: return 0;
}
}
}



}

97 changes: 97 additions & 0 deletions Lang/Instruction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// ROBOLOGO
// Copyright (C) 2011 [email protected]
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

using System;

namespace RoboLogo.Lang {

/// <summary>
/// Interface for all instructions.
/// </summary>
public abstract class Instruction {
public abstract void Execute(Interpreter interp);
}

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

public GotoInstruction(int index) {
mIndex = index;
}

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

/// <summary>
/// Implementation of a set-global variable instruction
/// </summary>
public class SetInstruction : Instruction {
string mName;
Expression mExpr;

public SetInstruction(string name, Expression exp) {
mName = name;
mExpr = exp;
}

override public void Execute(Interpreter interp) {
interp.SetVariable(mName, mExpr.Compute(interp));
}
}

/// <summary>
/// Implemention of a branch instruciton, used to implement conditionals and loops
/// </summary>
public class BranchInstruction : Instruction {
Expression mCondition;
int mTrueIndex;
int mFalseIndex;

public BranchInstruction(Expression condition, int trueIndex, int falseIndex) {
mCondition = condition;
mTrueIndex = trueIndex;
mFalseIndex = falseIndex;
}

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

/// <summary>
/// Implementation of a custom action instruction, for binding to user-space C# code
/// </summary>
public class ActionInstruction : Instruction {
Action<int> mAction;
Expression mExpr;

public ActionInstruction(Action<int> action, Expression exp) {
mAction = action;
mExpr = exp;
}

override public void Execute(Interpreter interp) {
mAction(mExpr.Compute(interp));
}
}

}

70 changes: 70 additions & 0 deletions Lang/Interpreter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// ROBOLOGO
// Copyright (C) 2011 [email protected]
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;

namespace RoboLogo.Lang {

/// <summary>
/// The interpreter is the facade-class for the virtual machine. It maintains an instruciton buffer,
/// an instruction pointer, and a dictionary of global variables.
/// </summary>

public class Interpreter {
Instruction[] mInstructions;
int mCurrentInstruction;
int mNextInstruction;
Dictionary<string, int> mEnvironment = new Dictionary<string, int>();

public Interpreter (Instruction[] instructions) {
mInstructions = instructions;
mCurrentInstruction = 0;
}

public bool ExecuteNextInstruction() {
if (mCurrentInstruction >= mInstructions.Length) { return false; }
mNextInstruction = mCurrentInstruction + 1;
mInstructions[mCurrentInstruction].Execute(this);
mCurrentInstruction = mNextInstruction;
return true;
}

internal void Goto(int n) {
mNextInstruction = n;
}

internal void SetVariable(string name, int val) {
if (!mEnvironment.ContainsKey(name)) {
mEnvironment.Add(name, val);
} else {
mEnvironment[name] = val;
}
}

internal bool GetVariable(string name, out int val) {
if (!mEnvironment.ContainsKey(name)) {
val = 0;
return false;
} else {
val = mEnvironment[name];
return true;
}
}
}

}

Loading

0 comments on commit 40b87c1

Please sign in to comment.