Browse files

Support indexing tuple and list variable values.

Fixes #87.
  • Loading branch information...
1 parent c484084 commit c2aaf7db5101dc2eb52eebed220c35f03706416c @kaos kaos committed Dec 9, 2013
Showing with 29 additions and 9 deletions.
  1. +7 −2 src/erlydtl_compiler.erl
  2. +1 −0 src/erlydtl_parser.yrl
  3. +14 −6 src/erlydtl_runtime.erl
  4. +7 −1 tests/src/erlydtl_unittests.erl
View
9 src/erlydtl_compiler.erl
@@ -1211,17 +1211,22 @@ resolve_variable_ast(VarTuple, Context, TreeWalker, EmptyIfUndefined)
resolve_variable_ast(VarTuple, Context, TreeWalker, FinderFunction) ->
resolve_variable_ast1(VarTuple, Context, TreeWalker, FinderFunction).
-resolve_variable_ast1({attribute, {{identifier, {Row, Col}, AttrName}, Variable}}, Context, TreeWalker, FinderFunction) ->
+resolve_variable_ast1({attribute, {{AttrKind, {Row, Col}, Attr}, Variable}}, Context, TreeWalker, FinderFunction) ->
{{VarAst, VarInfo}, TreeWalker1} = resolve_variable_ast(Variable, Context, TreeWalker, FinderFunction),
FileNameAst = case Context#dtl_context.parse_trail of
[] -> erl_syntax:atom(undefined);
[H|_] -> erl_syntax:string(H)
end,
+ AttrAst = erl_syntax:abstract(
+ case AttrKind of
+ number_literal -> erlang:list_to_integer(Attr);
+ _ -> Attr
+ end),
{Runtime, Finder} = FinderFunction,
{{erl_syntax:application(
erl_syntax:atom(Runtime),
erl_syntax:atom(Finder),
- [erl_syntax:atom(AttrName), VarAst, FileNameAst,
+ [AttrAst, VarAst, FileNameAst,
erl_syntax:tuple([erl_syntax:integer(Row), erl_syntax:integer(Col)])
]),
VarInfo},
View
1 src/erlydtl_parser.yrl
@@ -250,6 +250,7 @@ Values -> Values Value : '$1' ++ ['$2'].
Variable -> identifier : {variable, '$1'}.
Variable -> Variable '.' identifier : {attribute, {'$3', '$1'}}.
+Variable -> Variable '.' Literal : {attribute, {'$3', '$1'}}.
AutoEscapeBlock -> AutoEscapeBraced Elements EndAutoEscapeBraced : {autoescape, '$1', '$2'}.
AutoEscapeBraced -> open_tag autoescape_keyword identifier close_tag : '$3'.
View
20 src/erlydtl_runtime.erl
@@ -26,6 +26,10 @@ find_value(Key, L) when is_binary(Key), is_list(L) ->
false -> undefined;
{Key, Value} -> Value
end;
+find_value(Key, L) when is_integer(Key), is_list(L) ->
+ if Key < length(L) -> lists:nth(Key, L);
+ true -> undefined
+ end;
find_value(Key, {GBSize, GBData}) when is_integer(GBSize) ->
case gb_trees:lookup(Key, {GBSize, GBData}) of
{value, Val} ->
@@ -42,6 +46,10 @@ find_value(Key, Tuple) when is_tuple(Tuple) ->
_ ->
undefined
end;
+ _ when is_integer(Key) ->
+ if Key < size(Tuple) -> element(Key, Tuple);
+ true -> undefined
+ end;
Module ->
case lists:member({Key, 1}, Module:module_info(exports)) of
true ->
@@ -59,19 +67,19 @@ find_value(Key, Tuple) when is_tuple(Tuple) ->
end
end.
+fetch_value(Key, Data, _FileName, _Pos) ->
+ case find_value(Key, Data) of
+ undefined -> [];
+ Val -> Val
+ end.
+
find_deep_value([Key|Rest],Item) ->
case find_value(Key,Item) of
undefined -> undefined;
NewItem -> find_deep_value(Rest,NewItem)
end;
find_deep_value([],Item) -> Item.
-fetch_value(Key, Data, _FileName, _Pos) ->
- case find_value(Key, Data) of
- undefined -> [];
- Val -> Val
- end.
-
regroup(List, Attribute) ->
regroup(List, Attribute, []).
View
8 tests/src/erlydtl_unittests.erl
@@ -83,7 +83,13 @@ tests() ->
<<"{{ var1.some_var }}">>, [{var1, erlydtl_example_variable_storage:new("foo")}], <<"foo">>},
{"Nested attributes",
<<"{{ person.city.state.country }}">>, [{person, [{city, [{state, [{country, "Italy"}]}]}]}],
- <<"Italy">>}
+ <<"Italy">>},
+ {"Index list variable",
+ <<"{{ var1.2 }}">>, [{var1, [a, b, c]}],
+ <<"b">>},
+ {"Index tuple variable",
+ <<"{{ var1.2 }}">>, [{var1, {a, b, c}}],
+ <<"b">>}
]},
{"now", [
{"now functional",

0 comments on commit c2aaf7d

Please sign in to comment.