public void DefinedFunctionWithValueOfCall_CallFunctionWithArguments_ScopeInitializedCorrectly() { // prepare var variables = new List <string> { "arg1" }; var functionBlock = new Block(null, variables, "fun"); functionBlock.NestedBlocks.Add(new StringComponentInstruction(functionBlock.ScopePrototype, new ValueOf { VariableName = "arg1" })); var functionDictionary = new Dictionary <string, Block> { { "function", functionBlock } }; var scope_prototype = new ScopePrototype { Variables = new HashSet <string> { "model" }, }; var scope = new Scope(scope_prototype) { VariableValues = new Dictionary <string, AssignedValue> { { "model", new AssignedValue(JToken.Parse("['value1', 'value2']")) } } }; var functionCallInstruction = new FunctionCallInstruction(scope_prototype, new FunctionCall { FunctionName = "function", ArgumentValues = new List <Value> { new ValueOf { VariableName = "model", Index = 1 } } }); // act var memoryStream = new MemoryStream(); var streamWriter = new StreamWriter(memoryStream); var node = new Node { StreamWriter = streamWriter, NewLine = false, NestedLevel = 0, Scope = scope, FunctionsDict = functionDictionary }; functionCallInstruction.Execute(node); streamWriter.Flush(); // validate memoryStream.Position = 0; var streamReader = new StreamReader(memoryStream); //Assert.Equal("\nvalue2", streamReader.ReadToEnd()); Assert.Equal("value2", streamReader.ReadToEnd()); }
private FunctionCallInstruction PopulateFunctionCallInstruction(ScopePrototype scope, FunctionCall functionCall) { // check if the function has been declared in the scope Block function_block; if (!_functions.TryGetValue(functionCall.FunctionName, out function_block)) { throw new SemanticsException($"Function {functionCall.FunctionName} has not been declared in the scope of the function {scope.FunctionName}."); } // check if called arguments exist in the scope foreach (var argument in functionCall.ArgumentValues) { if (argument.GetType() == typeof(ValueOf)) { if (!scope.Variables.Contains(((ValueOf)argument).VariableName)) { throw new SemanticsException($"Variable {((ValueOf) argument).VariableName} has not been declared in the scope of the function {scope.FunctionName}."); } } } var funCallInstruction = new FunctionCallInstruction(scope, functionCall); return(funCallInstruction); }
public void DefinedFunction_CallFunctionWithArgumentsOutOfScope_ThrowRuntimeException() { // prepare var variables = new List <string> { "arg1" }; var functionBlock = new Block(null, variables, "fun"); var functionDictionary = new Dictionary <string, Block> { { "function", functionBlock } }; var scope_prototype = new ScopePrototype { Variables = new HashSet <string> { "model" }, }; var scope = new Scope(scope_prototype) { VariableValues = new Dictionary <string, AssignedValue> { { "model", new AssignedValue(JToken.Parse("['value1', 'value2']")) } } }; var functionCallInstruction = new FunctionCallInstruction(scope_prototype, new FunctionCall { FunctionName = "function", ArgumentValues = new List <Value> { new ValueOf { VariableName = "model", Index = 2 } } }); // act var streamWriter = new Mock <StreamWriter>(new MemoryStream()); var exceptionWasThrown = false; var node = new Node { StreamWriter = streamWriter.Object, NewLine = false, NestedLevel = 0, Scope = scope, FunctionsDict = functionDictionary }; try { functionCallInstruction.Execute(node); } catch (RuntimeException) { exceptionWasThrown = true; } // validate Assert.True(exceptionWasThrown); }
public void DefinedFunctionWithValueOfCallWithSimpleValue_CallFunctionWithArguments_ScopeInitializedCorrectly() { // prepare var variables = new List <string> { "arg1" }; var functionBlock = new Block(null, variables, "fun"); functionBlock.NestedBlocks.Add(new StringComponentInstruction(functionBlock.ScopePrototype, new ValueOf { VariableName = "arg1" })); var functionDictionary = new Dictionary <string, Block> { { "function", functionBlock } }; var scope_prototype = new ScopePrototype { Variables = new HashSet <string> { "model" }, }; var scope = new Scope(scope_prototype) { VariableValues = new Dictionary <string, AssignedValue> { { "model", new AssignedValue(JToken.Parse("'value2'")) } } }; var functionCallInstruction = new FunctionCallInstruction(scope_prototype, new FunctionCall { FunctionName = "function", ArgumentValues = new List <Value> { new ValueOf { VariableName = "model" } } }); // act var streamWriter = new Mock <StreamWriter>(new MemoryStream()); var node = new Node { StreamWriter = streamWriter.Object, NewLine = false, NestedLevel = 0, Scope = scope, FunctionsDict = functionDictionary }; functionCallInstruction.Execute(node); // validate streamWriter.Verify(s => s.Write("value2"), Times.Once); }
/// <summary> /// Ajoute tous les types dont dépend l'instruction inst dans le set passé en paramètres. /// </summary> void AggregateDependencies(Instruction inst, HashSet <ClankType> types) { if (inst is ClassDeclaration) { ClassDeclaration decl = (ClassDeclaration)inst; foreach (var instruction in decl.Instructions) { AggregateDependencies(instruction, types); } } else if (inst is Model.Language.Macros.RemoteFunctionWrapper) { var decl = (Model.Language.Macros.RemoteFunctionWrapper)inst; AggregateDependencies(decl.Func, types); } if (inst is VariableDeclarationInstruction) { VariableDeclarationInstruction decl = (VariableDeclarationInstruction)inst; AddToSet(types, decl.Var.Type); } else if (inst is VariableDeclarationAndAssignmentInstruction) { VariableDeclarationAndAssignmentInstruction decl = (VariableDeclarationAndAssignmentInstruction)inst; AddToSet(types, decl.Declaration.Var.Type); } else if (inst is FunctionDeclaration) { FunctionDeclaration decl = (FunctionDeclaration)inst; AddToSet(types, decl.Func.ReturnType); foreach (var arg in decl.Func.Arguments) { AddToSet(types, arg.ArgType); } foreach (var instruction in decl.Code) { AggregateDependencies(instruction, types); } } else if (inst is FunctionCallInstruction) { FunctionCallInstruction decl = (FunctionCallInstruction)inst; AddToSet(types, decl.Call.Func.ReturnType); foreach (var arg in decl.Call.Arguments) { AddToSet(types, arg.Type); } } }
public void DefinedFunctionWithRecursiveFunctionCall_CallFunctionWithArguments_TwoDifferentScopesUsed() { // prepare var scope_prototype = new ScopePrototype { Variables = new HashSet <string> { "arg1", "stopcondition" }, }; var variables = new List <string> { "arg1", "stopcondition" }; var functionBlock = new Block(null, variables, "function"); functionBlock.NestedBlocks.Add(new StringComponentInstruction(functionBlock.ScopePrototype, new ValueOf { VariableName = "arg1" })); functionBlock.NestedBlocks.Add(new IfInstruction(scope_prototype, new IfExpression { Condition = new SimpleCondition { LeftHandSideVariable = new ValueOf { VariableName = "stopcondition" } }, Negated = true }) { IfBlock = new List <Executable> { new FunctionCallInstruction(scope_prototype, new FunctionCall { FunctionName = "function", ArgumentValues = new List <Value> { new StringValue { StringComponents = new List <IStringComponent> { new Literal { Content = "another_value" } } }, new StringValue { StringComponents = new List <IStringComponent> { new Literal { Content = "true" } } }, } }) } }); functionBlock.NestedBlocks.Add(new StringComponentInstruction(functionBlock.ScopePrototype, new ValueOf { VariableName = "arg1" })); var functionDictionary = new Dictionary <string, Block> { { "function", functionBlock } }; var scope = new Scope(scope_prototype) { VariableValues = new Dictionary <string, AssignedValue> { { "arg1", new AssignedValue(JToken.Parse("'value2'")) } } }; var functionCallInstruction = new FunctionCallInstruction(scope_prototype, new FunctionCall { FunctionName = "function", ArgumentValues = new List <Value> { new ValueOf { VariableName = "arg1" }, new StringValue { StringComponents = new List <IStringComponent> { new Literal { Content = "false" } } } } }); // act var streamWriter = new Mock <StreamWriter>(new MemoryStream()); var node = new Node { StreamWriter = streamWriter.Object, NewLine = false, NestedLevel = 0, Scope = scope, FunctionsDict = functionDictionary }; functionCallInstruction.Execute(node); // validate streamWriter.Verify(s => s.Write("value2"), Times.Exactly(2)); streamWriter.Verify(s => s.Write("another_value"), Times.Exactly(2)); }