60 lines
2.0 KiB
C#
60 lines
2.0 KiB
C#
|
using QFSW.QC.Utilities;
|
|||
|
using System;
|
|||
|
using System.Text.RegularExpressions;
|
|||
|
|
|||
|
namespace QFSW.QC.Grammar
|
|||
|
{
|
|||
|
public class ExpressionBodyGrammar : IQcGrammarConstruct
|
|||
|
{
|
|||
|
private readonly Regex _expressionBodyRegex = new Regex(@"^{.+}\??$");
|
|||
|
|
|||
|
public int Precedence => 0;
|
|||
|
|
|||
|
public bool Match(string value, Type type)
|
|||
|
{
|
|||
|
return _expressionBodyRegex.IsMatch(value);
|
|||
|
}
|
|||
|
|
|||
|
public object Parse(string value, Type type, Func<string, Type, object> recursiveParser)
|
|||
|
{
|
|||
|
bool nullable = false;
|
|||
|
if (value.EndsWith("?"))
|
|||
|
{
|
|||
|
nullable = true;
|
|||
|
value = value.Substring(0, value.Length - 1);
|
|||
|
}
|
|||
|
|
|||
|
value = value.ReduceScope('{', '}');
|
|||
|
object result = QuantumConsoleProcessor.InvokeCommand(value);
|
|||
|
|
|||
|
if (result is null)
|
|||
|
{
|
|||
|
if (nullable)
|
|||
|
{
|
|||
|
if (type.IsClass)
|
|||
|
{
|
|||
|
return result;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
throw new ParserInputException($"Expression body {{{value}}} evaluated to null which is incompatible with the expected type '{type.GetDisplayName()}'.");
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
throw new ParserInputException($"Expression body {{{value}}} evaluated to null. If this is intended, please use nullable expression bodies, {{expr}}?");
|
|||
|
}
|
|||
|
}
|
|||
|
else if (result.GetType().IsCastableTo(type, true))
|
|||
|
{
|
|||
|
return type.Cast(result);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
throw new ParserInputException($"Expression body {{{value}}} evaluated to an object of type '{result.GetType().GetDisplayName()}', " +
|
|||
|
$"which is incompatible with the expected type '{type.GetDisplayName()}'.");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|