Beispiel #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));
        }
Beispiel #2
0
        /// <summary>
        /// Creates and returns a <see cref="SyntaxParser"/> instance for the given source text.
        /// This allows testing instance methods directly.
        /// </summary>
        protected SyntaxParser GetParserInstance(string source, out TestingDiagnosticSink diagnostics)
        {
            var sourceBytes = Encoding.UTF8.GetBytes(source);

            diagnostics = new TestingDiagnosticSink();

            return(new SyntaxParser(sourceBytes.AsMemory(), "test.cle", diagnostics));
        }
Beispiel #3
0
        /// <summary>
        /// Parses the given source text and returns the syntax tree if successful.
        /// </summary>
        protected SourceFileSyntax?ParseSource(string source, out TestingDiagnosticSink diagnostics)
        {
            var sourceBytes = Encoding.UTF8.GetBytes(source);

            diagnostics = new TestingDiagnosticSink();

            return(SyntaxParser.Parse(sourceBytes.AsMemory(), "test.cle", diagnostics));
        }
Beispiel #4
0
        public void Integer_literal_that_is_too_large_fails()
        {
            var position     = new TextPosition(10, 3, 4);
            var syntax       = new IntegerLiteralSyntax((ulong)int.MaxValue + 1, position);
            var method       = new CompiledMethod("Test::Method");
            var builder      = new BasicBlockGraphBuilder().GetInitialBlockBuilder();
            var nameResolver = new TestingResolver(new ScopedVariableMap());
            var diagnostics  = new TestingDiagnosticSink();

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

            Assert.That(localIndex, Is.EqualTo(-1));
            diagnostics.AssertDiagnosticAt(DiagnosticCode.TypeMismatch, position)
            .WithActual("uint32").WithExpected("int32");
        }
Beispiel #5
0
        public void Constant_comparison_compiled_successfully(string expressionString, bool expectedValue)
        {
            var expressionSyntax = ParseExpression(expressionString);
            var method           = new CompiledMethod("Test::Method");
            var builder          = new BasicBlockGraphBuilder().GetInitialBlockBuilder();
            var diagnostics      = new TestingDiagnosticSink();
            var nameResolver     = new TestingResolver(new ScopedVariableMap());

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

            Assert.That(diagnostics.Diagnostics, Is.Empty);
            Assert.That(localIndex, Is.EqualTo(0));
            Assert.That(method.Values[localIndex].Type, Is.EqualTo(SimpleType.Bool));
            AssertSingleLoad(builder, localIndex, expectedValue);
        }
Beispiel #6
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");
        }
Beispiel #7
0
        public void Int32_division_by_zero_in_constant_expression_fails(BinaryOperation op)
        {
            var position = new TextPosition(10, 3, 4);
            var syntax   = new BinaryExpressionSyntax(op,
                                                      new IntegerLiteralSyntax(2ul, default),
                                                      new IntegerLiteralSyntax(0, default),
                                                      position);
            var method       = new CompiledMethod("Test::Method");
            var builder      = new BasicBlockGraphBuilder().GetInitialBlockBuilder();
            var diagnostics  = new TestingDiagnosticSink();
            var nameResolver = new TestingResolver(new ScopedVariableMap());

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

            Assert.That(localIndex, Is.EqualTo(-1));
            diagnostics.AssertDiagnosticAt(DiagnosticCode.DivisionByConstantZero, position);
        }
Beispiel #8
0
        public void Compile_parameterless_int32_method_succeeds()
        {
            var position            = new TextPosition(280, 14, 8);
            var syntax              = MakeParameterlessMethod(Visibility.Private, "int32", position);
            var diagnostics         = new TestingDiagnosticSink();
            var declarationProvider = new TestingSingleFileDeclarationProvider();

            var result = MethodDeclarationCompiler.Compile(syntax, "long::ns", "int32.cle", 8, declarationProvider, diagnostics);

            Assert.That(diagnostics.Diagnostics, Is.Empty);
            Assert.That(result, Is.InstanceOf <NativeMethodDeclaration>());
            Assert.That((result as NativeMethodDeclaration) !.IsEntryPoint, Is.False);
            Assert.That(result !.ReturnType, Is.EqualTo(SimpleType.Int32));
            Assert.That(result.Visibility, Is.EqualTo(Visibility.Private));
            Assert.That(result.FullName, Is.EqualTo("long::ns::MethodName"));
            Assert.That(result.DefiningFilename, Is.EqualTo("int32.cle"));
            Assert.That(result.DefinitionPosition, Is.EqualTo(position));
            Assert.That(result.BodyIndex, Is.EqualTo(8));
        }
Beispiel #9
0
        public void Compile_parameterless_bool_method_succeeds()
        {
            var position            = new TextPosition(13, 3, 4);
            var syntax              = MakeParameterlessMethod(Visibility.Public, "bool", position);
            var diagnostics         = new TestingDiagnosticSink();
            var declarationProvider = new TestingSingleFileDeclarationProvider();

            var result = MethodDeclarationCompiler.Compile(syntax, "Namespace", "bool.cle", 7, declarationProvider, diagnostics);

            Assert.That(diagnostics.Diagnostics, Is.Empty);
            Assert.That(result, Is.InstanceOf <NativeMethodDeclaration>());
            Assert.That((result as NativeMethodDeclaration) !.IsEntryPoint, Is.False);
            Assert.That(result !.ReturnType, Is.EqualTo(SimpleType.Bool));
            Assert.That(result.Visibility, Is.EqualTo(Visibility.Public));
            Assert.That(result.FullName, Is.EqualTo("Namespace::MethodName"));
            Assert.That(result.DefiningFilename, Is.EqualTo("bool.cle"));
            Assert.That(result.DefinitionPosition, Is.EqualTo(position));
            Assert.That(result.BodyIndex, Is.EqualTo(7));
        }
Beispiel #10
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);
        }
Beispiel #11
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);
        }
Beispiel #12
0
        public void Boolean_literal_stored_in_bool_succeeds()
        {
            var syntax       = new BooleanLiteralSyntax(true, default);
            var method       = new CompiledMethod("Test::Method");
            var builder      = new BasicBlockGraphBuilder().GetInitialBlockBuilder();
            var nameResolver = new TestingResolver(new ScopedVariableMap());
            var diagnostics  = new TestingDiagnosticSink();

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

            Assert.That(localIndex, Is.EqualTo(0));
            Assert.That(diagnostics.Diagnostics, Is.Empty);
            Assert.That(method.Values, Has.Exactly(1).Items);

            var local = method.Values[0];

            Assert.That(local.Type, Is.EqualTo(SimpleType.Bool));
            AssertSingleLoad(builder, localIndex, true);
        }
Beispiel #13
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");
        }
Beispiel #14
0
        /// <summary>
        /// Parses the given source code, compiles the method declarations and
        /// returns the result of <see cref="MethodCompiler.CompileBody"/> on the first method.
        /// </summary>
        protected CompiledMethod?TryCompileFirstMethod(string source,
                                                       out TestingDiagnosticSink diagnostics)
        {
            var sourceBytes = Encoding.UTF8.GetBytes(source);

            diagnostics = new TestingDiagnosticSink();

            // Parse the source
            const string sourceFilename = "test.cle";
            var          syntaxTree     = SyntaxParser.Parse(sourceBytes.AsMemory(), sourceFilename, diagnostics);

            Assert.That(syntaxTree, Is.Not.Null, "Source file was not parsed successfully.");

            // Parse the declarations
            var declarationProvider            = new TestingSingleFileDeclarationProvider();
            MethodDeclaration?firstDeclaration = null;

            foreach (var functionSyntax in syntaxTree !.Functions)
            {
                var declaration = MethodDeclarationCompiler.Compile(functionSyntax, syntaxTree.Namespace, sourceFilename,
                                                                    declarationProvider.Methods.Count, declarationProvider, diagnostics);
                Assert.That(declaration, Is.Not.Null,
                            $"Method declaration for {functionSyntax.Name} was not compiled successfully.");

                if (firstDeclaration is null)
                {
                    firstDeclaration = declaration;
                }
                declarationProvider.Methods.Add(functionSyntax.Name, declaration !);
            }

            Assert.That(firstDeclaration, Is.Not.Null, "No methods were declared.");

            // Then compile the first method
            return(new MethodCompiler(declarationProvider, diagnostics)
                   .CompileBody(syntaxTree.Functions[0], firstDeclaration !, syntaxTree.Namespace, sourceFilename));
        }
Beispiel #15
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)));
        }