sbuilder-al 0.0.8

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,603 @@
1
+ module Sbuilder
2
+ module Al
3
+ module Model
4
+ # ==================================================================
5
+ # Builder classes called from {Sbuilder::Al::Model::Api}
6
+
7
+ module Builders
8
+
9
+ # ------------------------------------------------------------------
10
+ # @!group Domain
11
+
12
+ class DomainBuilder
13
+ def name(v=nil); @name=v; self;end
14
+ def value( v=nil) values( Sbuilder::Al::Model::Api::constantExpression{ value v } ); self; end
15
+ def literal( v=nil) values( Sbuilder::Al::Model::Api::tlaPlainname( v ) ); self; end
16
+ def values( v = [] )
17
+ @values ||= []
18
+ @values += v.is_a?(Array) ? v : [v]
19
+ self
20
+ end
21
+ def build
22
+ Domain.new( type: :domain, name: @name, values: @values )
23
+ end
24
+ end
25
+
26
+ # @!endgroup
27
+
28
+ # ------------------------------------------------------------------
29
+ # @!group Statements
30
+
31
+ class BlockBuilder
32
+
33
+ # block statemetns
34
+ def nop
35
+ statements( Sbuilder::Al::Model::Api::skipStatement )
36
+ end
37
+ # add a labeled statement
38
+ def label( lab=nil )
39
+ statements( Sbuilder::Al::Model::Api::skipStatement{ labeled lab } )
40
+ end
41
+
42
+ def jump( lab )
43
+ statements( Sbuilder::Al::Model::Api::jumpStatement( lab ) )
44
+ end
45
+
46
+ # Add jump statement to end label
47
+ # @param interfaceOperation [String] interfaceOperation to fail name(operation)
48
+ def done( interfaceOperation )
49
+ statements( Sbuilder::Al::Model::Api::jumpStatement( Sbuilder::Al::Model::Api::strLabelEnd(interfaceOperation) ) )
50
+ end
51
+
52
+ # Add jump statement to Abort failure label
53
+ # @param interfaceOperation [String] interfaceOperation to fail name(operation)
54
+ def failure( interfaceOperation )
55
+ statements( Sbuilder::Al::Model::Api::jumpStatement( Sbuilder::Al::Model::Api::strLabelFail(interfaceOperation) ) )
56
+ end
57
+
58
+ # Add jump statement to Abort label
59
+ # @param interfaceOperation [String] interfaceOperation to fail name(operation)
60
+ def aborted( interfaceOperation )
61
+ statements( Sbuilder::Al::Model::Api::jumpStatement( Sbuilder::Al::Model::Api::strLabelAbort(interfaceOperation) ) )
62
+ end
63
+
64
+ # @param expression [Expression] TLA-expresion to set on
65
+ # reponse value to, no expresion --> set only status
66
+ #
67
+ def ret( status, expression = nil )
68
+ statements( Sbuilder::Al::Model::Api::returnStatement do
69
+ status( status )
70
+ expression( expression ) unless expression.nil?
71
+ end
72
+ )
73
+ end
74
+
75
+ # Create {ReturnStatement} to set 'expression' to variable 'variableName'
76
+ #
77
+ # @param variableName [String] name of return variable to set
78
+ #
79
+ # @param expression [Expression] Expression to set to return
80
+ # variable
81
+ #
82
+ def returnValue( variableName, expression )
83
+ statements( Sbuilder::Al::Model::Api::returnStatement do
84
+ variable( variableName )
85
+ expression( expression )
86
+ end
87
+ )
88
+ end
89
+
90
+ def output( *msg )
91
+ msg = "" if msg.nil?
92
+ # msg = [ msg ] unless msg.is_a?(Array)
93
+ statements( Sbuilder::Al::Model::Api::outputStatement( msg ) )
94
+ end
95
+ def assignTo( &blk )
96
+ stmt = Sbuilder::Al::Model::Api::assignStatement(&blk)
97
+ statements( stmt )
98
+ end
99
+
100
+ def callMacro( meta, svc=nil, &blk )
101
+ # support callMacro( svc )
102
+ if svc.nil?
103
+ svc = meta
104
+ meta = nil
105
+ end
106
+ stmt = Sbuilder::Al::Model::Api::callStatement do
107
+ callType :macro
108
+ meta meta unless meta.nil?
109
+ name svc
110
+ yield self if blk
111
+ end
112
+ statements( stmt )
113
+ end
114
+ def callService( meta, svc, operation, &blk )
115
+ stmt = Sbuilder::Al::Model::Api::callStatement do
116
+ callType :service
117
+ meta meta
118
+ operation( operation )
119
+ name svc
120
+ yield self if blk
121
+ end
122
+ statements( stmt )
123
+ end
124
+ def ifThen( condExpression, &blk )
125
+ stmt = Sbuilder::Al::Model::Api::conditionalStatement() do
126
+ condition Sbuilder::Al::Model::Api::expression(condExpression)
127
+ ifBlock &blk
128
+ end
129
+ statements( stmt )
130
+ stmt
131
+ end
132
+
133
+ # Build block
134
+ def statements( v = [] )
135
+ @statements = @statements || []
136
+ @statements += v.is_a?( Array ) ? v : [v]
137
+ self
138
+ end
139
+ def build
140
+ Block.new( type: :block, statements: @statements )
141
+ end
142
+ end
143
+
144
+ class StatementBuilder
145
+ end
146
+
147
+ class SkipStatementBuilder < StatementBuilder
148
+ def labeled(v=nil) @labeled= v.nil? ? true : v; self; end
149
+ def build
150
+ SkipStatement.new( type: :skipStatement, labeled: @labeled )
151
+ end
152
+ end
153
+
154
+ class ReturnStatementBuilder
155
+ def status(v=nil) @status=Sbuilder::Al::Model::Api::expression(v); self; end
156
+ def expression(v=nil) @expression=Sbuilder::Al::Model::Api::expression(v); self; end
157
+ def variable(v=nil) @variable=v; self; end
158
+ def build
159
+ type =
160
+ if !@status.nil? && !@expression.nil?
161
+ :returnStatement
162
+ elsif !@status.nil?
163
+ :returnStatus
164
+ elsif !@variable.nil?
165
+ :returnValue
166
+ else
167
+ raise "Shuld define: variable+expression/status+expression/status"
168
+ end
169
+ ReturnStatement.new( type: type, status: @status, expression: @expression, variable: @variable )
170
+ end
171
+ end
172
+
173
+ class JumpStatementBuilder
174
+ def label(v=nil) @label=v; self; end
175
+ def build
176
+ JumpStatement.new( type: :jumpStatement, label: @label )
177
+ end
178
+ end
179
+
180
+ class ConditionalStatementBuilder
181
+ def condition(v=nil) @condition=Sbuilder::Al::Model::Api::expression(v); self; end
182
+ def ifBlock( &blk) @ifBlock=Sbuilder::Al::Model::Api::block( &blk ); self; end
183
+ def elseBlock( &blk ) @elseBlock=Sbuilder::Al::Model::Api::block( &blk ); self; end
184
+ def build
185
+ ConditionalStatement.new( type: :conditionalStatement, condition: @condition, ifBlock: @ifBlock, elseBlock: @elseBlock )
186
+ end
187
+ end
188
+
189
+ class AssignStatementBuilder
190
+ # variable referce v1/v2, parameter reference v2
191
+ def variable(v1=nil, v2=nil); @variable=Sbuilder::Al::Model::Api::reference(v1,v2); self;end
192
+ def rval(v=nil); @rval=Sbuilder::Al::Model::Api::expression(v); self;end
193
+ def build
194
+ AssignStatement.new( type: :assignStatement, variable: @variable, rval: @rval )
195
+ end
196
+ end
197
+
198
+ class CallStatementBuilder
199
+ def callType(v=nil); @callType=v; self;end
200
+ def meta(v=nil); @meta=v; self;end
201
+ def name(v=nil); @name=v; self;end
202
+ def operation(v=nil); @operation=v; self;end
203
+ def parameters( v = [] )
204
+ @parameters = @parameters || []
205
+ @parameters += v.is_a?( Array ) ? v : [v]
206
+ self
207
+ end
208
+ # convinience methods
209
+ def parameter( v )
210
+ parameters( Sbuilder::Al::Model::Api::expression(v) )
211
+ end
212
+ def build
213
+ CallStatement.new( type: :callStatement,
214
+ meta: @meta, name: @name, operation: @operation,
215
+ callType: @callType,
216
+ parameters: @parameters
217
+ )
218
+ end
219
+ end
220
+
221
+
222
+ class OutputStatementBuilder
223
+ def expression(v=nil)
224
+ @expression=Sbuilder::Al::Model::Api::expression(v)
225
+ self
226
+ end
227
+ def build
228
+ OutputStatement.new( type: :outputStatement, expression: @expression )
229
+ end
230
+ end
231
+
232
+
233
+ # @!endgroup
234
+
235
+ # ------------------------------------------------------------------
236
+ # @!group Parameter set
237
+
238
+ class ParameterSetBuilder
239
+
240
+ def parameter( name, isArray, domain=nil )
241
+ raise "Expect boolean for isArray, isArray='#{isArray}'" unless isArray.is_a?(TrueClass) || isArray.is_a?(FalseClass)
242
+ v = Sbuilder::Al::Model::Api::property do
243
+ name( name )
244
+ isArray( isArray )
245
+ domain( domain ) unless domain.nil?
246
+ end
247
+ properties(v)
248
+ end
249
+
250
+ def reference( name, isArray, definition )
251
+ v = Sbuilder::Al::Model::Api::property do
252
+ name( name )
253
+ isArray( isArray )
254
+ definition( definition )
255
+ end
256
+ properties(v)
257
+ end
258
+
259
+ def properties(v=[])
260
+ @properties = @properties || []
261
+ @properties += v.is_a?( Array ) ? v : [v]
262
+ self
263
+ end
264
+
265
+ # @return [Int] number of elements in @properties
266
+ def propertiesLength
267
+ @properties.nil? ? 0 : @properties.length
268
+ end
269
+
270
+ end
271
+
272
+ class ApiDefinitionBuilder < ParameterSetBuilder
273
+ def name(v=nil); @name=v; self;end
274
+ end
275
+
276
+ class DefinitionBuilder < ApiDefinitionBuilder
277
+ def build( meta=nil)
278
+ Definition.new( type: :definition, name: @name, properties: @properties )
279
+ end
280
+ end
281
+
282
+ # Build FunctionDefition using 'inputParameter' and
283
+ # 'outputParameter' methods, which accept DOMAIN names and
284
+ # create constant function paramater names, which can
285
+ # (SHOULD!) be mapped to domain names at some point.
286
+ class FunctionDefinitionBuilder < ApiDefinitionBuilder
287
+ # Create parameter 'P{propertiesLength}' with domain assiaction
288
+ def inputParameter( isArray, domain = nil )
289
+ # Create names p1, p2, ...
290
+ # name = "p#{propertiesLength + 1}"
291
+ name = Sbuilder::Al::Model::Api::inputParameterName(propertiesLength + 1)
292
+ parameter( name, isArray, domain )
293
+ end
294
+ def outputParameter( isArray, domain = nil )
295
+ # create names ret1, ret2, ...
296
+ # name = "ret#{ (@returns || []).length + 1 }"
297
+ name = Sbuilder::Al::Model::Api::outputParameterName( (@returns || []).length + 1)
298
+ parameter( name, isArray, domain )
299
+ end
300
+ # Create parameter 'RET{propertiesLength}' with domain assiaction
301
+ def returns( v=[])
302
+ @returns = @returns || []
303
+ @returns += v.is_a?( Array ) ? v : [v]
304
+ self
305
+ end
306
+ def build( meta=nil)
307
+ # Append @returns to last
308
+ FunctionDefinition.new( type: :function_definition, name: @name, properties: (@properties||[]) + (@returns||[]) )
309
+ end
310
+ end
311
+
312
+ class RequestBuilder < ParameterSetBuilder
313
+ def name(v=nil); @name=v; self;end
314
+ def build( meta=nil)
315
+ Request.new( type: :request, name: @name, properties: @properties )
316
+ end
317
+ end
318
+
319
+ class ResponseBuilder < ParameterSetBuilder
320
+ def name(v=nil); @name=v; self;end
321
+ def build( meta=nil)
322
+ Response.new( type: :response, name: @name, properties: @properties )
323
+ end
324
+ end
325
+
326
+ class PropertyBuilder
327
+ def name(v=nil); @name=v; self;end
328
+ def definition(v=nil); @definition=v; self;end
329
+ def isArray(v=nil); @isArray=v; self;end
330
+ def domain(v=nil); @domain=v; self;end
331
+ def build( meta=nil)
332
+ Property.new( type: :property, name: @name, isArray: @isArray, domain: @domain, definition: @definition )
333
+ end
334
+ end
335
+
336
+
337
+
338
+ # @!endgroup
339
+
340
+ # ------------------------------------------------------------------
341
+ # @!group Storage
342
+
343
+ class LocalBuilder
344
+ def name(v=nil); @name=v; self;end
345
+ def build( meta=nil)
346
+ Local.new( type=:local, name=@name, meta=meta )
347
+ end
348
+ end
349
+
350
+ class VariableBuilder
351
+ def name(v=nil); @name=v; self;end
352
+ def init(v=nil); @init=v; self;end
353
+ def build( meta=nil)
354
+ Variable.new( type=:variable, name=@name, meta=meta, init=@init )
355
+ end
356
+ end
357
+
358
+ class ParameterBuilder
359
+ def name(v=nil); @name=v; self;end
360
+ def build( meta=nil)
361
+ Parameter.new( type=:parameter, name=@name, meta=meta )
362
+ end
363
+ end
364
+
365
+ # @!endgroup
366
+ # ------------------------------------------------------------------
367
+ # @!group Expressions
368
+
369
+ class ConstantExpressionBuilder
370
+ def value(v=nil); @value=v; self;end
371
+ def build( meta=nil)
372
+ ConstantExpression.new( type: :constant_expression, value: @value )
373
+ end
374
+ end
375
+
376
+ class BinaryExpressionBuilder
377
+ def lval(v=nil); @lval=Sbuilder::Al::Model::Api::expression(v); self;end
378
+ def op(v=nil); @op=v; self;end
379
+ def rval(v=nil); @rval=Sbuilder::Al::Model::Api::expression(v); self;end
380
+ def build( meta=nil)
381
+ BinaryExpression.new( type: :binary_expression, lval: @lval, op: @op, rval: @rval )
382
+ end
383
+ end
384
+
385
+ class UnaryExpressionBuilder
386
+ def expr(v=nil); @expr=Sbuilder::Al::Model::Api::expression(v); self;end
387
+ def op(v=nil); @op=v; self;end
388
+ def build( meta=nil)
389
+ UnaryExpression.new( type: :unary_expression, expr: @expr, op: @op )
390
+ end
391
+ end
392
+
393
+
394
+
395
+ # Valid template names for TlaExpressionBuilder
396
+ TLA_TEMPLATES = {
397
+ :set => ->(gen, *args) { gen.gen_set( args ) },
398
+ :sequence => ->(gen, *args) { gen.gen_sequence( args ) },
399
+ :nil => ->(gen, *args) { gen.gen_nilElement( args ) },
400
+ :parenthesis => ->(gen, expr) { gen.gen_parenthesis( expr ) },
401
+ :set_iterate => ->(gen, variable, set ) { gen.gen_set_iterate( variable, set ) },
402
+ :set_generate => ->(gen, map, variable, set ) { gen.gen_set_map( map, gen.gen_set_iterate( variable, set )) },
403
+ :set_select => ->(gen, variable, set, select ) { gen.gen_set_map( gen.gen_set_iterate( variable, set ), select ) },
404
+ :plainname => ->(gen, name ) { gen.gen_plainname( name ) },
405
+ :record_field => ->(gen, record, field ) { gen.gen_record_field( record, field ) },
406
+ :record_index => ->(gen, record, index ) { gen.gen_record_named_field( record, index ) },
407
+ :IF_expression => ->(gen, condExpr, thenExpr, elseExpr) { gen.gen_IF( condExpr, thenExpr, elseExpr ) },
408
+ :operator_call => ->(gen, operator, *arguments ) { gen.gen_operator_call( operator, arguments ) },
409
+ :EXCEPT_expression => ->(gen, variable, *excepts) { gen.gen_EXCEPT( variable, excepts ) },
410
+ # :procedure_call => ->( gen, txName, operationName, params ) { gen.gen_procedure_call( gen.txName2ServiceProcedure( txName, operationName ), params ) },
411
+ :record_field_definition => ->( gen, name, value ) { gen.gen_record_field_definition( name, value ) },
412
+ :record => ->( gen, *arrOfFields ) { gen.gen_record_definition( arrOfFields ) },
413
+ }
414
+
415
+ class ParameterizedExpressionBuilder
416
+ def args(v=nil);
417
+ @args=@args|| []
418
+ @args += v.is_a?( Array ) ? v : [v]
419
+ self;
420
+ end
421
+ # convenience builder
422
+ def arg( v )
423
+ args( Sbuilder::Al::Model::Api::expression(v) )
424
+ end
425
+
426
+ end
427
+
428
+ class ReferenceExpressionBuilder
429
+ def reference(v=nil); @reference=Sbuilder::Al::Model::Api::reference(v); self;end
430
+ def build
431
+ ReferenceExpression.new( meta: @meta, reference: @reference )
432
+ end
433
+ end
434
+
435
+ class ReferenceBuilder
436
+ def fields( fld=nil)
437
+ if !fld.nil?
438
+ @fields = @fields||[]
439
+ @fields << fld
440
+ end
441
+ end
442
+ def name(v=nil); @name=v; self;end
443
+ end
444
+
445
+ class SimpleReferenceBuilder < ReferenceBuilder
446
+ def build
447
+ SimpleReference.new( type: :simple_reference, name: @name, fields:@fields )
448
+ end
449
+ end
450
+ class TxParameterReferenceBuilder < ReferenceBuilder
451
+ def meta(v=nil); @meta=v; self;end
452
+ def operation(v=nil); @operation=v; self;end
453
+ def build
454
+ TxParameterReference.new( type: :tx_parameter_reference, meta: @meta, name: @name, operation: @operation, fields:@fields )
455
+ end
456
+ end
457
+ class VariableReferenceBuilder < ReferenceBuilder
458
+ def meta(v=nil); @meta=v; self;end
459
+ def build
460
+ VariableReference.new( type: :variable_reference, meta: @meta, name: @name, fields:@fields )
461
+ end
462
+ end
463
+
464
+ class TlaExpressionBuilder < ParameterizedExpressionBuilder
465
+ def getTemplates
466
+ TLA_TEMPLATES
467
+ end
468
+
469
+ def template(v=nil); @template=v; self;end
470
+ def build( meta=nil)
471
+ raise Sbuilder::Al::Model::Api::ApiError, "Missing 'template' property in tlaExpression - must give one of valid templates: #{getTemplates.keys.join(',')}" if @template.nil?
472
+ raise Sbuilder::Al::Model::Api::ApiError, "Unsupported tla template '#{@template}' - valid templates: #{getTemplates.keys.join(',')}" if getTemplates[@template].nil?
473
+ TlaExpression.new( type: :tla_expression, template: @template, templateEval: getTemplates[@template], args: @args )
474
+ end
475
+ end
476
+
477
+
478
+ # @!endgroup
479
+
480
+ # ------------------------------------------------------------------
481
+ # @!group Transaction, function, macros etc
482
+
483
+ class CallableBuilder
484
+ def name(v=nil); @name=v; self;end
485
+ end
486
+
487
+ class FunctionCallableBuilder < CallableBuilder
488
+ def request(v=nil); @request=v; self;end
489
+ def locals(v=nil)
490
+ @locals = @locals || []
491
+ @locals += v.is_a?( Array ) ? v : [v]
492
+ self
493
+ end
494
+ def response(v=nil); @response=v; self;end
495
+ # Convenience methods:
496
+ def local( v) locals(v);self; end
497
+ def block(v=nil, &blk )
498
+ if block_given?
499
+ @block = Sbuilder::Al::Model::Api::block( &blk )
500
+ else
501
+ @block=v
502
+ end
503
+ self
504
+ end
505
+ end
506
+
507
+ class SnippetBuilder < FunctionCallableBuilder
508
+ def txt(v) @txt=v; self; end
509
+ def build(meta)
510
+ Snippet.new( type: :snippet, meta: meta, name: @name, txt: @txt )
511
+ end
512
+ end
513
+
514
+ class TransactionBuilder < FunctionCallableBuilder
515
+ def operation(v=nil) @operation=v; self; end
516
+ def interfaceOption(v=nil) @interfaceOption=v; self; end
517
+ def returnOption(v=nil) @returnOption=v; self; end
518
+ def sourceModule( v ) @sourceModule = v; self; end
519
+ def sourceLine( v ) @sourceLine = v; self; end
520
+ def sourceColumn( v ) @sourceColumn = v; self; end
521
+ def build(meta)
522
+ Transaction.new(
523
+ type: :transaction, meta: meta, name: @name, operation: @operation, locals: @locals,
524
+ request: @request, response: @response, block: @block,
525
+ interfaceOption: @interfaceOption, returnOption: @returnOption,
526
+ sourceModule: @sourceModule, sourceLine: @sourceLine, sourceColumn: @sourceColumn )
527
+ end
528
+ end
529
+
530
+ class FunctionBuilder < FunctionCallableBuilder
531
+ def build( meta=nil)
532
+ Function.new( type: :function, meta: meta, name: @name, locals: @locals,
533
+ request: @request, response: @response, block: @block )
534
+ end
535
+ end
536
+
537
+ class OperatorBuilder
538
+ def name(v=nil); @name=v; self;end
539
+ def parameters(v=nil)
540
+ @parameters = @parameters || []
541
+ @parameters += v.is_a?( Array ) ? v : [v]
542
+ self
543
+ end
544
+ def rval(v=nil); @rval= v; self; end
545
+ # Convenience methods:
546
+ def parameter( v) parameters(v);self; end
547
+ def expression( e )
548
+ @rval = Sbuilder::Al::Model::Api::expression( e )
549
+ self
550
+ end
551
+ # Build action
552
+ def build( meta=nil)
553
+ Operator.new( type: :operator, meta: meta, name: @name,
554
+ parameters: @parameters,
555
+ # rval: @rval || Sbuilder::Al::Model::Api::constantExpression{ value true }
556
+ rval: @rval || Sbuilder::Al::Model::Api::expression( true )
557
+ )
558
+ end
559
+ end
560
+
561
+ # Map appName to specName without implementation
562
+ class AliasBuilder
563
+ def name(v=nil); @name=v; self;end
564
+ def specName(v=nil); @specName=v; self;end
565
+ # Build action
566
+ def build( meta=nil )
567
+ Sbuilder::Al::Model::Alias.new( type: :alias, meta: meta, name: @name, specName: @specName )
568
+ end
569
+ end
570
+
571
+
572
+ class MacroBuilder
573
+ def name(v=nil); @name=v; self;end
574
+ def parameters(v=nil)
575
+ @parameters = @parameters || []
576
+ @parameters += v.is_a?( Array ) ? v : [v]
577
+ self
578
+ end
579
+ def block(v=nil, &blk )
580
+ if block_given?
581
+ @block = Sbuilder::Al::Model::Api::block( &blk )
582
+ else
583
+ @block=v
584
+ end
585
+ self
586
+ end
587
+
588
+ # Convenience methods:
589
+ def parameter( v) parameters(v);self; end
590
+ # Build action
591
+ def build( meta=nil)
592
+ Macro.new( type: :macro, meta: meta, name: @name, parameters: @parameters, block: @block )
593
+ end
594
+ end
595
+
596
+
597
+ # @!endgroup
598
+
599
+
600
+ end # builders
601
+ end # module Model
602
+ end # module Al
603
+ end # module Sbuilder