Skip to content

Latest commit

 

History

History
224 lines (201 loc) · 7.87 KB

File metadata and controls

224 lines (201 loc) · 7.87 KB

EN

How to create your own syntax for VCPL

It's very simple!
You only need to implement the ICodeConvertor interface. And register it in the environment that will be used for compilation An example of the implementation of the ICodeConvertor interface by the basic syntax converter CLite:

using VCPL.Exceptions;
namespace VCPL.CodeConversion
{
     public class CLIteConvertor : ICodeConvertor
     {
         public CodeLine Convert(int lineNumber, string line)
         {
             string FunctionName = "";
             string? ReturnData;
             List Args;

             line = line.Trim();

             int equalsIndex = line.IndexOf('=');
             if (equalsIndex == -1)
             {
                 ReturnData = null;
             }
             else
             {
                 ReturnData = line.Substring(0, equalsIndex).Trim();
                 if (ReturnData == "") throw new SyntaxException(lineNumber, "no variable before '=' symbol");
                 line = line.Substring(equalsIndex + 1).Trim();
             }

             int openParenIndex = line.IndexOf('(');
             int closeParenIndex = line.IndexOf(')');
             if (openParenIndex == -1 && closeParenIndex == -1)
             {
                 Args = new List { line };
             }
             else if ((openParenIndex == -1) != (closeParenIndex == -1))
             {
                 throw new SyntaxException(lineNumber, "no open parren or no close parren");
             }
             else if (openParenIndex > closeParenIndex)
             {
                 throw new SyntaxException(lineNumber, "no open parren");
             }
             else
             {
                 FunctionName = line.Substring(0, openParenIndex).Trim();
                 string argsString = line.Substring(openParenIndex + 1, closeParenIndex - openParenIndex - 1);
                 Args = GetArgsList(argsString);
             }
            
             if (ReturnData != null) { Args.Add(ReturnData); }
             return new CodeLine(lineNumber, FunctionName, Args);
         }

         private static List GetArgsList(string argsString)
         {
             List args = new List();

             int startIndex = 0;
             int endIndex = 0;
             bool inQuotes = false;
             char quoteChar = '\0';

             for (int i = 0; i < argsString.Length; i++)
             {
                 char currentChar = argsString[i];

                 if (!inQuotes && (currentChar == ',' || i == argsString.Length - 1))
                 {
                     endIndex = i;
                     if (i == argsString.Length - 1)
                     {
                         endIndex++;
                     }
                     string arg = argsString.Substring(startIndex, endIndex - startIndex).Trim();
                     args.Add(arg);
                     startIndex = i + 1;
                 }
                 else if (!inQuotes && (currentChar == '\'' || currentChar == '"'))
                 {
                     inQuotes = true;
                     quoteChar = currentChar;
                     startIndex = i;
                 }
                 else if (inQuotes && currentChar == quoteChar)
                 {
                     inQuotes = false;
                     if (i == argsString.Length - 1)
                     {
                         endIndex = i + 1;
                         string arg = argsString.Substring(startIndex, endIndex - startIndex).Trim();
                         args.Add(arg);
                     }
                 }
             }

             return args;
         }
     }
}

An example of registering a converter in the environment:

releaseEnvironment.envCodeConvertorsContainer.AddCodeConvertor("CLite", new CLiteConvertor());

UA

Як створити власний синтаксис для VCPL

Це дуже просто!
Вам необхідно лише реалізувати інтерфейс ICodeConvertor. Та зареєструвати його в оточенні яке буде використано про компіляції Приклад реалізації інтерфейсу ICodeConvertor базовим синтаксичним конвертором CLite:

using VCPL.Exceptions;
namespace VCPL.CodeConvertion
{
    public class CLiteConvertor : ICodeConvertor
    {
        public CodeLine Convert(int lineNumber, string line)
        {
            string FunctionName = "";
            string? ReturnData;
            List Args;

            line = line.Trim();

            int equalsIndex = line.IndexOf('=');
            if (equalsIndex == -1)
            {
                ReturnData = null;
            }
            else
            {
                ReturnData = line.Substring(0, equalsIndex).Trim();
                if (ReturnData == "") throw new SyntaxException(lineNumber, "no variable before '=' symbol");
                line = line.Substring(equalsIndex + 1).Trim();
            }

            int openParenIndex = line.IndexOf('(');
            int closeParenIndex = line.IndexOf(')');
            if (openParenIndex == -1 && closeParenIndex == -1)
            {
                Args = new List { line };
            }
            else if ((openParenIndex == -1) != (closeParenIndex == -1))
            {
                throw new SyntaxException(lineNumber, "no open parren or no close parren");
            }
            else if (openParenIndex > closeParenIndex)
            {
                throw new SyntaxException(lineNumber, "no open parren");
            }
            else
            {
                FunctionName = line.Substring(0, openParenIndex).Trim();
                string argsString = line.Substring(openParenIndex + 1, closeParenIndex - openParenIndex - 1);
                Args = GetArgsList(argsString);
            }
            
            if (ReturnData != null) { Args.Add(ReturnData); }
            return new CodeLine(lineNumber, FunctionName, Args);
        }

        private static List GetArgsList(string argsString)
        {
            List args = new List();

            int startIndex = 0;
            int endIndex = 0;
            bool inQuotes = false;
            char quoteChar = '\0';

            for (int i = 0; i < argsString.Length; i++)
            {
                char currentChar = argsString[i];

                if (!inQuotes && (currentChar == ',' || i == argsString.Length - 1))
                {
                    endIndex = i;
                    if (i == argsString.Length - 1)
                    {
                        endIndex++;
                    }
                    string arg = argsString.Substring(startIndex, endIndex - startIndex).Trim();
                    args.Add(arg);
                    startIndex = i + 1;
                }
                else if (!inQuotes && (currentChar == '\'' || currentChar == '"'))
                {
                    inQuotes = true;
                    quoteChar = currentChar;
                    startIndex = i;
                }
                else if (inQuotes && currentChar == quoteChar)
                {
                    inQuotes = false;
                    if (i == argsString.Length - 1)
                    {
                        endIndex = i + 1;
                        string arg = argsString.Substring(startIndex, endIndex - startIndex).Trim();
                        args.Add(arg);
                    }
                }
            }

            return args;
        }
    }
}

Приклад реєстрації конвертору в оточенні:

releaseEnvironment.envCodeConvertorsContainer.AddCodeConvertor("CLite", new CLiteConvertor());