sbuilder-ethereum 0.0.6

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