sbuilder-ial 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/VERSION +1 -0
- data/lib/action/exception.rb +13 -0
- data/lib/action/extender.rb +30 -0
- data/lib/action/file_path.rb +35 -0
- data/lib/action/model_builder.rb +74 -0
- data/lib/action/render/exception.rb +12 -0
- data/lib/action/render/producer.rb +193 -0
- data/lib/action/render/producer_ethereum.rb +404 -0
- data/lib/action/render/producer_ethereum_const.rb +221 -0
- data/lib/action/render/renderer.rb +142 -0
- data/lib/action/render/tla_element_generator.rb +1306 -0
- data/lib/action/script_eval.rb +32 -0
- data/lib/action/text.rb +17 -0
- data/lib/action/tla_rules.rb +512 -0
- data/lib/action/translator.rb +160 -0
- data/lib/app/app.rb +259 -0
- data/lib/ethereum/api.rb +669 -0
- data/lib/ethereum.rb +1 -0
- data/lib/fp/compositable.rb +185 -0
- data/lib/fp/error.rb +19 -0
- data/lib/fp/exception.rb +9 -0
- data/lib/fp/result.rb +19 -0
- data/lib/fp/sequence.rb +65 -0
- data/lib/ial/build.rb +12 -0
- data/lib/ial/exception.rb +13 -0
- data/lib/model/constants.rb +72 -0
- data/lib/model/model.rb +74 -0
- data/lib/model/model_dsl.rb +1038 -0
- data/lib/model/sexp.rb +58 -0
- data/lib/plugin/plugin.rb +273 -0
- data/lib/sbuilder-ial.rb +44 -0
- data/lib/utils/logger.rb +82 -0
- data/sbuilder-ial.gemspec +36 -0
- metadata +137 -0
@@ -0,0 +1,404 @@
|
|
1
|
+
require_relative 'producer_ethereum_const.rb'
|
2
|
+
|
3
|
+
module Sbuilder
|
4
|
+
module Ial
|
5
|
+
module Action
|
6
|
+
module Render
|
7
|
+
|
8
|
+
class ProducerEthereum < Producer
|
9
|
+
|
10
|
+
PROGNAME = nil # progname for logger default class name
|
11
|
+
include Sbuilder::Ial::MyLogger # mix logger
|
12
|
+
|
13
|
+
# @attr [Boolean] fixed_snippet_produced guarantee that
|
14
|
+
# 'p_base_snippets' called only once
|
15
|
+
@@fixed_snippet_produced=false
|
16
|
+
|
17
|
+
|
18
|
+
# ------------------------------------------------------------------
|
19
|
+
# @!group Construct & configure
|
20
|
+
|
21
|
+
def initialize( options = {}, metatypes=nil )
|
22
|
+
super( options, metatypes )
|
23
|
+
@logger = getLogger( nil, options )
|
24
|
+
@logger.info "#{__method__}: starting options=#{options}"
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.start( options = {}, metatypes=nil )
|
29
|
+
ProducerEthereum.new( options, metatypes )
|
30
|
+
end
|
31
|
+
# @!endgroup
|
32
|
+
|
33
|
+
# ------------------------------------------------------------------
|
34
|
+
# @!group Bridge to other modules
|
35
|
+
|
36
|
+
# @return [Hash] constanExpressions from
|
37
|
+
# 'Sbuilder::Ial::Model::Constants::CONSTANT_EXPRESSIONS'
|
38
|
+
#
|
39
|
+
# @option constanExpressions [:symbol] key constant
|
40
|
+
#
|
41
|
+
# @option constanExpressions [String] value constant in tla
|
42
|
+
# language
|
43
|
+
|
44
|
+
def constanExpressions
|
45
|
+
Sbuilder::Ial::Model::Constants::CONSTANT_EXPRESSIONS
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Hash] IAL_OPERATORS to map ialOperator to
|
49
|
+
# corresponding tlaOperatr
|
50
|
+
def ialOperators
|
51
|
+
Sbuilder::Ial::Model::Constants::IAL_OPERATORS
|
52
|
+
end
|
53
|
+
|
54
|
+
# @!endgroup
|
55
|
+
|
56
|
+
# ------------------------------------------------------------------
|
57
|
+
# @!group Production rules
|
58
|
+
|
59
|
+
# produce fixed snippet only once
|
60
|
+
def p_base_snippets
|
61
|
+
return [] if @@fixed_snippet_produced
|
62
|
+
# toggle flag to produce only once
|
63
|
+
@@fixed_snippet_produced = true
|
64
|
+
ProducerEthereumConstants::BASE_SNIPPETS
|
65
|
+
end
|
66
|
+
|
67
|
+
def p_variable_definition( varName, initExpression )
|
68
|
+
@logger.info "#{__method__}: varName=#{varName}, initExpression=#{initExpression}"
|
69
|
+
{
|
70
|
+
:metatype => metatype4varName,
|
71
|
+
:appName => varName,
|
72
|
+
:specName => nil,
|
73
|
+
:comment => "Variable #{varName}",
|
74
|
+
:template => gen_state_variable( varName2Specname( varName ), initExpression )
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
# Produce macro snippet for 'macroName'
|
79
|
+
def p_macro( macroName, parameters, stmts )
|
80
|
+
@logger.info "#{__method__}: macroName=#{macroName}, parameters=#{parameters}"
|
81
|
+
@logger.debug "#{__method__}: macroName=#{macroName} stmts=#{stmts}" if @logger.debug?
|
82
|
+
{
|
83
|
+
:metatype => metatype4macro,
|
84
|
+
:appName => macroName,
|
85
|
+
:specName => nil,
|
86
|
+
:comment => "Macro #{macroName}",
|
87
|
+
:template => gen_macro( macroName2Specname( macroName ), parameters, stmts )
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
# Produce 'operator' snippet for 'operatorName' with
|
92
|
+
# 'parameters' and 'body' -expression
|
93
|
+
def p_operator( operatorName, parameters, body )
|
94
|
+
{
|
95
|
+
:metatype => metatype4operator,
|
96
|
+
:appName => operatorName,
|
97
|
+
:specName => nil,
|
98
|
+
:comment => "Operator #{operatorName}",
|
99
|
+
:template => gen_operator( operatorName2Specname( operatorName ), parameters, body )
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
# Entry-macro for transaction 'txName'
|
104
|
+
def p_tx_entry( txName, operationName, stmts=nil )
|
105
|
+
@logger.info "#{__method__}: txName=#{txName}, operationName=#{operationName}"
|
106
|
+
@logger.debug "#{__method__}: txName=#{txName} stmts=#{stmts}" if @logger.debug?
|
107
|
+
|
108
|
+
# appName = "#{ctx[:transaction_entry].name}(action)"
|
109
|
+
metatype = metaTxEntry
|
110
|
+
appName = txName2appName( txName, operationName )
|
111
|
+
|
112
|
+
#
|
113
|
+
formalParameter_for_tx_input = 'input'
|
114
|
+
|
115
|
+
# default calls 'service procedure' of txName
|
116
|
+
if stmts.nil? || !stmts.any?
|
117
|
+
stmts =
|
118
|
+
s(gen_procedure_call( txName2ServiceProcedure( txName, operationName ), formalParameter_for_tx_input))
|
119
|
+
end
|
120
|
+
|
121
|
+
stmts = gen_stmts( stmts )
|
122
|
+
|
123
|
+
{
|
124
|
+
:metatype => metatype,
|
125
|
+
:appName => appName,
|
126
|
+
:specName => nil,
|
127
|
+
:comment => "Enter transaction '#{txName}'",
|
128
|
+
:template => gen_macro( gen_specname( metatype, appName), formalParameter_for_tx_input, stmts )
|
129
|
+
}
|
130
|
+
end
|
131
|
+
|
132
|
+
# @param [String:Array] locals array names of local variables
|
133
|
+
def p_tx_function( txName, operationName, locals, stmts )
|
134
|
+
@logger.info "#{__method__}: txName=#{txName}, locals=#{locals}"
|
135
|
+
@logger.debug "#{__method__}: txName=#{txName} stmts=#{stmts}" if @logger.debug?
|
136
|
+
metatype = metaTxFunc
|
137
|
+
appName = txName2appName( txName, operationName )
|
138
|
+
interfaceName = txName2interfaceName( txName, operationName )
|
139
|
+
labelPrefix = gen_specname( metatype, appName )
|
140
|
+
labeledStmts = gen_stmts(gen_serviceProcedureLabelStatements( stmts, labelPrefix ))
|
141
|
+
# functionName = gen_specname( metatype, appName )
|
142
|
+
{
|
143
|
+
:metatype => metatype,
|
144
|
+
:appName => appName,
|
145
|
+
:specName => nil,
|
146
|
+
:comment => "Implementation of transaction '#{txName}'",
|
147
|
+
:template => gen_service_procedure( txName2ServiceProcedure( txName, operationName ), interfaceName, locals, labeledStmts )
|
148
|
+
}
|
149
|
+
end
|
150
|
+
|
151
|
+
# Produce exit (macro) for transaction 'txName'
|
152
|
+
def p_tx_exit( txName, operationName )
|
153
|
+
metatype = metaTxExit
|
154
|
+
appName = txName2appName( txName, operationName )
|
155
|
+
specName = "dummy"
|
156
|
+
{
|
157
|
+
:metatype => metatype,
|
158
|
+
:appName => appName,
|
159
|
+
:specName => specName,
|
160
|
+
:comment => "Exit from transaction #{appName}",
|
161
|
+
:template => nil, # no body - just map appName->specName
|
162
|
+
:body => nil, # no body - just map appName->specName
|
163
|
+
}
|
164
|
+
end
|
165
|
+
|
166
|
+
# @!endgroup
|
167
|
+
|
168
|
+
# ------------------------------------------------------------------
|
169
|
+
# @!group Production rules
|
170
|
+
|
171
|
+
private def varName2Specname( varName )
|
172
|
+
gen_specname( metatype4varName, varName )
|
173
|
+
end
|
174
|
+
|
175
|
+
private def domainName2Specname( domainName )
|
176
|
+
# gen_plainname( domainName )
|
177
|
+
gen_specname( metatype4Domain, domainName )
|
178
|
+
end
|
179
|
+
|
180
|
+
def macroName2Specname( macroName )
|
181
|
+
gen_specname( metatype4macro, macroName )
|
182
|
+
end
|
183
|
+
|
184
|
+
def operatorName2Specname( operatorName )
|
185
|
+
gen_specname( metatype4operator, operatorName )
|
186
|
+
end
|
187
|
+
|
188
|
+
private def metatype4varName
|
189
|
+
metaApp
|
190
|
+
end
|
191
|
+
|
192
|
+
# Domain are known to be defined under metatype
|
193
|
+
# 'META_MODEL_DOMAINS'
|
194
|
+
private def metatype4Domain
|
195
|
+
Sbuilder::FacadeConstants::META_MODEL_DOMAINS
|
196
|
+
end
|
197
|
+
|
198
|
+
private def metatype4macro
|
199
|
+
metaApp
|
200
|
+
end
|
201
|
+
|
202
|
+
private def metatype4operator
|
203
|
+
metaApp
|
204
|
+
end
|
205
|
+
|
206
|
+
private def metatype4txFunction
|
207
|
+
metaTxFunc
|
208
|
+
end
|
209
|
+
|
210
|
+
private def txName2InputVariable( txName, operationName )
|
211
|
+
gen_interface_input_variable_name( txName2interfaceName( txName, operationName ), metatype4txFunction )
|
212
|
+
end
|
213
|
+
|
214
|
+
private def txName2appName( txName, operationName )
|
215
|
+
"#{txName}(#{operationName})"
|
216
|
+
end
|
217
|
+
|
218
|
+
private def txName2interfaceName( txName, operationName )
|
219
|
+
"#{txName}(#{operationName})"
|
220
|
+
end
|
221
|
+
|
222
|
+
private def txName2EntryMacro( txName )
|
223
|
+
gen_specname( metaTxEntry, txName2appName( txName ) )
|
224
|
+
end
|
225
|
+
|
226
|
+
private def txName2ServiceProcedure( txName, operationName )
|
227
|
+
gen_specname( metatype4txFunction, txName2appName( txName, operationName ) )
|
228
|
+
end
|
229
|
+
|
230
|
+
# @!endgroup
|
231
|
+
|
232
|
+
# ------------------------------------------------------------------
|
233
|
+
# @!group Production rules for statements
|
234
|
+
def p_skipStatement
|
235
|
+
@logger.info "#{__method__}"
|
236
|
+
s(gen_skip )
|
237
|
+
end
|
238
|
+
|
239
|
+
def p_conditionalStatement( condition, ifBlock, elseBlock )
|
240
|
+
@logger.info "#{__method__}: condition=#{condition}"
|
241
|
+
@logger.debug "#{__method__}: ifBlock=#{ifBlock}" if @logger.debug?
|
242
|
+
@logger.debug "#{__method__}: elseBlock=#{elseBlock}" if @logger.debug?
|
243
|
+
s(gen_if( condition, ifBlock, elseBlock ))
|
244
|
+
end
|
245
|
+
|
246
|
+
def p_callServiceStatement( txName, operation, parameters )
|
247
|
+
@logger.info "#{__method__}: txName=#{txName}, operation=#{operation}, parameters=#{parameters}"
|
248
|
+
serviceSpecname = txName2ServiceProcedure( txName, operation )
|
249
|
+
s(gen_procedure_call( serviceSpecname, parameters))
|
250
|
+
end
|
251
|
+
|
252
|
+
def p_callMacroStatement( macroName, parameters )
|
253
|
+
@logger.info "#{__method__}: macroTarget=#{macroName}, parameters=#{parameters}"
|
254
|
+
s(gen_macro_call( macroName2Specname( macroName ), parameters ))
|
255
|
+
end
|
256
|
+
|
257
|
+
def p_printStatement( msg )
|
258
|
+
@logger.info "#{__method__}: msg=#{msg}"
|
259
|
+
s(gen_print( msg ))
|
260
|
+
end
|
261
|
+
|
262
|
+
def p_assignTo( assignTo, rval )
|
263
|
+
@logger.info "#{__method__}: assignTo=#{assignTo}, rval=#{rval}"
|
264
|
+
s(gen_assign( assignTo, rval ))
|
265
|
+
end
|
266
|
+
|
267
|
+
|
268
|
+
# @!endgroup
|
269
|
+
|
270
|
+
# ------------------------------------------------------------------
|
271
|
+
# @!group Production rules for expressions
|
272
|
+
|
273
|
+
# @param [String] varName (appName) of variable expression
|
274
|
+
# @return [sTla] specname of variable 'varName'
|
275
|
+
def p_variable_expression( varName )
|
276
|
+
@logger.info "#{__method__}: varName=#{varName}"
|
277
|
+
varName2Specname( varName )
|
278
|
+
end
|
279
|
+
|
280
|
+
# ----------
|
281
|
+
# expressions referencign parameters
|
282
|
+
|
283
|
+
# Expression accessing 'parameterName' of transaction 'txtName'
|
284
|
+
#
|
285
|
+
# @return [sTla]
|
286
|
+
def p_tx_parameter_expression( txName, operationName, parameterName )
|
287
|
+
@logger.info "#{__method__}: txName=#{txName}, parameterName=#{parameterName}"
|
288
|
+
gen_record_field( txName2InputVariable(txName, operationName), parameterName )
|
289
|
+
end
|
290
|
+
|
291
|
+
# Expression referencing 'paramaterName' in 'macro'
|
292
|
+
def p_macro_parameter_expression( macroName, parameterName )
|
293
|
+
@logger.info "#{__method__}: macroName=#{macroName}, parameterName=#{parameterName}"
|
294
|
+
p_parameter_expression( parameterName )
|
295
|
+
end
|
296
|
+
|
297
|
+
# Expression referencing 'paramaterName' in 'operatorName'
|
298
|
+
def p_operator_parameter_expression( operatorName, parameterName )
|
299
|
+
@logger.info "#{__method__}: operatorName=#{operatorName}, parameterName=#{parameterName}"
|
300
|
+
p_parameter_expression( parameterName )
|
301
|
+
end
|
302
|
+
|
303
|
+
# Local DRY method to access paramterName
|
304
|
+
private def p_parameter_expression( parameterName )
|
305
|
+
gen_plainname( parameterName )
|
306
|
+
end
|
307
|
+
|
308
|
+
# ----------
|
309
|
+
# Operator expressions
|
310
|
+
|
311
|
+
def p_operator_expression( operatorName, args )
|
312
|
+
@logger.info "#{__method__}: operatorName=#{operatorName}, args=#{args}"
|
313
|
+
p_operator_expression_exec( operatorName2Specname( operatorName ), args )
|
314
|
+
end
|
315
|
+
|
316
|
+
# Call operator 'operatorName' with arguments. NB:
|
317
|
+
# 'operatorName' not mapped using metatype (it is
|
318
|
+
# infrastructure operator).
|
319
|
+
def p_infra_operator_expression( operatorName, args )
|
320
|
+
@logger.info "#{__method__}: operatorName=#{operatorName}, args=#{args}"
|
321
|
+
p_operator_expression_exec( operatorName, args )
|
322
|
+
end
|
323
|
+
|
324
|
+
private def p_operator_expression_exec( opExpression, args )
|
325
|
+
gen_operator_call( opExpression, args )
|
326
|
+
end
|
327
|
+
|
328
|
+
# ----------
|
329
|
+
|
330
|
+
# Expression for calling 'operatorName' with arguments 'args'
|
331
|
+
# Expression for accessing domain (set) with name 'domainName'
|
332
|
+
def p_domain_expression( domainName )
|
333
|
+
@logger.info "#{__method__}: domainName=#{domainName}"
|
334
|
+
domainName2Specname( domainName )
|
335
|
+
end
|
336
|
+
|
337
|
+
# expression refering to local variable 'local'
|
338
|
+
def p_local_expression( local )
|
339
|
+
@logger.info "#{__method__}: local=#{local}"
|
340
|
+
gen_plainname( local )
|
341
|
+
end
|
342
|
+
|
343
|
+
def p_binary_expression( lval, op, rval )
|
344
|
+
@logger.info "#{__method__}: lval=#{lval}, op=#{op}, rval=#{rval}"
|
345
|
+
gen_bin_op( p_op(op), lval, rval )
|
346
|
+
end
|
347
|
+
|
348
|
+
# @param [Lambda] templateEval is lambda ->(gen, args)
|
349
|
+
# evaluate the template
|
350
|
+
def p_template_expression( templateEval, args )
|
351
|
+
@logger.info "#{__method__}: template=#{templateEval}, args=#{args}"
|
352
|
+
# Sbuilder::Ial::Model::Constants::TLA_TEMPLATES[template].call(self, args)
|
353
|
+
templateEval[self, *args]
|
354
|
+
end
|
355
|
+
|
356
|
+
# @param [String|Numeric|TrueClass|FalseClass] val
|
357
|
+
def p_constant_expression( val )
|
358
|
+
@logger.info "#{__method__}: val=#{val}"
|
359
|
+
case val
|
360
|
+
when String
|
361
|
+
gen_str( val )
|
362
|
+
when Numeric
|
363
|
+
gen_constant( val )
|
364
|
+
when TrueClass
|
365
|
+
gen_constant( "TRUE" )
|
366
|
+
when FalseClass
|
367
|
+
gen_constant( "FALSE" )
|
368
|
+
when Symbol
|
369
|
+
# map symbol 'val' to sTla for constant expression
|
370
|
+
p_constant_value( val )
|
371
|
+
else
|
372
|
+
raise "Unsupported type #{val.class} for val '#{val}'"
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
# Map 'constSymbol' to gen_constant( 'constValue') using
|
377
|
+
# hash table 'constanExpressions'
|
378
|
+
#
|
379
|
+
# @param [:Symbol] constSymbol any value :empty
|
380
|
+
#
|
381
|
+
# @return [sTla] expression value for 'constSymbol'
|
382
|
+
def p_constant_value( constSymbol )
|
383
|
+
constValue = constanExpressions[constSymbol]
|
384
|
+
raise "Unsupported symbol value #{constSymbol}" if constValue.nil?
|
385
|
+
gen_constant(constValue)
|
386
|
+
end
|
387
|
+
|
388
|
+
# Map 'ialOp' to 'tlaOperator' using hash table 'ialOperators'
|
389
|
+
def p_op( ialOp )
|
390
|
+
tlaOperator = ialOperators[ialOp]
|
391
|
+
raise "Unsupported operator value #{ialOp}" if tlaOperator.nil?
|
392
|
+
tlaOperator
|
393
|
+
end
|
394
|
+
|
395
|
+
# @!endgroup
|
396
|
+
|
397
|
+
|
398
|
+
end # class ProducerEthreum < Producer
|
399
|
+
|
400
|
+
|
401
|
+
end
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
module Sbuilder
|
2
|
+
module Ial
|
3
|
+
module Action
|
4
|
+
module Render
|
5
|
+
class ProducerEthereumConstants
|
6
|
+
|
7
|
+
# Metatypes used to produce ethreum code
|
8
|
+
|
9
|
+
# OP_INFRA_SET_RESPONSE="InfrastructureServiceResponse"
|
10
|
+
OP_INFRA_RETURN="InfrastructureServiceReturn"
|
11
|
+
OP_INFRA_GET_RESPONSE="InfrastructureServiceGetResponse"
|
12
|
+
OP_INFRA_GET_STATUS="InfrastructureServiceGetStatus"
|
13
|
+
OP_INFRA_STATUS_INIT="InfrastructureServiceInit"
|
14
|
+
OP_INFRA_THROW="schedule_throw"
|
15
|
+
OP_INFRA_UPDATE_TOP='UpdateTop'
|
16
|
+
OP_INFRA_RESPONSES='responses'
|
17
|
+
OP_INFRA_NEXT_ID='NextId'
|
18
|
+
|
19
|
+
|
20
|
+
# ------------------------------------------------------------------
|
21
|
+
# FRAMEWORK -services
|
22
|
+
FW_SVC_UNIQUE_ELEMENTS='uniqueElements'
|
23
|
+
FW_OP_ELEMENT_EXISTS = 'elementExists'
|
24
|
+
FW_OP_GET_ELEMENT = "getElement"
|
25
|
+
|
26
|
+
FW_STATE_ACCOUNTS = "accounts"
|
27
|
+
FW_STATE_ACCOUNTS_TEMP = "accounts_temp"
|
28
|
+
FW_STATE_STORAGE_ROOT = 'storageRoot'
|
29
|
+
FW_STATE_STORAGE_ROOT_TEMP = 'storageRoot_temp'
|
30
|
+
FW_STATE_MINED = 'mined'
|
31
|
+
|
32
|
+
ETH_OPEATOR_INTRINSIC_GAS = 'intrinsicGas'
|
33
|
+
ETH_OPEATOR_TRANSACTION_GAS = 'transactionGas'
|
34
|
+
ETH_OPEATOR_UP_FRONT_COST = 'upFrontCost'
|
35
|
+
ETH_OPEATOR_GAS_VALUE = 'gasValue'
|
36
|
+
|
37
|
+
|
38
|
+
# ethereum specific services
|
39
|
+
TLA_SERVICE_POP="ethereum_service_pop"
|
40
|
+
|
41
|
+
|
42
|
+
INITIAL_SNIPPETS=
|
43
|
+
[
|
44
|
+
|
45
|
+
# ------------------------------------------------------------------
|
46
|
+
# Base snippets - i.e. no connection to ethreums
|
47
|
+
# {
|
48
|
+
# :comment => "macro to update existing contract",
|
49
|
+
# :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
|
50
|
+
# :appName => 'update_existing_contract',
|
51
|
+
# :body =>
|
52
|
+
# <<-EOS.unindent,
|
53
|
+
# macro update_existing_contract() {
|
54
|
+
# print <<"update_existing_contract">>;
|
55
|
+
# }
|
56
|
+
# EOS
|
57
|
+
# },
|
58
|
+
|
59
|
+
{
|
60
|
+
:comment => "Add element to sequence head",
|
61
|
+
:metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
|
62
|
+
:appName => 'Push',
|
63
|
+
:body =>
|
64
|
+
<<-EOS.unindent,
|
65
|
+
Push( s, e ) == <<e>> \\o s
|
66
|
+
EOS
|
67
|
+
},
|
68
|
+
|
69
|
+
{
|
70
|
+
:comment => "Update element to sequence head",
|
71
|
+
:metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
|
72
|
+
:appName => OP_INFRA_UPDATE_TOP,
|
73
|
+
:body =>
|
74
|
+
<<-EOS.unindent,
|
75
|
+
UpdateTop( s, e ) == <<e>> \\o Tail(s)
|
76
|
+
EOS
|
77
|
+
},
|
78
|
+
|
79
|
+
|
80
|
+
{
|
81
|
+
:comment => "Propgate top element to stack & pop",
|
82
|
+
:metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
|
83
|
+
:appName => 'PropageOnStack',
|
84
|
+
:body =>
|
85
|
+
<<-EOS.unindent,
|
86
|
+
(* PropageOnStack( s, v ) == [i \\in 1..Len(s) |-> v ] *)
|
87
|
+
PropageOnStack( s, v ) == [i \\in 1..Len(s) |-> IF i = 1 THEN v ELSE s[i] ]
|
88
|
+
EOS
|
89
|
+
},
|
90
|
+
|
91
|
+
{
|
92
|
+
:comment => "Check if unique element exists",
|
93
|
+
:metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
|
94
|
+
:appName => 'elementExists',
|
95
|
+
:body =>
|
96
|
+
<<-EOS.unindent,
|
97
|
+
elementExists( set, key, id ) == Cardinality( { e \\in set : e[key] = id } ) = 1
|
98
|
+
EOS
|
99
|
+
},
|
100
|
+
|
101
|
+
{
|
102
|
+
:comment => "Check if unique element exists",
|
103
|
+
:metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
|
104
|
+
:appName => 'getElement',
|
105
|
+
:body =>
|
106
|
+
<<-EOS.unindent,
|
107
|
+
(*
|
108
|
+
* Return element from 'set' such that element['key'] == 'id'
|
109
|
+
* Assume 'id' unique, and element exists
|
110
|
+
*)
|
111
|
+
getElement( set, key, id ) == ( CHOOSE x \\in { e \\in set : e[key] = id } : TRUE )
|
112
|
+
EOS
|
113
|
+
},
|
114
|
+
|
115
|
+
{
|
116
|
+
:comment => "stable when process finished running",
|
117
|
+
:metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
|
118
|
+
:appName => 'Stable',
|
119
|
+
:body =>
|
120
|
+
<<-EOS.unindent,
|
121
|
+
Stable == tx_running = FALSE
|
122
|
+
EOS
|
123
|
+
},
|
124
|
+
|
125
|
+
{
|
126
|
+
:comment => "Sum record fields",
|
127
|
+
:metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
|
128
|
+
:appName => 'SumRecordField',
|
129
|
+
:body =>
|
130
|
+
<<-EOS.unindent,
|
131
|
+
RECURSIVE SumRecordField(_,_)
|
132
|
+
(*
|
133
|
+
* Sum of field 'f' of record elements in set 'S'
|
134
|
+
*
|
135
|
+
* @param [Set] S set of records
|
136
|
+
* @param [String] f name of field
|
137
|
+
*)
|
138
|
+
SumRecordField(S,f) ==
|
139
|
+
IF S = {} THEN 0
|
140
|
+
ELSE LET x == CHOOSE x \\in S : TRUE
|
141
|
+
IN x[f] + SumRecordField(S \\ {x}, f)
|
142
|
+
EOS
|
143
|
+
},
|
144
|
+
|
145
|
+
{
|
146
|
+
:comment => "Sum function",
|
147
|
+
:metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
|
148
|
+
:appName => 'SumOfFunction',
|
149
|
+
:body =>
|
150
|
+
<<-EOS.unindent,
|
151
|
+
RECURSIVE SumOfFunction(_)
|
152
|
+
(*
|
153
|
+
* Sum of function values
|
154
|
+
*
|
155
|
+
* @param [Sequnce|Function] F to sum over
|
156
|
+
*
|
157
|
+
*)
|
158
|
+
SumOfFunction( F ) ==
|
159
|
+
IF F = <<>> THEN 0
|
160
|
+
ELSE LET x == CHOOSE x \\in DOMAIN F : TRUE
|
161
|
+
IN F[x] + SumOfFunction( [ v \\in DOMAIN F \\ {x} |-> F[v] ] )
|
162
|
+
EOS
|
163
|
+
},
|
164
|
+
|
165
|
+
{
|
166
|
+
:comment => "Operator to check element uniques in a set",
|
167
|
+
:metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
|
168
|
+
:appName => FW_SVC_UNIQUE_ELEMENTS,
|
169
|
+
:body =>
|
170
|
+
<<-EOS.unindent,
|
171
|
+
#{FW_SVC_UNIQUE_ELEMENTS}( set, key ) == \\A e1 \\in set: \\A e2 \\in set: e1[key] = e2[key] => e1 = e2
|
172
|
+
EOS
|
173
|
+
},
|
174
|
+
|
175
|
+
{
|
176
|
+
:comment => "Take given 'address', or choose any address from pool of 'ids'. Notice (CHOOSE operation is deterministic)",
|
177
|
+
:metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
|
178
|
+
:appName => OP_INFRA_NEXT_ID,
|
179
|
+
:body =>
|
180
|
+
<<-EOS.unindent,
|
181
|
+
#{OP_INFRA_NEXT_ID}( ids, address ) == CHOOSE x \\in ids: (address = x /\\ address # Nil) \\/ address = Nil
|
182
|
+
EOS
|
183
|
+
},
|
184
|
+
] # BASE_SNIPPETS
|
185
|
+
|
186
|
+
ETHEREUM_SNIPPETS =
|
187
|
+
[
|
188
|
+
{
|
189
|
+
:comment => 'Finish service procedure: propage stack top on succcess && pop',
|
190
|
+
:metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
|
191
|
+
:appName => TLA_SERVICE_POP,
|
192
|
+
:body => <<-EOS.unindent
|
193
|
+
(*
|
194
|
+
* Service procedure for 'interface' has finished.
|
195
|
+
* Check status of service response.
|
196
|
+
* For success make changes in procedure permanent by propagating
|
197
|
+
* stack top to top-1..bottom.
|
198
|
+
*
|
199
|
+
* In any case pop one element from stack.
|
200
|
+
*
|
201
|
+
*)
|
202
|
+
|
203
|
+
macro ethereum_service_pop( interface ) {
|
204
|
+
\\* TODO - add implementation
|
205
|
+
skip;
|
206
|
+
}
|
207
|
+
|
208
|
+
EOS
|
209
|
+
},
|
210
|
+
|
211
|
+
|
212
|
+
] # ETHEREUM_SNIPPETS
|
213
|
+
|
214
|
+
BASE_SNIPPETS = INITIAL_SNIPPETS + ETHEREUM_SNIPPETS
|
215
|
+
|
216
|
+
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|