Browse Source

Adding firstof functionality

Alex Songe 15 years ago
parent
commit
50080dbefc
1 changed files with 24 additions and 0 deletions
  1. 24 0
      src/erlydtl/erlydtl_parser.yrl

+ 24 - 0
src/erlydtl/erlydtl_parser.yrl

@@ -54,6 +54,10 @@ Nonterminals
     CycleNames
     CycleNamesCompat
 
+    FirstofTag
+    FirstofList
+    FirstofValues
+
     ForBlock
     ForBraced
     EndForBraced
@@ -114,6 +118,7 @@ Terminals
     endifnotequal_keyword
     equal
     extends_keyword
+    firstof_keyword
     for_keyword
     identifier
     if_keyword
@@ -144,6 +149,7 @@ Elements -> Elements NowTag : '$1' ++ ['$2'].
 Elements -> Elements LoadTag : '$1' ++ ['$2'].
 Elements -> Elements CycleTag : '$1' ++ ['$2'].
 Elements -> Elements BlockBlock : '$1' ++ ['$2'].
+Elements -> Elements FirstofTag : '$1' ++ ['$2'].
 Elements -> Elements ForBlock : '$1' ++ ['$2'].
 Elements -> Elements IfBlock : '$1' ++ ['$2'].
 Elements -> Elements IfEqualBlock : '$1' ++ ['$2'].
@@ -189,6 +195,11 @@ CycleNamesCompat -> identifier comma : ['$1'].
 CycleNamesCompat -> CycleNamesCompat identifier comma : '$1' ++ ['$2'].
 CycleNamesCompat -> CycleNamesCompat identifier : '$1' ++ ['$2'].
 
+FirstofTag -> open_tag firstof_keyword FirstofList close_tag : '$3'.
+FirstofList -> FirstofValues : firstof_create('$1').
+FirstofValues -> FirstofValues Value : ['$2'|'$1'].
+FirstofValues -> Value : ['$1'].
+
 ForBlock -> ForBraced Elements EndForBraced : {for, '$1', '$2'}.
 ForBraced -> open_tag for_keyword ForExpression close_tag : '$3'.
 EndForBraced -> open_tag endfor_keyword close_tag.
@@ -234,3 +245,16 @@ Args -> Args identifier equal Value : '$1' ++ [{'$2', '$4'}].
 
 CallTag -> open_tag call_keyword identifier close_tag : {call, '$3'}.
 CallWithTag -> open_tag call_keyword identifier with_keyword Value close_tag : {call, '$3', '$5'}.
+
+Erlang code.
+firstof_create(List) when is_list(List) ->
+    lists:foldl(fun
+        ({L, _, _}=Var, []) when L=:=string_literal;L=:=number_literal ->
+            Var;
+        ({L, _, _}, _) when L=:=string_literal;L=:=number_literal ->
+            erlang:error(errbadliteral);
+        (Var, []) ->
+            {'ifelse', Var, [Var], []};
+        (Var, Acc) ->
+            {'ifelse', Var, [Var], [Acc]} end,
+    [], List).