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());
Це дуже просто!
Вам необхідно лише реалізувати інтерфейс 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());