123123
This commit is contained in:
@@ -1,17 +1,19 @@
|
||||
namespace ZelWiki.Engine.Function
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information about an actual function call, its supplied parameters, and is matched with a defined function.
|
||||
/// 包含有关实际函数调用及其提供的参数的信息,并与定义的函数相匹配。
|
||||
/// </summary>
|
||||
public class FunctionCall
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the function being called.
|
||||
///
|
||||
/// </summary>
|
||||
public string Name { get; private set; }
|
||||
|
||||
public FunctionPrototype Prototype { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The arguments supplied by the caller.
|
||||
/// T
|
||||
/// </summary>
|
||||
public FunctionParameters Parameters { get; private set; }
|
||||
|
||||
@@ -25,7 +27,7 @@
|
||||
{
|
||||
if (arg.StartsWith(':') && arg.Contains('='))
|
||||
{
|
||||
var parsed = arg.Substring(1); //Skip the colon.
|
||||
var parsed = arg.Substring(1);
|
||||
int index = parsed.IndexOf('=');
|
||||
var name = parsed.Substring(0, index).Trim().ToLower();
|
||||
var value = parsed.Substring(index + 1).Trim();
|
||||
@@ -42,9 +44,9 @@
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks the passed value against the function prototype to ensure that the variable is the correct type, value, etc.
|
||||
/// 对照函数原型检查传递的值,以确保变量的类型,值等正确
|
||||
/// </summary>
|
||||
/// <param name="segment"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
private void EnforcePrototypeParamValue(PrototypeParameter param, string value)
|
||||
@@ -53,21 +55,25 @@
|
||||
{
|
||||
if (bool.TryParse(value, out bool _) == false)
|
||||
{
|
||||
throw new Exception($"Function [{Name}], the value [{value}] passed to parameter [{param.Name}] could not be converted to boolean.");
|
||||
throw new Exception(
|
||||
$"函数 [{Name}] 传递给 [{param.Name}] 的值 [{value}] 无法转化成布尔");
|
||||
}
|
||||
}
|
||||
|
||||
if (param.Type == "integer")
|
||||
{
|
||||
if (int.TryParse(value, out int _) == false)
|
||||
{
|
||||
throw new Exception($"Function [{Name}], the value [{value}] passed to parameter [{param.Name}] could not be converted to integer.");
|
||||
throw new Exception(
|
||||
$"函数 [{Name}] 传递给 [{param.Name}] 的值 [{value}] 无法转化成整数.");
|
||||
}
|
||||
}
|
||||
else if (param.Type == "float")
|
||||
{
|
||||
if (double.TryParse(value, out double _) == false)
|
||||
{
|
||||
throw new Exception($"Function [{Name}], the value [{value}] passed to parameter [{param.Name}] could not be converted to float.");
|
||||
throw new Exception(
|
||||
$"函数 [{Name}] 传递给 [{param.Name}] 的值 [{value}] 无法转化成小数.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,24 +81,22 @@
|
||||
{
|
||||
if (param.AllowedValues.Contains(value.ToLower()) == false)
|
||||
{
|
||||
throw new Exception($"Function [{Name}], the value [{value}] passed to parameter [{param.Name}] is not allowed. Allowed values are [{string.Join(",", param.AllowedValues)}].");
|
||||
throw new Exception(
|
||||
$"函数 [{Name}] 传递给 [{param.Name}] 的值 [{value}] 为非法数据. 合法值为 [{string.Join(",", param.AllowedValues)}].");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls through the supplied arguments and applies them to the prototype. Also identifies which supplied arguments are associated with each
|
||||
/// prototype argument and adds the ordinal based arguments to the name based collection. Ensures that each argument conforms with the prototype.
|
||||
///
|
||||
/// </summary>
|
||||
/// <exception cref="Exception"></exception>
|
||||
private void ApplyPrototype()
|
||||
{
|
||||
int index = 0;
|
||||
var index = 0;
|
||||
|
||||
//Keep a list of the arguments as they are associated with the prototype so that we can later reference them by name.
|
||||
var namedToAddLater = new List<NamedParameter>();
|
||||
|
||||
//Handle non-infinite ordinal based required parameters:
|
||||
for (; index < Prototype.Parameters.Count; index++)
|
||||
{
|
||||
var param = Prototype.Parameters[index];
|
||||
@@ -101,15 +105,15 @@
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (param.IsInfinite == true)
|
||||
|
||||
if (param.IsInfinite)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (Parameters.Ordinals.Count > index)
|
||||
{
|
||||
//Good, we have a value.
|
||||
string value = Parameters.Ordinals[index].Value;
|
||||
var value = Parameters.Ordinals[index].Value;
|
||||
Parameters.Ordinals[index].AssociateWithPrototypeParam(param.Name);
|
||||
EnforcePrototypeParamValue(param, value.ToLower());
|
||||
|
||||
@@ -123,33 +127,30 @@
|
||||
|
||||
bool hasEncounteredOptionalParameter = false;
|
||||
|
||||
//Handle remaining optional parameters:
|
||||
for (; index < Prototype.Parameters.Count; index++)
|
||||
{
|
||||
var param = Prototype.Parameters[index];
|
||||
|
||||
if (param.IsInfinite == true)
|
||||
if (param.IsInfinite)
|
||||
{
|
||||
if (param.IsRequired == true)
|
||||
if (param.IsRequired)
|
||||
{
|
||||
//Make sure we have at least one of these required infinite parameters passed.
|
||||
if (Parameters.Ordinals.Count > index)
|
||||
{
|
||||
//Good, we have a value.
|
||||
string value = Parameters.Ordinals[index].Value;
|
||||
var value = Parameters.Ordinals[index].Value;
|
||||
Parameters.Ordinals[index].AssociateWithPrototypeParam(param.Name);
|
||||
EnforcePrototypeParamValue(param, value.ToLower());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"Function [{Name}], the required infinite parameter [{param.Name}] was not passed.");
|
||||
throw new Exception(
|
||||
$"函数 [{Name}], 参数 [{param.Name}] 未通过.");
|
||||
}
|
||||
}
|
||||
|
||||
//Now that we have encountered an infinite parameter, it will swallow up all other ordinal based arguments. Might as well check the types and exit the loop.
|
||||
for (; index < Parameters.Ordinals.Count; index++)
|
||||
{
|
||||
string value = Parameters.Ordinals[index].Value;
|
||||
var value = Parameters.Ordinals[index].Value;
|
||||
Parameters.Ordinals[index].AssociateWithPrototypeParam(param.Name);
|
||||
EnforcePrototypeParamValue(param, value.ToLower());
|
||||
namedToAddLater.Add(new NamedParameter(param.Name, value));
|
||||
@@ -163,18 +164,20 @@
|
||||
hasEncounteredOptionalParameter = true;
|
||||
}
|
||||
|
||||
if (param.IsRequired == true && hasEncounteredOptionalParameter)
|
||||
if (param.IsRequired && hasEncounteredOptionalParameter)
|
||||
{
|
||||
throw new Exception($"Function [{Name}], the required parameter [{param.Name}] was found after other optional parameters.");
|
||||
throw new Exception(
|
||||
$"函数 [{Name}], 所必参数 [{param.Name}] 在其他可选参数之后找到.");
|
||||
}
|
||||
else if (param.IsInfinite == true)
|
||||
else if (param.IsInfinite)
|
||||
{
|
||||
throw new Exception($"Function [{Name}], encountered an unexpected number of infinite parameters in prototype for [{param.Name}].");
|
||||
throw new Exception(
|
||||
$"函数 [{Name}], 参数溢出 [{param.Name}].");
|
||||
}
|
||||
|
||||
if (Parameters.Ordinals.Count > index)
|
||||
{
|
||||
string value = Parameters.Ordinals[index].Value;
|
||||
var value = Parameters.Ordinals[index].Value;
|
||||
Parameters.Ordinals[index].AssociateWithPrototypeParam(param.Name);
|
||||
EnforcePrototypeParamValue(param, value.ToLower());
|
||||
namedToAddLater.Add(new NamedParameter(param.Name, value));
|
||||
@@ -183,8 +186,10 @@
|
||||
|
||||
foreach (var named in Parameters.Named)
|
||||
{
|
||||
var param = Prototype.Parameters.Where(o => o.Name.Equals(named.Name, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault()
|
||||
?? throw new Exception($"Function [{Name}], the named parameter [{named.Name}] is not defined in the function prototype.");
|
||||
var param = Prototype.Parameters
|
||||
.FirstOrDefault(o => o.Name.Equals(named.Name, StringComparison.InvariantCultureIgnoreCase))
|
||||
?? throw new Exception(
|
||||
$"函数 [{Name}], 命名参数 [{named.Name}] 未在函数原型中定义.");
|
||||
|
||||
EnforcePrototypeParamValue(param, named.Value);
|
||||
}
|
||||
@@ -194,17 +199,20 @@
|
||||
var unmatchedParams = Parameters.Ordinals.Where(o => o.IsMatched == false).ToList();
|
||||
if (unmatchedParams.Count != 0)
|
||||
{
|
||||
throw new Exception($"Function [{Name}], unmatched parameter value [{unmatchedParams.First().Value}].");
|
||||
throw new Exception($"函数 [{Name}], 不匹配的参数值 [{unmatchedParams.First().Value}].");
|
||||
}
|
||||
|
||||
var nonInfiniteParams = Prototype.Parameters.Where(o => o.IsInfinite == false).Select(o => o.Name.ToLower());
|
||||
var groups = Parameters.Named.Where(o => nonInfiniteParams.Contains(o.Name.ToLower())).GroupBy(o => o.Name.ToLower()).Where(o => o.Count() > 1);
|
||||
var nonInfiniteParams =
|
||||
Prototype.Parameters.Where(o => o.IsInfinite == false).Select(o => o.Name.ToLower());
|
||||
var groups = Parameters.Named.Where(o => nonInfiniteParams.Contains(o.Name.ToLower()))
|
||||
.GroupBy(o => o.Name.ToLower()).Where(o => o.Count() > 1);
|
||||
|
||||
if (groups.Any())
|
||||
{
|
||||
var group = groups.First();
|
||||
throw new Exception($"Function [{Name}], non-infinite parameter specified more than once: [{group.Key}].");
|
||||
throw new Exception(
|
||||
$"函数 [{Name}], 多次指定参数: [{group.Key}].");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user