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,1038 @@
1
+ module Sbuilder
2
+ module Ial
3
+ module Model
4
+
5
+ class ModelDslException < Exception; end
6
+
7
+ # ------------------------------------------------------------------
8
+ # DSL classes
9
+
10
+
11
+ # DSL elements
12
+
13
+ Library = Struct.new( :type, :name, :modules )
14
+
15
+ Domain = Struct.new( :type, :name, )
16
+ # Property = Struct.new( :type, :name, Constants::IAL_DOMAIN, :domain_ref )
17
+ Property = Struct.new( :type, :name )
18
+ class Property
19
+ attr_accessor :domain
20
+ attr_accessor :definition
21
+ def [](k)
22
+ return domain if k == :domain
23
+ return definition if k == :definition
24
+ super( k )
25
+ end
26
+ end
27
+
28
+ # Block
29
+ Block = Struct.new( :type, :statements )
30
+ class Block
31
+ # number of statements
32
+ def steps
33
+ (statements || []).length
34
+ end
35
+ end
36
+
37
+ # Storage
38
+ Storage = Struct.new( :type, :name, :init )
39
+ class Variable < Storage
40
+ end
41
+ class Local < Storage
42
+ end
43
+ class Parameter < Storage
44
+ end
45
+
46
+ # Statement
47
+ Statement = Struct.new( :type )
48
+ class PrintStatement < Statement
49
+ attr_accessor :expression
50
+ alias_method :msg, :expression
51
+ def [](k)
52
+ return expression if k == :expression || k == :msg
53
+ super( k )
54
+ end
55
+ end
56
+ class SkipStatement < Statement
57
+ end
58
+
59
+ # data maninpulations
60
+ class DataManipulationStatement < Statement
61
+ attr_accessor :variable
62
+ def [](k)
63
+ return variable if k == :variable
64
+ super( k )
65
+ end
66
+ end
67
+ class AssignStatement < DataManipulationStatement
68
+ attr_accessor :expression
69
+ def [](k)
70
+ return expression if k == :expression
71
+ super( k )
72
+ end
73
+ end
74
+
75
+ # other statements
76
+
77
+ class ConditionalStatement < Statement
78
+ attr_accessor :condition
79
+ attr_accessor :ifBlock
80
+ attr_accessor :elseBlock
81
+ # called from block ifThen {}.elseThen {}
82
+ def elseThen( &blk )
83
+ self.elseBlock = Sbuilder::Ial.block( &blk )
84
+ end
85
+ def [](k)
86
+ return condition if k == :condition
87
+ return ifBlock if k == :ifBlock
88
+ return elseBlock if k == :elseBlock
89
+ super( k )
90
+ end
91
+ end
92
+ class CallStatement < Statement
93
+ # :macro, :service
94
+ attr_accessor :target
95
+ attr_accessor :operation # for targetType :service
96
+ attr_accessor :targetType
97
+ attr_accessor :parameters
98
+ def [](k)
99
+ return target if k == :target
100
+ return operation if k == :operation
101
+ return targetType if k == :targetType
102
+ return parameters if k == :parameters
103
+ super( k )
104
+ end
105
+ end
106
+
107
+
108
+ # Expression
109
+ Expression = Struct.new( :type )
110
+ class Expression
111
+ def val; raise "Expect sub class to implement"; end
112
+ end
113
+
114
+ # Expression type String, Numeric, TrueClass, FalseClass or
115
+ # constant values in CONSTANT_EXPRESSIONS
116
+ #
117
+ # Properties:
118
+ #
119
+ # @property [String|Numeric|TrueClass|FalseClass|CONSTANT_EXPRESSIONS[const]] const
120
+ # for constant value
121
+ #
122
+ class ConstantExpression < Expression
123
+ attr_accessor :const
124
+ alias_method :val, :const
125
+ end
126
+
127
+ # Abtract class for TlaExpression and OperatorExpression
128
+ class ParameterizedExpression < Expression
129
+ attr_accessor :args
130
+ def [](k)
131
+ return args if k == :args
132
+ super( k )
133
+ end
134
+
135
+ end
136
+
137
+ # Create expressions using TLA templates defined in
138
+ # Constants::TLA_TEMPLATES. Examples of templates
139
+ #
140
+ # - :set => { # e1,e2, ...}
141
+ #
142
+ # - :sequence =><<e1,e2,..>>
143
+ #
144
+ class TlaExpression < ParameterizedExpression
145
+ # lambda expression corresponding to :template
146
+ attr_accessor :templateEval
147
+ attr_accessor :template
148
+ def [](k)
149
+ return template if k == :template
150
+ super( k )
151
+ end
152
+
153
+ end
154
+
155
+ # Expression 'called( *args )' for operator 'called' with
156
+ # arguments 'args'.
157
+ class OperatorExpression < ParameterizedExpression
158
+ attr_accessor :called
159
+ attr_accessor :infrastructureService
160
+ def [](k)
161
+ return called if k == :called
162
+ return infrastructureService if k == :infrastructureService
163
+ super( k )
164
+ end
165
+ end
166
+
167
+
168
+ # Exression referencing ':domain' or ':variable'
169
+ class ReferenceExpression < Expression
170
+ attr_accessor :refType # e.g. :domain, :variable, :parameter
171
+ attr_accessor :ref
172
+ end
173
+ class BinaryExpression < Expression
174
+ attr_accessor :lval
175
+ attr_accessor :op
176
+ attr_accessor :rval
177
+ def [](k)
178
+ return lval if k == :lval
179
+ return op if k == :op
180
+ return rval if k == :rval
181
+ super( k )
182
+ end
183
+ end
184
+
185
+
186
+ # Parameter set types
187
+ ParameterSet = Struct.new( :type, :properties )
188
+
189
+ class Definition < ParameterSet
190
+ attr_accessor :name
191
+ def [](k)
192
+ return name if k == :name
193
+ super( k )
194
+ end
195
+
196
+ end
197
+
198
+ class Request < ParameterSet
199
+ end
200
+ class Response < ParameterSet
201
+ end
202
+
203
+ # Callables
204
+ Callable = Struct.new( :type, :name )
205
+
206
+ class ParameterizedCallable < Callable
207
+ attr_accessor :parameters
208
+ def [](k)
209
+ return parameters if k == :parameters
210
+ super( k )
211
+ end
212
+ end
213
+
214
+ class FunctionTypeCallable < Callable
215
+ # @attr [Request] request
216
+ attr_accessor :request
217
+ attr_accessor :locals
218
+ attr_accessor :response
219
+ attr_accessor :block
220
+ # obj[:locals]
221
+ def [](k)
222
+ return locals if k == :locals
223
+ return response if k == :response
224
+ return request if k == :request
225
+ return block if k == :block
226
+ super( k )
227
+ end
228
+ end
229
+
230
+ class Transaction < FunctionTypeCallable
231
+ attr_accessor :entryBlock
232
+ attr_accessor :exitBlock
233
+ attr_accessor :operation
234
+ def [](k)
235
+ return operation if k == :operation
236
+ super( k )
237
+ end
238
+
239
+ end
240
+
241
+ class Function < FunctionTypeCallable
242
+ end
243
+
244
+ class Macro < ParameterizedCallable
245
+ attr_accessor :block
246
+ def [](k)
247
+ return block if k == :block
248
+ super( k )
249
+ end
250
+ end
251
+
252
+ class Operator < ParameterizedCallable
253
+ attr_accessor :body
254
+ def [](k)
255
+ return body if k == :body
256
+ super( k )
257
+ end
258
+ end
259
+
260
+
261
+ # ------------------------------------------------------------------
262
+ # DSL methods
263
+
264
+ class DomainBuilder
265
+ def name(v=nil); @name=v; self;end
266
+ def type(v=:domain); @type=v; self;end
267
+ def build
268
+ Domain.new( :domain, @name )
269
+ end
270
+ end
271
+
272
+ class PropertyBuilder
273
+ def name(v=nil); @name=v; self;end
274
+ def definition(v=nil)
275
+ @definition= v.is_a?( String ) ? Sbuilder::Ial.definition{ name v } : v
276
+ self
277
+ end
278
+ def domain(v=nil)
279
+ @domain= v.is_a?( String ) ? Sbuilder::Ial.domain{ name v } : v
280
+ self
281
+ end
282
+ def build
283
+ prop = Property.new( :property, @name )
284
+ prop.domain = @domain
285
+ prop.definition = @definition
286
+ prop
287
+ end
288
+ end
289
+ # ------------------------------------------------------------------
290
+ # Variable
291
+
292
+ class VariableBuilder
293
+ def name(v=nil); @name=v; self;end
294
+ def init(v=nil);
295
+ @init=Sbuilder::Ial::Model.map2expression(v)
296
+ self;
297
+ end
298
+ def build
299
+ v = Variable.new( :variable, @name, @init || Sbuilder::Ial.constantExpression(){ const Constants::CONSTANT_EXPRESSION_EMPTY } )
300
+ end
301
+ end
302
+
303
+ # ------------------------------------------------------------------
304
+ # Library
305
+
306
+ class LibraryBuilder
307
+ def name(v=nil); @name=v; self;end
308
+ def modules( v=nil)
309
+ if @modules.nil?
310
+ @modules = v.is_a?( Array ) ? v : [v]
311
+ else
312
+ # @modules = []
313
+ if v.is_a?( Array )
314
+ @modules = @modules + v
315
+ else
316
+ @modules << v
317
+ end
318
+ end
319
+ self
320
+ end
321
+ def build
322
+ Library.new( :library, @name || :default, @modules || [] )
323
+ end
324
+ end
325
+
326
+
327
+
328
+ # ------------------------------------------------------------------
329
+ # Local
330
+
331
+ class LocalBuilder
332
+ def name(v=nil); @name=v; self;end
333
+ def build
334
+ Local.new( :local, @name )
335
+ end
336
+ end
337
+
338
+ class ParameterBuilder
339
+ def name(v=nil); @name=v; self;end
340
+ def build
341
+ Parameter.new( :parameter, @name )
342
+ end
343
+ end
344
+
345
+
346
+ # ------------------------------------------------------------------
347
+ # Block
348
+
349
+ class BlockBuilder
350
+ def assignTo( &blk )
351
+ assignStmt = Sbuilder::Ial.assignStatement( &blk )
352
+ statements( [ assignStmt ] )
353
+ end
354
+
355
+ # add any statement using a proc
356
+ def addStatement( stmt=nil, &blk )
357
+ statements( [ stmt ] ) if stmt
358
+ if blk
359
+ statements( [ blk.call ] )
360
+ end
361
+ end
362
+
363
+ def addStatements( stmts=[] )
364
+ stmts = stmts.is_a?( Array ) ? stmts : [ stmts]
365
+ statements( stmts )
366
+ end
367
+
368
+
369
+ def ifThen( condExpression, &blk )
370
+ conditional = Sbuilder::Ial.conditionalStatement() do
371
+ condition condExpression
372
+ ifBlock &blk
373
+ end
374
+ statements([ conditional ])
375
+ # return 'conditional' allows chaining ifThen(true) {
376
+ # }.elseThen {} by
377
+ conditional
378
+ end
379
+ def nop; statements( [ Sbuilder::Ial.skipStatement(){} ] ); end
380
+ def output(msg=''); statements( [ Sbuilder::Ial.printStatement(){ expression msg } ] ); self; end
381
+ def callMacro( v=nil, params=[] ); statements( Sbuilder::Ial.callStatement(){ macro v; parameters params } ); self; end
382
+ def callService( tx=nil, o=nil, params=[] ); statements( Sbuilder::Ial.callStatement(){ service(tx,o) ; parameters params } ); self; end
383
+ def statements ( v=[] )
384
+ if @statements.nil?
385
+ @statements = v.is_a?( Array ) ? v : [v]
386
+ else
387
+ # @statements = []
388
+ if v.is_a?( Array )
389
+ @statements = @statements + v
390
+ else
391
+ @statements << v
392
+ end
393
+ end
394
+ end
395
+ def build
396
+ Block.new( :block, @statements || [] )
397
+ end
398
+ end
399
+
400
+ # ------------------------------------------------------------------
401
+ # Statements
402
+ class StatementBuilder
403
+ end
404
+
405
+ class PrintStatementBuilder < StatementBuilder
406
+ def expression(v=nil)
407
+ @expression=v.is_a?( Array ) ? v.map { |p| Sbuilder::Ial::Model.map2expression(p) } : Sbuilder::Ial::Model.map2expression(v)
408
+ self
409
+ end
410
+ alias_method :msg, :expression
411
+ def build
412
+ stmt = PrintStatement.new( :printStatement )
413
+ stmt.expression = @expression
414
+ stmt
415
+ end
416
+ end
417
+
418
+ class SkipStatementBuilder < StatementBuilder
419
+ def build
420
+ SkipStatement.new( :skipStatement )
421
+ end
422
+ end
423
+
424
+ # Data Maninpulation
425
+
426
+ class DataManipulationStatementBuilder < StatementBuilder
427
+ def variable( v=nil) @variable=Sbuilder::Ial.referenceExpression{ variable v }; self; end
428
+ def local( v=nil) @variable=Sbuilder::Ial.referenceExpression{ local v }; self; end
429
+ end
430
+
431
+ class AssignStatementBuilder < DataManipulationStatementBuilder
432
+ def expression( v=nil) @expression=v; self; end
433
+ def build
434
+ stmt = AssignStatement.new( :assignStatement )
435
+ stmt.variable = @variable
436
+ stmt.expression = Sbuilder::Ial::Model.map2expression(@expression)
437
+ stmt
438
+ end
439
+ end
440
+
441
+ # class DataManipulationWhereStatementBuilder < DataManipulationStatementBuilder
442
+ # def where( v=nil) @where=v; self; end
443
+ # end
444
+
445
+ # class DeleteStatementBuilder < DataManipulationWhereStatementBuilder
446
+ # def build
447
+ # stmt = DeleteStatement.new( :deleteStatement )
448
+ # stmt.variable = @variable
449
+ # stmt.where = Sbuilder::Ial::Model.map2expression(@where)
450
+ # stmt
451
+ # end
452
+ # end
453
+
454
+ # class UpdateStatementBuilder < DataManipulationWhereStatementBuilder
455
+ # def build
456
+ # stmt = UpdateStatement.new( :updateStatement )
457
+ # stmt.variable = @variable
458
+ # stmt.where = Sbuilder::Ial::Model.map2expression(@where)
459
+ # stmt
460
+ # end
461
+ # end
462
+
463
+
464
+ #
465
+
466
+ class ConditionalStatementBuilder < StatementBuilder
467
+ def condition(v=nil)
468
+ @condition = Sbuilder::Ial::Model.map2expression(v)
469
+ self
470
+ end
471
+ def ifBlock( &blk )
472
+ @ifBlock = Sbuilder::Ial.block( &blk )
473
+ end
474
+ def elseBlock( &blk )
475
+ @elseBlock = Sbuilder::Ial.block( &blk )
476
+ end
477
+ def build
478
+ stmt = ConditionalStatement.new( :conditionalStatement )
479
+ stmt.condition = @condition || Sbuilder::Ial.constantExpression{ const true }
480
+ stmt.ifBlock = @ifBlock || Sbuilder::Ial.block{ nop }
481
+ # nil causes exception, false flags no else block
482
+ stmt.elseBlock = @elseBlock || false
483
+ stmt
484
+ end
485
+ end
486
+
487
+ class CallStatementBuilder < StatementBuilder
488
+ def parameters(v=nil)
489
+ if @parameters.nil?
490
+ @parameters = v.is_a?( Array ) ? v.map { |p| Sbuilder::Ial::Model.map2expression(p) } : [ Sbuilder::Ial::Model.map2expression(v) ]
491
+ else
492
+ # @parameters = []
493
+ if v.is_a?( Array )
494
+ @parameters = @parameters + v.map { |p| Sbuilder::Ial::Model.map2expression(p) }
495
+ else
496
+ @parameters << Sbuilder::Ial::Model.map2expression(v)
497
+ end
498
+ end
499
+ self
500
+ end
501
+ def macro( v=nil)
502
+ @targetType=:macro
503
+ @target=v
504
+ end
505
+ def service( txName=nil, operation=nil)
506
+ @targetType=:service
507
+ @target=txName
508
+ @operation=operation
509
+ end
510
+ def build
511
+ stmt = CallStatement.new( :callStatement )
512
+ stmt.parameters = @parameters || []
513
+ stmt.targetType = @targetType
514
+ stmt.target = @target
515
+ stmt.operation = @operation
516
+ stmt
517
+ end
518
+ end
519
+
520
+
521
+ # ------------------------------------------------------------------
522
+ # Expressions
523
+
524
+ def map2expression( v )
525
+ if v.is_a?( Expression ) || v.nil?
526
+ v
527
+ elsif v.is_a?( Symbol ) && !Constants::CONSTANT_EXPRESSIONS[v].nil?
528
+ Sbuilder::Ial.constantExpression() { const v }
529
+ elsif v.is_a?( String ) || v.is_a?( Numeric ) || v.is_a?( TrueClass ) || v.is_a?( FalseClass )
530
+ Sbuilder::Ial.constantExpression() { const v }
531
+ elsif v.is_a?( Sbuilder::Ial.variable )
532
+ v
533
+ else
534
+ raise ModelDslException, "Unkwnown type for expression #{v}"
535
+ end
536
+ end
537
+ module_function :map2expression
538
+
539
+ class ExpressionBuilder
540
+ end
541
+
542
+ class ConstantExpressionBuilder < ExpressionBuilder
543
+ def const(v=nil); @const=v; self;end
544
+ def build
545
+ expression = ConstantExpression.new( :constantExpression )
546
+ expression.const = @const
547
+ expression
548
+ end
549
+ end
550
+ class ReferenceExpressionBuilder < ExpressionBuilder
551
+ def plain( v=nil)
552
+ @refType=:plain
553
+ @ref=v
554
+ end
555
+ def variable( v=nil)
556
+ @refType=:variable
557
+ @ref=v
558
+ end
559
+ def parameter( v=nil)
560
+ @refType=:parameter
561
+ @ref=v
562
+ end
563
+ def local( v=nil)
564
+ @refType=:local
565
+ @ref=v
566
+ end
567
+ def domain( v=nil)
568
+ @refType=:domain
569
+ @ref=v
570
+ end
571
+ def build
572
+ expression = ReferenceExpression.new( :referenceExpression )
573
+ expression.refType = @refType
574
+ expression.ref = @ref
575
+ expression
576
+ end
577
+ end
578
+
579
+
580
+ class BinaryExpressionBuilder < ExpressionBuilder
581
+ def binary(l=nil, o=nil,r=nil)
582
+ @lval=l
583
+ @op=o
584
+ @rval=r
585
+ self
586
+ end
587
+ alias_method :expression, :binary
588
+ def build
589
+ expression = BinaryExpression.new( :binaryExpression )
590
+ raise ModelDslException, "Invalid or missing expression: #{@lval.nil? ? ' missing lval' :''} #{@op.nil? ? ' missing operator': ''}#{@rval.nil? ? ' missing rval' :''}'" if @lval.nil? || @op.nil? || @rval.nil?
591
+ raise ModelDslException, "Unsupported operator '#{@op}' - valid opreators #{Constants::IAL_OPERATORS.keys.join(',')}" if Constants::IAL_OPERATORS[@op].nil?
592
+ expression.lval = Sbuilder::Ial::Model.map2expression(@lval)
593
+ expression.op = @op
594
+ expression.rval = Sbuilder::Ial::Model.map2expression(@rval)
595
+ expression
596
+ end
597
+ end
598
+
599
+ class ParameterizedExpressionBuilder < ExpressionBuilder
600
+ def args(v=nil)
601
+ if @args.nil?
602
+ @args = v.is_a?( Array ) ? v.map { |p| Sbuilder::Ial::Model.map2expression(p) } : [ Sbuilder::Ial::Model.map2expression(v) ]
603
+ else
604
+ # @args = []
605
+ if v.is_a?( Array )
606
+ @args = @args + v.map { |p| Sbuilder::Ial::Model.map2expression(p) }
607
+ else
608
+ @args << Sbuilder::Ial::Model.map2expression(v)
609
+ end
610
+ end
611
+ self
612
+ end
613
+ end
614
+
615
+ class TlaExpressionBuilder < ParameterizedExpressionBuilder
616
+ def template(v=nil); @template=v; self;end
617
+ def build
618
+ expression = TlaExpression.new( :tlaExpression )
619
+ raise ModelDslException, "Missing template '#{@template}' in tlaExpression - valid templates: #{Constants::TLA_TEMPLATES.keys.join(',')}" if @template.nil?
620
+ raise ModelDslException, "Unsupported tla template '#{@template}' - valid templates: #{Constants::TLA_TEMPLATES.keys.join(',')}" if Constants::TLA_TEMPLATES[@template].nil?
621
+ expression.template = @template
622
+ expression.templateEval = Constants::TLA_TEMPLATES[@template]
623
+ expression.args = @args && @args.map{ |e| Sbuilder::Ial::Model.map2expression(e) } || []
624
+ expression
625
+ end
626
+ end
627
+
628
+ class OperatorExpressionBuilder < ParameterizedExpressionBuilder
629
+ def called( v=nil) @called=v; self; end
630
+ def infrastructureService( v=nil) @infrastructureService=v; self; end
631
+ def build
632
+ expression = OperatorExpression.new( :operatorExpression )
633
+ expression.called = @called
634
+ expression.infrastructureService = @infrastructureService.nil? ? false : @infrastructureService
635
+ expression.args = @args || []
636
+ expression
637
+ end
638
+ end
639
+
640
+
641
+
642
+ # ------------------------------------------------------------------
643
+ # Transaction
644
+ class CallableBuilder
645
+ def name(v=nil); @name=v; self;end
646
+ def request(v=nil)
647
+ if v.is_a?( Array )
648
+ # expect array 'v' of properties
649
+ @request=Sbuilder::Ial.request() { properties v }
650
+ else
651
+ @request=v
652
+ end
653
+ self
654
+ end
655
+ def block(v=nil, &blk )
656
+ if block_given?
657
+ @block = Sbuilder::Ial.block( &blk )
658
+ else
659
+ @block=v; self;
660
+ end
661
+ end
662
+ private def map2Local( l )
663
+ l.is_a?( Local ) ? l : Sbuilder::Ial.local() { name l }
664
+ end
665
+ end
666
+
667
+ class FunctionCallableBuilder < CallableBuilder
668
+ def response(v=nil)
669
+ if v.is_a?( Array )
670
+ # expect array of properties
671
+ @response=Sbuilder::Ial.response() { properties v }
672
+ else
673
+ @response=v
674
+ end
675
+ self
676
+ end # response
677
+ def locals(v=[])
678
+ if @locals.nil?
679
+ @locals = v.is_a?( Array ) ? v.map{ |l| map2Local(l)} : [map2Local(v)]
680
+ else
681
+ # @locals = []
682
+ if v.is_a?( Array )
683
+ @locals = @locals + v.map{ |l| map2Local(l)}
684
+ else
685
+ @locals << map2Local(v)
686
+ end
687
+ end
688
+ self
689
+ end # locals
690
+ end
691
+
692
+ class TransactionBuilder < FunctionCallableBuilder
693
+ def operation(v=nil); @operation=v; self;end
694
+ def entryBlock(v=nil, &blk )
695
+ if block_given?
696
+ @entryBlock = Sbuilder::Ial.block( &blk )
697
+ else
698
+ @entryBlock=v; self;
699
+ end
700
+ end
701
+ def exitBlock(v=nil); @exitBlock=v; self;end
702
+ def build
703
+ transaction = Transaction.new( Constants::IAL_TRANSACTION, @name )
704
+ transaction.locals = @locals || []
705
+ transaction.operation = @operation || ""
706
+ transaction.response = @response || Sbuilder::Ial.response(){ properties [] }
707
+ transaction.request = @request || Sbuilder::Ial.request() { properties [] }
708
+ transaction.entryBlock = @entryBlock || BlockBuilder.new.build
709
+ transaction.block = @block || BlockBuilder.new.build
710
+ transaction.exitBlock = @exitBlock
711
+ transaction
712
+ end
713
+ end
714
+
715
+ class ParameterizedCallableBuilder < CallableBuilder
716
+ private def map2Parameter( p )
717
+ if p.is_a?( Parameter ) then
718
+ p
719
+ elsif p.is_a? String
720
+ Sbuilder::Ial.parameter() { name p }
721
+ else
722
+ raise "Invalid parameter #{p} expecting Parameter or String"
723
+ end
724
+ end
725
+ def parameters(v=nil)
726
+ if @parameters.nil?
727
+ @parameters = v.is_a?( Array ) ? v.map { |p| map2Parameter(p) } : [map2Parameter(v)]
728
+ else
729
+ # @parameters = []
730
+ if v.is_a?( Array )
731
+ @parameters = @parameters + v.map { |p| map2Parameter(p) }
732
+ else
733
+ @parameters << map2Parameter(v)
734
+ end
735
+ end
736
+ self
737
+ end # parameters
738
+ end
739
+
740
+ class MacroBuilder < ParameterizedCallableBuilder
741
+ def build
742
+ macro = Macro.new( Constants::IAL_MACRO, @name )
743
+ macro.parameters = @parameters || []
744
+ macro.block = @block || Sbuilder::Ial.block{ nop }
745
+ macro
746
+ end
747
+ end
748
+
749
+ class OperatorBuilder < ParameterizedCallableBuilder
750
+ def body(v=nil); @body=v; self;end
751
+ def expression(v=""); @body=Sbuilder::Ial::Model.map2expression(v); self;end
752
+ def build
753
+ operator = Operator.new( Constants::IAL_OPERATOR, @name )
754
+ operator.parameters = @parameters || []
755
+ operator.body = @body || Sbuilder::Ial.constantExpression(){ const true }
756
+ operator
757
+ end
758
+ end
759
+
760
+
761
+ # ------------------------------------------------------------------
762
+ # Paramaeter sets: Definition, Request, Response
763
+
764
+ class ParameterSetBuilder
765
+
766
+ # @param [Property|String|Hash] p
767
+ #
768
+ # @return [Property]
769
+ private def map2Property( p )
770
+ if p.is_a?( Property ) then
771
+ p
772
+ elsif p.is_a? String
773
+ Sbuilder::Ial.property() { name p }
774
+ elsif p.is_a?( Hash) && p.key?( :name ) && p.key?( :domain )
775
+ Sbuilder::Ial.property() { name p[:name]; domain p[:domain] }
776
+ elsif p.is_a?( Hash) && p.key?( :name ) && p.key?( :definition )
777
+ Sbuilder::Ial.property() { name p[:name]; definition p[:definition] }
778
+ else
779
+ raise "Invalid property #{p} expecting Property,String, or Hash with :name and :domain/:definition properties"
780
+ end
781
+ end
782
+ def properties ( v=[] )
783
+ if @properties.nil?
784
+ @properties = v.is_a?( Array ) ? v.map { |p| map2Property(p) } : [map2Property(v)]
785
+ else
786
+ # @properties = []
787
+ if v.is_a?( Array )
788
+ @properties = @properties + v.map { |p| map2Property(p) }
789
+ else
790
+ @properties << map2Property(v)
791
+ end
792
+ end
793
+ self
794
+ end
795
+ end
796
+
797
+ class RequestBuilder < ParameterSetBuilder
798
+ def build
799
+ parameterSet = Request.new( :request, @properties || [] )
800
+ parameterSet
801
+ end
802
+ end
803
+ # response
804
+
805
+ class ResponseBuilder < ParameterSetBuilder
806
+ def build
807
+ parameterSet = Response.new( :response, @properties || [] )
808
+ parameterSet
809
+ end
810
+ end
811
+
812
+ # definition
813
+
814
+ class DefinitionBuilder < ParameterSetBuilder
815
+ def name(v=nil); @name=v; self;end
816
+ def build
817
+ definitionParameterSet = Definition.new( :definition, @properties || [] )
818
+ definitionParameterSet.name = @name
819
+ definitionParameterSet
820
+ end
821
+ end
822
+
823
+ end # module Model
824
+
825
+ # ------------------------------------------------------------------
826
+ # Sbuilder::Ial API
827
+
828
+ def domain( &block )
829
+ Docile.dsl_eval( Sbuilder::Ial::Model::DomainBuilder.new, &block ).build
830
+ end
831
+ module_function :domain
832
+
833
+ def property( &block )
834
+ Docile.dsl_eval( Sbuilder::Ial::Model::PropertyBuilder.new, &block ).build
835
+ end
836
+ module_function :property
837
+
838
+ def variable( &block )
839
+ Docile.dsl_eval( Sbuilder::Ial::Model::VariableBuilder.new, &block ).build
840
+ end
841
+ module_function :variable
842
+
843
+ def library( &block )
844
+ Docile.dsl_eval( Sbuilder::Ial::Model::LibraryBuilder.new, &block ).build
845
+ end
846
+ module_function :library
847
+
848
+ def local( &block )
849
+ Docile.dsl_eval( Sbuilder::Ial::Model::LocalBuilder.new, &block ).build
850
+ end
851
+ module_function :local
852
+
853
+ def block( &block )
854
+ Docile.dsl_eval( Sbuilder::Ial::Model::BlockBuilder.new, &block ).build
855
+ end
856
+ module_function :block
857
+
858
+
859
+ def printStatement( &block )
860
+ Docile.dsl_eval( Sbuilder::Ial::Model::PrintStatementBuilder.new, &block ).build
861
+ end
862
+ module_function :printStatement
863
+
864
+
865
+ def skipStatement( &block )
866
+ Docile.dsl_eval( Sbuilder::Ial::Model::SkipStatementBuilder.new, &block ).build
867
+ end
868
+ module_function :skipStatement
869
+
870
+ def assignStatement( &block )
871
+ Docile.dsl_eval( Sbuilder::Ial::Model::AssignStatementBuilder.new, &block ).build
872
+ end
873
+ module_function :assignStatement
874
+
875
+ # def deleteStatement( &block )
876
+ # Docile.dsl_eval( Sbuilder::Ial::Model::DeleteStatementBuilder.new, &block ).build
877
+ # end
878
+ # module_function :deleteStatement
879
+
880
+ # def updateStatement( &block )
881
+ # Docile.dsl_eval( Sbuilder::Ial::Model::UpdateStatementBuilder.new, &block ).build
882
+ # end
883
+ # module_function :updateStatement
884
+
885
+
886
+ def callStatement( &block )
887
+ Docile.dsl_eval( Sbuilder::Ial::Model::CallStatementBuilder.new, &block ).build
888
+ end
889
+ module_function :callStatement
890
+
891
+ def conditionalStatement( &block )
892
+ Docile.dsl_eval( Sbuilder::Ial::Model::ConditionalStatementBuilder.new, &block ).build
893
+ end
894
+ module_function :conditionalStatement
895
+
896
+
897
+ def constantExpression( &block )
898
+ Docile.dsl_eval( Sbuilder::Ial::Model::ConstantExpressionBuilder.new, &block ).build
899
+ end
900
+ module_function :constantExpression
901
+
902
+
903
+ def referenceExpression( &block )
904
+ Docile.dsl_eval( Sbuilder::Ial::Model::ReferenceExpressionBuilder.new, &block ).build
905
+ end
906
+ module_function :referenceExpression
907
+
908
+
909
+ def binaryExpression( &block )
910
+ Docile.dsl_eval( Sbuilder::Ial::Model::BinaryExpressionBuilder.new, &block ).build
911
+ end
912
+ module_function :binaryExpression
913
+
914
+ def tlaExpression( &block )
915
+ Docile.dsl_eval( Sbuilder::Ial::Model::TlaExpressionBuilder.new, &block ).build
916
+ end
917
+ module_function :tlaExpression
918
+
919
+ def operatorExpression( &block )
920
+ Docile.dsl_eval( Sbuilder::Ial::Model::OperatorExpressionBuilder.new, &block ).build
921
+ end
922
+ module_function :operatorExpression
923
+
924
+
925
+ def transaction( &block )
926
+ Docile.dsl_eval( Sbuilder::Ial::Model::TransactionBuilder.new, &block ).build
927
+ end
928
+ module_function :transaction
929
+
930
+ def macro( &block )
931
+ Docile.dsl_eval( Sbuilder::Ial::Model::MacroBuilder.new, &block ).build
932
+ end
933
+ module_function :macro
934
+
935
+ def operator( &block )
936
+ Docile.dsl_eval( Sbuilder::Ial::Model::OperatorBuilder.new, &block ).build
937
+ end
938
+ module_function :operator
939
+
940
+ def parameter( &block )
941
+ Docile.dsl_eval( Sbuilder::Ial::Model::ParameterBuilder.new, &block ).build
942
+ end
943
+ module_function :parameter
944
+
945
+
946
+ def request( &block )
947
+ Docile.dsl_eval( Sbuilder::Ial::Model::RequestBuilder.new, &block ).build
948
+ end
949
+ module_function :request
950
+
951
+ def response( &block )
952
+ Docile.dsl_eval( Sbuilder::Ial::Model::ResponseBuilder.new, &block ).build
953
+ end
954
+ module_function :response
955
+
956
+ def definition( &block )
957
+ Docile.dsl_eval( Sbuilder::Ial::Model::DefinitionBuilder.new, &block ).build
958
+ end
959
+ module_function :definition
960
+
961
+
962
+ end # module Ial
963
+ end
964
+ # ------------------------------------------------------------------
965
+ # Public API
966
+
967
+ # def Domain( &blk )
968
+ # Sbuilder::Ial::Model.domain( &blk )
969
+ # end
970
+
971
+ # def Property( &blk )
972
+ # Sbuilder::Ial::Model.property( &blk )
973
+ # end
974
+
975
+ # # Paramater sets
976
+ # def Definition( &blk )
977
+ # Sbuilder::Ial::Model.definition( &blk )
978
+ # end
979
+ # def Request( &blk )
980
+ # Sbuilder::Ial::Model.request( &blk )
981
+ # end
982
+ # def Response( &blk )
983
+ # Sbuilder::Ial::Model.response( &blk )
984
+ # end
985
+
986
+ # def Variable( &blk )
987
+ # Sbuilder::Ial::Model.variable( &blk )
988
+ # end
989
+
990
+ # def Local( &blk )
991
+ # Sbuilder::Ial::Model.local( &blk )
992
+ # end
993
+
994
+ # # callables
995
+
996
+ # def Transaction( &blk )
997
+ # Sbuilder::Ial::Model.transaction( &blk )
998
+ # end
999
+
1000
+ # # block and statemets
1001
+
1002
+ # def Block( &blk )
1003
+ # Sbuilder::Ial::Model.block( &blk )
1004
+ # end
1005
+
1006
+
1007
+ # def PrintStatement( &blk )
1008
+ # Sbuilder::Ial::Model.printStatement( &blk )
1009
+ # end
1010
+
1011
+ # def skipStatement( &blk )
1012
+ # if block_given?
1013
+ # Sbuilder::Ial::Model.skipStatement( &blk )
1014
+ # else
1015
+ # Sbuilder::Ial::Model.skipStatement {}
1016
+ # end
1017
+ # end
1018
+
1019
+
1020
+ # def ConstantExpression( &blk )
1021
+ # Sbuilder::Ial::Model.constantExpression( &blk )
1022
+ # end
1023
+
1024
+ # def ReferenceExpression( &blk )
1025
+ # Sbuilder::Ial::Model.referenceExpression( &blk )
1026
+ # end
1027
+ # def BinaryExpression( &blk )
1028
+ # Sbuilder::Ial::Model.binaryExpression( &blk )
1029
+ # end
1030
+ # def TlaExpression( &blk )
1031
+ # Sbuilder::Ial::Model.tlaExpression( &blk )
1032
+ # end
1033
+
1034
+ # def Library( &blk )
1035
+ # Sbuilder::Ial::Model.library( &blk )
1036
+ # end
1037
+
1038
+