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
@@ -1,93 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DTRToRust
|
4
|
-
module Optimization
|
5
|
-
# This class is responsible for reducing binary operations that assign the result to the same variable
|
6
|
-
class BinaryXToSelfAssignmentReduction
|
7
|
-
def initialize(instructions)
|
8
|
-
@instructions = instructions
|
9
|
-
@cur_instruction = nil
|
10
|
-
@optimized_instructions = []
|
11
|
-
@memoize_assigns = {}
|
12
|
-
@to_remove = {}
|
13
|
-
@last_was_eavluate = nil
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.apply(instructions)
|
17
|
-
new(instructions).apply
|
18
|
-
end
|
19
|
-
|
20
|
-
def apply
|
21
|
-
@instructions.each_with_index do |instruction, index|
|
22
|
-
@cur_instruction = instruction
|
23
|
-
|
24
|
-
if skip_instruction?
|
25
|
-
@optimized_instructions << @cur_instruction
|
26
|
-
next unless @cur_instruction.assign && @cur_instruction.assign == @cur_instruction.assign.upcase
|
27
|
-
|
28
|
-
@memoize_assigns[@cur_instruction.assign] = {
|
29
|
-
inputs: @cur_instruction.inputs,
|
30
|
-
index:
|
31
|
-
}
|
32
|
-
next
|
33
|
-
end
|
34
|
-
|
35
|
-
apply_to_instruction(index)
|
36
|
-
end
|
37
|
-
actually_optimized_instructions = []
|
38
|
-
@optimized_instructions.each_with_index do |instruction, index|
|
39
|
-
actually_optimized_instructions << instruction unless @to_remove[index]
|
40
|
-
end
|
41
|
-
|
42
|
-
actually_optimized_instructions
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def skip_instruction?
|
48
|
-
!%w[add subtract divide multiply].include?(@cur_instruction.instruction)
|
49
|
-
end
|
50
|
-
|
51
|
-
def apply_to_instruction(index)
|
52
|
-
match_on0 = @cur_instruction.inputs[0] == @cur_instruction.assign
|
53
|
-
match_on1 = @cur_instruction.inputs[1] == @cur_instruction.assign
|
54
|
-
|
55
|
-
unless @cur_instruction.inputs.length == 2 &&
|
56
|
-
(match_on1 || match_on0)
|
57
|
-
|
58
|
-
@optimized_instructions << @cur_instruction
|
59
|
-
return
|
60
|
-
end
|
61
|
-
|
62
|
-
optimized_inputs = []
|
63
|
-
|
64
|
-
if @memoize_assigns[@cur_instruction.inputs[0]]
|
65
|
-
optimized_inputs << @memoize_assigns[@cur_instruction.inputs[0]][:inputs]
|
66
|
-
@to_remove[@memoize_assigns[@cur_instruction.inputs[0]][:index]] = true
|
67
|
-
else
|
68
|
-
optimized_inputs << @cur_instruction.inputs[0]
|
69
|
-
end
|
70
|
-
|
71
|
-
if @memoize_assigns[@cur_instruction.inputs[1]]
|
72
|
-
optimized_inputs << @memoize_assigns[@cur_instruction.inputs[1]][:inputs]
|
73
|
-
@to_remove[@memoize_assigns[@cur_instruction.inputs[1]][:index]] = true
|
74
|
-
else
|
75
|
-
optimized_inputs << @cur_instruction.inputs[1]
|
76
|
-
end
|
77
|
-
|
78
|
-
optimized_inputs.flatten!
|
79
|
-
assignment = match_on0 ? optimized_inputs[0] : optimized_inputsinputs[1]
|
80
|
-
|
81
|
-
@optimized_instructions << DTRCore::Instruction.new(@cur_instruction.instruction, optimized_inputs, assignment,
|
82
|
-
@cur_instruction.scope)
|
83
|
-
|
84
|
-
return unless @cur_instruction.assign && @cur_instruction.assign == @cur_instruction.assign.upcase
|
85
|
-
|
86
|
-
@memoize_assigns[@cur_instruction.assign] = {
|
87
|
-
inputs: optimized_inputs,
|
88
|
-
index:
|
89
|
-
}
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
@@ -1,123 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DTRToRust
|
4
|
-
module Optimization
|
5
|
-
# Optimizes the instructions by reducing chained invocation assignments
|
6
|
-
class ChainedInvocationAssignmentReduction
|
7
|
-
def initialize(instructions)
|
8
|
-
@instructions = instructions
|
9
|
-
@cur_instruction = nil
|
10
|
-
@optimized_instructions = []
|
11
|
-
@memoize_assigns = {}
|
12
|
-
@to_remove = {}
|
13
|
-
@last_was_eavluate = nil
|
14
|
-
end
|
15
|
-
|
16
|
-
def apply
|
17
|
-
@instructions.each_with_index do |instruction, index|
|
18
|
-
@cur_instruction = instruction
|
19
|
-
|
20
|
-
if skip_instruction?
|
21
|
-
@optimized_instructions << @cur_instruction
|
22
|
-
next
|
23
|
-
end
|
24
|
-
|
25
|
-
apply_to_instruction(index)
|
26
|
-
end
|
27
|
-
actually_optimized_instructions = []
|
28
|
-
@optimized_instructions.each_with_index do |instruction, index|
|
29
|
-
actually_optimized_instructions << instruction unless @to_remove[index]
|
30
|
-
end
|
31
|
-
|
32
|
-
actually_optimized_instructions
|
33
|
-
end
|
34
|
-
|
35
|
-
def skip_instruction?
|
36
|
-
@cur_instruction.instruction == 'instantiate_object'
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.apply(instructions)
|
40
|
-
new(instructions).apply
|
41
|
-
end
|
42
|
-
|
43
|
-
def apply_to_instruction(index)
|
44
|
-
@optimized_inputs = []
|
45
|
-
|
46
|
-
@cur_instruction&.inputs&.each do |input|
|
47
|
-
apply_to_instruction_input(@cur_instruction, input)
|
48
|
-
end
|
49
|
-
@optimized_instructions << DTRCore::Instruction.new(@cur_instruction.instruction, @optimized_inputs,
|
50
|
-
@cur_instruction&.assign, @cur_instruction.scope)
|
51
|
-
|
52
|
-
@memoize_assigns = {} unless clear_memoize?
|
53
|
-
return unless @cur_instruction.assign && @cur_instruction.assign == @cur_instruction.assign.upcase && !%w[
|
54
|
-
add subtract multiply divide
|
55
|
-
].include?(@cur_instruction.instruction)
|
56
|
-
|
57
|
-
@memoize_assigns[@cur_instruction.assign] = {
|
58
|
-
inputs: @optimized_inputs,
|
59
|
-
index:
|
60
|
-
}
|
61
|
-
end
|
62
|
-
|
63
|
-
def clear_memoize?
|
64
|
-
if @last_was_eavluate.nil?
|
65
|
-
@last_was_eavluate = @cur_instruction.instruction == 'evaluate'
|
66
|
-
return false
|
67
|
-
end
|
68
|
-
|
69
|
-
if @cur_instruction.instruction == 'evaluate'
|
70
|
-
if @last_was_eavluate
|
71
|
-
false
|
72
|
-
else
|
73
|
-
@last_was_eavluate = true
|
74
|
-
true
|
75
|
-
end
|
76
|
-
elsif @last_was_eavluate
|
77
|
-
@last_was_eavluate = false
|
78
|
-
true
|
79
|
-
else
|
80
|
-
false
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def apply_to_instruction_input(_instruction, input)
|
85
|
-
done_a_thing = false
|
86
|
-
memoize_assigns_to_clear = []
|
87
|
-
@memoize_assigns.each do |key, value|
|
88
|
-
next unless do_a_thing?(input, key, input.split('.')[0])
|
89
|
-
|
90
|
-
# input = input.gsub(key, "#{value[:inputs][0]}(#{value[:inputs][1..].join(', ')})")
|
91
|
-
|
92
|
-
input = input.gsub(key, evaluate_input(key, value).to_s)
|
93
|
-
@optimized_inputs << input # evaluate_input(key, value)
|
94
|
-
done_a_thing = true
|
95
|
-
@to_remove[value[:index]] = true
|
96
|
-
memoize_assigns_to_clear << key
|
97
|
-
next
|
98
|
-
end
|
99
|
-
|
100
|
-
@optimized_inputs << input unless done_a_thing
|
101
|
-
|
102
|
-
memoize_assigns_to_clear.each do |key|
|
103
|
-
@memoize_assigns.delete(key)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
def evaluate_input(_key, input)
|
108
|
-
InstructionHandler.new(DTRCore::Instruction.new('evaluate', input[:inputs], nil, 0), 0, [], [],
|
109
|
-
false).generate_rust.strip.gsub(';', '')
|
110
|
-
end
|
111
|
-
|
112
|
-
def do_a_thing?(input, key, input_beginning)
|
113
|
-
input &&
|
114
|
-
key &&
|
115
|
-
input_beginning == key &&
|
116
|
-
!(input.start_with?('"') &&
|
117
|
-
input.end_with?('"')) &&
|
118
|
-
@cur_instruction.instruction == 'evaluate' &&
|
119
|
-
!['equal_to', '!'].include?(@cur_instruction)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DTRToRust
|
4
|
-
module Optimization
|
5
|
-
# This class is responsible for converting field instructions to assignment instructions
|
6
|
-
class FieldToAssignmentConversion
|
7
|
-
def initialize(instructions)
|
8
|
-
@instructions = instructions
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.apply(instructions)
|
12
|
-
new(instructions).apply
|
13
|
-
end
|
14
|
-
|
15
|
-
def apply
|
16
|
-
@instructions.map do |instruction|
|
17
|
-
next instruction if skip_instruction?(instruction)
|
18
|
-
|
19
|
-
apply_to_instruction(instruction)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def skip_instruction?(instruction)
|
26
|
-
instruction.instruction != 'field'
|
27
|
-
end
|
28
|
-
|
29
|
-
def apply_to_instruction(instruction)
|
30
|
-
return instruction unless instruction.inputs.length == 2
|
31
|
-
|
32
|
-
DTRCore::Instruction.new('assign', ["#{instruction.inputs[0]}.#{instruction.inputs[1]}"], instruction.assign,
|
33
|
-
instruction.scope)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,89 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DTRToRust
|
4
|
-
module UserDefinedTypes
|
5
|
-
class Handler
|
6
|
-
def initialize(user_defined_type)
|
7
|
-
@user_defined_type = user_defined_type
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.generate(user_defined_type)
|
11
|
-
new(user_defined_type).generate
|
12
|
-
end
|
13
|
-
|
14
|
-
def generate
|
15
|
-
if struct?
|
16
|
-
generate_struct
|
17
|
-
elsif enum?
|
18
|
-
generate_enum
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def generate_struct
|
23
|
-
"#{derives}pub struct #{@user_defined_type.name.gsub('_STRUCT', '')} {\n#{generate_struct_attributes}\n}\n\n"
|
24
|
-
end
|
25
|
-
|
26
|
-
def generate_struct_attributes
|
27
|
-
@user_defined_type.attributes.map do |x|
|
28
|
-
" pub #{x[:name]}: #{Common::TypeTranslator.translate_type(x[:type])},"
|
29
|
-
end.join("\n")
|
30
|
-
end
|
31
|
-
|
32
|
-
def generate_enum
|
33
|
-
"#{derives}pub enum #{@user_defined_type.name.gsub('_ENUM', '')} {\n#{generate_enum_attributes}\n}\n\n"
|
34
|
-
end
|
35
|
-
|
36
|
-
def generate_enum_attributes
|
37
|
-
@user_defined_type.attributes.map do |x|
|
38
|
-
if x[:value]
|
39
|
-
" #{x[:name]} = #{x[:value]},"
|
40
|
-
elsif x[:type] && x[:type].start_with?('(') && x[:type].end_with?(')')
|
41
|
-
inner_types = x[:type].gsub('(', '').gsub(')', '').split(',').map do |x|
|
42
|
-
Common::TypeTranslator.translate_type(x)
|
43
|
-
end
|
44
|
-
if inner_types.size == 0 || x[:type] == '()'
|
45
|
-
" #{x[:name]},"
|
46
|
-
else
|
47
|
-
" #{x[:name]}(#{inner_types.join(', ')}),"
|
48
|
-
end
|
49
|
-
elsif x[:type] && x[:type].match(/\d+/)
|
50
|
-
" #{x[:name]} = #{x[:type]},"
|
51
|
-
elsif x[:type] && x[:type] != '()'
|
52
|
-
" #{x[:name]}(#{Common::TypeTranslator.translate_type(x[:type])}),"
|
53
|
-
else
|
54
|
-
" #{x[:name]},"
|
55
|
-
end
|
56
|
-
end.join("\n")
|
57
|
-
end
|
58
|
-
|
59
|
-
def derives
|
60
|
-
base = if error? && enum?
|
61
|
-
"#[contracterror]\n#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]\n"
|
62
|
-
else
|
63
|
-
"#[contracttype]\n#[derive(Clone, Debug, Eq, PartialEq)]\n"
|
64
|
-
end
|
65
|
-
|
66
|
-
base += "#[repr(u32)]\n" if numbered_enum?
|
67
|
-
|
68
|
-
base
|
69
|
-
end
|
70
|
-
|
71
|
-
# TODO: fix this terrible hack
|
72
|
-
def error?
|
73
|
-
@user_defined_type.name.start_with? 'Error'
|
74
|
-
end
|
75
|
-
|
76
|
-
def struct?
|
77
|
-
@user_defined_type.name.end_with? '_STRUCT'
|
78
|
-
end
|
79
|
-
|
80
|
-
def enum?
|
81
|
-
@user_defined_type.name.end_with? '_ENUM'
|
82
|
-
end
|
83
|
-
|
84
|
-
def numbered_enum?
|
85
|
-
enum? && @user_defined_type.attributes.all? { |x| x[:value] }
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|