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,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
+