External Functions and Procedures in C#

Soley Studio allows using external functions and procedures coded in C# (C-Sharp). This allows you to extend the functionalities of the GrGen library. In this article, we will give a short example for casting from string to integer values. This is not (natively) possible in GrGen but it is in C#. Here is an article about casting operations supported by GrGen.

C# offers many options. Here is a list of C# functions. Of course you can also implement you own functions.

This article will guide you through three steps:

  1. Create the external files (and a directory)
  2. Create C# functions in Soley Studio
  3. Execute external functions/procedures

1. Creating the external files and a directory

  • Add a new folder to the solution explorer and call it “Helpers” (you can choose a different name).
  • Add to this folder an “Empty Metamodel” file and name it “Helpers.gm” (you can choose a different name). You can add the file by right-clicking on the folder –> Add –> New File –> Empty Metamodel
  • Add to this folder an “External Implementation file” and name it “Helpers.cs” (you can choose a different name). You can add the file by right-clicking on the folder –> Add –> New File –> External Implementation File
  • Include the “Helpers.gm” file in the MainMetamodel.gm file as shown in the screenshot.

MainMetamodel.gm file extended with Helpers.gm file to include external functions written in C#. The Helpers.gm file contains the function names and links to the Helpers.cs file that contains the C# code.

 

2. Create C# external functions and procedures in Soley Studio

In the new *.gm file the name and structure of the external functions/procedures are defined, i.e. how to call these rules in GrGen.net. For our example we edit the Helpers.gm file like this:

 //ImplementationFile: Helpers.cs
 
 external procedure ToInt(/*value*/string):(boolean, int);

The first line in this document must start with //ImplementationFile: followed by the name of the *.cs file we created. The *.cs file will later contain the C# code.

Then we can start to define external functions or procedures. For our example, we create an external procedure  ToInt, which will be used to call the C# function. We use a procedure as we want to return more than one value. You can use an external function if you want to return only one value. As defined above, ToInt has one string input variable and two output variables ( a boolean and an integer value). This is partially defined by the C# function we are going to use for a casting operation. The boolean value returns whether the parsing was successful.

Next, we edit the Helpers.cs file and use C# to define what our procedure ToInt should do:

 using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Reflection;
 using de.unika.ipd.grGen.libGr;
 using de.unika.ipd.grGen.lgsp;
 using de.unika.ipd.grGen.Model_REPLACEWITHMODELNAME;
 
 namespace de.unika.ipd.grGen.expression
 {
     public partial class ExternalFunctions
     {
         public static int ExampleFunction(IActionExecutionEnvironment env, IGraph graph)
         {
             return 0;
         }
     } 
     public partial class ExternalProcedures
     {
         public static void ToInt(IActionExecutionEnvironment env, IGraph graph, string value, out bool success, out int intValue)
         {
             success = int.TryParse(value, out intValue);
         }
     }
 }

After adding an external implementation file (*.cs) in Soley Studio, it already contains a header with all necessary references and two sections for defining external functions and procedures. The programming language of this file is C#.

This article shows how to define the C# function TryParse, which allows casting a string to an integer variable.

In our example, we want to use the C# function TryParse, which allows casting a string to an integer variable. Here you can find more C# functions you could use. The highlighted part defines our ToInt procedure. The public static void part is always required for functions and procedures and the function name must match the name used in the *.gm file.

ToInt has five arguments (input and output). The first two arguments (  IActionExecutionEnvironment env, IGraph graph) must be set for every function and procedure. The others depend on the specific C# function. We define an input string argument (string value) and two output arguments (out bool success and out int intValue). Output arguments are defined by the keyword out.

If you define an external function, you do not have to define output values, as you can only return one value via a return statement. External functions are defined in the ExternalFunctions section.

3. Execution of the implemented external function/procedure

Once defined and build you can now use the external functions and procedures like any other function or procedure in GrGen. An example for our ToInt function could be:

rule castToInt{
   modify{ 
     eval{
       def var hierarchy:string="1";
       def var hier:int;
       (def var success:boolean, hier) = ToInt(hierarchy);
} } }

Do you have other C# functions you use? Let us know and we can add them as examples to share the knowledge with other users! Just leave a comment below 🙂

Was this article helpful?

Related Articles