Fixed order of arguments, fix various issues in lua output
This commit is contained in:
parent
e2cd6caa70
commit
a116fd1bdb
13 changed files with 128 additions and 50 deletions
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<LangVersion>8</LangVersion>
|
||||
<AssemblyName>AspectedRouting</AssemblyName>
|
||||
<RootNamespace>AspectedRouting</RootNamespace>
|
||||
|
|
|
@ -28,10 +28,10 @@ namespace AspectedRouting.IO.LuaSkeleton
|
|||
Assign(collectedMapping))
|
||||
).Invoke(bare)) {
|
||||
AddDep(Funcs.FirstOf.Name);
|
||||
return "first_match_of(tags, result, \n" +
|
||||
" " + ToLua(order.First(), key) + "," +
|
||||
return "first_match_of(\n" +
|
||||
" " + ToLua(order.First(), key) + ",\n" +
|
||||
("\n" + MappingToLua((Mapping) collectedMapping.First())).Indent().Indent() +
|
||||
")";
|
||||
",\n tags, result)";
|
||||
}
|
||||
|
||||
if (UnApply(
|
||||
|
@ -43,10 +43,10 @@ namespace AspectedRouting.IO.LuaSkeleton
|
|||
Assign(collectedMapping))
|
||||
).Invoke(bare)) {
|
||||
AddDep(Funcs.MustMatch.Name);
|
||||
return "must_match(tags, result, \n" +
|
||||
return "must_match(" +
|
||||
" " + ToLua(order.First(), key) + "," +
|
||||
("\n" + MappingToLua((Mapping) collectedMapping.First())).Indent().Indent() +
|
||||
")";
|
||||
",\n tags, result)";
|
||||
}
|
||||
|
||||
if (UnApply(
|
||||
|
@ -124,7 +124,14 @@ namespace AspectedRouting.IO.LuaSkeleton
|
|||
var fArgs = bare.DeconstructApply();
|
||||
if (fArgs != null) {
|
||||
var (f, args) = fArgs.Value;
|
||||
var baseFunc = (Function) f;
|
||||
|
||||
if(f is Constant constant) {
|
||||
return ConstantToLua(constant);
|
||||
}
|
||||
|
||||
if (!(f is Function baseFunc)) {
|
||||
throw new ArgumentException("Not a function: " + f);
|
||||
}
|
||||
|
||||
if (baseFunc.Name.Equals(Funcs.Id.Name)) {
|
||||
// This is an ugly hack
|
||||
|
|
|
@ -45,6 +45,10 @@ namespace AspectedRouting.IO.LuaSkeleton
|
|||
if (name.StartsWith("mapping")) {
|
||||
throw new Exception("A mapping was added as dependency - this is a bug");
|
||||
}
|
||||
|
||||
if (name.Contains("stringToTags")) {
|
||||
AddDep("table_to_list");
|
||||
}
|
||||
_dependencies.Add(name);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
function first_match_of(tags, result, order_of_keys, table)
|
||||
function first_match_of(order_of_keys, table, tags, result)
|
||||
if (result == nil) then
|
||||
result = { attributes_to_keep = {} }
|
||||
end
|
||||
for _, key in pairs(order_of_keys) do
|
||||
local v = tags[key]
|
||||
if (v ~= nil) then
|
|
@ -22,16 +22,34 @@ Arguments:
|
|||
- table which is the table to match
|
||||
|
||||
]]
|
||||
function must_match(tags, result, needed_keys, table)
|
||||
function must_match(needed_keys, table, tags, result)
|
||||
for _, key in ipairs(needed_keys) do
|
||||
local v = tags[key]
|
||||
if (v == nil) then
|
||||
-- a key is missing...
|
||||
return false
|
||||
|
||||
-- this probably means that we must return false... unless the mapping returns something for null!
|
||||
local mappng = table[key]
|
||||
if (mappng ~= nil) then
|
||||
-- there is a mapping! We might be in luck...
|
||||
local resultValue = mappng[v]
|
||||
if (resultValue == nil or resultValue == false) then
|
||||
-- nope, no luck after all
|
||||
return false
|
||||
end
|
||||
if (resultValue == true or resultValue == "yes") then
|
||||
return true
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local mapping = table[key]
|
||||
if (type(mapping) == "table") then
|
||||
if (mapping == nil) then
|
||||
-- the mapping is nil! That is fine, the key is present anyway
|
||||
-- we ignore
|
||||
elseif (type(mapping) == "table") then
|
||||
-- we have to map the value with a function:
|
||||
local resultValue = mapping[v]
|
||||
if (resultValue ~= nil or -- actually, having nil for a mapping is fine for this function!.
|
||||
|
@ -50,15 +68,19 @@ function must_match(tags, result, needed_keys, table)
|
|||
error("MustMatch got a string value it can't handle: " .. bool)
|
||||
end
|
||||
elseif (type(mapping) == "boolean") then
|
||||
if(not mapping) then
|
||||
if (not mapping) then
|
||||
return false
|
||||
end
|
||||
else
|
||||
error("The mapping is not a table. This is not supported. We got " .. tostring(mapping) .. " (" .. type(mapping)..")")
|
||||
error("The mapping is not a table. This is not supported. We got " .. tostring(mapping) .. " (" .. type(mapping) .. ")")
|
||||
end
|
||||
end
|
||||
|
||||
-- Now that we know for sure that every key matches, we add them all
|
||||
-- Now that we know for sure that every key matches, we add them all to the 'attributes_to_keep'
|
||||
if (result == nil) then
|
||||
-- euhm, well, seems like we don't are about the attributes_to_keep; early return!
|
||||
return true
|
||||
end
|
||||
for _, key in ipairs(needed_keys) do
|
||||
local v = tags[key] -- this is the only place where we use the original tags
|
||||
if (v ~= nil) then
|
|
@ -1,5 +1,8 @@
|
|||
function table_to_list(tags, result, factor_table)
|
||||
local list = {}
|
||||
if(tags == nil) then
|
||||
return list
|
||||
end
|
||||
for key, mapping in pairs(factor_table) do
|
||||
local v = tags[key]
|
||||
if (v ~= nil) then
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace AspectedRouting.Language.Functions
|
|||
"E.g. `$firstMatchOf ['maxspeed','highway'] {'maxspeed' --> $parse, 'highway' --> {residential --> 30, tertiary --> 50}}` applied on `{maxspeed=70, highway=tertiary}` will yield `70` as that is the first key in the list; `{highway=residential}` will yield `30`.";
|
||||
public override List<string> ArgNames { get; } = new List<string> {"s"};
|
||||
|
||||
public FirstMatchOf() : base("firstMatchOf", true,
|
||||
public FirstMatchOf() : base("first_match_of", true,
|
||||
new[]
|
||||
{
|
||||
// [String] -> (Tags -> [a]) -> Tags -> a
|
||||
|
@ -23,9 +23,10 @@ namespace AspectedRouting.Language.Functions
|
|||
)
|
||||
})
|
||||
{
|
||||
Funcs.AddBuiltin( this,"firstMatchOf");
|
||||
}
|
||||
|
||||
private FirstMatchOf(IEnumerable<Type> types) : base("firstMatchOf", types)
|
||||
private FirstMatchOf(IEnumerable<Type> types) : base("first_match_of", types)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -89,8 +89,12 @@ namespace AspectedRouting.Language.Functions
|
|||
|
||||
var key = (string) s;
|
||||
var otherARgs = arguments.ToList().GetRange(1, arguments.Length - 1);
|
||||
if (!StringToResultFunctions.TryGetValue(key, out var resultFunction))
|
||||
{
|
||||
if (!StringToResultFunctions.ContainsKey(key)) { // This is really roundabout, but it has to be
|
||||
return null;
|
||||
}
|
||||
|
||||
var resultFunction = StringToResultFunctions[key];
|
||||
if (resultFunction == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,22 @@
|
|||
using System.Collections.Generic;
|
||||
using AspectedRouting.Language.Expression;
|
||||
using AspectedRouting.Language.Typ;
|
||||
using Type = AspectedRouting.Language.Typ.Type;
|
||||
|
||||
namespace AspectedRouting.Language.Functions
|
||||
{
|
||||
public class MemberOf : Function
|
||||
{
|
||||
public MemberOf() : base(
|
||||
"memberOf", true,
|
||||
new[] {
|
||||
new Curry(
|
||||
new Curry(Typs.Tags, Typs.Bool),
|
||||
new Curry(Typs.Tags, Typs.Bool))
|
||||
}
|
||||
) { }
|
||||
|
||||
public MemberOf(IEnumerable<Type> types) : base("memberOf", types) { }
|
||||
|
||||
public override string Description { get; } =
|
||||
"This function returns true, if the way is member of a relation matching the specified function.\n" +
|
||||
"\n" +
|
||||
|
@ -23,44 +33,51 @@ namespace AspectedRouting.Language.Functions
|
|||
"\n\n" +
|
||||
"In the test.csv, one can simply use `_relation:<aspect_name>=yes` to mimic relations in your tests";
|
||||
|
||||
public override List<string> ArgNames { get; } = new List<string>
|
||||
{
|
||||
"f","tags"
|
||||
public override List<string> ArgNames { get; } = new List<string> {
|
||||
"f", "tags"
|
||||
};
|
||||
|
||||
public MemberOf() : base(
|
||||
"memberOf", true,
|
||||
new[]
|
||||
{
|
||||
new Curry(
|
||||
new Curry(Typs.Tags, Typs.Bool),
|
||||
new Curry(Typs.Tags, Typs.Bool))
|
||||
}
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public MemberOf(IEnumerable<Type> types) : base("memberOf", types)
|
||||
{
|
||||
}
|
||||
|
||||
public override object Evaluate(Context c, params IExpression[] arguments)
|
||||
{
|
||||
var tags =(Dictionary<string, string>) arguments[1].Evaluate(c);
|
||||
var tags = (Dictionary<string, string>) arguments[1].Evaluate(c);
|
||||
var name = c.AspectName.TrimStart('$');
|
||||
|
||||
if(tags.TryGetValue("_relation:"+name, out var v))
|
||||
{
|
||||
|
||||
if (tags.TryGetValue("_relation:" + name, out var v)) {
|
||||
return v;
|
||||
}
|
||||
|
||||
// In the case of tests, relations might be added with "_relation:1:<key>"
|
||||
// So, we create this table as dictionary
|
||||
var relationTags = new Dictionary<string, Dictionary<string, string>>();
|
||||
foreach (var tag in tags) {
|
||||
if (tag.Key.StartsWith("_relation:")) {
|
||||
var keyParts = tag.Key.Split(":");
|
||||
if (keyParts.Length != 3) {
|
||||
continue;
|
||||
}
|
||||
var relationName = keyParts[1];
|
||||
if (!relationTags.ContainsKey(relationName)) {
|
||||
relationTags.Add(relationName, new Dictionary<string, string>());
|
||||
}
|
||||
|
||||
relationTags[relationName].Add(keyParts[2], tag.Value);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var relationTagging in relationTags) {
|
||||
var result = arguments[0].Evaluate(c, new Constant(relationTagging.Value));
|
||||
if (result.Equals("yes")) {
|
||||
return "yes";
|
||||
}
|
||||
}
|
||||
|
||||
return "no";
|
||||
}
|
||||
|
||||
public override IExpression Specialize(IEnumerable<Type> allowedTypes)
|
||||
{
|
||||
var unified = Types.SpecializeTo(allowedTypes);
|
||||
if (unified == null)
|
||||
{
|
||||
if (unified == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace AspectedRouting.Language.Functions
|
|||
{
|
||||
public class MustMatch : Function
|
||||
{
|
||||
public MustMatch() : base("mustMatch", true,
|
||||
public MustMatch() : base("must_match", true,
|
||||
new[] {
|
||||
// [String] -> (Tags -> [string]) -> Tags -> bool
|
||||
Curry.ConstructFrom(Typs.Bool, // Result type on top!
|
||||
|
@ -15,9 +15,12 @@ namespace AspectedRouting.Language.Functions
|
|||
new Curry(Typs.Tags, new ListType(Typs.String)), // The function to execute on every key
|
||||
Typs.Tags // The tags to apply this on
|
||||
)
|
||||
}) { }
|
||||
})
|
||||
{
|
||||
Funcs.AddBuiltin(this, "mustMatch");
|
||||
}
|
||||
|
||||
private MustMatch(IEnumerable<Type> types) : base("mustMatch", types) { }
|
||||
private MustMatch(IEnumerable<Type> types) : base("must_match", types) { }
|
||||
|
||||
public override string Description { get; } = Utils.Lines(
|
||||
"Checks that every specified key is present and gives a non-false value.\n",
|
||||
|
@ -64,7 +67,18 @@ namespace AspectedRouting.Language.Functions
|
|||
}
|
||||
|
||||
if (!tags.ContainsKey(tagKey)) {
|
||||
// A required key is missing: return 'no'
|
||||
// A required key is missing
|
||||
// Normally, we return no; but there is a second chance
|
||||
// IF the mapping returns 'yes' on null, we make an exception and ignore it
|
||||
var applied = function.Evaluate(c, new Constant(new Dictionary<string, string> {
|
||||
{tagKey, ""}
|
||||
}));
|
||||
if (applied == null) {
|
||||
return "no";
|
||||
}
|
||||
if (applied.Equals("yes") || (applied is IEnumerable<object> l && l.Count() > 0 && l.ToList()[0].Equals("yes")) ) {
|
||||
continue; // We ignore the absence of the key
|
||||
}
|
||||
return "no";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,9 @@ namespace AspectedRouting.Language.Functions
|
|||
{
|
||||
var f = arguments[0];
|
||||
var tags = (Dictionary<string, string>) arguments[1].Evaluate(c);
|
||||
if (tags == null) {
|
||||
return null;
|
||||
}
|
||||
var result = new List<object>();
|
||||
foreach (var (k, v) in tags)
|
||||
{
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace AspectedRouting.Tests
|
|||
var testCase = 0;
|
||||
foreach (var test in Tests) {
|
||||
testCase++;
|
||||
var context = new Context();
|
||||
var context = new Context().WithAspectName("unittest");
|
||||
foreach (var (key, value) in test.tags) {
|
||||
if (key.StartsWith("#")) {
|
||||
context.AddParameter(key, value);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue