Add evaluateDouble
This commit is contained in:
parent
87362f93c1
commit
d304a80e7b
2 changed files with 89 additions and 45 deletions
|
@ -48,55 +48,67 @@ namespace AspectedRouting.Language
|
|||
* Builds a string representation that can be used to paste into C# test programs
|
||||
*/
|
||||
string Repr();
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static class ExpressionExtensions
|
||||
{
|
||||
|
||||
|
||||
public static void PrintRepr(this IExpression e)
|
||||
{
|
||||
Console.WriteLine(e.Repr()+"\n\n-----------\n");
|
||||
Console.WriteLine(e.Repr() + "\n\n-----------\n");
|
||||
}
|
||||
public static object Run(this IExpression e, Context c, Dictionary<string, string> tags)
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
var result = e.Apply(new Constant(tags)).Evaluate(c);
|
||||
while (result is IExpression ex) {
|
||||
while (result is IExpression ex)
|
||||
{
|
||||
result = ex.Apply(new Constant(tags)).Evaluate(c);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception err) {
|
||||
catch (Exception err)
|
||||
{
|
||||
throw new Exception($"While evaluating the expression {e} with arguments a list of tags", err);
|
||||
}
|
||||
}
|
||||
|
||||
public static double EvaluateDouble(this IExpression e, string paramName, Context c, params IExpression[] arguments)
|
||||
{
|
||||
return Utils.AsDouble(e.Evaluate(c, arguments), paramName);
|
||||
}
|
||||
|
||||
public static IExpression Specialize(this IExpression e, Type t)
|
||||
{
|
||||
if (t == null) {
|
||||
if (t == null)
|
||||
{
|
||||
throw new NullReferenceException("Cannot specialize to null");
|
||||
}
|
||||
|
||||
return e.Specialize(new[] {t});
|
||||
return e.Specialize(new[] { t });
|
||||
}
|
||||
|
||||
public static IExpression Specialize(this IExpression e, Dictionary<string, Type> substitutions)
|
||||
{
|
||||
var newTypes = new HashSet<Type>();
|
||||
|
||||
foreach (var oldType in e.Types) {
|
||||
foreach (var oldType in e.Types)
|
||||
{
|
||||
var newType = oldType.Substitute(substitutions);
|
||||
if (newType == null) {
|
||||
if (newType == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
newTypes.Add(newType);
|
||||
}
|
||||
|
||||
if (!newTypes.Any()) {
|
||||
if (!newTypes.Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -123,23 +135,28 @@ namespace AspectedRouting.Language
|
|||
var allExpressions = new HashSet<IExpression>();
|
||||
specializedExpressions = allExpressions;
|
||||
|
||||
foreach (var expr in exprs) {
|
||||
if (specializedTypes == null) {
|
||||
foreach (var expr in exprs)
|
||||
{
|
||||
if (specializedTypes == null)
|
||||
{
|
||||
specializedTypes = expr.Types; // This is t
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
var newlySpecialized = Typs.WidestCommonTypes(specializedTypes, expr.Types);
|
||||
if (!newlySpecialized.Any()) {
|
||||
throw new ArgumentException("Could not find a common ground for types "+specializedTypes.Pretty()+ " and "+expr.Types.Pretty());
|
||||
if (!newlySpecialized.Any())
|
||||
{
|
||||
throw new ArgumentException("Could not find a common ground for types " + specializedTypes.Pretty() + " and " + expr.Types.Pretty());
|
||||
}
|
||||
|
||||
specializedTypes = newlySpecialized;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
foreach (var expr in exprs) {
|
||||
foreach (var expr in exprs)
|
||||
{
|
||||
var e = expr.Specialize(specializedTypes);
|
||||
allExpressions.Add(e);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace AspectedRouting
|
|||
|
||||
public static List<T> InList<T>(this T t)
|
||||
{
|
||||
return new List<T> {t};
|
||||
return new List<T> { t };
|
||||
}
|
||||
|
||||
public static string Lined(this IEnumerable<string> lines)
|
||||
|
@ -31,9 +31,7 @@ namespace AspectedRouting
|
|||
public static int Multiply(this IEnumerable<int> ints)
|
||||
{
|
||||
var factor = 1;
|
||||
foreach (var i in ints) {
|
||||
factor += i;
|
||||
}
|
||||
foreach (var i in ints) factor += i;
|
||||
|
||||
return factor;
|
||||
}
|
||||
|
@ -54,28 +52,28 @@ namespace AspectedRouting
|
|||
{
|
||||
return "\"" + s + "\"";
|
||||
}
|
||||
|
||||
|
||||
public static string GenerateTagsOverview(IEnumerable<ProfileMetaData> profiles, Context context)
|
||||
{
|
||||
var allExpressions = new List<IExpression>();
|
||||
foreach (var profile in profiles) {
|
||||
foreach (var behaviour in profile.Behaviours) {
|
||||
foreach (var profile in profiles)
|
||||
foreach (var behaviour in profile.Behaviours)
|
||||
allExpressions.AddRange(profile.AllExpressions(context));
|
||||
}
|
||||
}
|
||||
|
||||
var explanations = new List<string>();
|
||||
foreach (var tag in allExpressions.PossibleTags()) {
|
||||
foreach (var tag in allExpressions.PossibleTags())
|
||||
{
|
||||
var values = new List<string>(tag.Value);
|
||||
values.Sort();
|
||||
explanations.Add(tag.Key.Quoted() + ": [" +
|
||||
string.Join(", ", values.Select(v => v.Quoted()))
|
||||
+ "]");
|
||||
}
|
||||
|
||||
explanations.Sort();
|
||||
|
||||
|
||||
return "{\n "+ String.Join(",\n ", explanations)+"\n}";
|
||||
|
||||
|
||||
return "{\n " + string.Join(",\n ", explanations) + "\n}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -88,38 +86,67 @@ namespace AspectedRouting
|
|||
/// <returns></returns>
|
||||
public static string GenerateExplanationJson(IEnumerable<ProfileMetaData> profiles, Context context)
|
||||
{
|
||||
|
||||
var metaItems = new List<string>();
|
||||
|
||||
foreach (var profile in profiles) {
|
||||
foreach (var profile in profiles)
|
||||
{
|
||||
var profileName = profile.Name;
|
||||
var author = profile.Author;
|
||||
var profileDescription = profile.Description;
|
||||
|
||||
|
||||
foreach (var behaviour in profile.Behaviours) {
|
||||
foreach (var behaviour in profile.Behaviours)
|
||||
{
|
||||
var behaviourDescription = behaviour.Value["description"].Evaluate(new Context()) as string;
|
||||
behaviourDescription ??= "";
|
||||
var keys = new List<string>();
|
||||
foreach (var tag in profile.AllExpressions(context).PossibleTags()) {
|
||||
keys.Add(tag.Key.Quoted());
|
||||
}
|
||||
foreach (var tag in profile.AllExpressions(context).PossibleTags()) keys.Add(tag.Key.Quoted());
|
||||
|
||||
var meta = new Dictionary<string, string> {
|
||||
{"name", behaviour.Key},
|
||||
{"type", profileName},
|
||||
{"author", author},
|
||||
{"description", behaviourDescription + " (" + profileDescription + ")"}
|
||||
var meta = new Dictionary<string, string>
|
||||
{
|
||||
{ "name", behaviour.Key },
|
||||
{ "type", profileName },
|
||||
{ "author", author },
|
||||
{ "description", behaviourDescription + " (" + profileDescription + ")" }
|
||||
};
|
||||
var json = string.Join(",", meta.Select(d =>
|
||||
$"\"{d.Key}\": \"{d.Value}\""));
|
||||
|
||||
|
||||
metaItems.Add($"{{{json}, " +
|
||||
$"\"usedKeys\": [{string.Join(", ",keys)}] }}\n");
|
||||
$"\"usedKeys\": [{string.Join(", ", keys)}] }}\n");
|
||||
}
|
||||
}
|
||||
|
||||
return "[" + string.Join(",\n", metaItems) + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an object, converts it to a double.
|
||||
* throws an exception if not a double
|
||||
*/
|
||||
public static double AsDouble(object obj, string paramName)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
throw new Exception($"Invalid value as result for {paramName}: got null");
|
||||
}
|
||||
switch (obj)
|
||||
{
|
||||
case bool b:
|
||||
return b ? 1.0 : 0.0;
|
||||
case double d:
|
||||
return d;
|
||||
case int j:
|
||||
return j;
|
||||
case string s:
|
||||
if (s.Equals("yes")) return 1.0;
|
||||
|
||||
if (s.Equals("no")) return 0.0;
|
||||
|
||||
throw new Exception($"Invalid value as result for {paramName}: got string {s}");
|
||||
default:
|
||||
throw new Exception($"Invalid value as result for {paramName}: got object {obj}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue