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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/code_generator.rb +90 -0
  3. data/lib/common/type_translator.rb +3 -3
  4. data/lib/contract_handler.rb +98 -0
  5. data/lib/contract_state/handler.rb +35 -0
  6. data/lib/function_handler.rb +47 -0
  7. data/lib/instruction/add.rb +4 -4
  8. data/lib/instruction/and.rb +2 -4
  9. data/lib/instruction/assign.rb +3 -3
  10. data/lib/instruction/binary_instruction.rb +22 -0
  11. data/lib/instruction/break.rb +12 -0
  12. data/lib/instruction/divide.rb +3 -3
  13. data/lib/instruction/end_of_iteration_check.rb +2 -2
  14. data/lib/instruction/evaluate.rb +26 -12
  15. data/lib/instruction/exit_with_message.rb +4 -3
  16. data/lib/instruction/field.rb +2 -2
  17. data/lib/instruction/handler.rb +18 -13
  18. data/lib/instruction/increment.rb +3 -2
  19. data/lib/instruction/instantiate_object.rb +31 -17
  20. data/lib/instruction/jump.rb +24 -5
  21. data/lib/instruction/multiply.rb +3 -3
  22. data/lib/instruction/or.rb +2 -4
  23. data/lib/instruction/print.rb +9 -8
  24. data/lib/instruction/return.rb +2 -2
  25. data/lib/instruction/subtract.rb +3 -4
  26. data/lib/instruction/{goto.rb → try_assign.rb} +3 -3
  27. data/lib/instruction_handler.rb +7 -11
  28. data/lib/lcpbt_forrest.rb +83 -0
  29. data/lib/left_child_preferential_binary_tree.rb +66 -0
  30. data/lib/non_translatables/handler.rb +23 -0
  31. data/lib/silviculturist.rb +149 -0
  32. data/lib/soroban_rust_backend.rb +51 -0
  33. data/lib/user_defined_types_handler.rb +87 -0
  34. metadata +19 -17
  35. data/lib/aggregator/scope_block_aggregator.rb +0 -72
  36. data/lib/common/input_interpreter.rb +0 -74
  37. data/lib/common/reference_appender.rb +0 -59
  38. data/lib/dtr_to_rust.rb +0 -54
  39. data/lib/generator.rb +0 -196
  40. data/lib/instruction/label.rb +0 -12
  41. data/lib/optimization/binary_x_to_self_assignment_reduction.rb +0 -93
  42. data/lib/optimization/chained_invocation_assignment_reduction.rb +0 -123
  43. data/lib/optimization/field_to_assignment_conversion.rb +0 -37
  44. 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