flowckerc 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6618e3366d09596072f37257e2730dd47790511b
4
+ data.tar.gz: 9767ab7b95d3a1e7198df9bb693d72634b0a2e77
5
+ SHA512:
6
+ metadata.gz: 4cf94ff7a0f75fcc81468d477ea1710549a397fccc3738f5206e1af45edf5ac5bd010814e96f4aebbe832eca6f9257fce4256fa56467567a1bb7c10547323cfe
7
+ data.tar.gz: 39706d2669d77631f9458d948676f5cdd9fc54eb61110698974066bf5c34af58ca8e2f4fc8018e6b82724ab9628a2445e4ed476999433993625353a27ed933df
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.0
data/COPYRIGHT ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (C) 2015 Leopoldo Lara Vazquez.
2
+
3
+ This program is free software: you can redistribute it and/or modify
4
+ it under the terms of the GNU Affero General Public License, version 3,
5
+ as published by the Free Software Foundation.
6
+
7
+ This program is distributed in the hope that it will be useful,
8
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
+ GNU Affero General Public License for more details.
11
+
12
+ You should have received a copy of the GNU Affero General Public License
13
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in flowckerc.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # Flowcker
2
+
3
+ Flowcker is a distributed processing platform, based on Flow based programming and linux containers (Docker).
4
+
5
+ Flow based programing (FBP) is a paradigm that makes distributed computing much easy to understand and develop.
6
+
7
+ Linux containers is a technology that facilitates the deployment and distribution of server software components.
8
+
9
+ Flowcker integrates FBP and Docker to make distributed processing software for Data Sciences, Scientific computation, Bioinformatics and the like much more easier and fun to develop.
10
+
11
+ # Status
12
+ Flowcker is currently at very early stages of development and documentation.
13
+
14
+ # Components
15
+ In github.com/flowcker/flowcker:
16
+ + common - Common components
17
+ + atom - Runtime for Flowcker atoms (FBP components)
18
+ + runtime - Runtime for Flowcker molecules (FBP graphs)
19
+
20
+ In github.com/flowcker/flowcker-stdlib:
21
+ + Standard library of atoms (FBP components)
22
+
23
+ In github.com/flowcker/flowckerc:
24
+ + Flowcker formula compiler
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/flowckerc ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright (C) 2015 Leopoldo Lara Vazquez.
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Affero General Public License as
7
+ # published by the Free Software Foundation, either version 3 of the
8
+ # License, or (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ $:.unshift Dir.pwd
19
+
20
+ require 'flowckerc'
21
+ require 'json'
22
+
23
+ if ARGV.length > 1
24
+ options = JSON.parse(File.read(ARGV[1]))
25
+ else
26
+ options = {}
27
+ end
28
+
29
+ formula = Flowckerc::Formula.new ARGV[0]
30
+
31
+ solution = Flowckerc::Solver.solve(formula, options)
32
+
33
+ puts JSON.pretty_generate(solution.molecule.toHash)
@@ -0,0 +1,14 @@
1
+
2
+ atom 'stdlib readHttp' do
3
+ name :readFile
4
+ config url: 'http://pastebin.com/raw.php?i=qc0z66VP'
5
+ out from: 'output', to: [:sum, 'input']
6
+ end
7
+
8
+ mix 'parallelsum.ff', :sum
9
+
10
+ atom 'stdlib updateRedisKey' do
11
+ name :writeFile
12
+ config addr: '192.168.59.103:49153', key: 'output'
13
+ inp to: 'input', from: [:sum, 'output']
14
+ end
@@ -0,0 +1,32 @@
1
+
2
+ atom 'stdlib readHttp' do
3
+ name :readFile
4
+ config url: 'http://pastebin.com/raw.php?i=qc0z66VP'
5
+ out from: 'output', to: [:split, 'input']
6
+ end
7
+
8
+ atom 'stdlib splitByLine' do
9
+ name :split
10
+ out from: 'output', to: [:add1, 'input']
11
+ out from: 'output', to: [:add2, 'input']
12
+ end
13
+
14
+ atom 'stdlib accumAdd' do
15
+ name :add1
16
+ out from: 'output', to: [:reduce, 'input']
17
+ end
18
+
19
+ atom 'stdlib accumAdd' do
20
+ name :add2
21
+ out from: 'output', to: [:reduce, 'input']
22
+ end
23
+
24
+ atom 'stdlib sum' do
25
+ name :reduce
26
+ out from: 'output', to: [:writeFile, 'input']
27
+ end
28
+
29
+ atom 'stdlib updateRedisKey' do
30
+ name :writeFile
31
+ config addr: '192.168.59.103:49153', key: 'output'
32
+ end
@@ -0,0 +1,22 @@
1
+ inport 'input', :split, 'input'
2
+ outport 'output', :reduce, 'output'
3
+
4
+ atom 'stdlib splitByLine' do
5
+ name :split
6
+ out from: 'output', to: [:add1, 'input']
7
+ out from: 'output', to: [:add2, 'input']
8
+ end
9
+
10
+ atom 'stdlib accumAdd' do
11
+ name :add1
12
+ out from: 'output', to: [:reduce, 'input']
13
+ end
14
+
15
+ atom 'stdlib accumAdd' do
16
+ name :add2
17
+ out from: 'output', to: [:reduce, 'input']
18
+ end
19
+
20
+ atom 'stdlib sum' do
21
+ name :reduce
22
+ end
@@ -0,0 +1,21 @@
1
+
2
+ atom 'stdlib readHttp' do
3
+ name :readFile
4
+ config url: 'http://pastebin.com/raw.php?i=qc0z66VP'
5
+ out from: 'output', to: [:split, 'input']
6
+ end
7
+
8
+ atom 'stdlib splitByLine' do
9
+ name :split
10
+ out from: 'output', to: [:add, 'input']
11
+ end
12
+
13
+ atom 'stdlib accumAdd' do
14
+ name :add
15
+ out from: 'output', to: [:writeFile, 'input']
16
+ end
17
+
18
+ atom 'stdlib updateRedisKey' do
19
+ name :writeFile
20
+ config addr: '192.168.59.103:49153', key: 'output'
21
+ end
data/flowckerc.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'flowckerc/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "flowckerc"
8
+ spec.version = Flowckerc::VERSION
9
+ spec.authors = ["Leo Lara"]
10
+ spec.email = ["leo@leolara.me"]
11
+
12
+ spec.summary = %q{flowckerc is Flowcker formula compiler}
13
+ spec.description = %q{Flowcker is a distributed processing platform, based on Flow based programming and linux containers (Docker).}
14
+ spec.homepage = "http://www.flowcker.io"
15
+ spec.license = "AGPLv3"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "bin"
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_runtime_dependency "hike", "~> 2.1.3"
23
+ spec.add_runtime_dependency "json", "~> 1.8.1"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.8"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ end
data/lib/flowckerc.rb ADDED
@@ -0,0 +1,206 @@
1
+ # Copyright (C) 2015 Leopoldo Lara Vazquez.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Affero General Public License, version 3,
5
+ # as published by the Free Software Foundation.
6
+ #
7
+ # This program is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
+ # GNU Affero General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Affero General Public License
13
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
+
15
+ require 'flowckerc/version'
16
+ require 'flowckerc/tokens'
17
+ require 'flowckerc/formula'
18
+
19
+ module Flowckerc
20
+ module UniqueID
21
+ @@count = 0
22
+
23
+ def self.next
24
+ @@count = @@count + 1
25
+ @@count
26
+ end
27
+ end
28
+
29
+ class SymTable
30
+ def initialize
31
+ @table = {}
32
+ end
33
+
34
+ def add sym, value
35
+ @table[sym] = value
36
+ end
37
+
38
+ def getId sym
39
+ @table[sym].id
40
+ end
41
+
42
+ def value sym
43
+ @table[sym]
44
+ end
45
+
46
+ def isAtom sym
47
+ @table[sym].is_a? Atom
48
+ end
49
+
50
+ def isSolution
51
+ @table[sym].is_a? FormulaSolution
52
+ end
53
+ end
54
+
55
+ class SolverClass
56
+ def solve formula, options={}
57
+ syms = SymTable.new
58
+ molecule = Molecule.new
59
+ molecule_ports = MoleculePorts.new
60
+
61
+ context = FormulaExecContext.new syms, molecule, molecule_ports, options
62
+ formula.eval context
63
+
64
+ LinksSolver.new(syms).solve(molecule.links)
65
+
66
+ solve_ports_ids syms, molecule_ports
67
+
68
+ FormulaSolution.new molecule, molecule_ports
69
+ end
70
+
71
+ private
72
+
73
+ def solve_ports_ids syms, molecule_ports
74
+ molecule_ports.inports.each do |inport|
75
+ if inport[:to_atom].is_a? Symbol
76
+ inport[:to_atom] = syms.getId inport[:to_atom]
77
+ end
78
+ end
79
+
80
+ molecule_ports.outports.each do |outport|
81
+ if outport[:from_atom].is_a? Symbol
82
+ outport[:from_atom] = syms.getId outport[:from_atom]
83
+ end
84
+ end
85
+ end
86
+
87
+ class LinksSolver
88
+ def initialize syms
89
+ @syms = syms
90
+ end
91
+
92
+ def solve links
93
+ links.each do |link|
94
+ if link.from_atom.is_a? Symbol
95
+ solve_src link
96
+ end
97
+ if link.to_atom.is_a? Symbol
98
+ solve_dst link
99
+ end
100
+ end
101
+ end
102
+
103
+ def solve_src link
104
+ name = link.from_atom
105
+ port = link.from_port
106
+ if @syms.isAtom name
107
+ link.from_atom = @syms.getId name
108
+ else
109
+ solution = @syms.value name
110
+ actual_port = solution.molecule_ports.outportByName port
111
+ link.from_atom = actual_port[:from_atom]
112
+ link.from_port = actual_port[:from_port]
113
+ end
114
+ end
115
+
116
+ def solve_dst link
117
+ name = link.to_atom
118
+ port = link.to_port
119
+ if @syms.isAtom name
120
+ link.to_atom = @syms.getId name
121
+ else
122
+ solution = @syms.value name
123
+ actual_port = solution.molecule_ports.inportByName port
124
+ link.to_atom = actual_port[:to_atom]
125
+ link.to_port = actual_port[:to_port]
126
+ end
127
+ end
128
+ end
129
+
130
+ class AtomExecContext
131
+ def initialize atom, parent
132
+ @atom = atom
133
+ @parent = parent
134
+ end
135
+
136
+ def out spec
137
+ from_port = spec[:from]
138
+ spec[:from] = [@atom.id, from_port]
139
+ @parent.link spec
140
+ end
141
+
142
+ def inp spec
143
+ to_port = spec[:to]
144
+ spec[:to] = [@atom.id, to_port]
145
+ @parent.link spec
146
+ end
147
+
148
+ def name atom_name
149
+ @parent.syms.add atom_name, @atom
150
+ end
151
+
152
+ def config data={}
153
+ @atom.config = data
154
+ end
155
+
156
+ def options
157
+ @parent.options
158
+ end
159
+ end
160
+
161
+ class FormulaExecContext
162
+ attr_reader :syms
163
+ attr_reader :options
164
+ def initialize syms, molecule, molecule_ports, options
165
+ @syms = syms
166
+ @molecule = molecule
167
+ @molecule_ports = molecule_ports
168
+ @options = options
169
+ end
170
+
171
+ def atom element, &blk
172
+ atom = Atom.new element
173
+ @molecule.atoms.push atom
174
+ AtomExecContext.new(atom, self).instance_exec &blk
175
+ end
176
+
177
+ def link spec={}
178
+ @molecule.links.push Link.new spec[:from][0], spec[:from][1], spec[:to][0], spec[:to][1]
179
+ end
180
+
181
+ def inport name, to_atom, to_port
182
+ @molecule_ports.inports.push name: name,
183
+ to_atom: to_atom,
184
+ to_port: to_port
185
+ end
186
+
187
+ def outport name, from_atom, from_port
188
+ @molecule_ports.outports.push name: name,
189
+ from_atom: from_atom,
190
+ from_port: from_port
191
+ end
192
+
193
+ def mix formula_file, name, options={}
194
+ formula = Formula.new formula_file
195
+ solution = Solver.solve formula, options
196
+ @molecule.atoms += solution.molecule.atoms
197
+ @molecule.links += solution.molecule.links
198
+
199
+ @syms.add name, solution
200
+ end
201
+ end
202
+ end
203
+
204
+ Solver = SolverClass.new
205
+
206
+ end
@@ -0,0 +1,33 @@
1
+ # Copyright (C) 2015 Leopoldo Lara Vazquez.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Affero General Public License, version 3,
5
+ # as published by the Free Software Foundation.
6
+ #
7
+ # This program is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
+ # GNU Affero General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Affero General Public License
13
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
+
15
+ require 'hike'
16
+
17
+ module Flowckerc
18
+ class Formula
19
+
20
+ @@trail = Hike::Trail.new "/"
21
+ @@trail.append_extensions ".ff"
22
+ @@trail.append_paths *$:
23
+
24
+ def initialize orig_file
25
+ @file = @@trail.find orig_file
26
+ raise 'Cannot find formula '+ orig_file if @file.nil?
27
+ end
28
+
29
+ def eval context
30
+ context.instance_eval File.read(@file), @file
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,127 @@
1
+ # Copyright (C) 2015 Leopoldo Lara Vazquez.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Affero General Public License, version 3,
5
+ # as published by the Free Software Foundation.
6
+ #
7
+ # This program is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
+ # GNU Affero General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Affero General Public License
13
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
+
15
+ module Flowckerc
16
+ class Link
17
+ attr_reader :id
18
+ attr_accessor :from_atom
19
+ attr_accessor :from_port
20
+ attr_accessor :to_atom
21
+ attr_accessor :to_port
22
+
23
+ def initialize from_atom, from_port, to_atom, to_port
24
+ @id = UniqueID.next
25
+ @from_atom = from_atom
26
+ @from_port = from_port
27
+ @to_atom = to_atom
28
+ @to_port = to_port
29
+ end
30
+
31
+ def toHash
32
+ {
33
+ id: @id,
34
+ from: {
35
+ atomID: @from_atom,
36
+ port: {
37
+ name: @from_port
38
+ }
39
+ },
40
+ to: {
41
+ atomID: @to_atom,
42
+ port: {
43
+ name: @to_port
44
+ }
45
+ }
46
+ }
47
+ end
48
+ end
49
+
50
+ class Atom
51
+ attr_reader :id
52
+ attr_reader :element
53
+ attr_accessor :config
54
+
55
+ def initialize element
56
+ @id = UniqueID.next
57
+ @element = element
58
+ @config = {}
59
+ end
60
+
61
+ def toHash
62
+ {
63
+ id: @id,
64
+ element: @element,
65
+ config: @config
66
+ }
67
+ end
68
+ end
69
+
70
+ class Molecule
71
+ attr_accessor :atoms
72
+ attr_accessor :links
73
+
74
+ def initialize
75
+ @atoms = []
76
+ @links = []
77
+ end
78
+
79
+ def toHash
80
+ res = {}
81
+ res[:atoms] = @atoms.map do |atom|
82
+ atom.toHash
83
+ end
84
+
85
+ res[:links] = @links.map do |link|
86
+ link.toHash
87
+ end
88
+ res
89
+ end
90
+ end
91
+
92
+ class MoleculePorts
93
+ attr_accessor :inports
94
+ attr_accessor :outports
95
+
96
+ def initialize
97
+ @inports = []
98
+ @outports = []
99
+ end
100
+
101
+ def inportByName name
102
+ @inports.each do |port|
103
+ return port if port[:name] == name
104
+ end
105
+ return nil
106
+ end
107
+
108
+ def outportByName name
109
+ @outports.each do |port|
110
+ return port if port[:name] == name
111
+ end
112
+ return nil
113
+ end
114
+ end
115
+
116
+ class FormulaSolution
117
+ attr_accessor :molecule
118
+ attr_accessor :molecule_ports
119
+
120
+ def initialize molecule, molecule_ports
121
+ @molecule = molecule
122
+ @molecule_ports = molecule_ports
123
+ end
124
+ end
125
+
126
+
127
+ end
@@ -0,0 +1,3 @@
1
+ module Flowckerc
2
+ VERSION = "0.0.0"
3
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flowckerc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Leo Lara
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hike
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.1.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.1.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.8.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.8'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.8'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ description: Flowcker is a distributed processing platform, based on Flow based programming
70
+ and linux containers (Docker).
71
+ email:
72
+ - leo@leolara.me
73
+ executables:
74
+ - flowckerc
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - ".gitignore"
79
+ - ".rspec"
80
+ - ".travis.yml"
81
+ - COPYRIGHT
82
+ - Gemfile
83
+ - README.md
84
+ - Rakefile
85
+ - bin/flowckerc
86
+ - examples/http_parallelsum_redis.ff
87
+ - examples/http_parallelsum_redis_simple.ff
88
+ - examples/parallelsum.ff
89
+ - examples/serialsum.ff
90
+ - flowckerc.gemspec
91
+ - lib/flowckerc.rb
92
+ - lib/flowckerc/formula.rb
93
+ - lib/flowckerc/tokens.rb
94
+ - lib/flowckerc/version.rb
95
+ homepage: http://www.flowcker.io
96
+ licenses:
97
+ - AGPLv3
98
+ metadata: {}
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project:
115
+ rubygems_version: 2.4.6
116
+ signing_key:
117
+ specification_version: 4
118
+ summary: flowckerc is Flowcker formula compiler
119
+ test_files: []