public void IfElseIfElseStatement()
        {
            var source   = @"
if(x > 5) {
  more = 1;
} else if(x < 5) {
  less = 1;
} else {
  equal = 1;
}";
            var code     = CreateCode(source);
            var expected = @"
IF x > 5 JUMP #0
IF x < 5 JUMP #1
equal = 1
JUMP #2
LABEL #1
less = 1
LABEL #2
JUMP #3
LABEL #0
more = 1
LABEL #3";

            Assert.AreEqual(11, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
        public void AllowsLongChainOfReadOnlyFields()
        {
            var source        = @"
class Test {
  private static readonly C c = new C();

  public void Run() {
    var v = Test.c.Value.Value.Value;
  }
}

class A {
  public readonly int Value;
}

class B {
  public readonly A Value;
}

class C {
  public readonly B Value;
}";
            var semanticModel = DocumentFactory.Create().CreateSemanticModel(source);
            var method        = semanticModel.SyntaxTree.GetRoot().DescendantNodes()
                                .OfType <MethodDeclarationSyntax>()
                                .Single();


            var code     = CodeFactory.Create(method.Body, semanticModel);
            var expected = @"
DECL v
v = \literal";

            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
        public void ForStatementWithoutConditionButConditionalBreak()
        {
            var source   = @"
for(var i = 0; ; ++i) {
  if(i > 3) {
    break;
  }
}";
            var code     = CreateCode(source);
            var expected = @"
DECL i
i = 0
LABEL #0
JUMP #1
JUMP #2
LABEL #1
IF i > 3 JUMP #3
JUMP #4
LABEL #3
JUMP #2
LABEL #4
LABEL #5
i = i + 1
JUMP #0
LABEL #2";

            Assert.AreEqual(15, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
        public void NestedForStatement()
        {
            var source   = @"
for(int i = 0; i < 100; i++) {
  for(var j = 0; j < 100; j += 5) {
    x = x + 0;
  }
}";
            var code     = CreateCode(source);
            var expected = @"
DECL i
i = 0
LABEL #0
IF i < 100 JUMP #1
JUMP #2
LABEL #1
DECL j
j = 0
LABEL #3
IF j < 100 JUMP #4
JUMP #5
LABEL #4
x = x + 0
LABEL #6
j = j + 5
JUMP #3
LABEL #5
LABEL #7
i = i + 1
JUMP #0
LABEL #2";

            Assert.AreEqual(21, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
        public void ForStatementWithContinue()
        {
            var source   = @"
for(var i = 0; i < 10; ++i) {
  if(i%4 == 0) {
    continue;
  }
  var x = 0;
}";
            var code     = CreateCode(source);
            var expected = @"
DECL i
i = 0
LABEL #0
IF i < 10 JUMP #1
JUMP #2
LABEL #1
IF i % 4 == 0 JUMP #3
JUMP #4
LABEL #3
JUMP #5
LABEL #4
DECL x
x = 0
LABEL #5
i = i + 1
JUMP #0
LABEL #2";

            Assert.AreEqual(17, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
        public void DoStatementWithBreak()
        {
            var source   = @"
do {
  x = 5;
  if(i > 0) {
    break;
  }
  i += 1;
} while(i < 100);";
            var code     = CreateCode(source);
            var expected = @"
LABEL #0
x = 5
IF i > 0 JUMP #1
JUMP #2
LABEL #1
JUMP #3
LABEL #2
i = i + 1
LABEL #4
IF i < 100 JUMP #0
LABEL #3";

            Assert.AreEqual(11, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
示例#7
0
        public void NestedConditionalExpressions()
        {
            var source   = @"var x = a > 0 ? 1 : (a < 0 ? 1 : 0);";
            var code     = _CreateCode(source);
            var expected = @"
DECL x
DECL $temp_0
IF a > 0 JUMP #0
DECL $temp_1
IF a < 0 JUMP #1
$temp_1 = 0
JUMP #2
LABEL #1
$temp_1 = 1
LABEL #2
$temp_0 = $temp_1
JUMP #3
LABEL #0
$temp_0 = 1
LABEL #3
x = $temp_0";

            Assert.AreEqual(16, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
示例#8
0
        public void WhileStatementWithContinue()
        {
            var source   = @"
while(i < 100) {
  if(i%2 == 0) {
    continue;
  }
}";
            var code     = CreateCode(source);
            var expected = @"
LABEL #0
IF i < 100 JUMP #1
JUMP #2
LABEL #1
IF i % 2 == 0 JUMP #3
JUMP #4
LABEL #3
JUMP #0
LABEL #4
JUMP #0
LABEL #2";

            Assert.AreEqual(11, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
示例#9
0
        public void MethodWithReturnValueAndBranchedReturnStatement()
        {
            var source   = @"
int Method1(int x) {
  if(x > 0) {
    return 0;
  }
  return x;
}";
            var code     = CreateCode(source, "Method1");
            var expected = @"
DECL x
x = $arg_Method1_0
DECL $result_Method1
IF x > 0 JUMP #0
JUMP #1
LABEL #0
$result_Method1 = 0
JUMP #2
LABEL #1
$result_Method1 = x
JUMP #2
LABEL #2";

            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
示例#10
0
        public void NestedWhileStatement()
        {
            var source   = @"
while(i < 100) {
  while(j < 100) {
    j = j + 1;
  }
  i = i + 1;
}";
            var code     = CreateCode(source);
            var expected = @"
LABEL #0
IF i < 100 JUMP #1
JUMP #2
LABEL #1
LABEL #3
IF j < 100 JUMP #4
JUMP #5
LABEL #4
j = j + 1
JUMP #3
LABEL #5
i = i + 1
JUMP #0
LABEL #2";

            Assert.AreEqual(14, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
        public void NestedDoStatement()
        {
            var source   = @"
do {
  do {
    j = j + 1;
  } while(j < 100);
  i = i + 1;
} while(i < 100);";
            var code     = CreateCode(source);
            var expected = @"
LABEL #0
LABEL #1
j = j + 1
LABEL #2
IF j < 100 JUMP #1
LABEL #3
i = i + 1
LABEL #4
IF i < 100 JUMP #0
LABEL #5";

            Assert.AreEqual(10, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
        public void DoStatementWithContinue()
        {
            var source   = @"
do {
  x = 4;
  if(i != 5) {
    continue;
  }
  x = 5;
} while(i < 100);";
            var code     = CreateCode(source);
            var expected = @"
LABEL #0
x = 4
IF i != 5 JUMP #1
JUMP #2
LABEL #1
JUMP #3
LABEL #2
x = 5
LABEL #3
IF i < 100 JUMP #0
LABEL #4";

            Assert.AreEqual(11, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
        public void NestedIfElseStatement()
        {
            var source   = @"
if(1 == 5) {
  if(1 == 1) {
    x = 0;
  } else {
    y = 2;
  }
} else {
  x = 5;
}";
            var code     = CreateCode(source);
            var expected = @"
IF 1 == 5 JUMP #0
x = 5
JUMP #1
LABEL #0
IF 1 == 1 JUMP #2
y = 2
JUMP #3
LABEL #2
x = 0
LABEL #3
LABEL #1";

            Assert.AreEqual(11, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
示例#14
0
        public void AssignmentsAndDeclarationsWithMultipleNestings()
        {
            var source   = @"
var x = 0;
var y = 10;
x = y;

y = (5 + x) * y + x * y / y";
            var code     = _CreateCode(source);
            var expected = @"
DECL x
x = 0
DECL y
y = 10
x = y
DECL $temp_0
$temp_0 = 5 + x
DECL $temp_1
$temp_1 = $temp_0 * y
DECL $temp_2
$temp_2 = x * y
DECL $temp_3
$temp_3 = $temp_2 / y
y = $temp_1 + $temp_3";

            Assert.AreEqual(14, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
示例#15
0
        public void MethodWithoutParametersAndEmptyBody()
        {
            var source = @"void Test() {}";
            var code   = CreateCode(source, "Test");

            Assert.AreEqual(1, code.Root.Count);
            Assert.AreEqual("LABEL #0", CodeStringifier.Generate(code));
        }
示例#16
0
        public void WriteAccessToArrayWithVariableIndex()
        {
            var source   = @"shared[x] = 1;";
            var code     = _CreateCode(source);
            var expected = @"shared[x] = 1";

            Assert.AreEqual(1, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
        public void DirectInvocationWithArguments()
        {
            var source   = @"Method(1 + 1, a, x, 4 * b);";
            var code     = CreateCode(source);
            var expected = @"INVOKE Method(1 + 1, a, x, 4 * b)";

            Assert.AreEqual(1, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
        public void SingleDeclarationWithoutInitializer()
        {
            var source   = @"int variable;";
            var code     = CreateCode(source);
            var expected = @"DECL variable";

            Assert.AreEqual(1, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
        public void SingleAssignment()
        {
            var source   = @"variable = 2;";
            var code     = CreateCode(source);
            var expected = @"variable = 2";

            Assert.AreEqual(1, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
        public void EmptyBlock()
        {
            var source   = @"";
            var code     = CreateCode(source);
            var expected = @"";

            Assert.AreEqual(0, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
示例#21
0
        public void NegativeVariableAssignment()
        {
            var source   = @"x = -y;";
            var code     = _CreateCode(source);
            var expected = @"x = -y";

            Assert.AreEqual(1, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
        public void DeclarationWithBooleanConstant()
        {
            var source   = @"var variable = true;";
            var code     = CreateCode(source);
            var expected = @"
DECL variable
variable = \literal";

            Assert.AreEqual(2, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
        public void InvocationNestedInAssignment()
        {
            var source   = @"var result = First(x) + Second(1, 2);";
            var code     = CreateCode(source);
            var expected = @"
DECL result
result = First(x) + Second(1, 2)";

            Assert.AreEqual(2, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
        public void SingleDeclaration()
        {
            var source   = @"var variable = 1;";
            var code     = CreateCode(source);
            var expected = @"
DECL variable
variable = 1";

            Assert.AreEqual(2, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
示例#25
0
        public void MethodWithExpressionBodyWithoutArguments()
        {
            var source   = @"int Method1() => 5;";
            var code     = CreateCode(source, "Method1");
            var expected = @"
DECL $result_Method1
$result_Method1 = 5
LABEL #0";

            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
        public void DeclarationWithConditionalExpression()
        {
            var source   = @"var variable = a > 0 ? a : 0;";
            var code     = CreateCode(source);
            var expected = @"
DECL variable
variable = a > 0 ? a : 0";

            Assert.AreEqual(2, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
示例#27
0
        public void DeclarationWithConstantBinaryExpression()
        {
            var source   = @"var x = 5 * 4";
            var code     = _CreateCode(source);
            var expected = @"
DECL x
x = 5 * 4";

            Assert.AreEqual(2, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
示例#28
0
        public void NegativeConstantDeclaration()
        {
            var source   = @"var x = -10;";
            var code     = _CreateCode(source);
            var expected = @"
DECL x
x = -10";

            Assert.AreEqual(2, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
示例#29
0
        public void WriteAccessToArrayWithExpressionIndex()
        {
            var source   = @"shared[x + 1] = 1;";
            var code     = _CreateCode(source);
            var expected = @"
DECL $temp_0
$temp_0 = x + 1
shared[$temp_0] = 1";

            Assert.AreEqual(3, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }
示例#30
0
        public void DirectMethodInvocationWithAddExpressionAsArgument()
        {
            var source   = @"Method(1 + 3);";
            var code     = _CreateCode(source);
            var expected = @"
DECL $temp_0
$temp_0 = 1 + 3
INVOKE Method($temp_0)";

            Assert.AreEqual(3, InstructionCounter.Count(code));
            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code));
        }