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