Beispiel #1
0
        void Function_success_and_write_self_and_params_to_symbol_table()
        {
            var name = new IdentifierToken("SendRequest", default);

            var scope = new SymbolScope();

            scope.AddSymbol(new VariableSymbol("lll3", false, false, DataType.Long));

            var param1 = new FunctionParamAst(null, new IdentifierToken("length1", default),
                                              new OperatorToken(Operator.Colon, default), new IdentifierToken("int", default));
            var paramList = new FunctionParamListAst(new FunctionParamAst[] { param1 });

            var functionBlock = new Mock <BlockStatementAst>().Object;

            var ast = new FunctionAst(
                new KeywordToken(Keyword.Fn, default), name, new OperatorToken(Operator.LeftParen, default),
                paramList, new OperatorToken(Operator.RightParen, default),
                new OperatorToken(Operator.Arrow, default), returnType: new IdentifierToken("int", default),
                functionBlock
                );

            var generator = ConfigureGenerator(scope, mock =>
            {
                mock.Setup(p => p.ProcessBlockStatement(functionBlock, It.IsAny <bool>())).Returns(false);
            });

            generator.ProcessFunction(ast);

            // Assert


            // self
            Assert.True(scope.FindSymbolShallow(ast.Name.Value, out Symbol symx));
            var funcSym = Assert.IsType <FunctionSymbol>(symx);

            Assert.Equal(DataType.Long, funcSym.ReturnType);
            Assert.Equal(DataType.Long, funcSym.ParamTypes.Single());

            // params
            Assert.True(scope.FindSymbolShallow(name.Value, out Symbol s0));
            scope = (s0 as FunctionSymbol).BodyBlockScope;

            Assert.True(scope.FindSymbolShallow(param1.Name.Value, out Symbol sym1));
            var var1 = Assert.IsType <VariableSymbol>(sym1);

            Assert.Equal(param1.IsConstant, var1.IsConstant);
            Assert.False(var1.IsGlobal);
            Assert.Equal(DataType.Long, var1.Type);
            Assert.Equal(param1.Name.Value, var1.Name);
        }
Beispiel #2
0
        void ProcessConstDeclaration_adds_symbol_if_all_ok()
        {
            var scope = new SymbolScope();

            var name = new IdentifierToken("pi", default);

            var initialExpression = new Mock <ExpressionAst>().Object;

            var initialType = DataType.Double;
            var declareType = "double";

            var ast = new ConstDeclarationStatementAst(
                new KeywordToken(Keyword.Const, default), name, new OperatorToken(Operator.Colon, default),
                type: new IdentifierToken(declareType, default),
                new OperatorToken(Operator.Assign, default),
                initialExpression, new OperatorToken(Operator.Semicolon, default));

            var generator = ConfigureGenerator(scope, mock =>
            {
                mock.Setup(p => p.ProcessExpression(initialExpression)).Returns(initialType);
            });

            generator.ProcessConstDeclarationStatement(ast);

            Assert.True(scope.FindSymbolShallow(name.Value, out Symbol symbol));
            var variableSymbol = Assert.IsType <VariableSymbol>(symbol);

            Assert.Equal(name.Value, variableSymbol.Name);
            Assert.True(variableSymbol.IsConstant);
            Assert.True(variableSymbol.IsGlobal);
            Assert.Equal(DataType.Double, variableSymbol.Type);
        }
Beispiel #3
0
        void ProcessLetDeclaration_adds_symbol_if_previous_shits_ok_and_no_initial_expr()
        {
            var scope = new SymbolScope();

            var name = new IdentifierToken("requestsClient", default);

            var declareType = "double";

            var ast = new LetDeclarationStatementAst(
                new KeywordToken(Keyword.Let, default), name, new OperatorToken(Operator.Colon, default),
                type: new IdentifierToken(declareType, default),
                new OperatorToken(Operator.Assign, default),
                initialExpression: null, new OperatorToken(Operator.Semicolon, default));

            var generator = ConfigureGenerator(scope, mock =>
            {
            });

            generator.ProcessLetDeclarationStatement(ast);

            Assert.True(scope.FindSymbolShallow(name.Value, out Symbol symbol));
            var variableSymbol = Assert.IsType <VariableSymbol>(symbol);

            Assert.Equal(name.Value, variableSymbol.Name);
            Assert.False(variableSymbol.IsConstant);
            Assert.True(variableSymbol.IsGlobal);
            Assert.Equal(DataType.Double, variableSymbol.Type);
        }
Beispiel #4
0
        void ProcessLetDeclaration_registers_to_function_and_writes_function_bucket_when_in_func()
        {
            // Arrange
            var expr = new Mock <ExpressionAst>().Object;
            var ast  = new LetDeclarationStatementAst(
                new KeywordToken(Keyword.Let, default), new IdentifierToken("x", default),
                new OperatorToken(Operator.Colon, default), new IdentifierToken("int", default),
                new OperatorToken(Operator.Assign, default), expr,
                new OperatorToken(Operator.Semicolon, default));

            var function = new FunctionSymbol("print", DataType.Long, new DataType[0]);

            var scope     = new SymbolScope();
            var generator = ConfigureGenerator(scope, mock =>
            {
                mock.Setup(p => p.ProcessExpression(expr)).Returns(DataType.Long);
            });

            generator.GlobalBuilder.RegisterFunction(function);
            generator.EnterFunctionDefination(function);

            var ins1 = new object[] { "push", 111L };

            generator.ExpressionBucket.Add(ins1);// this is initial value expr

            // Act
            generator.ProcessLetDeclarationStatement(ast);

            // Assert
            Assert.Empty(generator.ExpressionBucket.Pop());

            Assert.True(scope.FindSymbolShallow("x", out Symbol symbol));

            var varx = Assert.IsType <VariableSymbol>(symbol);

            Assert.Contains(varx, function.Builder.LocalVariables);

            Assert.NotNull(varx.LocalLocation);
            Assert.Equal(0, varx.LocalLocation.Id);
            Assert.False(varx.LocalLocation.IsArgument);

            var funcBody = function.Builder.Bucket.InstructionList;

            Assert.Equal(3, funcBody.Count);
            AssertJsonEqual(new object[] { "loca", 0 }, funcBody[0].Parts);
            AssertJsonEqual(ins1, funcBody[1].Parts);
            AssertJsonEqual(new object[] { "store.64" }, funcBody[2].Parts);
        }
Beispiel #5
0
        void ProcessLetDeclaration_registers_and_set_instructions_when_out_of_func()
        {
            // Arrange
            var expr = new Mock <ExpressionAst>().Object;
            var ast  = new LetDeclarationStatementAst(
                new KeywordToken(Keyword.Let, default), new IdentifierToken("x", default),
                new OperatorToken(Operator.Colon, default), new IdentifierToken("int", default),
                new OperatorToken(Operator.Assign, default), expr,
                new OperatorToken(Operator.Semicolon, default));

            var scope     = new SymbolScope();
            var generator = ConfigureGenerator(scope, mock =>
            {
                mock.Setup(p => p.ProcessExpression(expr)).Returns(DataType.Long);
            });

            var ins1 = new Instruction(new object[] { "push", 111L });

            generator.ExpressionBucket.Add(ins1);// this is initial value expr

            // Act
            generator.ProcessLetDeclarationStatement(ast);

            // Assert
            Assert.Empty(generator.ExpressionBucket.Pop());

            Assert.True(scope.FindSymbolShallow("x", out Symbol symbol));

            var varx = Assert.IsType <VariableSymbol>(symbol);

            Assert.Contains(varx, generator.GlobalBuilder.GlobalVariablesView);

            Assert.NotNull(varx.GlobalVariableBuilder);
            Assert.Single(varx.GlobalVariableBuilder.LoadValueInstructions);
            Assert.Equal(ins1, varx.GlobalVariableBuilder.LoadValueInstructions.Single());
        }