dtr_to_rust 0.8.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
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