sbuilder-ial 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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'