A few changes were made to provide default values for context attributes so that parse_transform:transform/4 could be called for non-top-level forms. I don't know if this is generally useful or if it just fit my weird use case.
See examples/pmod.erl and examples/ex_pmod.erl
This works similarly to OTP's parameterized modules, which they are
now saying that they will drop. Since they drop the compiler support,
a slightly different notation is needed.
-pmod_vars([V1, V2, ...]). % defines the 'global' variables.
-pmod_funs([F1/A1, ...]). % defines which functions are to be exported.
The functions listed in -pmod_funs/1 are transformed to take an extra
argument, and a new(V1, V2, ...) function is added and exported.
Example:
Eshell V5.9 (abort with ^G)
1> c(ex_pmod).
{ok,ex_pmod}
2> M = ex_pmod:new(a,b).
{ex_pmod,{a,b}}
3> M:b(x,y).
{x,y,a,b}
Error markers ({error, Term} tuples) in Forms are special-cased by do/5
and make it return a error tuple itself instead of just letting them
through. I don't think it is good behaviour as the compiler and its
friends already handle error markers correctly. Furthermore it makes
parse_trans_codegen:parse_transform/2 fails when passing the error tuple
to parse_trans:revert/1.
'$form' works much like '$var', only that it makes it possible to
inject ready-made abstract forms into the generated
functions/expressions. The following call:
gen(Name, F) ->
codegen:gen_function(Name, fun(X) -> X =:= {'$form',F} end).
generates the following if called like this: gen(is_foo, {atom,0,foo})
is_foo(X) ->
X =:= foo.