lfe_gen(3)                                                          lfe_gen(3)



NAME
       lfe_gen - Lisp Flavoured Erlang (LFE) dynamic code generator

SYNOPSIS
       This module provides an experimental interface for dynamically generat‐
       ing modules.

DATA TYPES
       sexpr()

       An LFE s-expression, a list structure.

EXPORTS
       compile_forms(Forms) -> CompRet

       where

              Forms = [sexpr()]
              CompRet = BinRet | ErrRet
              BinRet = {ok,ModuleName,Binary,Warnings}
              ErrRet = {error,Errors,Warnings}

       Compile a list of LFE forms which comprise an LFE module.  For example:

              lfe_gen:compile_forms([[defmodule,foo,[export,[a,0]]],
                                     [defun,a,[],[quote,yes]]])

       Both WarningList and ErrorList have the following format:

              [{FileName,[ErrorInfo]}]

       ErrorInfo is described below.  When generating Errors and Warnings  the
       "line number" is the index of the form in which the error occured.

       new_module(Name) -> ModDef.

       add_exports([{Name,Arity}], ModDef) -> ModDef.

       add_imports({from,Module,[{Name,Arity}]}, ModDef) -> ModDef.

       add_form(Form, ModDef) -> ModDef.

       print_mod(ModDef) -> iolist().

       compile_mod(Mod) -> CompRet

       where

              CompRet = BinRet | ErrRet
              BinRet = {ok,ModuleName,Binary,Warnings}
              ErrRet = {error,Errors,Warnings}

       These  functions are used to incrementally create a module which can at
       the end be compiled by compile_mod/1.  The same example as above  could
       be written:

              M0 = lfe_gen:new_module(foo),
              M1 = lfe_gen:add_exports([{a,0}], M0),
              M2 = lfe_gen:add_form([defun,a,[],[quote,yes]], M1),
              lfe_gen:compile_mod(M2)

EXAMPLE
       In  this  example  we build a module of parameters where each parameter
       has a number of features which each have a value.  We will  create  one
       function  for each parameter and the feature is the functions argument.
       The value for each feature is returned.

       We are creating code equivalent to:

              -module(Name).
              -export([<param1>/1,...]).

              <param1>(Feature) ->
                  case Feature of
                      <feature1> -> <value1>;
                      ...
                      _ -> erlang:error({unknown_feature,<param1>,Feature)
                  end.
              ...

       but generating it and compiling it directly in memory without  generat‐
       ing a text file.  We assume that we have collected the data and have it
       in the form:

              Params = [{Parameter,[{Feature,Value}]}]

       The equivalent LFE code which we will be generating is:

              (defmodule Name
                (export (<param1> 1) (<param2> 1) ... ))

              (defun <param1> (f)
                (case f
                  ('<feature1> '<value1>)
                  ...
                  (f (: erlang error (tuple 'unknown_feature '<param1> f)))))
              ...

       The following code builds and compiles a module from the parameter  da‐
       ta:

              make_module(Name, Params) ->
                  Mod0 = lfe_gen:new_module(Name),
                  Exps = map(fun ({F,_}) -> {F,1} end, Params),
                  Mod1 = lfe_gen:add_exports(Exps, Mod0),
                  Mod2 = make_funcs(Params, Mod1),
                  lfe_gen:compile_mod(Mod2).

              make_funcs([{Param,Fs}|Ps], Mod) ->
                  %% Define catch-all which generates more explicit exit value.
                  CatchAll = [f,[':',erlang,error,
                                 [tuple,unknown_feature,[quote,Param],f]]],
                  %% Build case clauses
                  Cls = foldr(fun ({Feature,Value}, Cls) ->
                                      [[[quote,Feature],[quote,Value]]|Cls]
                              end, [CatchAll], Params),
                  %% Build function.
                  Func = [defun,Param,[f],['case',f,Cls]],
                  make_funcs(Ps, lfe_gen:add_form(Func, Mod));
              make_funcs([], Mod) -> Mod.                     %All done

ERROR INFORMATION
       The ErrorInfo mentioned above is the standard ErrorInfo structure which
       is returned from all IO modules.  It has the following format:

       {ErrorLine,Module,ErrorDescriptor}

       A string describing the error is obtained with the following call:

              apply(Module, format_error, ErrorDescriptor)

SEE ALSO
       lfe_comp(3), lfe_macro(3)

AUTHORS
       Robert Virding.



                                   2008-2016                        lfe_gen(3)
