improve call and conditions api
This commit is contained in:
parent
f3796d29b4
commit
ce62a78f5a
2 changed files with 76 additions and 120 deletions
68
lib.nix
68
lib.nix
|
@ -26,6 +26,9 @@ let
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
error = message: throw "[nix2lua] ${message}";
|
error = message: throw "[nix2lua] ${message}";
|
||||||
|
validationError = expr: message:
|
||||||
|
let val = if builtins.isFunction expr then "Function" else "Value '${toString expr}'"; in
|
||||||
|
error "${val} ${message}";
|
||||||
warn = msg: builtins.trace "[nix2lua] warning: ${msg}";
|
warn = msg: builtins.trace "[nix2lua] warning: ${msg}";
|
||||||
deprecated = before: now: warn "`${before}` is deprecated. Use `${now}` instead";
|
deprecated = before: now: warn "`${before}` is deprecated. Use `${now}` instead";
|
||||||
|
|
||||||
|
@ -34,11 +37,11 @@ let
|
||||||
validString = expr:
|
validString = expr:
|
||||||
if isRaw expr then validString expr.raw
|
if isRaw expr then validString expr.raw
|
||||||
else if isString expr || isPath expr then toString expr
|
else if isString expr || isPath expr then toString expr
|
||||||
else error "Value '${toString expr}' is not a valid string";
|
else validationError expr "is not a valid string";
|
||||||
|
|
||||||
validFuncName = fnName:
|
validFuncName = fnName:
|
||||||
if isString fnName && builtins.stringLength fnName > 0 then raw fnName
|
if isString fnName && builtins.stringLength fnName > 0 then raw fnName
|
||||||
else error "Value '${toString fnName}' is not a valid function name";
|
else validationError fnName "is not a valid function name";
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Low-Level
|
# Low-Level
|
||||||
|
@ -46,25 +49,16 @@ let
|
||||||
|
|
||||||
isRaw = expr: getType expr == "raw";
|
isRaw = expr: getType expr == "raw";
|
||||||
raw = expr:
|
raw = expr:
|
||||||
if isRaw expr then
|
if isRaw expr then { _type = "raw"; raw = expr.raw; }
|
||||||
{ _type = "raw"; raw = expr.raw; }
|
else if isString expr then { _type = "raw"; raw = expr; }
|
||||||
else if isString expr then
|
else validationError expr "is not supported for a raw type";
|
||||||
{ _type = "raw"; raw = expr; }
|
|
||||||
else
|
|
||||||
error "Value '${toString expr}' is not supported for a raw type";
|
|
||||||
|
|
||||||
isJoin = expr: getType expr == "_join";
|
isJoin = expr: getType expr == "_join";
|
||||||
join = sep: expr:
|
join = sep: expr:
|
||||||
if isList expr then { _type = "_join"; sep = validString sep; parts = expr; }
|
if isList expr then { _type = "_join"; sep = validString sep; parts = expr; }
|
||||||
else error "Value '${toString expr}' is not supported for a join type";
|
else validationError expr "is not supported for a join type";
|
||||||
|
|
||||||
concat = join "";
|
concat = join "";
|
||||||
concatLines = lines:
|
|
||||||
join "\n" (
|
|
||||||
lines
|
|
||||||
# add an empty line at the end
|
|
||||||
++ [ (raw "") ]
|
|
||||||
);
|
|
||||||
pipe = join ".";
|
pipe = join ".";
|
||||||
pipe1 = lft: rgt: pipe [ lft rgt ];
|
pipe1 = lft: rgt: pipe [ lft rgt ];
|
||||||
spaceBetween = join " ";
|
spaceBetween = join " ";
|
||||||
|
@ -74,10 +68,17 @@ let
|
||||||
wrapParen = wrap "(" ")";
|
wrapParen = wrap "(" ")";
|
||||||
|
|
||||||
call = fnName: args:
|
call = fnName: args:
|
||||||
concat [ (validFuncName fnName) (wrapParen (join ", " args)) ];
|
concat [
|
||||||
|
(validFuncName fnName)
|
||||||
|
(wrapParen (
|
||||||
|
if isList args then join ", " args
|
||||||
|
else if builtins.isFunction args then validationError args "is not supported to call args"
|
||||||
|
else args
|
||||||
|
))
|
||||||
|
];
|
||||||
call0 = fnName: call fnName [ ];
|
call0 = fnName: call fnName [ ];
|
||||||
call1 = fnName: arg: call fnName [ arg ];
|
call1 = fnName: arg: call fnName [ arg ];
|
||||||
require = name: call1 "require" name;
|
require = name: call "require" name;
|
||||||
|
|
||||||
kw_and = raw "and";
|
kw_and = raw "and";
|
||||||
kw_or = raw "or";
|
kw_or = raw "or";
|
||||||
|
@ -117,36 +118,38 @@ let
|
||||||
or = op kw_or;
|
or = op kw_or;
|
||||||
not = expr: spaceBetween [ kw_not expr ];
|
not = expr: spaceBetween [ kw_not expr ];
|
||||||
|
|
||||||
|
# Type: validBlockBody :: a -> [b]
|
||||||
|
validBlockBody = body:
|
||||||
|
if isList body then body
|
||||||
|
else if isAttrs body then [ body ]
|
||||||
|
else validationError body "is not valid block body";
|
||||||
|
|
||||||
local = expr: spaceBetween [ kw_local expr ];
|
local = expr: spaceBetween [ kw_local expr ];
|
||||||
set = variable: value: join " = " [ (raw variable) value ];
|
set = variable: value: join " = " [ (raw variable) value ];
|
||||||
func = fnName: params: body:
|
func = fnName: params: body:
|
||||||
let
|
(spaceBetween
|
||||||
f =
|
|
||||||
if isList body then concatLines
|
|
||||||
else if isAttrs body then spaceBetween
|
|
||||||
else error "Value ${toString body} is not a valid function body";
|
|
||||||
in
|
|
||||||
(f
|
|
||||||
([
|
([
|
||||||
(concat [
|
(concat [
|
||||||
(spaceBetween [ kw_function (validFuncName fnName) ])
|
(spaceBetween [ kw_function (validFuncName fnName) ])
|
||||||
(wrapParen (join ", " (map raw params)))
|
(wrapParen (join ", " (map raw params)))
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
++ (if isList body then body else if isAttrs body then [ body ] else [ ])
|
++ (validBlockBody body)
|
||||||
++ [ kw_end ])
|
++ [ kw_end ])
|
||||||
);
|
);
|
||||||
|
func0 = fnName: func fnName [ ];
|
||||||
lambda = func "";
|
lambda = func "";
|
||||||
lambda0 = lambda [ ];
|
lambda0 = lambda [ ];
|
||||||
|
|
||||||
return = expr: spaceBetween ([ kw_return expr ]);
|
return = expr: spaceBetween ([ kw_return expr ]);
|
||||||
return_void = return null;
|
return_void = return
|
||||||
|
null;
|
||||||
|
|
||||||
ifelse = condition: trueBody: falseBody:
|
ifelse = condition: trueBody: falseBody:
|
||||||
(concatLines
|
(spaceBetween
|
||||||
([ (spaceBetween [ kw_if condition kw_then ]) ]
|
([ kw_if condition kw_then ]
|
||||||
++ trueBody
|
++ (validBlockBody trueBody)
|
||||||
++ (if falseBody != [ ] then [ kw_else ] ++ falseBody else [ ])
|
++ (if falseBody != [ ] then [ kw_else ] ++ (validBlockBody falseBody) else [ ])
|
||||||
++ [ kw_end ])
|
++ [ kw_end ])
|
||||||
);
|
);
|
||||||
if' = condition: trueBody: ifelse condition trueBody [ ];
|
if' = condition: trueBody: ifelse condition trueBody [ ];
|
||||||
|
@ -198,17 +201,18 @@ in
|
||||||
mkLuaRaw = deprecated "mkLuaRaw" "raw" raw;
|
mkLuaRaw = deprecated "mkLuaRaw" "raw" raw;
|
||||||
mkCall = deprecated "mkCall" "call" call;
|
mkCall = deprecated "mkCall" "call" call;
|
||||||
mkNamedField = deprecated "mkNamedField" "namedField" namedField;
|
mkNamedField = deprecated "mkNamedField" "namedField" namedField;
|
||||||
|
concatLines = deprecated "concatLines" "spaceBetween" spaceBetween;
|
||||||
|
|
||||||
inherit toLua;
|
inherit toLua;
|
||||||
|
|
||||||
inherit LuaNil;
|
inherit LuaNil;
|
||||||
inherit raw join concat concatLines;
|
inherit raw join concat spaceBetween;
|
||||||
inherit pipe pipe1;
|
inherit pipe pipe1;
|
||||||
|
|
||||||
inherit namedField require local set ifelse if';
|
inherit namedField require local set ifelse if';
|
||||||
|
|
||||||
inherit call call0 call1;
|
inherit call call0 call1;
|
||||||
inherit func lambda lambda0;
|
inherit func func0 lambda lambda0;
|
||||||
|
|
||||||
inherit op;
|
inherit op;
|
||||||
inherit eq ne gt lt gte lte;
|
inherit eq ne gt lt gte lte;
|
||||||
|
|
128
lib.test.nix
128
lib.test.nix
|
@ -33,11 +33,11 @@ with nix2lua; pkgs.lib.runTests {
|
||||||
};
|
};
|
||||||
"test returns a lua string" = {
|
"test returns a lua string" = {
|
||||||
expr = toLua "hello world";
|
expr = toLua "hello world";
|
||||||
expected = "\"hello world\"";
|
expected = ''"hello world"'';
|
||||||
};
|
};
|
||||||
"test returns a path as a lua string" = {
|
"test returns a path as a lua string" = {
|
||||||
expr = toLua /hello/world;
|
expr = toLua /hello/world;
|
||||||
expected = "\"/hello/world\"";
|
expected = ''"/hello/world"'';
|
||||||
};
|
};
|
||||||
"test returns an integer number" = {
|
"test returns an integer number" = {
|
||||||
expr = toLua 10;
|
expr = toLua 10;
|
||||||
|
@ -61,11 +61,11 @@ with nix2lua; pkgs.lib.runTests {
|
||||||
};
|
};
|
||||||
"test returns table with all primitive types" = {
|
"test returns table with all primitive types" = {
|
||||||
expr = toLua [ "hello" 10 10.1 true ];
|
expr = toLua [ "hello" 10 10.1 true ];
|
||||||
expected = "{ \"hello\", 10, 10.100000, true }";
|
expected = ''{ "hello", 10, 10.100000, true }'';
|
||||||
};
|
};
|
||||||
"test returns table without null values" = {
|
"test returns table without null values" = {
|
||||||
expr = toLua [ null "hello" null 10 null 10.1 null true null ];
|
expr = toLua [ null "hello" null 10 null 10.1 null true null ];
|
||||||
expected = "{ \"hello\", 10, 10.100000, true }";
|
expected = ''{ "hello", 10, 10.100000, true }'';
|
||||||
};
|
};
|
||||||
"test returns named table" = {
|
"test returns named table" = {
|
||||||
expr = toLua {
|
expr = toLua {
|
||||||
|
@ -75,11 +75,11 @@ with nix2lua; pkgs.lib.runTests {
|
||||||
success = true;
|
success = true;
|
||||||
fail = false;
|
fail = false;
|
||||||
};
|
};
|
||||||
expected = "{ [\"fail\"] = false, [\"float\"] = 10.100000, [\"foo\"] = \"hello\", [\"int\"] = 10, [\"success\"] = true }";
|
expected = ''{ ["fail"] = false, ["float"] = 10.100000, ["foo"] = "hello", ["int"] = 10, ["success"] = true }'';
|
||||||
};
|
};
|
||||||
"test returns named table without nullable items" = {
|
"test returns named table without nullable items" = {
|
||||||
expr = toLua { foo = "hello"; bar = null; };
|
expr = toLua { foo = "hello"; bar = null; };
|
||||||
expected = "{ [\"foo\"] = \"hello\" }";
|
expected = ''{ ["foo"] = "hello" }'';
|
||||||
};
|
};
|
||||||
"test returns recursive named table" = {
|
"test returns recursive named table" = {
|
||||||
expr = toLua {
|
expr = toLua {
|
||||||
|
@ -89,11 +89,11 @@ with nix2lua; pkgs.lib.runTests {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
expected = "{ [\"first\"] = { [\"second\"] = { [\"last\"] = \"hello\" } } }";
|
expected = ''{ ["first"] = { ["second"] = { ["last"] = "hello" } } }'';
|
||||||
};
|
};
|
||||||
"test return recursive table" = {
|
"test return recursive table" = {
|
||||||
expr = toLua [ [ [ "foo" ] "bar" ] ];
|
expr = toLua [ [ [ "foo" ] "bar" ] ];
|
||||||
expected = "{ { { \"foo\" }, \"bar\" } }";
|
expected = ''{ { { "foo" }, "bar" } }'';
|
||||||
};
|
};
|
||||||
"test returns table with one named field" = {
|
"test returns table with one named field" = {
|
||||||
expr = toLua [
|
expr = toLua [
|
||||||
|
@ -101,7 +101,7 @@ with nix2lua; pkgs.lib.runTests {
|
||||||
(namedField "foo" "hello")
|
(namedField "foo" "hello")
|
||||||
10
|
10
|
||||||
];
|
];
|
||||||
expected = "{ \"foo\", [\"foo\"] = \"hello\", 10 }";
|
expected = ''{ "foo", ["foo"] = "hello", 10 }'';
|
||||||
};
|
};
|
||||||
"test returns raw string" = {
|
"test returns raw string" = {
|
||||||
expr = toLua (raw "hello");
|
expr = toLua (raw "hello");
|
||||||
|
@ -113,7 +113,7 @@ with nix2lua; pkgs.lib.runTests {
|
||||||
};
|
};
|
||||||
"test returns path as string" = {
|
"test returns path as string" = {
|
||||||
expr = toLua /foo/bar;
|
expr = toLua /foo/bar;
|
||||||
expected = "\"/foo/bar\"";
|
expected = ''"/foo/bar"'';
|
||||||
};
|
};
|
||||||
"test throws an error when you try to use named field withoun table" = {
|
"test throws an error when you try to use named field withoun table" = {
|
||||||
expr = tryEval (toLua (namedField "foo" "bar"));
|
expr = tryEval (toLua (namedField "foo" "bar"));
|
||||||
|
@ -121,17 +121,14 @@ with nix2lua; pkgs.lib.runTests {
|
||||||
};
|
};
|
||||||
"test returns call function with arguments" = {
|
"test returns call function with arguments" = {
|
||||||
expr = toLua (call "root_pattern" [ "deno.json" "deno.jsonc" ]);
|
expr = toLua (call "root_pattern" [ "deno.json" "deno.jsonc" ]);
|
||||||
expected = "root_pattern(\"deno.json\", \"deno.jsonc\")";
|
expected = ''root_pattern("deno.json", "deno.jsonc")'';
|
||||||
};
|
};
|
||||||
"test returns concated lines" = {
|
"test returns concated expressions" = {
|
||||||
expr = toLua (concatLines [
|
expr = toLua (spaceBetween [
|
||||||
(call "foo" [ 1 2 ])
|
(call "foo" [ 1 2 ])
|
||||||
(call "bar" [ "baz" "biz" ])
|
(call "bar" [ "baz" "biz" ])
|
||||||
]);
|
]);
|
||||||
expected = ''
|
expected = ''foo(1, 2) bar("baz", "biz")'';
|
||||||
foo(1, 2)
|
|
||||||
bar("baz", "biz")
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
"test returns a pipe with many function call" = {
|
"test returns a pipe with many function call" = {
|
||||||
expr = toLua (pipe [
|
expr = toLua (pipe [
|
||||||
|
@ -149,18 +146,13 @@ with nix2lua; pkgs.lib.runTests {
|
||||||
expected = "local parser_config.d2 = { }";
|
expected = "local parser_config.d2 = { }";
|
||||||
};
|
};
|
||||||
"test returns all operations" = {
|
"test returns all operations" = {
|
||||||
expr = toLua (concatLines [
|
expr = toLua (spaceBetween [
|
||||||
(eq (mul (add 1 2) (sub 2 1)) 3)
|
(set "a" (eq (mul (add 1 2) (sub 2 1)) 3))
|
||||||
(not (eq (mul (add 1 2) (sub 2 1)) 3))
|
(set "b" (not (eq (mul (add 1 2) (sub 2 1)) 3)))
|
||||||
(not 10)
|
(set "c" (not 10))
|
||||||
(gt 10 5)
|
(set "d" (gt 10 5))
|
||||||
]);
|
]);
|
||||||
expected = ''
|
expected = ''a = (((1 + 2) * (2 - 1)) == 3) b = not (((1 + 2) * (2 - 1)) == 3) c = not 10 d = (10 > 5)'';
|
||||||
(((1 + 2) * (2 - 1)) == 3)
|
|
||||||
not (((1 + 2) * (2 - 1)) == 3)
|
|
||||||
not 10
|
|
||||||
(10 > 5)
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
"test returns rendered condition" = {
|
"test returns rendered condition" = {
|
||||||
expr = toLua (set "name"
|
expr = toLua (set "name"
|
||||||
|
@ -168,82 +160,42 @@ with nix2lua; pkgs.lib.runTests {
|
||||||
);
|
);
|
||||||
expected = "name = ((a >= 1) and (a <= 10))";
|
expected = "name = ((a >= 1) and (a <= 10))";
|
||||||
};
|
};
|
||||||
"test returns defined multiline function" = {
|
"test returns defined function" = {
|
||||||
expr = toLua (func "hello" [ "a" "b" ] [
|
expr = toLua (func "hello" [ "a" "b" ] [
|
||||||
(eq (mul (add (var "a") 2) (sub 2 1)) 3)
|
(set "a" (eq (mul (add 1 2) (sub 2 1)) 3))
|
||||||
(not (eq (mul (add (var "b") 2) (sub 2 1)) 3))
|
(set "b" (not (eq (mul (add 1 2) (sub 2 1)) 3)))
|
||||||
(not 10)
|
(set "c" (not 10))
|
||||||
(gt 10 5)
|
(set "d" (gt 10 5))
|
||||||
]);
|
]);
|
||||||
expected = ''
|
expected = ''function hello(a, b) a = (((1 + 2) * (2 - 1)) == 3) b = not (((1 + 2) * (2 - 1)) == 3) c = not 10 d = (10 > 5) end'';
|
||||||
function hello(a, b)
|
|
||||||
(((a + 2) * (2 - 1)) == 3)
|
|
||||||
not (((b + 2) * (2 - 1)) == 3)
|
|
||||||
not 10
|
|
||||||
(10 > 5)
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
"test returns defined singleline function" = {
|
"test returns defined singleline function" = {
|
||||||
expr = toLua (func "hello" [ "a" ] (call1 "h.world" (var "a")));
|
expr = toLua (func "hello" [ "a" ] (call1 "h.world" (var "a")));
|
||||||
expected = "function hello(a) h.world(a) end";
|
expected = "function hello(a) h.world(a) end";
|
||||||
};
|
};
|
||||||
"test returns if statement" = {
|
"test returns if statement" = {
|
||||||
expr = toLua (if' (eq 10 10) [
|
expr = toLua (if' (eq 10 10) (call "print" [ 10 ]));
|
||||||
(call "print" [ 10 ])
|
expected = ''if (10 == 10) then print(10) end'';
|
||||||
]);
|
|
||||||
expected = ''
|
|
||||||
if (10 == 10) then
|
|
||||||
print(10)
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
"test returns if else statement" = {
|
"test returns if else statement" = {
|
||||||
expr = toLua (ifelse (eq 10 10) [
|
expr = toLua (ifelse (eq 10 10) [
|
||||||
(call "print" [ "10 == 10" ])
|
(call "print" "10 == 10")
|
||||||
|
(call "print" "10 == 10")
|
||||||
] [
|
] [
|
||||||
(call "print" [ "10 != 10" ])
|
(call "print" "10 != 10")
|
||||||
|
(call "print" "10 != 10")
|
||||||
]);
|
]);
|
||||||
expected = ''
|
expected = ''if (10 == 10) then print("10 == 10") print("10 == 10") else print("10 != 10") print("10 != 10") end'';
|
||||||
if (10 == 10) then
|
|
||||||
print("10 == 10")
|
|
||||||
else
|
|
||||||
print("10 != 10")
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
"test returns a deep if else statement" = {
|
"test returns a deep if else statement" = {
|
||||||
expr = toLua (ifelse (eq 10 10) [
|
expr = toLua (ifelse (eq 10 10)
|
||||||
(if' true [ (call "print" [ "yes" ]) ])
|
(if' true (call "print" "yes"))
|
||||||
] [
|
(if' true (call "print" "no"))
|
||||||
(if' true [ (call "print" [ "no" ]) ])
|
);
|
||||||
]);
|
expected = ''if (10 == 10) then if true then print("yes") end else if true then print("no") end end'';
|
||||||
expected = ''
|
|
||||||
if (10 == 10) then
|
|
||||||
if true then
|
|
||||||
print("yes")
|
|
||||||
end
|
|
||||||
|
|
||||||
else
|
|
||||||
if true then
|
|
||||||
print("no")
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
"test returns a returns keyword" = {
|
"test returns a returns keyword" = {
|
||||||
expr = toLua (ifelse (eq 10 10) [
|
expr = toLua (ifelse (eq 10 10) return_void (return 10));
|
||||||
return_void
|
expected = ''if (10 == 10) then return else return 10 end'';
|
||||||
] [
|
|
||||||
(return 10)
|
|
||||||
]);
|
|
||||||
expected = ''
|
|
||||||
if (10 == 10) then
|
|
||||||
return
|
|
||||||
else
|
|
||||||
return 10
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue