Packages

FT FormalTalk ERP.UNO Compiler

Current section

Files

Jump to
ft lib FT.ex
Raw

lib/FT.ex

defmodule FT do
# FormalTalk ERP.UNO Compiler 3.1.0
#
# Supported code generators:
# [x] module
# [x] route
# [ ] import
# [ ] notice
# [ ] event
# [ ] form
# Erlang AST definitions
def latom(x), do: :erlang.list_to_atom x
def cons([]), do: {:nil,1}
def cons([x|t]), do: {:cons,1,x,cons(t)}
def mod(name), do: {:attribute,1,:module,name}
def compile_all(), do: {:attribute,1,:compile,:export_all}
def string(val), do: {:string,1,val}
def integer(val), do: {:integer,1,val}
def binary(val), do: {:bin,1,[{:bin_element,1,string(val),:default,[:utf8]}]}
def var(val), do: {:var,1,latom(val)}
def atom(val) when is_atom(val), do: {:atom,1,val}
def atom(val) when is_list(val), do: {:atom,1,latom(val)}
def fun(mod,name,arity), do: {:fun,1,{:function,mod,name,{:integer,1,arity}}}
def testFile(), do: :inputProc |> testFile |> compileForms
# Imported module records
def record(recname,recfields) do
fields = :lists.map(fn {name,default,type} ->
defx = case default do
[] -> cons([])
x when is_integer(x) -> integer(x)
x when is_list(x) -> string(x)
x when is_binary(x) -> binary(:erlang.binary_to_list(x))
end
{:typed_record_field,{:record_field,1,atom(name),defx},type}
end, recfields)
{:attribute,1,:record,{recname,fields}}
end
# routeProc{} onstructor invocation generation
def routeProcInvoke(folder,users,folderType,{mod,fun}) do
usrs = :lists.map fn x -> atom(x) end, users
ft = case folderType do
[] -> var('FT')
x when is_binary(x) -> binary(:erlang.binary_to_list(x))
end
args = [{:folder,binary(folder)},
{:folderType,ft},
{:users,cons(usrs)},
{:callback,fun(atom(mod),atom(fun),2)}]
fields = :lists.map fn {name,val} -> {:record_field,1,atom(name),val} end, args
{:record,1,:routeProc,fields}
end
# Route clause generator
def routeClause(s,d,commands) do
routeCommands = :lists.map fn {folder,users,folderType,callback} ->
routeProcInvoke(folder,users,folderType,callback) end, commands
cmds = cons(routeCommands)
{:clause,1,[{:tuple,1,[atom(:request),string(s),string(d)]},var('FT')],[],[cmds]}
end
# Route function generator
def routeFun(name,clauses) do
routeClauses = :lists.map fn {s,d,cmds} -> routeClause(s,d,cmds) end, clauses
{:function,1,name,2,routeClauses}
end
# Compile AST form to disk and reload
def compileForms(ast) do
:filelib.ensure_dir 'priv/out/'
case :compile.forms ast, [:debug_info,:return] do
{:ok,name,beam,_} ->
:file.write_file 'priv/out/' ++ :erlang.atom_to_list(name) ++ '.beam', beam
:code.purge name
:code.load_file name
{name,beam}
_ ->
{[],[]}
end
end
# Sample AST form of route function generation
def testFile(name) do
[
mod(name),
compile_all(),
record(:routeProc, [{:id,[],{:type,1,:list,[]}},
{:operation,[],{:type,1,:term,[]}},
{:feed,[],{:type,1,:term,[]}},
{:type,[],{:type,1,:term,[]}},
{:folder,[],{:type,1,:term,[]}},
{:users,[],{:type,1,:term,[]}},
{:folderType,[],{:type,1,:term,[]}},
{:callback,[],{:type,1,:term,[]}},
{:reject,[],{:type,1,:term,[]}},
{:options,[],{:type,1,:term,[]}}
]),
routeFun(:routeTo, [{'gwConfirmation','Implementation',
[{'approval', ['to'], [], {'Elixir.CRM.KEP','toExecutors'}}
]}]),
]
end
end