sbuilder-ial 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|