public void For() { VirtualMachine vm = new VirtualMachine(); List <byte> data = new InstructionsBuilder() .Main() .ReturnSignature(1) .Body(b => { //set literal to 0 so we have a start value to add b.Literal(0); b.For() .NumberOfLoops(5) //loop 5 times .Body(fb => { //add 2 to the previous number fb.Add() .Right(2); }); b.Return(); }) .ToInstructions(); //confirm that five adds happened: 0 + 2 + 2 + 2 + 2 + 2 var results = vm.Interpret(data); Assert.AreEqual(10, results[0]); }
public void IfFalse() { VirtualMachine vm = new VirtualMachine(); List <byte> data = new InstructionsBuilder() .Main() .ReturnSignature(1) .Body(b => { b.If() .Condition(false) .Body(ib => { //return 7 ib.Literal(7); ib.Return(); }); //return 3 b.Literal(3); b.Return(); }) .ToInstructions(); //confirm 3 var results = vm.Interpret(data); Assert.AreEqual(3, results[0]); }
public void CustomFunction() { VirtualMachine vm = new VirtualMachine(); vm.CustomFunctions = new Action <VirtualMachine>[] { _customFunction1 }; List <byte> data = new InstructionsBuilder() .Main() .ReturnSignature(1) .Body(b => { //set literal to 1 so we can use it in customFunction_0 b.Literal(1); b.CustomFunction() .Id(0); b.Return(); }) .ToInstructions(); var results = vm.Interpret(data); //confirm 1 + 2 Assert.AreEqual(3, results[0]); }
public void NestedIfBothTrue() { VirtualMachine vm = new VirtualMachine(); List <byte> data = new InstructionsBuilder() .Main() .ReturnSignature(1) .Body(b => { b.If() .Condition(true) .Body(outterIf => { outterIf.If() .Condition(true) .Body(innerIf => { //return 7 innerIf.Literal(7); innerIf.Return(); }); }); }) .ToInstructions(); //confirm 7 var results = vm.Interpret(data); Assert.AreEqual(7, results[0]); }
public void CreateAndSet() { VirtualMachine vm = new VirtualMachine(); byte varId = 0; List <byte> data = new InstructionsBuilder() .Main() .ReturnSignature(1) .Body(b => { //define var_0 of type_1 b.DefVar() .Id(varId) .Type(1); //set var_0 to = 1 b.SetVar() .Id(varId) .Value(1); //get var_0 b.GetVar() .Id(varId); b.Return(); }) .ToInstructions(); var results = vm.Interpret(data); Assert.AreEqual(1, results.Length); Assert.AreEqual(1, results[0]); }
private static IEnumerable <IInstruction> GetIfStatementInstructions(this IfStatement ifStatement) { return(InstructionsBuilder.BuildIf(ifStatement.ConditionExpression.GetInstructions(), ifStatement.TrueCaseBlockStatement.GetInstructions(), ifStatement.FasleCaseBlockStatement != null ? ifStatement.FasleCaseBlockStatement.GetInstructions() : new List <IInstruction>())); }
private static IEnumerable <IInstruction> GetForStatementInstructions(this ForStatement forStatement) { return(InstructionsBuilder.BuildFor( forStatement.InitializationStatement?.GetInstructions() ?? Enumerable.Empty <IInstruction>(), forStatement.BlockOrSingleStatement.GetInstructions(), forStatement.ConditionExpression?.GetInstructions() ?? Enumerable.Empty <IInstruction>(), forStatement.IterationStatement?.GetInstructions() ?? Enumerable.Empty <IInstruction>())); }
public void FunctionWithNoReturn() { VirtualMachine vm = new VirtualMachine(); byte varId = 0; byte functionId = 1; List <byte> data = new InstructionsBuilder() .Main() .ReturnSignature(1) .Body(b => { //define var_0 of type_1 b.DefVar() .Id(varId) .Type(1); b.DefFunction() .Id(functionId) .Body(fb => { //get var fb.GetVar() .Id(varId); //add 1 fb.Add() .Right(1); //save var_0 fb.SetVar() .Id(varId); }); //run function_1 three times b.For() .NumberOfLoops(3) .Body(fb => { fb.Function() .Id(functionId); }); //return var_0 b.GetVar() .Id(varId); b.Return(); }) .ToInstructions(); var results = vm.Interpret(data); //confirm var_0 is 3 Assert.AreEqual(3, results[0]); }
public void FunctionWithReturn() { VirtualMachine vm = new VirtualMachine(); byte functionId = 1; List <byte> data = new InstructionsBuilder() .Main() .ReturnSignature(1) .Body(b => { b.DefFunction() .Id(functionId) .ReturnSignature(1) .Body(fb => { fb.Add() .Right(1); fb.Return(); }); //set literal to 0 as a starting point for addition b.Literal(0); //run function_1 three times b.For() .NumberOfLoops(3) .Body(fb => { fb.Function() .Id(functionId); }); b.Return(); }) .ToInstructions(); var results = vm.Interpret(data); //confirm that result is 3 Assert.AreEqual(3, results[0]); }
public void CreateAndSet() { VirtualMachine vm = new VirtualMachine(); List <byte> data = new InstructionsBuilder() .Main() .ReturnSignature(2, true) .Body(b => { byte typeId = 2; byte arrayId = 0; b.DefType() .Id(typeId) .NumberOfFields(2); b.DefArray() .Type(typeId) .Id(arrayId) .Length(1); b.SetArrayValueAtIndex() .Value(2) .Value(3) .Id(arrayId) .Index(0); b.GetArray() .Id(arrayId); b.Return(); }) .ToInstructions(); var results = vm.Interpret(data); Assert.AreEqual(2, results.Length); Assert.AreEqual(3, results[0]); Assert.AreEqual(2, results[1]); }
public void GreaterThan() { VirtualMachine vm = new VirtualMachine(); List <byte> data = new InstructionsBuilder() .Main() .ReturnSignature(1) .Body(b => { b.EqualTo() .Left(2) .Right(1); b.Return(); }) .ToInstructions(); var results = vm.Interpret(data); //confirm false Assert.AreEqual(0, results[0]); }
public void NestedFor() { VirtualMachine vm = new VirtualMachine(); List <byte> data = new InstructionsBuilder() .Main() .ReturnSignature(1) .Body(b => { //set literal to 0 so we have a start value to add b.Literal(0); b.For() .NumberOfLoops(2) //loop 2 times .Body(outterLoop => { //add 5 to the previous number outterLoop.Add() .Right(5); outterLoop.For() .NumberOfLoops(10) //loop 10 times .Body(innerLoop => { //add 3 to the previous number innerLoop.Add() .Right(3); }); }); b.Return(); }) .ToInstructions(); //confirm [(5) + (30)] + [(5) + (30)] var results = vm.Interpret(data); Assert.AreEqual(70, results[0]); }
public void Multiplication() { VirtualMachine vm = new VirtualMachine(); List <byte> data = new InstructionsBuilder() .Main() .ReturnSignature(1) .Body(b => { b.Multiply() .Left(5) .Right(3); b.Return(); }) .ToInstructions(); var results = vm.Interpret(data); //confirm 5 * 3 Assert.AreEqual(15, results[0]); }
public void Division() { VirtualMachine vm = new VirtualMachine(); List <byte> data = new InstructionsBuilder() .Main() .ReturnSignature(1) .Body(b => { b.Divide() .Left(6) .Right(2); b.Return(); }) .ToInstructions(); var results = vm.Interpret(data); //confirm 6/2 Assert.AreEqual(3, results[0]); }
public void Addition() { VirtualMachine vm = new VirtualMachine(); List <byte> data = new InstructionsBuilder() .Main() .ReturnSignature(1) .Body(b => { b.Add() .Left(3) .Right(5); b.Return(); }) .ToInstructions(); var fluentResults = vm.Interpret(data); var results = vm.Interpret(data); //confirm 3 + 5 Assert.AreEqual(8, results[0]); }
private static IEnumerable <IInstruction> GetWhileStatementInstructions(this WhileStatement whileStatement) { return(InstructionsBuilder.BuildWhile(whileStatement.ConditionExpression.GetInstructions(), whileStatement.BlockOrSingleStatement.GetInstructions())); }
private static IEnumerable <IInstruction> GetExpressionInstructions(this Expression expression) { List <IInstruction> instructions = new List <IInstruction>(); //instructions.AddRange(expression.Left.GetInstructions()); //if (expression.Right != null) // instructions.AddRange(expression.Right.GetInstructions()); switch (expression.ExpressionType) { case Tree.Nodes.Enums.ExpressionType.Add: instructions.AddRange( GetArithmethicsInstuction( expression.Left.GetInstructions(), expression.Right.GetInstructions(), GetAddInstruction(expression.Left.ReturnType))); break; case Tree.Nodes.Enums.ExpressionType.Sub: instructions.AddRange( GetArithmethicsInstuction( expression.Left.GetInstructions(), expression.Right.GetInstructions(), GetSubInstruction(expression.Left.ReturnType))); break; case Tree.Nodes.Enums.ExpressionType.Mul: instructions.AddRange( GetArithmethicsInstuction( expression.Left.GetInstructions(), expression.Right.GetInstructions(), GetMulInstruction(expression.Left.ReturnType))); break; case Tree.Nodes.Enums.ExpressionType.Div: instructions.AddRange( GetArithmethicsInstuction( expression.Left.GetInstructions(), expression.Right.GetInstructions(), GetDivInstruction(expression.Left.ReturnType))); break; case Tree.Nodes.Enums.ExpressionType.Equal: instructions.AddRange(InstructionsBuilder.BuildCompareInstrution(expression.Left.GetInstructions(), expression.Right.GetInstructions(), If_icmpeqInstruction)); break; case Tree.Nodes.Enums.ExpressionType.Greater: instructions.AddRange(InstructionsBuilder.BuildCompareInstrution(expression.Left.GetInstructions(), expression.Right.GetInstructions(), If_icmpgtInstruction)); break; case Tree.Nodes.Enums.ExpressionType.EqualOrGreater: instructions.AddRange(InstructionsBuilder.BuildCompareInstrution(expression.Left.GetInstructions(), expression.Right.GetInstructions(), If_icmpgeInstruction)); break; case Tree.Nodes.Enums.ExpressionType.Less: instructions.AddRange(InstructionsBuilder.BuildCompareInstrution(expression.Left.GetInstructions(), expression.Right.GetInstructions(), If_icmpltInstruction)); break; case Tree.Nodes.Enums.ExpressionType.EqualOrLess: instructions.AddRange(InstructionsBuilder.BuildCompareInstrution(expression.Left.GetInstructions(), expression.Right.GetInstructions(), If_icmpleInstruction)); break; case Tree.Nodes.Enums.ExpressionType.NotEqual: instructions.AddRange(InstructionsBuilder.BuildCompareInstrution(expression.Left.GetInstructions(), expression.Right.GetInstructions(), If_icmpneInstruction)); break; case Tree.Nodes.Enums.ExpressionType.Not: return(InstructionsBuilder.BuildLogicalNot(expression.Left.GetInstructions())); case Tree.Nodes.Enums.ExpressionType.Or: return(InstructionsBuilder.BuildLogicalOr(expression.Left.GetInstructions(), expression.Right.GetInstructions())); case Tree.Nodes.Enums.ExpressionType.And: return(InstructionsBuilder.BuildLogicalAnd(expression.Left.GetInstructions(), expression.Right.GetInstructions())); //case Tree.Nodes.Enums.ExpressionType.FunctionCall: // break; //case Tree.Nodes.Enums.ExpressionType.VariableDeclaration: // break; //case Tree.Nodes.Enums.ExpressionType.VariableReference: // break; case Tree.Nodes.Enums.ExpressionType.ArrayElementReference: break; default: throw new NotImplementedException($"Expression code generation: {expression}"); } return(instructions); }