Home

Awesome

Algorithm Simulator

This is a prototype of a portable algorithm interpreter based on the architecture of SoftwareZator.

What Is The Concept

The concept is to be able to simulate and debug an algorithm by using C# at runtime. For a bigger challenge, we want to be able to use it in a cross-platform project.

It means several things :

Remark : the code is not very complicated, but the project architecture is complex because it uses a LOT of abstraction.

Use Case

Features

FeaturesSupported
start the algorithm interpreteryes
stop the algorithm interpreter (even in an infinite loop)yes
pause the algorithm interpreteryes
debug modeyes
[debug mode] step overyes
[debug mode] step intoyes
[debug mode] step outyes
[debug mode] breakpointyes
variableyes
arrayyes
classyes
class propertiesyes
methodyes
recursivityyes
loop (while/do while)yes
call a methodyes
use feature from .Net/WinRTyes
detect when a user call too many methods in the same thread (aka. stack overflow)yes
async functionsyes
keep a call stack with info on variables valuesyes
try catchno
interaction with the UIno
inheritance with classesno
idle the programno
programming language parserno

Performances

Performances are not comparable with a JavaScript runtime or a compiled language like C++. The reason is that this interpreter is made in C# and it's designed to be maintenable, more than fast. It also use a lot of RAM.

ScenariosExecution time (in millisec)
a loop with 100 iterations17.5 at first run, 6.6 at second run

The first time you run the interpreter, in particular when you start to run it, performances can be much slower than the second time you run the same program. The reason is that the interpreter put in cache some data used to optimize the execution speed of the binary operator.

How Does It Work

  1. First of all, we create a Program that represents a program with classes and methods.
  2. We add our global variables (it is simpler to manage in the algorithm interpreter).
  3. In a method, we add an algorithm. This algorithm is represented by an action. An action, in SoftwareZator, as in this algorithm interpreter, it is a part of an algorithm that does something. For example :
  1. And then, we start the Simulator.

What Does The Simulator

  1. The first step is to create a dictionary that contains a definition of each variable in the project and their associated values.
  2. Then, we start to simulate/interpret each Action of the algorithm :

Sample

The following algorithm :

PROGRAM MyApp

    CLASS FirstClass

        FUNCTION Main()
            RETURN FirstMethod(10)
        END FUNCTION

        FUNCTION FirstMethod(num)
            IF (num > 1)
                RETURN FirstMethod(num - 1)
            RETURN num
        END FUNCTION

    END CLASS

END PROGRAM

Can be translated and interpreted by the algorithm interpreter like this in C# :

var program = new AlgorithmProgram("MyApp");
var firstClass = new AlgorithmClassDeclaration("FirstClass");

var entryPoint = new AlgorithmEntryPointMethod(); // FUNCTION Main()
entryPoint.Statements.Add(new AlgorithmReturnStatement(new AlgorithmInvokeMethodExpression(new AlgorithmThisReferenceExpression(), "FirstMethod", new AlgorithmPrimitiveExpression(10)))); // RETURN FirstMethod(10)
firstClass.Members.Add(entryPoint);
    
var firstMethod = new AlgorithmClassMethodDeclaration("FirstMethod", false);
firstMethod.Arguments.Add(new AlgorithmParameterDeclaration("num")); // FUNCTION FirstMethod(num)

var argument = new AlgorithmBinaryOperatorExpression(new AlgorithmVariableReferenceExpression("num"), AlgorithmBinaryOperatorType.Subtraction, new AlgorithmPrimitiveExpression(1)); // num - 1

var returnStatement = new AlgorithmReturnStatement(new AlgorithmInvokeMethodExpression(new AlgorithmThisReferenceExpression(), "FirstMethod", argument)); // RETURN FirstMethod(num - 1)

var condition = new AlgorithmBinaryOperatorExpression(new AlgorithmVariableReferenceExpression("num"), AlgorithmBinaryOperatorType.GreaterThan, new AlgorithmPrimitiveExpression(1));
firstMethod.Statements.Add(new AlgorithmConditionStatement(condition, new AlgorithmStatementCollection() { returnStatement }, null)); // IF (num > 1)
firstMethod.Statements.Add(new AlgorithmReturnStatement(new AlgorithmVariableReferenceExpression("num"))); // RETURN num

firstClass.Members.Add(firstMethod);

program.Classes.Add(firstClass);
program.UpdateEntryPointPath();

var algorithmInterpreter = new AlgorithmInterpreter(program);

var task = algorithmInterpreter.StartAsync(debugMode: true);

task.Wait();

Change log

Check the change log here