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()}'.");
|
|
}
|
|
}
|
|
}
|
|
}
|