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