dtr_to_rust 0.8.1 → 0.12.0
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 +4 -4
- data/lib/code_generator.rb +90 -0
- data/lib/common/type_translator.rb +3 -3
- data/lib/contract_handler.rb +98 -0
- data/lib/contract_state/handler.rb +35 -0
- data/lib/function_handler.rb +47 -0
- data/lib/instruction/add.rb +4 -4
- data/lib/instruction/and.rb +2 -4
- data/lib/instruction/assign.rb +3 -3
- data/lib/instruction/binary_instruction.rb +22 -0
- data/lib/instruction/break.rb +12 -0
- data/lib/instruction/divide.rb +3 -3
- data/lib/instruction/end_of_iteration_check.rb +2 -2
- data/lib/instruction/evaluate.rb +26 -12
- data/lib/instruction/exit_with_message.rb +4 -3
- data/lib/instruction/field.rb +2 -2
- data/lib/instruction/handler.rb +18 -13
- data/lib/instruction/increment.rb +3 -2
- data/lib/instruction/instantiate_object.rb +31 -17
- data/lib/instruction/jump.rb +24 -5
- data/lib/instruction/multiply.rb +3 -3
- data/lib/instruction/or.rb +2 -4
- data/lib/instruction/print.rb +9 -8
- data/lib/instruction/return.rb +2 -2
- data/lib/instruction/subtract.rb +3 -4
- data/lib/instruction/{goto.rb → try_assign.rb} +3 -3
- data/lib/instruction_handler.rb +7 -11
- data/lib/lcpbt_forrest.rb +83 -0
- data/lib/left_child_preferential_binary_tree.rb +66 -0
- data/lib/non_translatables/handler.rb +23 -0
- data/lib/silviculturist.rb +149 -0
- data/lib/soroban_rust_backend.rb +51 -0
- data/lib/user_defined_types_handler.rb +87 -0
- metadata +19 -17
- data/lib/aggregator/scope_block_aggregator.rb +0 -72
- data/lib/common/input_interpreter.rb +0 -74
- data/lib/common/reference_appender.rb +0 -59
- data/lib/dtr_to_rust.rb +0 -54
- data/lib/generator.rb +0 -196
- data/lib/instruction/label.rb +0 -12
- data/lib/optimization/binary_x_to_self_assignment_reduction.rb +0 -93
- data/lib/optimization/chained_invocation_assignment_reduction.rb +0 -123
- data/lib/optimization/field_to_assignment_conversion.rb +0 -37
- data/lib/user_defined_types/handler.rb +0 -89
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SorobanRustBackend
|
4
|
+
class UserDefinedTypesHandler
|
5
|
+
def initialize(user_defined_type)
|
6
|
+
@user_defined_type = user_defined_type
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.generate(user_defined_type)
|
10
|
+
new(user_defined_type).generate
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate
|
14
|
+
if struct?
|
15
|
+
generate_struct
|
16
|
+
elsif enum?
|
17
|
+
generate_enum
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate_struct
|
22
|
+
"#{derives}pub struct #{@user_defined_type.name.gsub('_STRUCT', '')} {\n#{generate_struct_attributes}\n}\n\n"
|
23
|
+
end
|
24
|
+
|
25
|
+
def generate_struct_attributes
|
26
|
+
@user_defined_type.attributes.map do |x|
|
27
|
+
" pub #{x[:name]}: #{Common::TypeTranslator.translate_type(x[:type])},"
|
28
|
+
end.join("\n")
|
29
|
+
end
|
30
|
+
|
31
|
+
def generate_enum
|
32
|
+
"#{derives}pub enum #{@user_defined_type.name.gsub('_ENUM', '')} {\n#{generate_enum_attributes}\n}\n\n"
|
33
|
+
end
|
34
|
+
|
35
|
+
def generate_enum_attributes
|
36
|
+
@user_defined_type.attributes.map do |x|
|
37
|
+
if x[:value]
|
38
|
+
" #{x[:name]} = #{x[:value]},"
|
39
|
+
elsif x[:type]&.start_with?('(') && x[:type]&.end_with?(')')
|
40
|
+
inner_types = x[:type].gsub('(', '').gsub(')', '').split(',').map do |x|
|
41
|
+
Common::TypeTranslator.translate_type(x)
|
42
|
+
end
|
43
|
+
if inner_types.empty? || x[:type] == '()'
|
44
|
+
" #{x[:name]}: (),"
|
45
|
+
else
|
46
|
+
" #{x[:name]}: (#{inner_types.join(', ')}),"
|
47
|
+
end
|
48
|
+
elsif x[:type]&.match(/\d+/)
|
49
|
+
" #{x[:name]} = #{x[:type]},"
|
50
|
+
elsif x[:type] && x[:type] != '()'
|
51
|
+
" #{x[:name]}: (#{Common::TypeTranslator.translate_type(x[:type])}),"
|
52
|
+
else
|
53
|
+
" #{x[:name]}: (),"
|
54
|
+
end
|
55
|
+
end.join("\n")
|
56
|
+
end
|
57
|
+
|
58
|
+
def derives
|
59
|
+
base = if error? && enum?
|
60
|
+
"#[contracterror]\n#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]\n"
|
61
|
+
else
|
62
|
+
"#[contracttype]\n#[derive(Clone, Debug, Eq, PartialEq)]\n"
|
63
|
+
end
|
64
|
+
|
65
|
+
base += "#[repr(u32)]\n" if numbered_enum?
|
66
|
+
|
67
|
+
base
|
68
|
+
end
|
69
|
+
|
70
|
+
# TODO: fix this terrible hack
|
71
|
+
def error?
|
72
|
+
@user_defined_type.name.start_with? 'Error'
|
73
|
+
end
|
74
|
+
|
75
|
+
def struct?
|
76
|
+
@user_defined_type.name.end_with? '_STRUCT'
|
77
|
+
end
|
78
|
+
|
79
|
+
def enum?
|
80
|
+
@user_defined_type.name.end_with? '_ENUM'
|
81
|
+
end
|
82
|
+
|
83
|
+
def numbered_enum?
|
84
|
+
enum? && @user_defined_type.attributes.all? { |x| x[:value] }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dtr_to_rust
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Durst
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-07-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Rust to DTR translator (Digicus Textual Representation).
|
14
14
|
email:
|
@@ -17,42 +17,44 @@ executables: []
|
|
17
17
|
extensions: []
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
|
-
- lib/
|
21
|
-
- lib/common/input_interpreter.rb
|
22
|
-
- lib/common/reference_appender.rb
|
20
|
+
- lib/code_generator.rb
|
23
21
|
- lib/common/type_translator.rb
|
24
|
-
- lib/
|
25
|
-
- lib/
|
22
|
+
- lib/contract_handler.rb
|
23
|
+
- lib/contract_state/handler.rb
|
24
|
+
- lib/function_handler.rb
|
26
25
|
- lib/instruction/add.rb
|
27
26
|
- lib/instruction/and.rb
|
28
27
|
- lib/instruction/assign.rb
|
28
|
+
- lib/instruction/binary_instruction.rb
|
29
|
+
- lib/instruction/break.rb
|
29
30
|
- lib/instruction/divide.rb
|
30
31
|
- lib/instruction/end_of_iteration_check.rb
|
31
32
|
- lib/instruction/evaluate.rb
|
32
33
|
- lib/instruction/exit_with_message.rb
|
33
34
|
- lib/instruction/field.rb
|
34
|
-
- lib/instruction/goto.rb
|
35
35
|
- lib/instruction/handler.rb
|
36
36
|
- lib/instruction/increment.rb
|
37
37
|
- lib/instruction/instantiate_object.rb
|
38
38
|
- lib/instruction/jump.rb
|
39
|
-
- lib/instruction/label.rb
|
40
39
|
- lib/instruction/multiply.rb
|
41
40
|
- lib/instruction/or.rb
|
42
41
|
- lib/instruction/print.rb
|
43
42
|
- lib/instruction/return.rb
|
44
43
|
- lib/instruction/subtract.rb
|
44
|
+
- lib/instruction/try_assign.rb
|
45
45
|
- lib/instruction_handler.rb
|
46
|
-
- lib/
|
47
|
-
- lib/
|
48
|
-
- lib/
|
49
|
-
- lib/
|
46
|
+
- lib/lcpbt_forrest.rb
|
47
|
+
- lib/left_child_preferential_binary_tree.rb
|
48
|
+
- lib/non_translatables/handler.rb
|
49
|
+
- lib/silviculturist.rb
|
50
|
+
- lib/soroban_rust_backend.rb
|
51
|
+
- lib/user_defined_types_handler.rb
|
50
52
|
homepage: https://spaced-out-thoughts-dev-foundation.github.io/digicus/
|
51
53
|
licenses:
|
52
54
|
- MIT
|
53
55
|
metadata:
|
54
56
|
rubygems_mfa_required: 'true'
|
55
|
-
post_install_message:
|
57
|
+
post_install_message:
|
56
58
|
rdoc_options: []
|
57
59
|
require_paths:
|
58
60
|
- lib
|
@@ -67,8 +69,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
67
69
|
- !ruby/object:Gem::Version
|
68
70
|
version: '0'
|
69
71
|
requirements: []
|
70
|
-
rubygems_version: 3.
|
71
|
-
signing_key:
|
72
|
+
rubygems_version: 3.4.10
|
73
|
+
signing_key:
|
72
74
|
specification_version: 4
|
73
75
|
summary: Rust to DTR translator (Digicus Textual Representation).
|
74
76
|
test_files: []
|
@@ -1,72 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DTRToRust
|
4
|
-
module Aggregator
|
5
|
-
# Aggregates instructions into scope blocks
|
6
|
-
class ScopeBlockAggregator
|
7
|
-
def initialize(instructions)
|
8
|
-
@instructions = instructions
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.aggregate(instructions)
|
12
|
-
new(instructions).aggregate
|
13
|
-
end
|
14
|
-
|
15
|
-
def aggregate
|
16
|
-
sequential_scope_blocks = sequentially_group_by_scope(@instructions)
|
17
|
-
|
18
|
-
decorate_scope_blocks(sequential_scope_blocks)
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def sequentially_group_by_scope(_instructions)
|
24
|
-
return [] if @instructions.empty?
|
25
|
-
|
26
|
-
scope_blocks = []
|
27
|
-
current_scope = nil
|
28
|
-
current_scope_block = []
|
29
|
-
|
30
|
-
@instructions.each do |instruction|
|
31
|
-
if current_scope == instruction.scope
|
32
|
-
current_scope_block << instruction
|
33
|
-
else
|
34
|
-
scope_blocks << current_scope_block unless current_scope_block.empty?
|
35
|
-
current_scope_block = [instruction]
|
36
|
-
current_scope = instruction.scope
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
scope_blocks << current_scope_block unless current_scope_block.empty?
|
41
|
-
|
42
|
-
scope_blocks
|
43
|
-
end
|
44
|
-
|
45
|
-
def decorate_scope_blocks(scope_blocks)
|
46
|
-
current_scope = nil
|
47
|
-
current_scope_decorated_value = nil
|
48
|
-
scope_memoize = {}
|
49
|
-
|
50
|
-
scope_blocks.map do |scope_block|
|
51
|
-
if current_scope.nil?
|
52
|
-
current_scope = scope_block.first.scope
|
53
|
-
current_scope_decorated_value = 0
|
54
|
-
scope_memoize[current_scope] = current_scope_decorated_value
|
55
|
-
elsif scope_memoize[scope_block.first.scope]
|
56
|
-
current_scope = scope_block.first.scope
|
57
|
-
current_scope_decorated_value = scope_memoize[current_scope]
|
58
|
-
elsif current_scope < scope_block.first.scope
|
59
|
-
current_scope = scope_block.first.scope
|
60
|
-
current_scope_decorated_value += 1
|
61
|
-
scope_memoize[current_scope] = current_scope_decorated_value
|
62
|
-
else
|
63
|
-
current_scope = scope_block.first.scope
|
64
|
-
current_scope_decorated_value -= 1
|
65
|
-
scope_memoize[current_scope] = current_scope_decorated_value
|
66
|
-
end
|
67
|
-
{ block: scope_block, scope: current_scope, decorated_value: current_scope_decorated_value }
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DTRToRust
|
4
|
-
module Common
|
5
|
-
# This class is responsible for interpreting the input string.
|
6
|
-
class InputInterpreter
|
7
|
-
def initialize(input)
|
8
|
-
@input = input
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.interpret(input)
|
12
|
-
new(input).interpret
|
13
|
-
end
|
14
|
-
|
15
|
-
def interpret
|
16
|
-
if number?(@input)
|
17
|
-
number_return(@input)
|
18
|
-
elsif string?(@input)
|
19
|
-
string_return(@input)
|
20
|
-
elsif boolean?(@input)
|
21
|
-
boolean_return(@input)
|
22
|
-
else
|
23
|
-
variable_return(@input)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
## Variable ##
|
30
|
-
def variable?(input)
|
31
|
-
!string?(input) && !number?(input)
|
32
|
-
end
|
33
|
-
|
34
|
-
def variable_return(_input)
|
35
|
-
{ value: @input, type: 'variable', needs_reference: !@input.start_with?('&') }
|
36
|
-
end
|
37
|
-
|
38
|
-
## String ##
|
39
|
-
def string?(input)
|
40
|
-
input.is_a?(String) && (input.match?(/".*"/) || input.match?(/'.*'/))
|
41
|
-
end
|
42
|
-
|
43
|
-
def string_return(_input)
|
44
|
-
{ value: @input, type: 'string', needs_reference: false }
|
45
|
-
end
|
46
|
-
|
47
|
-
## Number ##
|
48
|
-
def number?(input)
|
49
|
-
input.is_a?(Numeric) || input&.match?(/^\s*\d+\.?\d*\s*$/)
|
50
|
-
end
|
51
|
-
|
52
|
-
def number_return(_input)
|
53
|
-
{ value: contains_decimal?(@input.to_s) ? @input.to_f : @input.to_i, type: 'number', needs_reference: false }
|
54
|
-
end
|
55
|
-
|
56
|
-
def contains_decimal?(str)
|
57
|
-
# Define a regular expression pattern for a decimal number
|
58
|
-
decimal_pattern = /\d+\.\d+/
|
59
|
-
|
60
|
-
# Check if the string matches the pattern
|
61
|
-
!!(str =~ decimal_pattern)
|
62
|
-
end
|
63
|
-
|
64
|
-
## Boolean ##
|
65
|
-
def boolean?(input)
|
66
|
-
input.is_a?(TrueClass) || input.is_a?(FalseClass) || input&.match?(/true|false/)
|
67
|
-
end
|
68
|
-
|
69
|
-
def boolean_return(_input)
|
70
|
-
{ value: @input, type: 'boolean', needs_reference: false }
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DTRToRust
|
4
|
-
module Common
|
5
|
-
# This module appends references to variables.
|
6
|
-
module ReferenceAppender
|
7
|
-
def self.call(input, ref_nums: false)
|
8
|
-
# Hack to get tests to pass
|
9
|
-
return '&signature_payload.into()' if input == 'signature_payload.into()'
|
10
|
-
|
11
|
-
decorated_input = Common::InputInterpreter.interpret(input)
|
12
|
-
|
13
|
-
# HACK: is likely chain of method calls
|
14
|
-
# ex: env.storage().instance().get(COUNTER).unwrap_or(0);
|
15
|
-
# --> env.storage().instance().get(&COUNTER).unwrap_or(0);
|
16
|
-
if decorated_input[:type] != 'number' &&
|
17
|
-
decorated_input[:value].include?('.') &&
|
18
|
-
decorated_input[:value].include?('(') && decorated_input[:value].include?(')')
|
19
|
-
more_complex_ref_appender(input, decorated_input)
|
20
|
-
elsif decorated_input[:needs_reference]
|
21
|
-
"&#{decorated_input[:value]}"
|
22
|
-
elsif decorated_input[:type] == 'number'
|
23
|
-
ref_nums ? "&#{decorated_input[:value]}" : decorated_input[:value]
|
24
|
-
else
|
25
|
-
decorated_input[:value]
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.more_complex_ref_appender(_input, decorated_input)
|
30
|
-
decorated_input[:value].split('.').map do |x|
|
31
|
-
x = x.strip
|
32
|
-
if call_with_input?(x)
|
33
|
-
matches = x.scan(/\((.*?)\)/)
|
34
|
-
things = matches
|
35
|
-
.flatten
|
36
|
-
.filter(&method(:not_empty_string?))
|
37
|
-
.map(&method(:wild_stuff))
|
38
|
-
.join(', ')
|
39
|
-
"#{x.split('(')[0]}(#{things})"
|
40
|
-
else
|
41
|
-
x
|
42
|
-
end
|
43
|
-
end.join('.')
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.not_empty_string?(input)
|
47
|
-
input != ''
|
48
|
-
end
|
49
|
-
|
50
|
-
def self.wild_stuff(input)
|
51
|
-
input.split(',').map { |x| ReferenceAppender.call(x.strip) }.join(', ')
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.call_with_input?(input)
|
55
|
-
input.include?('(') && input.end_with?(')') && !input.end_with?('()')
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
data/lib/dtr_to_rust.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# This is the main module for the DTR to Rust gem.
|
4
|
-
module DTRToRust
|
5
|
-
autoload :Generator, 'generator'
|
6
|
-
autoload :InstructionHandler, 'instruction_handler'
|
7
|
-
|
8
|
-
# This module contains all the classes that handle the different types of instructions.
|
9
|
-
module Instruction
|
10
|
-
autoload :Evaluate, 'instruction/evaluate'
|
11
|
-
autoload :Field, 'instruction/field'
|
12
|
-
autoload :Handler, 'instruction/handler'
|
13
|
-
autoload :Print, 'instruction/print'
|
14
|
-
autoload :Return, 'instruction/return'
|
15
|
-
autoload :InstantiateObject, 'instruction/instantiate_object'
|
16
|
-
autoload :Add, 'instruction/add'
|
17
|
-
autoload :Subtract, 'instruction/subtract'
|
18
|
-
autoload :Multiply, 'instruction/multiply'
|
19
|
-
autoload :Divide, 'instruction/divide'
|
20
|
-
autoload :Assign, 'instruction/assign'
|
21
|
-
autoload :Jump, 'instruction/jump'
|
22
|
-
autoload :Goto, 'instruction/goto'
|
23
|
-
autoload :ExitWithMessage, 'instruction/exit_with_message'
|
24
|
-
autoload :And, 'instruction/and'
|
25
|
-
autoload :Or, 'instruction/or'
|
26
|
-
autoload :Label, 'instruction/label'
|
27
|
-
autoload :EndOfIterationCheck, 'instruction/end_of_iteration_check'
|
28
|
-
autoload :Increment, 'instruction/increment'
|
29
|
-
end
|
30
|
-
|
31
|
-
# This module contains all the classes that handle common logic.
|
32
|
-
module Common
|
33
|
-
autoload :InputInterpreter, 'common/input_interpreter'
|
34
|
-
autoload :ReferenceAppender, 'common/reference_appender'
|
35
|
-
autoload :TypeTranslator, 'common/type_translator'
|
36
|
-
end
|
37
|
-
|
38
|
-
# This module contains all the classes that handle optimization.
|
39
|
-
module Optimization
|
40
|
-
autoload :ChainedInvocationAssignmentReduction, 'optimization/chained_invocation_assignment_reduction'
|
41
|
-
autoload :FieldToAssignmentConversion, 'optimization/field_to_assignment_conversion'
|
42
|
-
autoload :BinaryXToSelfAssignmentReduction, 'optimization/binary_x_to_self_assignment_reduction'
|
43
|
-
end
|
44
|
-
|
45
|
-
# This module contains all the classes that handle user defined types.
|
46
|
-
module UserDefinedTypes
|
47
|
-
autoload :Handler, 'user_defined_types/handler'
|
48
|
-
end
|
49
|
-
|
50
|
-
# This module contains all the classes that handle the aggregation of instructions.
|
51
|
-
module Aggregator
|
52
|
-
autoload :ScopeBlockAggregator, 'aggregator/scope_block_aggregator'
|
53
|
-
end
|
54
|
-
end
|
data/lib/generator.rb
DELETED
@@ -1,196 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'dtr_core'
|
4
|
-
|
5
|
-
module DTRToRust
|
6
|
-
# Generates Rust code from a DTR contract
|
7
|
-
class Generator
|
8
|
-
def initialize(content)
|
9
|
-
@dtr_contract = ::DTRCore::Contract.from_dtr_raw(content)
|
10
|
-
end
|
11
|
-
|
12
|
-
def generate
|
13
|
-
@content = ''
|
14
|
-
|
15
|
-
generate_user_defined_types
|
16
|
-
generate_state
|
17
|
-
generate_contract_name
|
18
|
-
generate_interface
|
19
|
-
generate_helpers
|
20
|
-
|
21
|
-
generate_contract_header
|
22
|
-
|
23
|
-
@content
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.generate_from_file(file_path)
|
27
|
-
new(File.read(file_path)).generate
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.generate_from_string(dtr_string)
|
31
|
-
new(dtr_string).generate
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
attr_reader :dtr_contract
|
37
|
-
|
38
|
-
def generate_contract_header
|
39
|
-
imports_super_set = %w[
|
40
|
-
Address
|
41
|
-
BytesN
|
42
|
-
contract
|
43
|
-
contractimpl
|
44
|
-
contracttype
|
45
|
-
contracterror
|
46
|
-
symbol_short
|
47
|
-
vec
|
48
|
-
Env
|
49
|
-
Symbol
|
50
|
-
Vec
|
51
|
-
log
|
52
|
-
token
|
53
|
-
]
|
54
|
-
|
55
|
-
used_imports = []
|
56
|
-
|
57
|
-
@content.split.each do |word|
|
58
|
-
imports_super_set.each do |import|
|
59
|
-
used_imports << import if word.include?(import)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
used_imports.uniq!
|
64
|
-
|
65
|
-
# TODO: unsure how to check this one
|
66
|
-
used_imports << 'auth::Context'
|
67
|
-
used_imports << 'IntoVal'
|
68
|
-
|
69
|
-
# TODO: don't hardcode imports
|
70
|
-
@content = "#![no_std]\nuse soroban_sdk::{#{used_imports.join(', ')}};\n\n" + @content
|
71
|
-
end
|
72
|
-
|
73
|
-
def generate_contract_name
|
74
|
-
@content += "#[contract]\npub struct #{dtr_contract.name};\n\n"
|
75
|
-
end
|
76
|
-
|
77
|
-
def generate_state
|
78
|
-
return if dtr_contract.state.nil?
|
79
|
-
|
80
|
-
dtr_contract.state.each do |state_value|
|
81
|
-
if state_value.type == 'String'
|
82
|
-
@content += "const #{state_value.name}: Symbol = symbol_short!(#{state_value.initial_value});\n"
|
83
|
-
else
|
84
|
-
@content += "const #{state_value.name}: #{Common::TypeTranslator.translate_type(state_value.type)} = #{state_value.initial_value};\n"
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
@content += "\n"
|
89
|
-
end
|
90
|
-
|
91
|
-
def generate_interface
|
92
|
-
@content += "#[contractimpl]\nimpl #{dtr_contract.name} {#{generate_functions_each(dtr_contract.interface,
|
93
|
-
false)}}\n"
|
94
|
-
end
|
95
|
-
|
96
|
-
def generate_helpers
|
97
|
-
@content += "#{generate_functions_each(dtr_contract.helpers, true)}\n"
|
98
|
-
end
|
99
|
-
|
100
|
-
def generate_functions_each(functions, is_helper)
|
101
|
-
function_names = functions&.map(&:name)
|
102
|
-
|
103
|
-
functions&.map do |function|
|
104
|
-
optimized_instructions = optimize_instructions(function.instructions)
|
105
|
-
|
106
|
-
instruction_blocks = Aggregator::ScopeBlockAggregator.aggregate(optimized_instructions)
|
107
|
-
|
108
|
-
return_string = "\n#{is_helper ? '' : ' '}pub fn #{function.name}(#{generate_function_args(function)}) "
|
109
|
-
return_string += generate_function_output(function)
|
110
|
-
return_string += " {\n"
|
111
|
-
if function.output
|
112
|
-
return_string += " let Thing_to_return: #{Common::TypeTranslator.translate_type(function.output)};\n"
|
113
|
-
end
|
114
|
-
return_string += "#{generate_instructions_for_blocks(instruction_blocks, function_names,
|
115
|
-
is_helper)}"
|
116
|
-
|
117
|
-
if @last_scope.positive?
|
118
|
-
while @last_scope.positive?
|
119
|
-
return_string += "\n" + form_rust_string('}', @last_scope,
|
120
|
-
is_helper)
|
121
|
-
@last_scope -= 1
|
122
|
-
end
|
123
|
-
end
|
124
|
-
return_string += "\n#{is_helper ? '' : ' '}}\n"
|
125
|
-
|
126
|
-
return_string
|
127
|
-
end&.join("\n")
|
128
|
-
end
|
129
|
-
|
130
|
-
def optimize_instructions(instructions)
|
131
|
-
stage1_optimized = Optimization::FieldToAssignmentConversion.apply(instructions)
|
132
|
-
stage2_optimized = Optimization::BinaryXToSelfAssignmentReduction.apply(stage1_optimized)
|
133
|
-
Optimization::ChainedInvocationAssignmentReduction.apply(stage2_optimized)
|
134
|
-
end
|
135
|
-
|
136
|
-
def generate_function_output(function)
|
137
|
-
return '' if function.output.nil?
|
138
|
-
|
139
|
-
"-> #{Common::TypeTranslator.translate_type(function.output)}"
|
140
|
-
end
|
141
|
-
|
142
|
-
def generate_function_args(function)
|
143
|
-
all_inputs = [] + function.inputs
|
144
|
-
|
145
|
-
all_inputs.map { |x| "#{x[:name]}: #{Common::TypeTranslator.translate_type(x[:type_name])}" }.join(', ')
|
146
|
-
end
|
147
|
-
|
148
|
-
def generate_instructions_for_blocks(instruction_blocks, function_names, is_helper)
|
149
|
-
instruction_blocks.map do |block|
|
150
|
-
spacing_scope = block[:decorated_value]
|
151
|
-
content = ''
|
152
|
-
if @last_scope && @last_scope > spacing_scope
|
153
|
-
while @last_scope > spacing_scope
|
154
|
-
content += form_rust_string("}\n", @last_scope, is_helper)
|
155
|
-
@last_scope -= 1
|
156
|
-
end
|
157
|
-
end
|
158
|
-
@last_scope = spacing_scope
|
159
|
-
content += generate_instructions_each(block[:block], spacing_scope, function_names, is_helper)
|
160
|
-
|
161
|
-
content
|
162
|
-
end.join("\n")
|
163
|
-
end
|
164
|
-
|
165
|
-
def generate_instructions_each(instructions, spacing_scope, function_names, is_helper)
|
166
|
-
instructions.map do |instruction|
|
167
|
-
content = ''
|
168
|
-
content += generate_instruction(instruction, spacing_scope, function_names, is_helper)
|
169
|
-
|
170
|
-
content
|
171
|
-
end.join("\n")
|
172
|
-
end
|
173
|
-
|
174
|
-
def form_rust_string(instruction_string, scope, is_helper)
|
175
|
-
"#{spacing(scope, is_helper)}#{instruction_string}"
|
176
|
-
end
|
177
|
-
|
178
|
-
def spacing(scope, is_helper)
|
179
|
-
' ' * (is_helper ? 0 : scope + 1)
|
180
|
-
end
|
181
|
-
|
182
|
-
def generate_instruction(instruction, spacing_scope, function_names, is_helper)
|
183
|
-
handler = InstructionHandler.new(instruction, spacing_scope, function_names,
|
184
|
-
dtr_contract.user_defined_types || [], is_helper)
|
185
|
-
handler.generate_rust
|
186
|
-
end
|
187
|
-
|
188
|
-
def generate_user_defined_types
|
189
|
-
return if dtr_contract.user_defined_types.nil?
|
190
|
-
|
191
|
-
dtr_contract.user_defined_types.each do |udt|
|
192
|
-
@content += DTRToRust::UserDefinedTypes::Handler.generate(udt)
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
data/lib/instruction/label.rb
DELETED