Add snippets, more fixes to 'must_match', various small iprovements

This commit is contained in:
Pieter Vander Vennet 2021-04-05 18:33:46 +02:00
parent a116fd1bdb
commit 6cefdf5602
11 changed files with 134 additions and 20 deletions

View file

@ -11,7 +11,7 @@ namespace AspectedRouting.IO.LuaSnippets
public override string Convert(LuaSkeleton.LuaSkeleton lua, string assignTo, List<IExpression> args)
{
var fCond = args[0];
var fCond = args[0].Optimize();
var fValue = args[1];
IExpression fElse = null;
var arg = args[2];
@ -26,7 +26,7 @@ namespace AspectedRouting.IO.LuaSnippets
var condApplied = fCond.Apply(arg);
var isString = condApplied.Types.First().Equals(Typs.String);
result += Snippets.Convert(lua, c, condApplied)+"\n";
result += "if ( "+c + (isString ? " == \"yes\"" : "") + " ) then \n";
result += $"if ( {c} or {c} == \"yes\" ) then \n";
result += " " + Snippets.Convert(lua, assignTo, fValue.Apply(arg)).Indent() ;
if (fElse != null) {

View file

@ -0,0 +1,39 @@
using System.Collections.Generic;
using System.Linq;
using AspectedRouting.Language;
using AspectedRouting.Language.Typ;
namespace AspectedRouting.IO.LuaSnippets
{
public class IfThenElseSnippet : LuaSnippet
{
public IfThenElseSnippet() : base(Funcs.If) { }
public override string Convert(LuaSkeleton.LuaSkeleton lua, string assignTo, List<IExpression> args)
{
var cond = args[0].Optimize();
var ifTrue = args[1];
IExpression ifElse = null;
if (args.Count == 3) {
ifElse = args[2];
}
var c = lua.FreeVar("cond");
var result = "";
result += "local " + c+"\n";
var isString = cond.Types.First().Equals(Typs.String);
result += Snippets.Convert(lua, c, cond)+"\n";
result += $"if ( {c} or {c} == \"yes\" ) then \n";
result += " " + Snippets.Convert(lua, assignTo, ifTrue).Indent() ;
if (ifElse != null) {
result += "else\n";
result += " " + Snippets.Convert(lua, assignTo, ifElse).Indent();
}
result += "end\n";
return result;
}
}
}

View file

@ -0,0 +1,43 @@
using System.Collections.Generic;
using AspectedRouting.IO.LuaSkeleton;
using AspectedRouting.Language;
using AspectedRouting.Language.Expression;
namespace AspectedRouting.IO.LuaSnippets
{
public class MustMatchSnippet : LuaSnippet
{
public MustMatchSnippet() : base(Funcs.MustMatch) { }
public override string Convert(LuaSkeleton.LuaSkeleton lua, string assignTo, List<IExpression> args)
{
var neededKeysExpr = args[0];
var funcExpr = args[1];
var tagsExpr = args[2];
var result = "";
var neededKeys = lua.FreeVar("neededKeys");
var tags = "";
if (tagsExpr is LuaLiteral literal) {
tags = literal.Lua;
}
else {
tags = lua.FreeVar("tags");
result += $"local {tags}";
result += Snippets.Convert(lua, tags, tagsExpr);
}
result += $"local {neededKeys}\n";
result += Snippets.Convert(lua, neededKeys, neededKeysExpr);
var key = lua.FreeVar("key");
var value = lua.FreeVar("value");
result += $"for _, {key} in ipairs({neededKeys}) do\n";
result += $" local {value} = {tags}[{key}]\n";
result += $" if ({value} == nil) then\n";
result += $" -- The value is nil, so mustmatch probably fails...\n";
throw new System.NotImplementedException();
}
}
}

View file

@ -4,6 +4,7 @@ using System.Linq;
using AspectedRouting.Language;
using AspectedRouting.Language.Expression;
using AspectedRouting.Language.Functions;
using AspectedRouting.Language.Typ;
namespace AspectedRouting.IO.LuaSnippets
{
@ -17,10 +18,12 @@ namespace AspectedRouting.IO.LuaSnippets
new SumSnippet(),
new MaxSnippet(),
new MinSnippet(),
new IfThenElseSnippet(),
new IfThenElseDottedSnippet(),
new InvSnippet(),
new HeadSnippet(),
new MemberOfSnippet()
new MemberOfSnippet(),
// new MustMatchSnippet()
};
private static readonly Dictionary<string, LuaSnippet> SnippetsIndex = AllSnippets.ToDictionary(
@ -31,7 +34,10 @@ namespace AspectedRouting.IO.LuaSnippets
{
var opt = e.Optimize();
if (!Equals(e.Types.First(), opt.Types.First())) {
// Note that optimization might optimize to a _subtype_ of the original expresion - which is fine!
var origType = e.Types.First();
var optType = opt.Types.First();
if (!origType.Equals(optType) && !origType.IsSuperSet(optType)) {
throw new Exception("Optimization went wrong!");
}
e = opt;

View file

@ -40,7 +40,7 @@ namespace AspectedRouting.IO.itinero1
" result.attributes_to_keep = {}",
"",
" local access = " + access,
" if (access == nil or access == \"no\") then",
" if (access == nil or access == \"no\" or access == false) then",
" return",
" end",
" tags.access = access",

View file

@ -24,7 +24,8 @@ namespace AspectedRouting.IO.itinero1
{
_profile = profile;
_context = context;
_aspectTestSuites = aspectTestSuites;
_aspectTestSuites = aspectTestSuites?.Where(suite => suite != null)
?.Select(testSuite => testSuite.WithoutRelationTests())?.ToList();
_profileTests = profileTests;
_skeleton = new LuaSkeleton.LuaSkeleton(context, false);
_parameterPrinter = new LuaParameterPrinter(profile, _skeleton);

View file

@ -122,7 +122,7 @@ namespace AspectedRouting.IO.itinero2
" -- we overwrite the 'access_forward'-value with no; whatever it was...",
" access_forward = \"no\"",
" end",
" if(access_forward ~= nil and access_forward ~= \"no\") then",
" if(access_forward ~= nil and access_forward ~= \"no\" and access_forward ~= false) then",
" tags.access = access_forward -- might be relevant, e.g. for 'access=dismount' for bicycles",
" result.forward_speed = " + _skeleton.ToLua(_profile.Speed).Indent(),
" tags.speed = result.forward_speed",
@ -142,7 +142,7 @@ namespace AspectedRouting.IO.itinero2
" -- we overwrite the 'access_forward'-value with no; whatever it was...",
" access_backward = \"no\"",
" end",
" if(access_backward ~= nil and access_backward ~= \"no\") then",
" if(access_backward ~= nil and access_backward ~= \"no\" and access_backward ~= false) then",
" tags.access = access_backward",
" result.backward_speed = " + _skeleton.ToLua(_profile.Speed).Indent(),
" tags.speed = result.backward_speed",

View file

@ -25,28 +25,29 @@ Arguments:
function must_match(needed_keys, table, tags, result)
for _, key in ipairs(needed_keys) do
local v = tags[key]
local mapping = table[key]
if (v == nil) then
-- a key is missing...
-- 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]
-- note that the mapping might already be executed
if (mapping == true or mapping == "yes") then
-- The function for this key returned "true" despite being fed 'nil'
-- So, we can safely assume that the absence of this key is fine!
-- PASS
elseif (type(mapping) == "table") then
-- there is a mapping! We might be in luck... What does it have for 'nil'?
local resultValue = mapping[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 (mapping == nil) then
if (mapping == nil) then
-- the mapping is nil! That is fine, the key is present anyway
-- we ignore
elseif (type(mapping) == "table") then

View file

@ -1,3 +1,6 @@
function stringToTags(table, tags)
if (tags == nil) then
return table
end
return table_to_list(tags, {}, table)
end

View file

@ -11,8 +11,12 @@ function unit_test(f, fname, index, expected, parameters, tags)
-- OK!
elseif(tonumber(actual) and tonumber(expected) and math.abs(tonumber(actual) - tonumber(expected)) < 0.1) then
-- OK!
elseif (tostring(actual) ~= expected) then
print("[" .. fname .. "] " .. index .. " failed: expected " .. expected .. " but got " .. tostring(actual))
elseif (expected == "no" and actual == false) then
-- OK!
elseif (expected == actual) then
-- OK!
elseif (tostring(actual) ~= tostring(expected)) then
print("[" .. fname .. "] " .. index .. " failed: expected " .. tostring(expected) .. " but got " .. tostring(actual))
failed_tests = true
end
end

View file

@ -53,6 +53,23 @@ namespace AspectedRouting.Tests
return new AspectTestSuite(function, tests);
}
/// <summary>
/// Returns a test suite where no tests are kept which contain keys of the scheme '_relation:<name>:<key>'
/// </summary>
/// <returns></returns>
public AspectTestSuite WithoutRelationTests()
{
var newTests = new List<(string expected, Dictionary<string, string> tags)>();
foreach (var (expected, tags) in Tests) {
if (tags.Keys.Any(key => key.StartsWith("_relation") && key.Split(":").Length ==3)) {
continue;
}
newTests.Add((expected, tags));
}
return new AspectTestSuite(FunctionToApply, newTests);
}
public bool Run()
{