salespaulo / erl_ft

[ERPUNO] πŸ’Ž FT: ΠšΠΎΠΌΠΏΡ–Π»ΡΡ‚ΠΎΡ€ ΠΌΠΎΠ²ΠΈ FormalTalk для ERP.UNO

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

FT: FormalTalk ERP/1 Compiler

Actions Status Hex pm



FormalTalk is the LEEX/YECC front-end to DSL of BPE, FORM and KVS programming -- the core libraries of ERP.UNO State Enterprise open-source stack.

FT is the FormalTalk ERP.UNO compiler that compiles BPE and FORM modules defined in FormalTalk language to BEAM byte-code that is accessible from Erlang and Elixir environments. The type system of FormalTalk in essense is an Erlang AST type system along with record set from ERP.UNO schema.

The main purpose of FormalTalk is to provide an ability to reconfiguration of processes and forms used in products: MIA:Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΎΠ±Ρ–Π³, ΠœΠ†Π:Зброя, ΠœΠ†Π:Π—Π°ΠΊΡƒΠΏΡ–Π²Π»Ρ–, ΠœΠ†Π:ΠŸΡ€ΠΎΠ²Π°Π΄ΠΆΠ΅Π½Π½Ρ and others. This text format is also used as intermediary language for business designer.

$ mix deps.get
$ iex -S mix
> :ft.console []
FormalTalk: ERP.UNO Compiler Β© Π”ΠŸ Β«Π†ΠΠ€ΠžΠ’Π•Π₯Β» 3.2.2

   Usage := :ft.console [ cmds ]
    args := <empty> | <word> args
    cmds := <empty> | command args
 command := parse | lex | read | fst | snd | load | file

 Sample: :ft.console ['snd','load','priv/erp.uno/form/input.form']

KVS module sample:

module person kvs
import location
import organization
record Person
begin id = seq 10 : term
    | cn = [] : [] + binary
    | name = [] : [] + binary
    | displayName = [] : [] + binary
    | location = [] : ERP.Loc
    | hours = 0 : integer
    | type = [] : term end

> :ft.console ['parse','file','priv/kvs/person.kvs' ]
{:ok,
 {:module, {:name, "person"}, {:kvs, 1},
  [
    {:import, {:name, "location"}},
    {:import, {:name, "organization"}},
    {:record, {:name, "Person"}, {:args, []},
     [
       decl: {:field, "id", ["seq", "10"], {:type, ["term"]}},
       decl: {:field, "cn", ["[]"], {:type, ["[]", "binary"]}},
       decl: {:field, "name", ["[]"], {:type, ["[]", "binary"]}},
       decl: {:field, "displayName", ["[]"], {:type, ["[]", "binary"]}},
       decl: {:field, "location", ["[]"], {:type, ["ERP.Loc"]}},
       decl: {:field, "hours", ["0"], {:type, ["integer"]}},
       decl: {:field, "type", ["[]"], {:type, ["term"]}}
     ]}
  ]}}

FORM module sample:

module inputForm form

event id begin ERP.inputOrder end

form new name doc:ERP.inputOrder options
begin pid = options.pid
    | user = options.user
    | regBind = orgPath user
    | pid = options.pid
    | corrOpt = options
    | corrOpt.postback = postback
    | corrOpt.required = true
    | coorOpt = dict
    | coorOpt.users = doc.coordination
    | document "inputOrder" name
    [ butOk title postback { postback :inputOrder doc.id pid }
    | butCancel "Бкасувати" postback { :cancel postback :inputOrder doc.id pid }
    | butTemplate "Π¨Π°Π±Π»ΠΎΠ½" postback { :templates :create :inputOrder } on postback=:create ]
    [ project comboLookup "Π’Ρ–Π΄Ρ…ΠΈΠ»Π΅Π½ΠΎ Π· ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€Π΅ΠΌ"
    | urgent bool "Π’Π΅Ρ€ΠΌΡ–Π½ΠΎΠ²ΠΎ" required
    | id string "НомСр Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°"
    | seq_id string "Π£Π½Ρ–ΠΊΠ°Π»ΡŒΠ½ΠΈΠΉ Π½ΠΎΠΌΠ΅Ρ€"
    | to comboLookupVec "ΠŸΠ΅Ρ€Π²ΠΈΠ½Π½ΠΈΠΉ розгляд" CRM.Forms.Person regBind
    | nomenclature comboLookup "НомСнклатура" CRM.Forms.DeedCat "/crm/deeds"
    | document_type string "Π’ΠΈΠ΄ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°"
    | signed string "ΠŸΡ–Π΄ΠΏΠΈΡΠ°Π²"
    | generic corr controlTask corrOpt
    | date calendar "Π”Π°Ρ‚Π° Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°"
    | dueDate calendar "Π’Π΅Ρ€ΠΌΡ–Π½ виконання" min=:erlang.date() default=FormatDate.add_days(29)
    | note textarea "ΠŸΡ€ΠΈΠΌΡ–Ρ‚ΠΊΠ°"
    | add_sheets number "К-Ρ‚ΡŒ Π°Ρ€ΠΊΡƒΡˆΡ–Π² Π΄ΠΎΠ΄Π°Ρ‚ΠΊΡ–Π²"
    | bizTask_initiator comboLookupVec CRM.Forms.Person "/acc"
    | modified_by comboLookupVec CRM.Forms.Person "/acc"
    | registered_by comboLookup "РСєстратор" required CRM.Forms.Person regBind default=user
    | generic topic controlTask corrOpt
    | generic coordination doc.coordination ] end

> :ft.console ['parse','file','priv/form/input.form' ]
{:ok,
 {:module, "inputForm", :form,
  [
    {:event, {:name, "id"}, [], [decl: {:call, ["ERP.inputOrder"]}]},
    {:form, {:name, "new"}, {:args, ["name", "doc:ERP.inputOrder", "options"]},
     [
       decl: {:assign, "pid", {:args, ["options.pid"]}},
       decl: {:assign, "user", {:args, ["options.user"]}},
       decl: {:assign, "regBind", {:args, ["orgPath", "user"]}},
       decl: {:assign, "pid", {:args, ["options.pid"]}},
       decl: {:assign, "corrOpt", {:args, ["options"]}},
       decl: {:assign, "corrOpt.postback", {:args, ["postback"]}},
       decl: {:assign, "corrOpt.required", {:args, ["true"]}},
       decl: {:assign, "coorOpt", {:args, ["dict"]}},
       decl: {:assign, "coorOpt.users", {:args, ["doc.coordination"]}},
       decl: {:document, "\"inputOrder\"", "name",
        {:buttons,
         [
           {:button, "butOk", "title",
            ["{", "postback", ":inputOrder", "doc.id", "pid", "}"]},
           {:button, "butCancel", "Бкасувати",
            ["{", ":cancel", "postback", ":inputOrder", "doc.id", "pid", "}"]},
           {:button, "butTemplate", "Π¨Π°Π±Π»ΠΎΠ½",
            ["{", ":templates", ":create", ":inputOrder", "}", "on",
             "postback=:create"]}
         ]},
        {:fields,
         [
           {:field, "project", "comboLookup",
            ["Π’Ρ–Π΄Ρ…ΠΈΠ»Π΅Π½ΠΎ Π· ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€Π΅ΠΌ"]},
           {:field, "urgent", "bool", ["Π’Π΅Ρ€ΠΌΡ–Π½ΠΎΠ²ΠΎ", "required"]},
           {:field, "id", "string", ["НомСр Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°"]},
           {:field, "seq_id", "string", ["Π£Π½Ρ–ΠΊΠ°Π»ΡŒΠ½ΠΈΠΉ Π½ΠΎΠΌΠ΅Ρ€"]},
           {:field, "to", "comboLookupVec",
            ["ΠŸΠ΅Ρ€Π²ΠΈΠ½Π½ΠΈΠΉ розгляд", "CRM.Forms.Person", "regBind"]},
           {:field, "nomenclature", "comboLookup",
            ["НомСнклатура", "CRM.Forms.DeedCat", "/crm/deeds"]},
           {:field, "document_type", "string", ["Π’ΠΈΠ΄ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°"]},
           {:field, "signed", "string", ["ΠŸΡ–Π΄ΠΏΠΈΡΠ°Π²"]},
           {:field, "generic", "corr", ["controlTask", "corrOpt"]},
           {:field, "date", "calendar", ["Π”Π°Ρ‚Π° Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°"]},
           {:field, "dueDate", "calendar",
            ["Π’Π΅Ρ€ΠΌΡ–Π½ виконання", "min=:erlang.date()",
             "default=FormatDate.add_days(29)"]},
           {:field, "note", "textarea", ["ΠŸΡ€ΠΈΠΌΡ–Ρ‚ΠΊΠ°"]},
           {:field, "add_sheets", "number",
            ["К-Ρ‚ΡŒ Π°Ρ€ΠΊΡƒΡˆΡ–Π² Π΄ΠΎΠ΄Π°Ρ‚ΠΊΡ–Π²"]},
           {:field, "bizTask_initiator", "comboLookupVec",
            ["CRM.Forms.Person", "/acc"]},
           {:field, "modified_by", "comboLookupVec",
            ["CRM.Forms.Person", "/acc"]},
           {:field, "registered_by", "comboLookup",
            ["РСєстратор", ...]},
           {:field, "generic", "topic", [...]},
           {:field, "generic", "coordination", ...}
         ]}}
     ]}
  ]}}

BPE module sample:

module input bpe

event action broadcastEvent begin result [ ] proc stop end
event action messageEvent process userStarted=system begin result [ ] proc stop end
event action messageEvent payload={next,*} begin output.bpe.action msg proc end
event action messageEvent name=DocumentStatistics payload=payload
begin call personal_stat proc.id executed payload | result [ ] proc stop end

event action messageEvent name=RemoveDocumentStatistics payload=payload
begin call remove_personal_stat proc.id executed payload | result [ ] proc stop end

event action messageEvent name=Implementation
begin doc = proc.docs.hd | doc.project = call projAction execute doc.project msg.payload []
    | proc.docs = [doc] | result [ next { proc.id } ] proc reply end

event action messageEvent name=Executed
begin result [ generate_history { executed proc.id msg.sender.id proc.docs.hd }
               spawn Elixir.History | next { proc.id } ] proc reply end

event action request to=Archive
begin newDoc = proc.docs.hd | newProc = proc | newProc.docs = [newDoc]
    | unindexUrgent proc newDoc | newState = call actionGen req proc newProc
    | result [ general req newState newDoc | stop ] newState reply proc.executors end

route routeTo
begin (Cr,R):R,[] | (R,gwND):O,R | (gwND,Det):D,[] | (*,InC):A,To
    | (gwC,I):A,To,toExecutors | (*,G):G,[];P,M | (*,A):A,[] end
{:event, {:name, "action"}, {:args, ["request", "to=gwRejected"]},
  [
    decl: {:assign, "newProc",{:args, ["call", "actionGen", "req", "proc", "proc"]}},
    decl: {:result,
      [
        cont: ["general", "req", "newPproc", "newDoc"],
        cont: ["next", "proc.id"]
      ], {:args, ["newProc", "reply", "proc.executors"]}}
  ]},
{:route, {:name, "routeTo"}, [],
  [
    decl: {:call, ["(Cr,R):R,[]"]},
    decl: {:call, ["(R,gwND):O,R"]},
    decl: {:call, ["(gwND,Det):D,[]"]},
    decl: {:call, ["(*,InC):A,To"]},
    decl: {:call, ["(gwC,I):A,To,toExecutors"]},
    decl: {:call, ["(*,G):G,[];P,M"]},
    decl: {:call, ["(*,A):A,[]"]}
  ]},

Mentions

Credits

  • Максим Π‘ΠΎΡ…Π°Ρ†ΡŒΠΊΠΈΠΉ

About

[ERPUNO] πŸ’Ž FT: ΠšΠΎΠΌΠΏΡ–Π»ΡΡ‚ΠΎΡ€ ΠΌΠΎΠ²ΠΈ FormalTalk для ERP.UNO

License:Other


Languages

Language:Elixir 62.7%Language:Erlang 37.3%