Exemplo n.º 1
0
        public void Bool_non_constant_unary_expression_compiled_successfully(string expressionString, Opcode expectedOp)
        {
            var expressionSyntax = ParseExpression(expressionString);
            var method           = new CompiledMethod("Test::Method");
            var builder          = new BasicBlockGraphBuilder().GetInitialBlockBuilder();
            var diagnostics      = new TestingDiagnosticSink();
            var variableMap      = new ScopedVariableMap();

            variableMap.PushScope();
            variableMap.TryAddVariable("a", method.AddLocal(SimpleType.Bool, LocalFlags.None));

            var localIndex = ExpressionCompiler.TryCompileExpression(expressionSyntax,
                                                                     SimpleType.Bool, method, builder, new TestingResolver(variableMap), diagnostics);

            Assert.That(diagnostics.Diagnostics, Is.Empty);
            Assert.That(localIndex, Is.EqualTo(1));
            Assert.That(method.Values[localIndex].Type, Is.EqualTo(SimpleType.Bool));
            Assert.That(builder.Instructions, Has.Exactly(1).Items);

            var instruction = builder.Instructions[0];

            Assert.That(instruction.Operation, Is.EqualTo(expectedOp));
            Assert.That(instruction.Left, Is.EqualTo(0));
            Assert.That(instruction.Destination, Is.EqualTo(1));
        }
Exemplo n.º 2
0
        public void Pushing_and_popping_very_many_scopes()
        {
            var       map        = new ScopedVariableMap();
            const int scopeCount = 100;

            for (var i = 0; i < scopeCount; i++)
            {
                map.PushScope();
                map.TryAddVariable(i.ToString(), i);
            }
            for (var i = 0; i < scopeCount; i++)
            {
                map.PopScope();
            }

            // Now some of the new scopes should come from the cache
            // Verify that the cached scopes are empty
            for (var i = 0; i < scopeCount; i++)
            {
                map.PushScope();
            }
            for (var i = 0; i < scopeCount; i++)
            {
                Assert.That(map.TryGetVariable(i.ToString(), out _), Is.False);
            }
            for (var i = 0; i < scopeCount; i++)
            {
                map.PopScope();
            }
        }
Exemplo n.º 3
0
        public void Cannot_add_same_name_to_same_scope()
        {
            var map = new ScopedVariableMap();

            map.PushScope();
            Assert.That(map.TryAddVariable("a", 1), Is.True);
            Assert.That(map.TryAddVariable("a", 2), Is.False);
        }
Exemplo n.º 4
0
        public void Cannot_do_operations_if_there_is_no_scope()
        {
            var map = new ScopedVariableMap();

            Assert.That(() => map.TryAddVariable("a", 0), Throws.InvalidOperationException);
            Assert.That(() => map.TryGetVariable("a", out _), Throws.InvalidOperationException);
            Assert.That(() => map.PopScope(), Throws.InvalidOperationException);
        }
Exemplo n.º 5
0
        public void Variable_not_found_in_any_scope()
        {
            var map = new ScopedVariableMap();

            map.PushScope();
            Assert.That(map.TryAddVariable("a", 1), Is.True);
            map.PushScope();
            Assert.That(map.TryAddVariable("b", 2), Is.True);
            Assert.That(map.TryGetVariable("c", out _), Is.False);
        }
Exemplo n.º 6
0
        public void Variable_found_in_outer_scope()
        {
            var map = new ScopedVariableMap();

            map.PushScope();
            Assert.That(map.TryAddVariable("a", 1), Is.True);
            map.PushScope();
            Assert.That(map.TryGetVariable("a", out var index), Is.True);
            Assert.That(index, Is.EqualTo(1));
        }
Exemplo n.º 7
0
        public void Can_add_variable_to_outer_scope_after_defining_in_inner()
        {
            // TODO: This behavior could be changed; for now it is simpler
            var map = new ScopedVariableMap();

            map.PushScope();
            map.PushScope();
            Assert.That(map.TryAddVariable("a", 1), Is.True);
            map.PopScope();
            Assert.That(map.TryAddVariable("a", 2), Is.True);
        }
Exemplo n.º 8
0
        public void Variable_found_in_same_scope()
        {
            var map = new ScopedVariableMap();

            map.PushScope();
            Assert.That(map.TryAddVariable("a", 1), Is.True);
            Assert.That(map.TryAddVariable("b", 17), Is.True);
            Assert.That(map.TryGetVariable("a", out var a), Is.True);
            Assert.That(a, Is.EqualTo(1));
            Assert.That(map.TryGetVariable("b", out var b), Is.True);
            Assert.That(b, Is.EqualTo(17));
        }
Exemplo n.º 9
0
        public void Reset_clears_stack()
        {
            var map = new ScopedVariableMap();

            map.PushScope();
            map.PushScope();
            map.TryAddVariable("a", 1);
            map.PushScope();

            map.Reset();

            Assert.That(() => map.TryGetVariable("a", out _), Throws.InvalidOperationException);
        }
Exemplo n.º 10
0
        public void Variable_visible_in_inner_but_not_outer_scope()
        {
            var map = new ScopedVariableMap();

            map.PushScope();
            Assert.That(map.TryAddVariable("a", 1), Is.True);
            map.PushScope();
            Assert.That(map.TryAddVariable("b", 2), Is.True);

            Assert.That(map.TryGetVariable("b", out var index), Is.True);
            Assert.That(index, Is.EqualTo(2));

            map.PopScope();
            Assert.That(map.TryGetVariable("b", out _), Is.False);
        }
Exemplo n.º 11
0
        public void Variable_reference_must_refer_to_existent_variable()
        {
            var position    = new TextPosition(10, 3, 4);
            var syntax      = new IdentifierSyntax("a", position);
            var method      = new CompiledMethod("Test::Method");
            var builder     = new BasicBlockGraphBuilder().GetInitialBlockBuilder();
            var diagnostics = new TestingDiagnosticSink();
            var variableMap = new ScopedVariableMap();

            variableMap.PushScope();

            var localIndex = ExpressionCompiler.TryCompileExpression(
                syntax, SimpleType.Int32, method, builder, new TestingResolver(variableMap), diagnostics);

            Assert.That(localIndex, Is.EqualTo(-1));
            diagnostics.AssertDiagnosticAt(DiagnosticCode.VariableNotFound, position).WithActual("a");
        }
Exemplo n.º 12
0
        public void Operator_not_defined_for_type_in_non_constant(string expressionString, string operatorName, string typeName)
        {
            var expressionSyntax = ParseExpression(expressionString);
            var method           = new CompiledMethod("Test::Method");
            var builder          = new BasicBlockGraphBuilder().GetInitialBlockBuilder();
            var diagnostics      = new TestingDiagnosticSink();
            var variableMap      = new ScopedVariableMap();

            variableMap.PushScope();
            variableMap.TryAddVariable("b", method.AddLocal(SimpleType.Bool, LocalFlags.None));
            variableMap.TryAddVariable("i", method.AddLocal(SimpleType.Int32, LocalFlags.None));

            var localIndex = ExpressionCompiler.TryCompileExpression(
                expressionSyntax, SimpleType.Void, method, builder, new TestingResolver(variableMap), diagnostics);

            Assert.That(localIndex, Is.EqualTo(-1));
            diagnostics.AssertDiagnosticAt(DiagnosticCode.OperatorNotDefined, expressionSyntax.Position)
            .WithActual(operatorName).WithExpected(typeName);
        }
Exemplo n.º 13
0
        public void Variable_reference_returns_local_index_of_variable()
        {
            var syntax      = new IdentifierSyntax("a", default);
            var method      = new CompiledMethod("Test::Method");
            var builder     = new BasicBlockGraphBuilder().GetInitialBlockBuilder();
            var diagnostics = new TestingDiagnosticSink();

            var variableMap = new ScopedVariableMap();

            variableMap.PushScope();
            variableMap.TryAddVariable("a", 0);
            method.AddLocal(SimpleType.Bool, LocalFlags.None);

            var localIndex = ExpressionCompiler.TryCompileExpression(
                syntax, SimpleType.Bool, method, builder, new TestingResolver(variableMap), diagnostics);

            Assert.That(localIndex, Is.EqualTo(0));
            Assert.That(diagnostics.Diagnostics, Is.Empty);
        }
Exemplo n.º 14
0
        public int SmallMethod()
        {
            // This is based on NameParsing.IsDigit
            var map = new ScopedVariableMap();
            var sum = 0;

            // Execute the scenario a few times to simulate the map being reused
            for (var i = 0; i < 5; i++)
            {
                map.PushScope();
                map.TryAddVariable("ch", 1);
                map.TryGetVariable("ch", out var a);
                map.TryGetVariable("ch", out var b);
                map.PopScope();

                sum += a + b;
            }

            return(sum);
        }
Exemplo n.º 15
0
        public void Variable_reference_must_have_correct_type()
        {
            var position    = new TextPosition(10, 3, 4);
            var syntax      = new IdentifierSyntax("a", position);
            var method      = new CompiledMethod("Test::Method");
            var builder     = new BasicBlockGraphBuilder().GetInitialBlockBuilder();
            var diagnostics = new TestingDiagnosticSink();

            var variableMap = new ScopedVariableMap();

            variableMap.PushScope();
            variableMap.TryAddVariable("a", 0);
            method.AddLocal(SimpleType.Bool, LocalFlags.None);

            var localIndex = ExpressionCompiler.TryCompileExpression(
                syntax, SimpleType.Int32, method, builder, new TestingResolver(variableMap), diagnostics);

            Assert.That(localIndex, Is.EqualTo(-1));
            diagnostics.AssertDiagnosticAt(DiagnosticCode.TypeMismatch, position)
            .WithActual("bool").WithExpected("int32");
        }
Exemplo n.º 16
0
        public int LargerMethod()
        {
            // This is a synthetic benchmark, aiming to still be somewhat realistic
            var map = new ScopedVariableMap();
            var sum = 0;

            // Execute the scenario a few times to simulate the map being reused
            for (var iteration = 0; iteration < 5; iteration++)
            {
                // Create a lot of nested scopes and add variables to them
                for (var i = 0; i < ScopeCount; i++)
                {
                    map.PushScope();
                    for (var j = 0; j < VariablesPerScope; j++)
                    {
                        var index = i * ScopeCount + j;
                        map.TryAddVariable(_variableNames[index], index);
                    }
                }

                // Go through all the variables
                for (var i = 0; i < ScopeCount * VariablesPerScope; i++)
                {
                    // Do not go through them in exact order
                    map.TryGetVariable(_variableNames[i * 3 % (ScopeCount * VariablesPerScope)], out var index);
                    sum += index;
                }

                // Remove the scopes
                for (var i = 0; i < ScopeCount; i++)
                {
                    map.PopScope();
                }
            }

            return(sum);
        }
Exemplo n.º 17
0
        public void Non_constant_inequality_compiled_successfully()
        {
            var expressionSyntax = ParseExpression("a != b");
            var method           = new CompiledMethod("Test::Method");
            var builder          = new BasicBlockGraphBuilder().GetInitialBlockBuilder();
            var diagnostics      = new TestingDiagnosticSink();
            var variableMap      = new ScopedVariableMap();

            variableMap.PushScope();
            variableMap.TryAddVariable("a", method.AddLocal(SimpleType.Int32, LocalFlags.None));
            variableMap.TryAddVariable("b", method.AddLocal(SimpleType.Int32, LocalFlags.None));

            var localIndex = ExpressionCompiler.TryCompileExpression(expressionSyntax,
                                                                     SimpleType.Bool, method, builder, new TestingResolver(variableMap), diagnostics);

            Assert.That(diagnostics.Diagnostics, Is.Empty);
            Assert.That(localIndex, Is.EqualTo(3));
            Assert.That(method.Values[localIndex].Type, Is.EqualTo(SimpleType.Bool));
            Assert.That(builder.Instructions, Has.Exactly(2).Items);

            // a != b is compiled as !(a == b)
            Assert.That(builder.Instructions[0], Is.EqualTo(new Instruction(Opcode.Equal, 0, 1, 2)));
            Assert.That(builder.Instructions[1], Is.EqualTo(new Instruction(Opcode.BitwiseNot, 2, 0, 3)));
        }