-module(gurka_transform). -export([parse_transform/2]). parse_transform(Forms, _Options) -> forms(Forms). forms([]) -> []; forms([Form | Forms]) -> [form(Form) | forms(Forms)]. form({function, Line, Name, Arity, Clauses}) when Name =:= setup_feature; Name =:= setup_scenario; Name =:= given; Name =:= 'when'; Name =:= then -> function(Line, Name, Arity, Clauses); form(Form) -> Form. function(Line, Name, Arity, Clauses) -> {function, Line, Name, Arity, clauses(Clauses)}. clauses([]) -> []; clauses([Clause | Clauses]) -> [clause(Clause) | clauses(Clauses)]. clause({clause, ClauseLine, [{bin, _, [{bin_element, _, {string, StringLine, String}, default, default}]} | Head], Guard, Exprs}) -> {clause, ClauseLine, [process_string(StringLine, String) | Head], Guard, Exprs}; clause({clause, ClauseLine, [{string, StringLine, String} | Head], Guard, Exprs}) -> {clause, ClauseLine, [process_string(StringLine, String) | Head], Guard, Exprs}; clause({clause, ClauseLine, [{tuple, _, [{bin, _, [{bin_element, _, {string, StringLine, String}, default, default}]}, {cons, _, _, _}]} | Head], Guard, Exprs}) -> {clause, ClauseLine, [process_string(StringLine, String) | Head], Guard, Exprs}; clause({clause, ClauseLine, [{tuple, _, [{string, StringLine, String}, {cons, _, _, _}]} | Head], Guard, Exprs}) -> {clause, ClauseLine, [process_string(StringLine, String) | Head], Guard, Exprs}; clause({clause, Line, Head, Guard, Exprs}) -> {clause, Line, Head, Guard, Exprs}; clause(Clause) -> Clause. process_string(Row, String) -> Tokens = gurka_parser:tokens(list_to_binary(String)), Pattern = build_pattern(Row, Tokens), {match, Row, {var, Row, 'Tokens'}, Pattern}. build_pattern(Row, []) -> {nil, Row}; build_pattern(Row, [<<$\$, Token/binary>> | Tokens]) -> Var = {var, Row, binary_to_atom(Token, utf8)}, {cons, Row, Var, build_pattern(Row, Tokens)}; build_pattern(Row, [Token | Tokens]) -> Bin = {bin, Row, [{bin_element, Row, {string, Row, binary_to_list(Token)}, default, default}]}, {cons, Row, Bin, build_pattern(Row, Tokens)}.