sbuilder-ial 0.0.1

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.
@@ -0,0 +1,185 @@
1
+ module Sbuilder
2
+ module Fp
3
+
4
+ module Compositable
5
+
6
+ def initialize( value )
7
+ # @value = join(value)
8
+ @value = value
9
+ end
10
+
11
+ # @attr [Object] value wrapped
12
+ attr_reader :value
13
+
14
+ # @return [Error|nil]
15
+ def error
16
+ return nil unless isError
17
+ return self if is_a?( Error )
18
+ value.error
19
+ end
20
+
21
+ def method_missing( m, *args, &block)
22
+ value.public_send( m, *args, &block)
23
+ end
24
+
25
+
26
+ def to_s
27
+ value.to_s
28
+ end
29
+
30
+ def isError
31
+ # return @value.isError if @value.respond_to?( :isError )
32
+ @value.is_a?( Error ) || is_a?( Error )
33
+ end
34
+
35
+ def isSuccess
36
+ !isError
37
+ end
38
+
39
+ # Composition operator. Can bind (with *args) to an instance
40
+ # method (given as a :symbol), proc, or block.
41
+ def and_then( proc=nil, *args, &block )
42
+
43
+ # make error pass trough
44
+ return self if isError
45
+
46
+ #
47
+ proc = _proc( proc, *args, &block )
48
+ begin
49
+ ret = proc.arity == 0 ? proc.call( &block ) : proc.call( value, &block )
50
+ ret = self.class.new( ret ) if ret.is_a?( Fixnum ) || !ret.singleton_class.include?(Compositable)
51
+ rescue FpException => fpError
52
+ ret = Error( fpError )
53
+ end
54
+
55
+ ret
56
+ end
57
+ alias :>> :and_then
58
+
59
+
60
+ def or_else( proc=nil, *args, &block )
61
+
62
+ # transparent unless error
63
+ return self unless isError
64
+
65
+ proc = _proc( proc, *args, &block )
66
+ ret = proc.call( value )
67
+
68
+ ret
69
+
70
+ end
71
+ alias :'__' :or_else
72
+
73
+ # Pipe to enable side effects
74
+ def pipe(proc=nil, &block)
75
+ (proc || block).call(self)
76
+ self
77
+ end
78
+ alias :<< :pipe
79
+
80
+
81
+ def _proc( proc=nil, *args, &block )
82
+ # referring to an instance method (given as a symbol in 'proc')
83
+ if proc.is_a? Symbol
84
+ if respond_to?(proc)
85
+ proc = method(proc).to_proc
86
+ elsif value.respond_to?(proc)
87
+ proc = value.method(proc).to_proc
88
+ else
89
+ raise "Unknown method symbol '#{proc}' in #{self}"
90
+ end
91
+ end
92
+ proc = proc || block
93
+
94
+ # curry possible *args
95
+ if args.count > 0 then
96
+ proc = proc.curry[*args]
97
+ if !proc.is_a?( Proc ) then
98
+ # all parameters in proc bound, wrap it as lambda to
99
+ # return a fixed value
100
+ procRet = proc
101
+ proc = ->() { procRet }
102
+ end
103
+ end
104
+ proc
105
+ end # _proc
106
+
107
+ # ------------------------------------------------------------------
108
+
109
+ # lwrap (lambda wrapper) for an instance method
110
+ #
111
+ # @Return [lamba] lamba(v)' calling to a instance method 'm'
112
+ # curried with '*args'
113
+
114
+ def lwrap( m, *args )
115
+ # find instance method & curry
116
+ p = method( m ).to_proc
117
+ p = args.count > 0 ? p.curry[*args] : p
118
+
119
+ # create lamba(v) calling to p[v]
120
+ self.class._lwrap( p, args )
121
+
122
+ end
123
+
124
+ def Error( o )
125
+ self.class.Error( o )
126
+ end
127
+
128
+ def Result( o )
129
+ Sbuilder::Fp.Result( o )
130
+ end
131
+
132
+
133
+ # ------------------------------------------------------------------
134
+ # class methods
135
+
136
+ # Add class methods from module 'ClassMethods'
137
+ def self.included(base)
138
+ base.extend(ClassMethods)
139
+ end
140
+
141
+ module ClassMethods
142
+
143
+ def Error( o )
144
+ # Sbuilder::Fp::Error.new( o )
145
+ Sbuilder::Fp.Error( o )
146
+ end
147
+
148
+ # lwrap (lambda wrapper) for a class method
149
+ #
150
+ # @Return [lamba] lamba(v)' calling a class method 'm' curried
151
+ # with '*args'
152
+ def lwrap( m = :new, *args )
153
+ # find class method & curry
154
+ p = method( m ).to_proc
155
+ p = args.count > 0 ? p.curry[*args] : p
156
+ # create lamba(v) calling to p[v]
157
+ _lwrap( p, args )
158
+ end
159
+
160
+
161
+ # @return [lambda] lamdba(v) for proc 'p' curried with
162
+ # '*args'. lamba return is wrapped into object instance of
163
+ # current class, unless the return is already 'Compositable',
164
+ # short circuits 'Error'
165
+ def _lwrap( p, *args )
166
+
167
+ ->(v) do
168
+ if v.is_a?(Error) then
169
+ # short circuit error
170
+ v
171
+ else
172
+ # ret = p[v]
173
+ ret = p.arity == 0 ? p.call : p[v]
174
+ ret = self.new( ret ) unless ret.singleton_class.include? Compositable
175
+ ret
176
+ end
177
+ end
178
+ end # self._lwrap
179
+
180
+
181
+ end # module ClassMethods
182
+
183
+ end # module Compositable
184
+ end
185
+ end
data/lib/fp/error.rb ADDED
@@ -0,0 +1,19 @@
1
+ module Sbuilder
2
+ module Fp
3
+
4
+ class Error
5
+
6
+ include Sbuilder::Fp::Compositable
7
+
8
+ end
9
+
10
+ # ------------------------------------------------------------------
11
+ # Module function allows calling Sbuilder::Fp.Error( wrapped )
12
+
13
+ def Error( o )
14
+ Sbuilder::Fp::Error.new( o )
15
+ end
16
+ module_function :Error
17
+
18
+ end
19
+ end
@@ -0,0 +1,9 @@
1
+ module Sbuilder
2
+ module Fp
3
+
4
+ class FpException < Exception
5
+ end
6
+
7
+
8
+ end
9
+ end
data/lib/fp/result.rb ADDED
@@ -0,0 +1,19 @@
1
+ module Sbuilder
2
+ module Fp
3
+
4
+ class Result
5
+
6
+ include Sbuilder::Fp::Compositable
7
+
8
+ end
9
+
10
+ # ------------------------------------------------------------------
11
+ # Entry points
12
+ def Result( o )
13
+ return o if o.is_a?( Result ) || o.is_a?( Error )
14
+ Sbuilder::Fp::Result.new( o )
15
+ end
16
+ module_function :Result
17
+
18
+ end
19
+ end
@@ -0,0 +1,65 @@
1
+ module Sbuilder
2
+ module Fp
3
+
4
+ class Sequence
5
+
6
+ include Sbuilder::Fp::Compositable
7
+
8
+ # Composition operator. Can bind (with *args) to an instance
9
+ # method (given as a :symbol), proc, or block.
10
+ def and_then( proc=nil, *args, &block )
11
+
12
+ proc = _proc( proc, *args, &block )
13
+
14
+ # toggle for any error
15
+ inError = false
16
+
17
+ # ----------
18
+ # Iterate sequence using lamba
19
+
20
+ blockAsProc = ->(v) do
21
+ begin
22
+ mapped_v = proc.arity == 0 ? proc.call( &block ) : proc.call( v, &block )
23
+ # Guarantee that sequenced results are wrapped within
24
+ # 'Compositable'. Use Fixnum check to avoid error "can't
25
+ # define singleton" for 'immadiate values (i.e. Fixnums)
26
+ mapped_v = Result(mapped_v) if mapped_v.is_a?( Fixnum ) || !mapped_v.singleton_class.include?( Compositable)
27
+ inError = inError || mapped_v.isError
28
+ rescue FpException => fpError
29
+ inError = true
30
+ mapped_v = Error(fpError)
31
+ end
32
+ mapped_v
33
+ end
34
+ ret = value.map &blockAsProc
35
+
36
+ ret = inError ? Error( ret ) : Result( ret )
37
+ ret
38
+ end
39
+
40
+
41
+
42
+ def self.wrap( wrapped )
43
+ Sequence.new( wrapped )
44
+ end
45
+
46
+ def self.from_array( array )
47
+ array = [ array ] unless array.is_a?( Array )
48
+ Sequence.new( array.lazy )
49
+ end
50
+
51
+
52
+ end
53
+
54
+ # ------------------------------------------------------------------
55
+ # Entry points
56
+ def Sequence( o )
57
+ o = [ o ] unless o.is_a?( Array )
58
+ Sbuilder::Fp::Sequence.wrap( o )
59
+ end
60
+ module_function :Sequence
61
+
62
+
63
+ end
64
+ end
65
+
data/lib/ial/build.rb ADDED
@@ -0,0 +1,12 @@
1
+ module Sbuilder
2
+ module Ial
3
+ module Ial
4
+ class Build
5
+
6
+
7
+
8
+
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ module Sbuilder
2
+ module Ial
3
+ module Ial
4
+
5
+ class IalException < Sbuilder::Fp::FpException; end
6
+
7
+ class PropertyException < IalException; end
8
+
9
+ class UnkwonSexpType < IalException; end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,72 @@
1
+ module Sbuilder
2
+ module Ial
3
+ module Model
4
+
5
+ class Constants
6
+
7
+ # types
8
+ IAL_LIBRARY = :library
9
+ IAL_DOMAIN = :domain
10
+ IAL_DEFINITION = :definition
11
+ IAL_VARIABLE = :variable
12
+ IAL_TRANSACTION = :transaction
13
+ IAL_MACRO = :macro
14
+ IAL_OPERATOR = :operator
15
+
16
+ # Lookup 'type' names to initilize by default
17
+ LOOKUPS_TO_INIT = [ IAL_LIBRARY, IAL_DOMAIN, IAL_DEFINITION, IAL_VARIABLE, IAL_TRANSACTION, IAL_MACRO, IAL_OPERATOR ]
18
+
19
+ # ------------------------------------------------------------------
20
+ # Expressions
21
+
22
+ CONSTANT_EXPRESSION_NIL = :nil
23
+ CONSTANT_EXPRESSION_EMPTY = :empty
24
+
25
+ CONSTANT_EXPRESSIONS = {
26
+ CONSTANT_EXPRESSION_EMPTY => '{}',
27
+ CONSTANT_EXPRESSION_NIL => 'Nil',
28
+ }
29
+
30
+ # ------------------------------------------------------------------
31
+ # Operators
32
+
33
+ OPERATOR_SET_MINUS = :set_minus
34
+ OPERATOR_SET_UNION = :union
35
+ OPERATOR_PLUS = :plus
36
+ OPERATOR_MINUS = :minus
37
+ OPERATOR_MULT = :mult
38
+ OPERATOR_DIV = :div
39
+ OPERATOR_EQUAL = :equal
40
+
41
+ # map operator names to TLA implementation
42
+ IAL_OPERATORS = {
43
+ OPERATOR_SET_MINUS => '\\',
44
+ OPERATOR_SET_UNION => '\\union',
45
+ OPERATOR_PLUS => '+',
46
+ OPERATOR_MINUS => '-',
47
+ OPERATOR_MULT => '*',
48
+ OPERATOR_DIV => '/',
49
+ OPERATOR_EQUAL => '=',
50
+ }
51
+
52
+ # ------------------------------------------------------------------
53
+ # Tla templates
54
+
55
+
56
+ TLA_TEMPLATES = {
57
+ :set => ->(gen, *args) { gen.gen_set( *args ) },
58
+ :set_generate => ->(gen, map, variable, set ) { gen.gen_set_map( map, gen.gen_set_iterate( variable, set )) },
59
+ :plainname => ->(gen, name ) { gen.gen_plainname( name ) },
60
+ :sequence => ->(gen, *args) { gen.gen_sequence( args ) },
61
+ :record_field => ->(gen, *args) { gen.gen_record_field( *args ) },
62
+ :IF_expression => ->(gen, condExpr, thenExpr, elseExpr) { gen.gen_IF( condExpr, thenExpr, elseExpr ) },
63
+ :EXCEPT_expression => ->(gen, variable, *excepts) { gen.gen_EXCEPT( variable, excepts ) },
64
+ :procedure_call => ->( gen, txName, operationName, params ) { gen.gen_procedure_call( gen.txName2ServiceProcedure( txName, operationName ), params ) },
65
+ :record_field_definition => ->( gen, name, value ) { gen.gen_record_field_definition( name, value ) },
66
+ :record => ->( gen, *arrOfFields ) { gen.gen_record_definition( arrOfFields ) },
67
+ }
68
+
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,74 @@
1
+ require 'docile'
2
+
3
+
4
+ module Sbuilder
5
+ module Ial
6
+ module Model
7
+
8
+ class Model
9
+
10
+ # ------------------------------------------------------------------
11
+ # Contrcut && configure
12
+
13
+ # @param [:Symbol:Array] lookupsToInit lookup types to inialize
14
+ def initialize( lookupsToInit = [] )
15
+ @lookups = {}
16
+ lookupsToInit.each do |type|
17
+ initLookup( type )
18
+ end
19
+ end
20
+
21
+ def self.start
22
+ self.new( Sbuilder::Ial::Model::Constants::LOOKUPS_TO_INIT )
23
+ end
24
+
25
+ # @attr [Hash] lookups
26
+ attr_reader :lookups
27
+
28
+ # has operations
29
+
30
+ def []( key )
31
+ @lookups[key]
32
+ end
33
+
34
+ def keys()
35
+ @lookups.keys
36
+ end
37
+
38
+ # Creates a lookup hash for 'type'
39
+ #
40
+ # @param [:Symbol] type of looupk to create
41
+ def initLookup( type )
42
+ raise "Lookup already initiazed for type' #{type}'" unless lookups[type].nil?
43
+ lookups[type] = {}
44
+ self
45
+ end
46
+
47
+ # ------------------------------------------------------------------
48
+ # Use
49
+
50
+ # sets lookups[type][ref] = value
51
+ def define( type, ref, value )
52
+ raise "Application error: lookups[#{type}] - not initiliazed - should have run 'initLookup( #{type} - known lookups #{lookups.keys.join(',')})'" unless lookups[type].is_a?(Hash)
53
+ lookups[type][ref] = value
54
+ self
55
+ end
56
+
57
+ # @return lookups[type][ref]| lookups[type].keys
58
+ def lookup( type, ref=nil )
59
+ raise "Should have run 'initLookup( #{type} )'" if lookups[type].nil?
60
+ return lookups[type].keys if ref.nil?
61
+ lookups[type][ref]
62
+ end
63
+
64
+
65
+
66
+ end # class Model
67
+
68
+
69
+ end
70
+ end
71
+ end
72
+
73
+
74
+ require_relative 'model_dsl'