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,1306 @@
1
+ require 'mustache'
2
+ require 'sbuilder'
3
+
4
+ module Sbuilder
5
+ module Ial
6
+ module Action
7
+ module Render
8
+
9
+ ###
10
+ # Api to create TLA generate elements i.e. data SEXPs defining TLA
11
+ # language elements, and mustache partials to render data
12
+ # SEXPs to TLA language.
13
+ #
14
+ #
15
+ class TlaElementGenerator
16
+
17
+ PROGNAME = nil # progname for logger default class name
18
+ include Sbuilder::Ial::MyLogger # mix logger
19
+
20
+ # @attr [Hash] partials intialized with #setPartials, cumulated
21
+ # using #addPartial
22
+ attr_reader :partials
23
+
24
+ # @attr [Hash] partials_duplicateCheck, used only as guarantee
25
+ # againts redefinition
26
+ attr_reader :partials_duplicateCheck
27
+
28
+ # # @attr [Hash] validMetatypes raise exception for unknwon mentateyps
29
+ # attr_reader :validMetatypes
30
+
31
+ # @attr [Hash] labeledStmts
32
+ #
33
+ # @option labeledStmts [:Symbol] <sTlaType> generate template
34
+ # map to true is label should be followed
35
+ attr_reader :labeledStmts
36
+
37
+ # text to prefix trace print
38
+ TRACE_PREFIX="TRACE>"
39
+
40
+ # Constants
41
+ TLA_LABEL_ABORT = "_abort"
42
+ TLA_LABEL_END = "_end"
43
+ TLA_LABEL_FAIL = "_fail"
44
+
45
+
46
+
47
+ # ------------------------------------------------------------------
48
+ # @!group Construct & configure
49
+
50
+ def initialize( options = {} )
51
+ @options = options
52
+ @logger = getLogger( nil, options )
53
+ @logger.info "#{__method__}: initalized"
54
+
55
+ # initially no known template requiring labe
56
+ @labeledStmts = {}
57
+
58
+ end
59
+
60
+ # Init w. application context
61
+ def self.start( partials = {} )
62
+ tlaGenerator = TlaElementGenerator.new
63
+ tlaGenerator.setPartials( partials )
64
+ # tlaGenerator.setValidMetatypes( METATYPES )
65
+ tlaGenerator
66
+ end
67
+
68
+
69
+ # # @return [Hash] defaultPartials for mustache templates
70
+ # def self.defaultPartials
71
+ # {
72
+ # :Snippet => <<-EOS
73
+ # (* {|metatype|}:{|appName|}{|# comment |} - {|{ comment }|}{|/ comment |} *)
74
+ # {|#snippet|}{|#EVAL|}.{|/EVAL|}{|/snippet|}
75
+ # EOS
76
+ # }
77
+ # end
78
+
79
+ def setPartials( partials )
80
+ @partials = partials
81
+ @partials_duplicateCheck = {}
82
+ end
83
+
84
+ # def setValidMetatypes( validMetatypes )
85
+ # @validMetatypes = validMetatypes
86
+ # end
87
+
88
+
89
+ # @!endgroup
90
+
91
+
92
+ # ------------------------------------------------------------------
93
+ # @!group Utitilities to create generate elements
94
+
95
+ # create s() with +sym+ (to dispatch correct template) and +hash+ as
96
+ # template data to render.
97
+ def stla( sym, hash)
98
+ sTla = s( sym, hash )
99
+
100
+ # sTla.define_singleton_method( :patch, lambda { |key,val| self[1][key] = val } )
101
+ # sTla.define_singleton_method( :h ) do
102
+ # self[1]
103
+ # end
104
+ # sTla.define_singleton_method( :e ) do
105
+ # s(self[1])
106
+ # end
107
+ sTla
108
+ end
109
+
110
+
111
+ ###
112
+ # Add +partialTemplate+ with name +partialSymbol+ to partial
113
+ # collection.
114
+ #
115
+ # NOTICE: as an optimization Mustache template implementation
116
+ # can use partials, which are initalized using
117
+ # 'Mustache.templateify' to speed up rendering phase.
118
+ #
119
+ # @param [Symbol] partialSymbol identifying partial
120
+ #
121
+ # @param [String] partialTemplate to render element SEXP
122
+ #
123
+ #
124
+ def addPartial( partialSymbol, partialTemplate )
125
+ raise "Should have called #setPartials before actions" if partials.nil?
126
+ # would like to guarantee that no template refinition takes
127
+ # place - currently assume that implementation is correct and
128
+ # just return
129
+
130
+ return if partials.key?(partialSymbol)
131
+ raise <<-EOS.unindent if partials_duplicateCheck.key?(partialSymbol) && partials_duplicateCheckpartials[partialSymbol] != partialTemplate
132
+ Partial #{partialSymbol} redefinitition:
133
+
134
+ Previous:
135
+ #{partials[partialSymbol]}
136
+
137
+ New:
138
+ #{partialTemplate}
139
+
140
+ EOS
141
+
142
+ partials[partialSymbol] = Mustache.templateify(partialTemplate)
143
+ partials_duplicateCheck[partialSymbol] = partialTemplate
144
+ end
145
+
146
+ # @!endgroup
147
+
148
+
149
+ # ------------------------------------------------------------------
150
+ # @!group Statement labeling
151
+
152
+ ##
153
+ # Configure +sTlaType+ in +labeledStmts+ to require a label
154
+ #
155
+ # @see requiresLabelAfter
156
+ def tlaStatementTypeRequiresLabel( sTlaType )
157
+ labeledStmts[sTlaType] = true
158
+ end
159
+
160
+ ##
161
+ # Flag +stmt+ to include label if +hiddenStmt+ requires label.
162
+ #
163
+ # @param [Boolean ] labelFollowingStatemaent used return 'true'
164
+ # for 'isLabedStatement' if within a block. If not within block delegate
165
+ # to labedStatement
166
+ #
167
+ # @see requiresLabelAfter
168
+ def statementRequiresLabel( stmt, labedStatement=nil )
169
+ stmt.define_singleton_method( :labelFollowingStatement ) do |inBlock|
170
+ return true if labedStatement.nil?
171
+ inBlock ? true : labedStatement
172
+ end
173
+ end
174
+
175
+ ##
176
+ # Statement 'stmt' contains a block with 'stmts', which should
177
+ # also be labeled. Later, use :labelBlockStatements to return
178
+ # 'stmts' to label.
179
+ def setLabelBlockStatements( stmt, stmts, methodName = :labelBlockStatements )
180
+ stmt.define_singleton_method( methodName ) do
181
+ stmts
182
+ end
183
+ end
184
+
185
+
186
+ ##
187
+ # Check whether +stmt+ with +stmt.sexp_type+ should be followed
188
+ # by a labeled statement.
189
+ #
190
+ # @param [SexpTla] stmt sexp which may respond to ':labelFollowingStatement'
191
+ #
192
+ # @return [Boolean] true is +sTlaType+ is found in
193
+ # +labeledStmts+ hash OR stmt.labelFollowingStatement
194
+ def requiresLabelAfter( stmt, inBlock=false )
195
+ return false unless stmt
196
+ # if s( s(:sym, ..), s(:sym,)) vs. s(:sym, ..)
197
+ sTlaType = stmt.any? && !stmt[0].is_a?(Symbol) ? stmt.last.sexp_type : stmt.sexp_type
198
+
199
+ # static
200
+ if labeledStmts[sTlaType] ||
201
+ ( stmt.respond_to?(:labelFollowingStatement) && stmt.labelFollowingStatement(inBlock))
202
+ return true
203
+ end
204
+ # dynamic recursion to block
205
+ if stmt.respond_to?(:requiresLabelAfterChecker)
206
+ stmt.requiresLabelAfterChecker.each do |st|
207
+ return true if requiresLabelAfter( st, true )
208
+ end
209
+ end
210
+ return false
211
+ end
212
+
213
+ def gen_serviceProcedureLabelStatements( stmts, labelPrefix )
214
+ stmts = stmts[1][:stmts] if stmts.is_a?(Array) && stmts[0] == :TLA_stmts
215
+ stmts, index = serviceProcedureLabelStatementsWorker( stmts, labelPrefix, 0, 0, true )
216
+ stmts
217
+ end
218
+
219
+ ##
220
+ # @return [Array, index] stmts as passed as input, index incremented
221
+ private def serviceProcedureLabelStatementsWorker( stmts, labelPrefix, index, level, labelFirst )
222
+ assignments = []
223
+ stmts.each_with_index do |stmt,i|
224
+
225
+ # prev stamement in current block
226
+ prevStmt = stmts[i-1] if i > 0
227
+ # puts "#{' ' * level } - #{level}: #{labelPrefix[1][:specname][:appName]}-#{index} #{stmts[i][0]}"
228
+ if labelFirst || ( !prevStmt.nil? && requiresLabelAfter( prevStmt ) ) || ( stmt[0] == :TLA_assign ) && assignments.include?( getLvalVariableName(stmt[1][:lval]) )
229
+ stmts[i] = gen_labeled_stmt( stmt, labelPrefix, index )
230
+ # puts "#{' ' * level } - #{level}: --> label #{labelPrefix[1][:specname][:appName]}-#{index} #{stmt[0]}"
231
+ index += 1
232
+ # restart collection
233
+ assignments = []
234
+ end
235
+ # collect assingments
236
+ assignments << getLvalVariableName(stmt[1][:lval]) if stmt[0] == :TLA_assign
237
+
238
+ labelFirst = false
239
+
240
+ # then & while>?
241
+ if stmt.respond_to?( :labelBlockStatements )
242
+ # recursion
243
+ s, index = serviceProcedureLabelStatementsWorker( stmt.labelBlockStatements, labelPrefix, index, level+1, false )
244
+ end
245
+
246
+ # else block
247
+ if stmt.respond_to?( :labelBlockStatementsElse )
248
+ # recursion
249
+ s, index = serviceProcedureLabelStatementsWorker( stmt.labelBlockStatementsElse, labelPrefix, index, level+1, false )
250
+ end
251
+
252
+
253
+ end
254
+ return stmts, index
255
+ end
256
+
257
+
258
+ # @param [TLA_plainname] lval from which to extract variable name
259
+ def getLvalVariableName( lval )
260
+ case lval[0]
261
+ when :TLA_plainname
262
+ lval[1][:name]
263
+ when :TLA_specname
264
+ lval[1][:specname][:appName]
265
+ else
266
+ raise "Unknown lval type '#{lval[0]}' in #{lval}"
267
+ end
268
+ end
269
+
270
+
271
+
272
+ # @!endgroup
273
+
274
+ # ------------------------------------------------------------------
275
+ # @!group Create TLA specific generate element SEXPs
276
+
277
+ def gen_label_it( tla )
278
+ sym = :TLA_label_it
279
+ tlaStatementTypeRequiresLabel( sym )
280
+ addPartial( sym, "{|#EVAL|}tla{|/EVAL|}" )
281
+ stla( sym, { :tla => tla } )
282
+ end
283
+
284
+ def gen_macro( name, parameters, stmts )
285
+
286
+ sym = :TLA_macro
287
+ addPartial(
288
+ sym,
289
+ "macro {|#EVAL|}name{|/EVAL|}( {|#parameters|}{|#EVAL|}parameter{|/EVAL|}{|_comma|}{|/parameters|} ) {\n"\
290
+ "{|#EVAL|}stmts{|/EVAL|}"\
291
+ "}"
292
+ )
293
+
294
+ # allow singleton parameter
295
+ parameters = parameters.is_a?( Array ) ? parameters : [parameters]
296
+
297
+ stla( sym, {
298
+ :name => name,
299
+ :parameters => parameters.any? ?
300
+ parameters.map.with_index do |p,i|
301
+ { :_comma => (i+1) == parameters.length ? '' : ',',
302
+ :parameter => p.is_a?(String) ? gen_plainname( p ): p,
303
+ }
304
+ end :
305
+ false,
306
+ :stmts => stmts,
307
+ })
308
+ end
309
+
310
+ def gen_service_procedure( serviceName, interfaceName, localVariables, stmts=gen_stmts(s()) )
311
+
312
+ sym = :TLA_Procedure
313
+ addPartial(
314
+ sym,
315
+ <<-EOS.unindent
316
+ procedure {|#EVAL|}name{|/EVAL|}( {|#EVAL|}name{|/EVAL|}_input )
317
+ {|#locals|}variable {|/locals|}{|#localVariables|} {|#EVAL|}variable{|/EVAL|}{|_comma|}{|/localVariables|}{|#locals|};
318
+ {|/locals|}{|!
319
+ Start procudedure block
320
+ |}{
321
+ {|#EVAL|}name{|/EVAL|}_start:
322
+ {|#EVAL|}start{|/EVAL|};
323
+
324
+ (* Body of {|#EVAL|}interfaceName{|/EVAL|} *)
325
+ {|#EVAL|}stmts{|/EVAL|}
326
+
327
+ {|#EVAL|}name{|/EVAL|}_exit:
328
+ goto {|#EVAL|}name{|/EVAL|}#{TLA_LABEL_END};
329
+ {|#EVAL|}name{|/EVAL|}#{TLA_LABEL_FAIL}:
330
+ \\* throw command sends here
331
+ InfrastructureServiceReturn( "{|#EVAL|}interfaceName{|/EVAL|}", FALSE, Nil);
332
+ goto {|#EVAL|}name{|/EVAL|}_end;
333
+
334
+ {|#EVAL|}name{|/EVAL|}#{TLA_LABEL_ABORT}:
335
+ \\* should not happen??
336
+ print <<"ABORT {|#EVAL|}name{|/EVAL|}">>;
337
+ InfrastructureServiceReturn( "{|#EVAL|}interfaceName{|/EVAL|}", Abort, Nil);
338
+ \\* schedule_throw( "{|#EVAL|}name{|/EVAL|}_exit" );
339
+ {|#EVAL|}name{|/EVAL|}#{TLA_LABEL_END}:
340
+ ethereum_service_pop( "{|#EVAL|}interfaceName{|/EVAL|}" );
341
+ {|#EVAL|}return{|/EVAL|};
342
+ }
343
+ EOS
344
+ )
345
+
346
+ name = serviceName.is_a?( String) ? gen_plainname(serviceName) : serviceName
347
+
348
+ stla( sym, {
349
+ :name => name,
350
+ :locals => localVariables && localVariables.length > 0 ? true : false,
351
+ :localVariables => localVariables.map.with_index do |v,i|
352
+ {
353
+ :variable => v.is_a?(String) ? gen_plainname(v) : v,
354
+ :_comma => (i+1) == localVariables.length ? '' : ',',
355
+ }
356
+ end,
357
+ :interfaceName => interfaceName.is_a?( String) ? gen_plainname(interfaceName) : interfaceName,
358
+ :start => gen_traced_stmt(
359
+ gen_skip,
360
+ s( "ENTRY:" ), # + entry_exit,
361
+ ),
362
+ :stmts => stmts,
363
+ :return =>
364
+ gen_traced_stmt(
365
+ gen_return,
366
+ s( "EXIT:", ), # + entry_exit,
367
+ ),
368
+ })
369
+ end
370
+
371
+
372
+
373
+ ##
374
+ # @return +specName+
375
+ def gen_expression2( expr1, op, expr2 )
376
+ sym = :TLA_expression2
377
+ addPartial( sym, "{|#EVAL|}expr1{|/EVAL|} {|#EVAL|}op{|/EVAL|} {|#EVAL|}expr2{|/EVAL|}" )
378
+ stla( sym, {
379
+ :expr1 => expr1,
380
+ :op => op,
381
+ :expr2 => expr2,
382
+ })
383
+ end
384
+
385
+ ##
386
+ # @return [ f1 |-> type1, f2 |->type2 ]
387
+ def gen_record_definition( arrOfFields )
388
+
389
+ sym = :TLA_record_definition
390
+ addPartial( sym, "[ {|#fields|}{|#EVAL|}val{|/EVAL|}{|_comma|} {|/fields|}]" )
391
+
392
+ # simplify if just one given
393
+ arrOfFields = arrOfFields[0].is_a?( Symbol ) ? s(arrOfFields) : arrOfFields
394
+
395
+ # last element no comma
396
+ stla( sym,
397
+ {
398
+ :fields => arrOfFields.map.with_index { |f,i|
399
+ { :_comma => (i+1) == arrOfFields.length ? '' : ',', :val => f }
400
+ }
401
+ })
402
+
403
+ end
404
+
405
+
406
+ ##
407
+ # +variable+ \in +set+
408
+ def gen_set_iterate( variable, set )
409
+
410
+ sym = :TLA_set_iterate
411
+ addPartial( sym, "{|#EVAL|}variable{|/EVAL|} \\in {|#EVAL|}set{|/EVAL|} " )
412
+
413
+ # last element no comma
414
+ stla( sym,
415
+ {
416
+ :variable => variable.is_a?( String) ? gen_plainname(variable) : variable,
417
+ :set => set.is_a?( String) ? gen_plainname(set) : set,
418
+ })
419
+ end
420
+
421
+ ##
422
+ # { map : S}
423
+ def gen_set_map( map, set )
424
+
425
+ sym = :TLA_set_map
426
+ addPartial( sym, "{ {|#EVAL|}map{|/EVAL|} : {|#EVAL|}set{|/EVAL|} } " )
427
+
428
+ # last element no comma
429
+ stla( sym,
430
+ {
431
+ :map => map.is_a?( String) ? gen_plainname(map) : map,
432
+ :set => set.is_a?( String) ? gen_plainname(set) : set,
433
+ })
434
+ end
435
+
436
+
437
+
438
+
439
+ # # @return [ idName |-> idVal, f2 |-> Nil, ... ]
440
+ def gen_new_record( idVal, arrOfFields )
441
+
442
+ sym = :TLA_new_record
443
+ addPartial(
444
+ sym,
445
+ <<-EOS.unindent
446
+ [ {|#EVAL|}idVal{|/EVAL|}, {|#fields|}{|#EVAL|}val{|/EVAL|}{|_comma|} {|/fields|} ]
447
+ EOS
448
+ )
449
+
450
+ # last element no comma
451
+ stla( sym,
452
+ {
453
+ :idVal => idVal,
454
+ :fields => arrOfFields.map.with_index do |f,i|
455
+ { :_comma => (i+1) == arrOfFields.length ? '' : ',',
456
+ :val => f
457
+ }
458
+ end
459
+ })
460
+
461
+
462
+ end
463
+
464
+ def gen_record_field_definition( name, value )
465
+ # name |-> value (notice spaces)
466
+ gen_name_op_operand( name, '|->', value )
467
+ end
468
+ def gen_record_field( record, field )
469
+ # A.x
470
+ gen_name_op_operand( record, '.', field, "" )
471
+ end
472
+ def gen_record_named_field( record, field )
473
+ # A[x]
474
+ sym = :TLA_record_named_field
475
+
476
+ addPartial( sym, "{|#EVAL|}record{|/EVAL|}{|sepl|}{|#EVAL|}field{|/EVAL|}{|sepr|}" )
477
+
478
+ stla( sym,
479
+ {
480
+ :record => record.is_a?( String ) ? gen_plainname(record) : record,
481
+ :sepl => '[',
482
+ :sepr => ']',
483
+ :field => field.is_a?( String ) ? gen_plainname(field) : field,
484
+ })
485
+ end
486
+
487
+
488
+
489
+ def gen_name_op_operand( name, op, operand, sep=" " )
490
+
491
+ sym = :TLA_name_op_operand
492
+ addPartial( sym, "{|#EVAL|}name{|/EVAL|}{|sep|}{|{op}|}{|sep|}{|#EVAL|}operand{|/EVAL|}" )
493
+
494
+ stla( sym,
495
+ {
496
+ :name => name.is_a?( String ) ? gen_plainname(name) : name,
497
+ :op => op,
498
+ :sep => sep,
499
+ :operand => operand.is_a?( String ) ? gen_plainname(operand) : operand,
500
+ })
501
+
502
+ end
503
+
504
+ ##
505
+ # Map interface to service name e.g./customer(get), Demo()
506
+ def gen_service_name( interface )
507
+ gen_identifier( interface )
508
+ end
509
+
510
+ def gen_identifier( identifier, posfix="" )
511
+
512
+ sym = :TLA_identifier
513
+ addPartial( sym, "{|#EVAL|}identifier{|/EVAL|}{|#EVAL|}postfix{|/EVAL|}" )
514
+
515
+ stla( sym, {
516
+ :identifier => identifier.is_a?( String) ?
517
+ gen_plainname(identifier) :
518
+ identifier,
519
+ :postfix => posfix.is_a?( String) ? gen_plainname(posfix) : posfix,
520
+ })
521
+ end
522
+
523
+
524
+ ##
525
+ # @return Nil
526
+ def gen_empty_set()
527
+ sym = :TLA_emptyset
528
+
529
+ addPartial( sym, "{}" )
530
+
531
+ stla(sym, {
532
+ })
533
+ end
534
+
535
+ def gen_list( elements )
536
+ sym = :TLA_list
537
+ addPartial( sym, "{|#elements|}{|#EVAL|}element{|/EVAL|}{|_comma|}{|/elements|}" )
538
+
539
+ # allow singleton parameter
540
+
541
+ elements = elements.is_a?( String) ? gen_plainname(elements) : elements
542
+ elements = elements[0].is_a?( Symbol ) ? s(elements) : elements
543
+
544
+ stla( sym,
545
+ {
546
+ :elements => elements.map.with_index { |f,i|
547
+ { :_comma => (i+1) == elements.length ? '' : ',', :element => f }
548
+ }
549
+ })
550
+
551
+
552
+ end
553
+
554
+ ##
555
+ # @return Nil
556
+ def gen_set( element )
557
+ sym = :TLA_set
558
+ addPartial( sym, "{ {|#EVAL|}element{|/EVAL|} } " )
559
+
560
+ stla(sym, {
561
+ :element => element
562
+ })
563
+ end
564
+
565
+ def gen_sequence( elements )
566
+ sym = :TLA_sequence
567
+ addPartial( sym, "<<{|#elements|}{|#EVAL|}element{|/EVAL|}{|_comma|}{|/elements|}>>" )
568
+
569
+ elements = elements.is_a?( String) ? gen_plainname(elements) : elements
570
+ elements = elements[0].is_a?( Symbol ) ? s(elements) : elements
571
+
572
+ stla(sym, {
573
+ :elements => elements.any? ?
574
+ elements.map.with_index do |p,i|
575
+ { :_comma => (i+1) == elements.length ? '' : ',',
576
+ :element => p.is_a?(String) ? gen_plainname( p ): p,
577
+ }
578
+ end :
579
+ false,
580
+ })
581
+ end
582
+
583
+
584
+ def gen_TRUE
585
+ gen_plainname( "TRUE" )
586
+ end
587
+
588
+ def gen_FALSE
589
+ gen_plainname( "FALSE" )
590
+ end
591
+
592
+ ##
593
+ # @return Nil
594
+ def gen_nilElement()
595
+ sym = :TLA_nil_element
596
+
597
+ addPartial( sym, "Nil" )
598
+
599
+ stla( sym, {})
600
+ end
601
+
602
+
603
+ def gen_op_set_minus()
604
+ gen_op_operator( "\\" )
605
+ end
606
+
607
+ ##
608
+ # Common behavior to output operator +op+
609
+ def gen_op_operator( op )
610
+ sym = :TLA_op_operator
611
+
612
+ addPartial( sym, "{|operator|}" )
613
+
614
+ stla( sym, {
615
+ :operator => op
616
+ })
617
+
618
+ end
619
+
620
+ ##
621
+ # Define state variable +variable+ and initialize
622
+ # with +initExpr+
623
+ def gen_state_variable( variable, initExpr )
624
+ sym = :TLA_state_variable
625
+ addPartial( sym, "{|#EVAL|}variable{|/EVAL|} = {|#EVAL|}init_expression{|/EVAL|};" )
626
+
627
+ stla( sym, {
628
+ :variable => variable,
629
+ :init_expression => initExpr,
630
+ })
631
+ end
632
+
633
+ ##
634
+ # @param [String] interfaceName e.g. 'Demo()' or 'Demo(set)'
635
+ #
636
+ # @return [String] input variable name
637
+ def gen_interface_input_variable_name( interfaceName, metatype=:solidity_contract_function )
638
+ gen_identifier( gen_specname( metatype, interfaceName), "_input" )
639
+ end
640
+
641
+ ##
642
+ # @param [String] interfaceName e.g. 'Demo()' or 'Demo(set)'
643
+ #
644
+ def gen_interface_abort_label( interfaceName, serviceName=nil )
645
+ serviceName = gen_serviceName( interfaceName ) if serviceName.nil?
646
+ gen_identifier( serviceName, TlaElementText::TLA_LABEL_ABORT )
647
+ end
648
+
649
+ def gen_interface_end_label( interfaceName, serviceName=nil )
650
+ serviceName = gen_serviceName( interfaceName ) if serviceName.nil?
651
+ gen_identifier( serviceName, TlaElementText::TLA_LABEL_END )
652
+ end
653
+
654
+ ##
655
+ # Solidity code should check for error
656
+ def gen_interface_fail_label( interfaceName, serviceName=nil )
657
+ serviceName = gen_serviceName( interfaceName ) if serviceName.nil?
658
+ gen_identifier( serviceName, TlaElementText::TLA_LABEL_FAIL )
659
+ end
660
+
661
+ private def gen_serviceName( interfaceName )
662
+ metatype = :solidity_contract_function
663
+ gen_specname( metatype, interfaceName)
664
+ end
665
+
666
+
667
+ ##
668
+ # Create +specName+ corresponging +appName+ in +metatype+
669
+ def gen_specname( metatype, appName )
670
+
671
+ sym = :TLA_specname
672
+ addPartial( sym, "#{spec_name('specname')}" )
673
+
674
+ stla( sym,{
675
+ :specname => {
676
+ :metatype => metatype,
677
+ :appName => appName,
678
+ }})
679
+ end
680
+
681
+ # @return name (which can be processed by EVAL)
682
+ def gen_plainname( name )
683
+
684
+ sym = :TLA_plainname
685
+ addPartial( sym, "{|{name}|}" )
686
+
687
+ stla( sym, {
688
+ :name => name
689
+ })
690
+ end
691
+
692
+ def gen_constant( constant )
693
+ gen_plainname( constant )
694
+ end
695
+
696
+ # @return "str"
697
+ def gen_str( str )
698
+
699
+ sym = :TLA_str
700
+ addPartial( sym, '"{|#EVAL|}str{|/EVAL|}"' )
701
+
702
+ stla( sym, {
703
+ :str=> str.is_a?( String ) ? gen_plainname(str) : str,
704
+ })
705
+ end
706
+
707
+ # @return "str"
708
+ def gen_parenthesis( str )
709
+
710
+ sym = :TLA_parenthesis
711
+ addPartial( sym, '( {|#EVAL|}str{|/EVAL|} )' )
712
+
713
+ stla( sym, {
714
+ :str=> str.is_a?( String ) ? gen_plainname(str) : str,
715
+ })
716
+ end
717
+
718
+
719
+ # ------------------------------------------------------------------
720
+ # Statements
721
+
722
+ def gen_stmts( stmts )
723
+ # do not wrap twice
724
+ return stmts if stmts.is_a?( Array ) && stmts.any? && stmts[0] == :TLA_stmts
725
+
726
+ sym = :TLA_stmts
727
+ addPartial( sym,
728
+ "{|#stmts|}{|#EVAL|}.{|/EVAL|};\n"\
729
+ "{|/stmts|}"
730
+ )
731
+
732
+ stmts = stla( sym, {
733
+ # 1 stmt or array of stmts
734
+ :stmts => stmts && stmts.any? && stmts[0].is_a?(Symbol) ? s(stmts) : stmts
735
+ })
736
+
737
+ # add method to return statements in stmts block for checking
738
+ # the need to add label after if-statement
739
+ methodName = :requiresLabelAfterChecker
740
+ stmts.define_singleton_method( methodName ) do
741
+ # pass if & else
742
+ stmts[1][:stmts]
743
+ end
744
+
745
+ stmts
746
+
747
+ end
748
+
749
+ # @param [Integer|String] labelIndex generate unique labels using index
750
+ #
751
+ def gen_labeled_stmt( stmt, labelPrefix=false, labelIndex=0 )
752
+ sym = :TLA_labeled_stmt
753
+ addPartial( sym, "{|#label|}{|#EVAL|}labelPrefix{|/EVAL|}_{|labelIndex|}: {|/label|}{|#EVAL|}stmt{|/EVAL|}" )
754
+ labTla = stla( sym, {
755
+ :stmt => stmt,
756
+ :label => labelPrefix ? true : false,
757
+ :labelPrefix => labelPrefix.is_a?( String) ? gen_plainname(labelPrefix) : labelPrefix,
758
+ :labelIndex => labelIndex,
759
+ })
760
+
761
+ # labelel stmt should be followed by a label - if it is infront
762
+ # +stmt+, which should be followed by a label or if
763
+ # label is used within block
764
+ statementRequiresLabel( labTla, requiresLabelAfter( stmt ))
765
+ labTla
766
+ end
767
+
768
+ ##
769
+ # Generate statement, which may also generate trace output.
770
+ #
771
+ # @param [Array] traceArray message/evaluatable mesage
772
+ # @option traceArray [String|TlaSexp] parameter for print operation
773
+ #
774
+ def gen_traced_stmt( stmt, traceArray=false )
775
+ sym = :TLA_traced_stmt
776
+ addPartial( sym,
777
+ <<-EOS.unindent
778
+ {|#trace|}{|^preferences.tla-trace|}\\* {|/preferences.tla-trace|} {|#EVAL|}trace_print{|/EVAL|};
779
+ {|^preferences.tla-trace|}
780
+ {|/preferences.tla-trace|}{|/trace|}{|#EVAL|}stmt{|/EVAL|}
781
+ EOS
782
+ )
783
+
784
+ trace_stmt = stla( sym, {
785
+ :stmt => stmt,
786
+ :trace => traceArray ? true : false,
787
+ :trace_print => gen_print( traceArray ),
788
+ })
789
+
790
+ # trace_stmt should be followed by a label - if it is infront
791
+ # +stmt+, which should be followed by a label
792
+ statementRequiresLabel( trace_stmt ) if requiresLabelAfter( stmt )
793
+ trace_stmt
794
+
795
+ end
796
+
797
+ def gen_print( parameters )
798
+ sym = :TLA_print
799
+ addPartial(
800
+ sym,
801
+ "print <<"\
802
+ "{|#parameters|}{|#EVAL|}parameter{|/EVAL|}{|_comma|}{|/parameters|}"\
803
+ ">>"
804
+ )
805
+
806
+ # String mapper to Sexp && convert whole into to s() -array
807
+ parameters = gen_str( parameters ) if parameters.is_a?( String )
808
+ parameters = parameters[0].is_a?( Symbol ) ? s(parameters) : parameters
809
+ # parameters.unshift( TRACE_PREFIX )
810
+
811
+ stla( sym, {
812
+ :parameters => parameters.any? ?
813
+ parameters.map.with_index do |p,i|
814
+ { :_comma => (i+1) == parameters.length ? '' : ',',
815
+ :parameter => p.is_a?(String) ? gen_str(p) : p
816
+ }
817
+ end :
818
+ false,
819
+ })
820
+
821
+ end
822
+
823
+ def gen_assign( lval, rval )
824
+ sym = :TLA_assign
825
+ # tlaStatementTypeRequiresLabel( sym )
826
+ addPartial( sym, "{|#EVAL|}lval{|/EVAL|} := {|#EVAL|}rval{|/EVAL|}" )
827
+ stla( sym, {
828
+ :lval => lval.is_a?( String) ? gen_plainname(lval) : lval,
829
+ :rval => rval.is_a?( String) ? gen_plainname(rval) : rval,
830
+ })
831
+ end
832
+
833
+ def gen_return()
834
+
835
+ sym = :TLA_return
836
+ tlaStatementTypeRequiresLabel( sym )
837
+ addPartial( sym, "return" )
838
+ stla( sym, {})
839
+
840
+ end
841
+
842
+ def gen_assert( cond, msg )
843
+
844
+ sym = :TLA_assert
845
+ tlaStatementTypeRequiresLabel( sym )
846
+ addPartial( sym,
847
+ "(* {|#EVAL|}msg{|/EVAL|} *)\n"\
848
+ "assert( {|#EVAL|}cond{|/EVAL|} )"
849
+ )
850
+ stla( sym, {
851
+ :cond => cond.is_a?(String) ? gen_plainname(cond) : cond,
852
+ :msg => msg.is_a?(String) ? gen_str(msg) : msg,
853
+ })
854
+ end
855
+
856
+
857
+
858
+
859
+ def gen_free_text( str )
860
+ sym = :TLA_free_text
861
+ addPartial( sym, "{|{text}|}" )
862
+ # tlaStatementTypeRequiresLabel( sym )
863
+ stla( sym, {
864
+ :text => str,
865
+ })
866
+ end
867
+
868
+ ##
869
+ # preable at the start of service procedure
870
+ def gen_check_resume( procedureName )
871
+
872
+ sym = :TLA_check_resume
873
+ addPartial(
874
+ sym,
875
+ <<-EOS.unindent
876
+ (* check if resuming {|#EVAL|}procedureName{|/EVAL|} *)
877
+ if ( resume_context # Nil ) {
878
+ (* prepare stack entry with resume context followed by
879
+ a return to jump to resume location *)
880
+ stack := <<resume_context.ret_ctx >> \\o stack[self];
881
+ {|#EVAL|}procedureName{|/EVAL|}_resumed:
882
+ return;
883
+ }
884
+ EOS
885
+ )
886
+ tlaStatementTypeRequiresLabel( sym )
887
+ stla( sym, {
888
+ :procedureName => procedureName,
889
+ })
890
+
891
+ end
892
+
893
+ def gen_construct_contract( stateVariable, newContract, idPool, id )
894
+ sym = :TLA_construct_contract
895
+ addPartial( sym,
896
+ <<-EOS.unindent
897
+ \\* construct {|#EVAL|}contracts{|/EVAL|}
898
+ create_new_contract( {|#EVAL|}contracts{|/EVAL|}, {|#EVAL|}newContract{|/EVAL|}, {|#EVAL|}idPool{|/EVAL|}, {|#EVAL|}id{|/EVAL|} )
899
+ EOS
900
+ )
901
+ stla( sym, {
902
+ :contracts => stateVariable,
903
+ :newContract => newContract,
904
+ :idPool => idPool,
905
+ :id => id,
906
+ })
907
+
908
+ end
909
+
910
+
911
+ def gen_debug_msg( str )
912
+ sym = :TLA_debug_msg
913
+ # addPartial( sym, '{|^preferences.tla-debug|}\*{|/preferences.tla-debug|} print << "DEBUG: {|#EVAL|}text{|/EVAL|}" >>' )
914
+ addPartial( sym, 'print << "DEBUG: {|#EVAL|}text{|/EVAL|}" >>' )
915
+ # tlaStatementTypeRequiresLabel( sym )
916
+ stla( sym, {
917
+ :text => str.is_a?( String ) ? gen_plainname(str) : str,
918
+ })
919
+ end
920
+
921
+ def gen_commented( content )
922
+ sym = :TLA_commented
923
+ addPartial( sym,
924
+ "(* {|#EVAL|}content{|/EVAL|} *)\n"\
925
+ "skip"
926
+ )
927
+ stla( sym, {
928
+ :content => content.is_a?( String ) ? gen_plainname(content) : content,
929
+ })
930
+ end
931
+
932
+
933
+ def gen_procedure_call( procedure, parameters=s() )
934
+ sym = :TLA_procedure_call
935
+ # add label after proc.call
936
+ tlaStatementTypeRequiresLabel( sym )
937
+ addPartial(
938
+ sym,
939
+ "call {|#EVAL|}procedure{|/EVAL|}( {|#parameters|}{|#EVAL|}parameter{|/EVAL|}{|_comma|}{|/parameters|})"
940
+ )
941
+
942
+ parameters = parameters.is_a?( String ) ? gen_plainname(parameters) : parameters
943
+ parameters = parameters[0].is_a?( Symbol ) ? s(parameters) : parameters
944
+ stla( sym, {
945
+ :procedure => procedure.is_a?( String ) ? gen_plainname(procedure) : procedure,
946
+ # false or [ {:p, _comma: }]
947
+ :parameters => parameters.any? ?
948
+ parameters.map.with_index do |p,i|
949
+ { :_comma => (i+1) == parameters.length ? '' : ',',
950
+ :parameter => p
951
+ }
952
+ end :
953
+ false,
954
+ })
955
+ end
956
+
957
+ def gen_and( lhs, rhs )
958
+ gen_bin_op( '/\\', lhs, rhs )
959
+ end
960
+
961
+ def gen_not( expression )
962
+ gen_unary_op( '~', expression )
963
+ # sym = :TLA_not
964
+ # addPartial(
965
+ # sym,
966
+ # "~{|#EVAL|}expression{|/EVAL|}"
967
+ # )
968
+ # stla( sym, {
969
+ # :expression =>expression,
970
+ # })
971
+ end
972
+
973
+ def gen_unary_op( op, expr )
974
+ sym = :TLA_unary_op
975
+ addPartial(
976
+ sym, "{|{op}|} {|#EVAL|}expr{|/EVAL|}"
977
+ )
978
+
979
+ stla( sym, {
980
+ :expr => expr.is_a?( String) ? gen_plainname(expr) : expr,
981
+ :op => op,
982
+ })
983
+ end
984
+
985
+ def gen_bin_op( op, lhs, rhs )
986
+ sym = :TLA_bin_op
987
+ addPartial(
988
+ sym, "{|#EVAL|}lhs{|/EVAL|} {|{op}|} {|#EVAL|}rhs{|/EVAL|}"
989
+ )
990
+
991
+ stla( sym, {
992
+ :lhs => lhs.is_a?( String) ? gen_plainname(lhs) : lhs,
993
+ :op => op,
994
+ :rhs => rhs.is_a?( String) ? gen_plainname(rhs) : rhs,
995
+ })
996
+ end
997
+
998
+ def gen_either( stmt, stmts )
999
+ sym = :TLA_either
1000
+ tlaStatementTypeRequiresLabel( sym )
1001
+ addPartial(
1002
+ sym,
1003
+ "either {|#EVAL|}stmt{|/EVAL|}" \
1004
+ "{|#stmts|} or {|#EVAL|}.{|/EVAL|}"\
1005
+ "{|/stmts|}"
1006
+ )
1007
+
1008
+ stla( sym, {
1009
+ :stmt => stmt,
1010
+ :stmts => stmts[0].is_a?(Symbol) ? s(stmts) : stmts,
1011
+ })
1012
+
1013
+ end
1014
+
1015
+ # @param [TLA_stmts|sTla] thenStatement
1016
+ # @param [TLA_stmts|sTla|nil|false] elseStatement
1017
+ def gen_if( expression, thenStatement, elseStatement=nil )
1018
+ sym = :TLA_if
1019
+ addPartial(
1020
+ sym,
1021
+
1022
+ "if ( {|#EVAL|}cond{|/EVAL|} ) {\n"\
1023
+ ' {|#EVAL|}then{|/EVAL|}'\
1024
+ '}{|#else_given|} '\
1025
+ "else {\n"\
1026
+ ' {|#EVAL|}else{|/EVAL|}'\
1027
+ '}{|/else_given|}'
1028
+ )
1029
+
1030
+
1031
+ stmt_if = stla( sym, {
1032
+ :cond => expression.is_a?(String) ? gen_plainname(expression) : expression,
1033
+ # :then => gen_stmts( thenStatement.length == 1 ? s(stmt) : thenStatement ),
1034
+ :then => thenStatement[0] == :TLA_stmts ? thenStatement : gen_stmts( thenStatement ),
1035
+ :else_given => elseStatement && elseStatement.length > 0 ? true : false,
1036
+ :else => elseStatement ? ( elseStatement[0] == :TLA_stmts ? elseStatement : gen_stmts( elseStatement ) ) : false,
1037
+ })
1038
+
1039
+ # add label if then part of else part requires label
1040
+ # statementRequiresLabel( stmt_if ) if requiresLabelAfter( thenStatement) || requiresLabelAfter(elseStatement)
1041
+
1042
+ # add method to return statements in then/else braches for
1043
+ # checking the need to add label after if-statement
1044
+ methodName = :requiresLabelAfterChecker
1045
+ stmt_if.define_singleton_method( methodName ) do
1046
+ # pass if & else
1047
+ stmt_if[1][:then][1][:stmts] + ( stmt_if[1][:else] ? stmt_if[1][:else][1][:stmts] : [] )
1048
+ end
1049
+
1050
+ # add method to recurse into then/else block to label
1051
+ # statements within these blocks
1052
+ setLabelBlockStatements( stmt_if, stmt_if[1][:then][1][:stmts] )
1053
+ setLabelBlockStatements( stmt_if, stmt_if[1][:else][1][:stmts], :labelBlockStatementsElse ) if elseStatement
1054
+
1055
+ stmt_if
1056
+ end
1057
+
1058
+ def gen_IF( expression, thenExpr, elseExpr )
1059
+ sym = :TLA_IF
1060
+ addPartial(
1061
+ sym,
1062
+
1063
+ "IF {|#EVAL|}cond{|/EVAL|} THEN "\
1064
+ '{|#EVAL|}then{|/EVAL|} '\
1065
+ 'ELSE '\
1066
+ '{|#EVAL|}else{|/EVAL|}'
1067
+ )
1068
+
1069
+ stla( sym, {
1070
+ :cond => expression.is_a?( String) ? gen_plainname(expression) : expression,
1071
+ # :then => gen_stmts( thenExpr.length == 1 ? s(stmt) : thenExpr ),
1072
+ :then => thenExpr.is_a?( String) ? gen_plainname(thenExpr) : thenExpr,
1073
+ :else => elseExpr.is_a?( String) ? gen_plainname(elseExpr) : elseExpr,
1074
+ })
1075
+ end
1076
+
1077
+ def gen_EXCEPT( variable, excepts )
1078
+ sym = :TLA_EXCEPT
1079
+ addPartial(
1080
+ sym,
1081
+ "[ {|#EVAL|}variable{|/EVAL|} "\
1082
+ "EXCEPT "\
1083
+ '{|#excepts|}{|#EVAL|}except{|/EVAL|}{|_comma|}{|/excepts|} '\
1084
+ ']'
1085
+ )
1086
+
1087
+ # if signleton given
1088
+ excepts = excepts[0].is_a?(Symbol) ? s(excepts) : excepts
1089
+ stla( sym, {
1090
+ :variable => variable.is_a?( String ) ? gen_plainname(variable ) : variable,
1091
+ # :then => gen_stmts( thenExpr.length == 1 ? s(stmt) : thenExpr ),
1092
+ :excepts => excepts.any? ?
1093
+ excepts.map.with_index do |p,i|
1094
+ { :_comma => (i+1) == excepts.length ? '' : ',',
1095
+ :except => p
1096
+ }
1097
+ end :
1098
+ false,
1099
+ })
1100
+ end
1101
+
1102
+
1103
+ def gen_skip()
1104
+ sym = :TLA_skip
1105
+ addPartial( sym, "skip" )
1106
+ # tlaStatementTypeRequiresLabel( sym )
1107
+ stla( sym, {})
1108
+ end
1109
+
1110
+ ##
1111
+ # skip statement, but reqeuires label
1112
+ def gen_label()
1113
+ sym = :TLA_label
1114
+ tlaStatementTypeRequiresLabel( sym )
1115
+ addPartial( sym, "skip" )
1116
+ stla( sym, {})
1117
+ end
1118
+
1119
+
1120
+
1121
+ # ------------------------------------------------------------------
1122
+ # NOT USED
1123
+
1124
+
1125
+ # Generate element for a lval to set a +return_variable+ of +function_name+
1126
+ def lval_function_return( function_name, return_variable )
1127
+
1128
+ sym = :TLA_lval_function_return
1129
+ addPartial( sym,
1130
+ "{|function_name|}_{|return_variable|}" )
1131
+
1132
+ stla( sym,
1133
+ {
1134
+ :function_name =>function_name,
1135
+ :return_variable =>return_variable,
1136
+ })
1137
+
1138
+ end
1139
+
1140
+ # TODO: remove
1141
+ def rval_todo_remove
1142
+
1143
+ sym = :TLA_rval_todo_remove
1144
+ addPartial( sym, "{|demo|}" )
1145
+
1146
+ stla( sym,
1147
+ {
1148
+ :demo =>1,
1149
+ })
1150
+ end
1151
+
1152
+ # Usefull as a placeholder
1153
+ def gen_operator_dummy( metatype, name )
1154
+ gen_operator(
1155
+ gen_specname( metatype, name ),
1156
+ s(),
1157
+ gen_free_text( "TRUE" ),
1158
+ )
1159
+ end
1160
+
1161
+ def gen_operator_call( operatorName, parameters=[] )
1162
+ sym = :TLA_operator_call
1163
+ addPartial(
1164
+ sym,
1165
+ "{|#EVAL|}operatorName{|/EVAL|}"\
1166
+ "{|#parameters.length|}( {|/parameters.length|}"\
1167
+ "{|#parameters|}{|#EVAL|}parameter{|/EVAL|}{|_comma|}{|/parameters|}"\
1168
+ "{|#parameters.length|} ){|/parameters.length|}"
1169
+ )
1170
+
1171
+ parameters = parameters[0].is_a?( Symbol ) ? s(parameters) : parameters
1172
+
1173
+ stla( sym, {
1174
+ :operatorName => operatorName.is_a?( String ) ? gen_plainname(operatorName ) : operatorName,
1175
+ :parameters => parameters.any? ?
1176
+ parameters.map.with_index do |p,i|
1177
+ { :_comma => (i+1) == parameters.length ? '' : ',',
1178
+ :parameter => p
1179
+ }
1180
+ end :
1181
+ false,
1182
+ })
1183
+
1184
+ end
1185
+
1186
+ ##
1187
+ # Like operator call, but allways use ()
1188
+ def gen_macro_call( macroName, parameters=[] )
1189
+ sym = :TLA_macro_call
1190
+ addPartial(
1191
+ sym,
1192
+ "{|#EVAL|}macroName{|/EVAL|}("\
1193
+ "{|#parameters|}{|#EVAL|}parameter{|/EVAL|}{|_comma|}{|/parameters|}"\
1194
+ ")"
1195
+ )
1196
+
1197
+ parameters = parameters[0].is_a?( Symbol ) ? s(parameters) : parameters
1198
+
1199
+ stla( sym, {
1200
+ :macroName => macroName.is_a?( String ) ? gen_plainname(macroName ) : macroName,
1201
+ :parameters => parameters.any? ?
1202
+ parameters.map.with_index do |p,i|
1203
+ { :_comma => (i+1) == parameters.length ? '' : ',',
1204
+ :parameter => p
1205
+ }
1206
+ end :
1207
+ false,
1208
+ })
1209
+
1210
+ end
1211
+
1212
+
1213
+
1214
+ def gen_goto( label )
1215
+ sym = :TLA_goto
1216
+ tlaStatementTypeRequiresLabel( sym )
1217
+ addPartial( sym, "goto {|#EVAL|}goto{|/EVAL|}" )
1218
+
1219
+ stla( sym, {
1220
+ :goto => label.is_a?( String) ? gen_plainname(label) : label,
1221
+ })
1222
+
1223
+ end
1224
+
1225
+
1226
+
1227
+ #
1228
+ def gen_operator( operatorName, parameters, operatorBody )
1229
+ sym = :TLA_operator
1230
+ addPartial(
1231
+ sym,
1232
+ "{|#EVAL|}operatorName{|/EVAL|}{|#parameters.length|}({|/parameters.length|}{|#parameters|}{|#EVAL|}parameter{|/EVAL|}{|_comma|}{|/parameters|}{|#parameters.length|}){|/parameters.length|} == {|#EVAL|}operatorBody{|/EVAL|}"
1233
+ )
1234
+
1235
+ stla( sym,
1236
+ {
1237
+ :operatorName => operatorName,
1238
+ :parameters => parameters.any? ?
1239
+ parameters.map.with_index do |p,i|
1240
+ { :_comma => (i+1) == parameters.length ? '' : ',',
1241
+ :parameter => p.is_a?(String) ? gen_plainname( p ): p,
1242
+ }
1243
+ end :
1244
+ false,
1245
+ :operatorBody => operatorBody.is_a?( String ) ? gen_plainname( operatorBody ) : operatorBody,
1246
+ })
1247
+ end
1248
+
1249
+ def return_stmt( functionNameDef )
1250
+ sym = :TLA_return_stmt
1251
+ addPartial( sym, "goto #{spec_name('return_from')}_exit; \\* return contract '{| return_from |}'" )
1252
+
1253
+ stla( sym,
1254
+ {
1255
+ :return_from =>functionNameDef
1256
+ })
1257
+ end
1258
+
1259
+
1260
+ # NOT USED
1261
+ # ------------------------------------------------------------------
1262
+
1263
+
1264
+
1265
+ # ------------------------------------------------------------------
1266
+ # @!group common idioms
1267
+
1268
+ ##
1269
+ # Mustache SPEC_NAME lamba call for +metatype+ & +appName+
1270
+ # access unique name for +metatype+/+appName+ combination in
1271
+ # specification code.
1272
+ #
1273
+ # @param [Hash] specNameDef name in tla generate element
1274
+ # @options specNameDef [Symbol] :metatype
1275
+ # @options specNameDef [Symbol] :appName
1276
+ #
1277
+ # @return [String] string wrapped within SPEC_NAME mustache
1278
+ # lambda call
1279
+ def spec_name( specNameDef )
1280
+ # "{{#SPEC_NAME}}#{specNameDef[:metatype]}.#{specNameDef[:appName]}{{/SPEC_NAME}}"
1281
+ # "{{#SPEC_NAME}}{{#{specNameDef}.metatype}}.{{#{specNameDef}.appName}}{{/SPEC_NAME}}"
1282
+ # "{{#SPEC_NAME}}{{metatype}}.{{appName}}{{/SPEC_NAME}}"
1283
+ "{{#SPEC_NAME}}{|#{specNameDef}.metatype|}.{|#{specNameDef}.appName|}{{/SPEC_NAME}}"
1284
+ end
1285
+
1286
+ def appName( specNameDef )
1287
+ "{|#{specNameDef}.metatype|}.{|#{specNameDef}.appName|}"
1288
+ end
1289
+
1290
+
1291
+ def exit_label( funcNameDef )
1292
+ end
1293
+
1294
+
1295
+
1296
+ # @!endgroup
1297
+
1298
+
1299
+ end # class TlaElementGenerator
1300
+
1301
+
1302
+ end
1303
+ end
1304
+ end
1305
+ end
1306
+