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); }
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); }
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); }
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); }
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()); }