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,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module DTRToRust
3
+ module SorobanRustBackend
4
4
  module Instruction
5
5
  # This class is responsible for generating Rust code for the LogString instruction.
6
6
  class InstantiateObject < Handler
@@ -11,7 +11,9 @@ module DTRToRust
11
11
  when 'UDT'
12
12
  handle_udt
13
13
  when 'Tuple'
14
- form_rust_string("let mut #{@instruction.assign} = (#{normalish_inputs});")
14
+ "let mut #{@instruction.assign} = (#{normalish_inputs});"
15
+ when 'Range'
16
+ "let mut #{@instruction.assign} = #{range_inputs};"
15
17
  else
16
18
  raise "Unknown object type: #{@instruction.inputs[0]}"
17
19
  end
@@ -20,7 +22,13 @@ module DTRToRust
20
22
  private
21
23
 
22
24
  def handle_list
23
- form_rust_string("let mut #{@instruction.assign} = vec![#{normalish_inputs}];")
25
+ "let mut #{@instruction.assign} = vec![#{normalish_inputs}];"
26
+ end
27
+
28
+ def range_inputs
29
+ @instruction.inputs[1..].map do |x|
30
+ foobar(x)
31
+ end.join('..')
24
32
  end
25
33
 
26
34
  def normalish_inputs
@@ -38,13 +46,18 @@ module DTRToRust
38
46
  end
39
47
 
40
48
  def handle_udt
41
- udt_found = @user_defined_types.filter { |udt| udt_name_fix(udt) == @instruction.inputs[1] }
49
+ # udt_found = @user_defined_types.filter { |udt| udt_name_fix(udt) == @instruction.inputs[1] }
42
50
 
43
- assignment = "let mut #{@instruction.assign} = "
44
- udt = "#{@instruction.inputs[1]}{"
45
- inputs = inputs_to_rust_string(@instruction.inputs[2..], udt_found[0].attributes.map { |x| x[:name] })
46
- end_ = '};'
47
- form_rust_string("#{assignment}#{udt}#{inputs}#{end_}")
51
+ # assignment = "let mut #{@instruction.assign} = "
52
+ # udt = "#{@instruction.inputs[1]}{"
53
+ # inputs = inputs_to_rust_string(@instruction.inputs[2..], udt_found[0].attributes.map { |x| x[:name] })
54
+ # end_ = '};'
55
+ # form_rust_string("#{assignment}#{udt}#{inputs}#{end_}")
56
+
57
+ "let mut #{@instruction.assign} = #{@instruction.inputs[1]}{#{inputs_to_rust_string(@instruction.inputs[2..],
58
+ @instruction.inputs[1])}}"
59
+
60
+ # raise 'Not implemented'
48
61
  end
49
62
 
50
63
  def inputs_to_rust_string(inputs, udt_type_names)
@@ -57,15 +70,16 @@ module DTRToRust
57
70
  end
58
71
 
59
72
  def foobar(input)
60
- decorated_input = Common::InputInterpreter.interpret(input)
73
+ input
74
+ # decorated_input = Common::InputInterpreter.interpret(input)
61
75
 
62
- if decorated_input[:type] == 'string'
63
- "symbol_short!(#{input})"
64
- elsif decorated_input[:needs_reference] && input == 'env'
65
- "&#{input}"
66
- else
67
- input
68
- end
76
+ # if decorated_input[:type] == 'string'
77
+ # "symbol_short!(#{input})"
78
+ # elsif decorated_input[:needs_reference] && input == 'env'
79
+ # "&#{input}"
80
+ # else
81
+ # input
82
+ # end
69
83
  end
70
84
 
71
85
  def handle_input(input, udt_type_name)
@@ -1,27 +1,46 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module DTRToRust
3
+ module SorobanRustBackend
4
4
  module Instruction
5
5
  # This class handles the jump instruction.
6
6
  class Jump < Handler
7
7
  def handle
8
+ last_instruction_is_else_if = @instruction.inputs[@instruction.inputs.size - 1] == 'ELSE_IF_BRANCH'
9
+ last_instruction_is_while_loop = @instruction.inputs[@instruction.inputs.size - 1] == 'WHILE_LOOP'
10
+
8
11
  if @instruction.inputs.size == 1
9
12
  handle_unconditional_jump
10
13
  elsif @instruction.inputs.size == 2
11
- handle_conditional_jump
14
+ last_instruction_is_else_if ? handle_unconditional_jump : handle_conditional_jump
15
+ elsif @instruction.inputs.size == 3 && last_instruction_is_else_if
16
+ handle_conditional_else_if_jump
17
+ elsif @instruction.inputs.size == 4 && last_instruction_is_while_loop
18
+ handle_while_loop
12
19
  else
13
- raise 'Invalid jump instruction'
20
+ raise 'Invalid jump instruction. Received too many inputs: ' + @instruction.inputs.size.to_s
14
21
  end
15
22
  end
16
23
 
17
24
  private
18
25
 
19
26
  def handle_conditional_jump
20
- form_rust_string("if #{@instruction.inputs[0]} {")
27
+ "if #{@instruction.inputs[0]} {"
28
+ end
29
+
30
+ def handle_while_loop
31
+ "while let Some(#{@instruction.inputs[0]}) = OPTION_#{@instruction.inputs[0]} {"
32
+ end
33
+
34
+ def handle_conditional_else_if_jump
35
+ "else if #{@instruction.inputs[0]} {"
21
36
  end
22
37
 
23
38
  def handle_unconditional_jump
24
- form_rust_string('else {')
39
+ if @instruction.scope.to_i < @instruction.inputs[0].to_i
40
+ 'else {'
41
+ else
42
+ '}'
43
+ end
25
44
  end
26
45
  end
27
46
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module DTRToRust
3
+ module SorobanRustBackend
4
4
  module Instruction
5
5
  # This class handles the add instruction.
6
6
  class Multiply < Handler
7
- def handle
8
- form_rust_string("#{@instruction.assign} = #{@instruction.inputs[0]} * #{@instruction.inputs[1]};")
7
+ def initialize(instruction, metadata)
8
+ super('&', instruction, metadata)
9
9
  end
10
10
  end
11
11
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module DTRToRust
3
+ module SorobanRustBackend
4
4
  module Instruction
5
5
  # This class handles the or instruction.
6
6
  class Or < Handler
@@ -10,9 +10,7 @@ module DTRToRust
10
10
 
11
11
  assignment_rust = "let #{assignment} = "
12
12
  body_rust = "#{inputs[0]} || #{inputs[1]};"
13
- rust_string = "#{assignment.nil? ? '' : assignment_rust}#{body_rust}"
14
-
15
- form_rust_string(rust_string)
13
+ "#{assignment.nil? ? '' : assignment_rust}#{body_rust}"
16
14
  end
17
15
  end
18
16
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module DTRToRust
3
+ module SorobanRustBackend
4
4
  module Instruction
5
5
  # This class is responsible for generating Rust code for the LogString instruction.
6
6
  class Print < Handler
7
7
  def handle
8
- form_rust_string("log!(#{inputs_to_rust_string(@instruction.inputs)});")
8
+ "log!(#{inputs_to_rust_string(@instruction.inputs)});"
9
9
  end
10
10
 
11
11
  private
@@ -15,13 +15,14 @@ module DTRToRust
15
15
  end
16
16
 
17
17
  def ref_appender(input)
18
- decorated_input = Common::InputInterpreter.interpret(input)
18
+ input
19
+ # decorated_input = Common::InputInterpreter.interpret(input)
19
20
 
20
- if decorated_input[:needs_reference] && decorated_input[:value] == 'env'
21
- "&#{decorated_input[:value]}"
22
- else
23
- decorated_input[:value]
24
- end
21
+ # if decorated_input[:needs_reference] && decorated_input[:value] == 'env'
22
+ # "&#{decorated_input[:value]}"
23
+ # else
24
+ # decorated_input[:value]
25
+ # end
25
26
  end
26
27
  end
27
28
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module DTRToRust
3
+ module SorobanRustBackend
4
4
  module Instruction
5
5
  # This class is responsible for generating Rust code for the Return instruction.
6
6
  class Return < Handler
7
7
  def handle
8
- form_rust_string(@instruction.inputs[0])
8
+ "return #{@instruction.inputs[0]};"
9
9
  end
10
10
  end
11
11
  end
@@ -1,12 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module DTRToRust
3
+ module SorobanRustBackend
4
4
  module Instruction
5
5
  # This class handles the add instruction.
6
6
  class Subtract < Handler
7
- def handle
8
- # TODO: fix this, depends if this is init or not
9
- form_rust_string("#{@instruction.assign} = #{@instruction.inputs[0]} - #{@instruction.inputs[1]};")
7
+ def initialize(instruction, metadata)
8
+ super('-', instruction, metadata)
10
9
  end
11
10
  end
12
11
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module DTRToRust
3
+ module SorobanRustBackend
4
4
  module Instruction
5
5
  # This class handles the goto instruction.
6
- class Goto < Handler
6
+ class TryAssign < Handler
7
7
  def handle
8
- form_rust_string("goto: #{@instruction.inputs[0]}")
8
+ "let #{@instruction.inputs[0]} = #{@instruction.inputs[1]}.try_into();"
9
9
  end
10
10
  end
11
11
  end
@@ -1,14 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module DTRToRust
3
+ module SorobanRustBackend
4
4
  # This class is responsible for generating Rust code for a single instruction.
5
5
  class InstructionHandler
6
- def initialize(instruction, spacing_scope, function_names, user_defined_types, is_helper)
6
+ def initialize(instruction, metadata)
7
7
  @instruction = instruction
8
- @spacing_scope = spacing_scope
9
- @function_names = function_names
10
- @user_defined_types = user_defined_types
11
- @is_helper = is_helper
8
+ @metadata = metadata
12
9
  end
13
10
 
14
11
  def generate_rust
@@ -16,20 +13,18 @@ module DTRToRust
16
13
  raise "Unknown instruction type: #{@instruction.instruction}"
17
14
  end
18
15
 
19
- EXPRESSION_FOOBAR[@instruction.instruction.strip].send(:handle, @instruction, @spacing_scope, @function_names,
20
- @user_defined_types, @is_helper)
16
+ EXPRESSION_FOOBAR[@instruction.instruction.strip].send(:handle, @instruction, @metadata)
21
17
  end
22
18
 
23
19
  private
24
20
 
25
21
  EXPRESSION_FOOBAR = {
26
22
  'assign' => Instruction::Assign,
23
+ 'break' => Instruction::Break,
27
24
  'jump' => Instruction::Jump,
28
- 'goto' => Instruction::Goto,
29
25
  'exit_with_message' => Instruction::ExitWithMessage,
30
26
  'and' => Instruction::And,
31
27
  'or' => Instruction::Or,
32
- 'label' => Instruction::Label,
33
28
  'add' => Instruction::Add,
34
29
  'subtract' => Instruction::Subtract,
35
30
  'multiply' => Instruction::Multiply,
@@ -40,7 +35,8 @@ module DTRToRust
40
35
  'evaluate' => Instruction::Evaluate,
41
36
  'field' => Instruction::Field,
42
37
  'end_of_iteration_check' => Instruction::EndOfIterationCheck,
43
- 'increment' => Instruction::Increment
38
+ 'increment' => Instruction::Increment,
39
+ 'try_assign' => Instruction::TryAssign
44
40
  }.freeze
45
41
 
46
42
  def handle_empty_instruction
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SorobanRustBackend
4
+ class LCPBT_Forrest
5
+ attr_accessor :trees
6
+
7
+ def initialize
8
+ @trees = []
9
+ end
10
+
11
+ def add_tree(tree)
12
+ @trees << tree
13
+ end
14
+
15
+ def traverse
16
+ @trees.map(&:traverse)
17
+ end
18
+
19
+ def traverse_with_indentation
20
+ @trees.compact.map(&:traverse_with_indentation)
21
+ end
22
+
23
+ # This represents a traversal through a unique path, covering all trees in the forest
24
+ # only once. This is useful for code generation.
25
+ def traverse_to_ids
26
+ id_map = {}
27
+ result = []
28
+
29
+ traverse
30
+ .map { |x| x.map(&:id) }
31
+ .each do |x|
32
+ sub_result = []
33
+ x.each do |y|
34
+ next if id_map[y]
35
+
36
+ sub_result << y
37
+ id_map[y] = true
38
+ end
39
+ result << sub_result
40
+ end
41
+
42
+ result
43
+ end
44
+
45
+ def code_generator_traverse(&block)
46
+ traverse_with_indentation
47
+ .map { |tree| tree.reverse.uniq.reverse.map(&block) }
48
+ end
49
+
50
+ def size
51
+ @trees.size
52
+ end
53
+
54
+ def all_paths_to(instruction_id)
55
+ @trees.map { |x| x.all_paths_to(instruction_id) }.flatten(1).compact
56
+ end
57
+
58
+ def walk_it
59
+ @trees.each do |x|
60
+ puts "Walking tree #{x.tree_id}"
61
+
62
+ stack = []
63
+ symbol_table = {}
64
+
65
+ stack << x
66
+
67
+ while stack.any?
68
+ current = stack.pop
69
+
70
+ if current.value.assign
71
+ symbol_table[current.value.assign] = {
72
+ value: current.value.id
73
+ }
74
+ end
75
+
76
+ stack << current.left_child if current.left_child
77
+
78
+ stack << current.right_child if current.right_child
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module SorobanRustBackend
6
+ class LeftChildPreferentialBinaryTree
7
+ attr_accessor :value, :left_child, :right_child, :tree_id, :metadata
8
+
9
+ def initialize(value, metadata:, indentation: 0)
10
+ @tree_id = SecureRandom.uuid
11
+ @indentation = indentation
12
+ @value = value
13
+ @left_child = nil
14
+ @right_child = nil
15
+ @metadata = metadata
16
+ end
17
+
18
+ def set_left_child(node)
19
+ raise 'Left child already exists' if @left_child
20
+
21
+ @left_child = node
22
+ end
23
+
24
+ def set_right_child(node)
25
+ raise 'Right child already exists' if @right_child
26
+
27
+ @right_child = node
28
+ end
29
+
30
+ def traverse
31
+ result = []
32
+ result << @value
33
+ result += @left_child.traverse if @left_child
34
+ result += @right_child.traverse if @right_child
35
+ result
36
+ end
37
+
38
+ def traverse_with_indentation
39
+ result = []
40
+ result << [@value, @indentation, @metadata]
41
+ result += @left_child.traverse_with_indentation if @left_child
42
+ result += @right_child.traverse_with_indentation if @right_child
43
+ result
44
+ end
45
+
46
+ def all_paths_to(instruction_id, cur_result: [])
47
+ if value.id == instruction_id
48
+ return cur_result.empty? ? [[instruction_id]] : cur_result + [instruction_id]
49
+ end
50
+
51
+ result = nil
52
+
53
+ if @left_child
54
+ left_child_traverse = @left_child.all_paths_to(instruction_id, cur_result: cur_result + [value.id])
55
+ result = left_child_traverse unless left_child_traverse.nil?
56
+ end
57
+
58
+ if @right_child
59
+ right_child_traverse = @right_child.all_paths_to(instruction_id, cur_result: cur_result + [value.id])
60
+ result = result.nil? ? right_child_traverse : [result, right_child_traverse]
61
+ end
62
+
63
+ result
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,23 @@
1
+ module SorobanRustBackend
2
+ module NonTranslatables
3
+ class Handler
4
+ def initialize(non_translatables)
5
+ @non_translatables = non_translatables
6
+ end
7
+
8
+ def self.generate(non_translatables)
9
+ new(non_translatables).generate
10
+ end
11
+
12
+ def generate
13
+ generate_non_translatables
14
+ end
15
+
16
+ private
17
+
18
+ def generate_non_translatables
19
+ @non_translatables
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SorobanRustBackend
4
+ class Silviculturist
5
+ attr_accessor :forrest
6
+
7
+ def initialize(instructions, base_indentation: 0)
8
+ @instructions = instructions
9
+ @forrest = LCPBT_Forrest.new
10
+ @seen_instructions = {}
11
+ @base_indentation = base_indentation
12
+ end
13
+
14
+ def make_forrest
15
+ index = 0
16
+ while index < @instructions.size
17
+ instructions = @instructions[index..]
18
+ scope = 0
19
+ tree = plant_trees(scope, instructions, metadata: { last_node_was_conditional_jump: false, parent_scope: nil, symbol_table: {} },
20
+ indentation: @base_indentation)
21
+ @forrest.add_tree(tree)
22
+
23
+ seen = true
24
+ while seen && index < @instructions.size
25
+ index += 1
26
+ seen = @instructions[index].nil? || @seen_instructions[@instructions[index].id]
27
+ end
28
+ end
29
+ end
30
+
31
+ def plant_trees(scope, instructions, metadata:, from_id: nil, indentation: 0)
32
+ cur_instruction = instructions[0]
33
+
34
+ return nil if cur_instruction.nil?
35
+
36
+ if cur_instruction.scope != scope
37
+ return plant_trees(scope, instructions[1..], from_id: cur_instruction.id,
38
+ indentation:, metadata:)
39
+ end
40
+
41
+ return @seen_instructions[cur_instruction.id] if @seen_instructions[cur_instruction.id]
42
+
43
+ down_jump = cur_instruction.instruction == 'jump' && (
44
+ (cur_instruction.inputs.size == 1 && cur_instruction.inputs[0].to_i < scope) ||
45
+ (cur_instruction.inputs.size == 2 && cur_instruction.inputs[1].to_i < scope))
46
+
47
+ rest_of_instructions = instructions[1..]
48
+
49
+ tree = LeftChildPreferentialBinaryTree.new(cur_instruction,
50
+ indentation: if down_jump
51
+ indentation - 1
52
+ else
53
+ indentation
54
+ end, metadata:)
55
+ @seen_instructions[cur_instruction.id] = tree
56
+
57
+ case cur_instruction.instruction
58
+ when 'jump'
59
+ case cur_instruction.inputs.filter { |x| x.to_s.strip != 'ELSE_IF_BRANCH' }.size
60
+ # unconditional jump
61
+ when 1
62
+ new_scope = cur_instruction.inputs[0].to_i
63
+
64
+ # halt when going back to 0
65
+ return tree if new_scope.zero?
66
+
67
+ tree.set_left_child(plant_trees(new_scope, rest_of_instructions, from_id: cur_instruction.id,
68
+ indentation: down_jump ? indentation - 1 : indentation + 1, metadata: { last_node_was_conditional_jump: true, parent_scope: scope, symbol_table: metadata[:symbol_table] }))
69
+ # conditional jump
70
+ when 2
71
+ # detour
72
+ new_scope = cur_instruction.inputs[1].to_i
73
+
74
+ tree.set_left_child(plant_trees(new_scope, rest_of_instructions,
75
+ from_id: cur_instruction.id, indentation: down_jump ? indentation - 1 : indentation + 1, metadata: { last_node_was_conditional_jump: true, parent_scope: scope, symbol_table: metadata[:symbol_table] }))
76
+ # continue
77
+ tree.set_right_child(plant_trees(scope, rest_of_instructions, from_id: cur_instruction.id,
78
+ indentation:, metadata: { last_node_was_conditional_jump: true, parent_scope: scope, symbol_table: metadata[:symbol_table] }))
79
+ # if-let
80
+ when 3
81
+ raise 'We do not yet support if-let statements'
82
+ end
83
+ # the way a goto works is that you want to drop out of the loop back to the scope you were at
84
+ # when you started the loop
85
+ when 'goto'
86
+ goto_target_id = cur_instruction.inputs[0].to_i
87
+ return_scope = @instructions.find { |x| x.id == goto_target_id }.scope
88
+
89
+ tree.metadata[:return_scope] = return_scope
90
+
91
+ return tree if return_scope.zero?
92
+
93
+ # TODO: fix indentation
94
+ tree.set_left_child(plant_trees(return_scope.to_i, rest_of_instructions, from_id: cur_instruction.id,
95
+ indentation:, metadata: {
96
+ last_node_was_conditional_jump: false,
97
+ parent_scope: scope,
98
+ symbol_table: metadata[:symbol_table]
99
+ }))
100
+
101
+ when 'try_assign'
102
+ metadata = {
103
+ last_node_was_conditional_jump: false,
104
+ parent_scope: scope,
105
+ try_assign: {
106
+ lhs: cur_instruction.inputs[1],
107
+ rhs: cur_instruction.inputs[0],
108
+ assign: cur_instruction.assign
109
+ },
110
+ symbol_table: metadata[:symbol_table]
111
+ }
112
+
113
+ return plant_trees(scope, rest_of_instructions, from_id: cur_instruction.id,
114
+ indentation:, metadata:)
115
+ when 'end_of_iteration_check'
116
+ metadata = {
117
+ last_node_was_conditional_jump: false,
118
+ parent_scope: scope,
119
+ try_assign: nil,
120
+ end_of_iteration_check: {
121
+ lhs: cur_instruction.inputs[0],
122
+ rhs: cur_instruction.inputs[1],
123
+ assign: cur_instruction.assign
124
+ },
125
+ symbol_table: metadata[:symbol_table]
126
+ }
127
+
128
+ return plant_trees(scope, rest_of_instructions, from_id: cur_instruction.id, indentation:, metadata:)
129
+ else
130
+ last_symbol_table = metadata[:symbol_table]
131
+ last_symbol_table[cur_instruction.assign] = {} unless last_symbol_table.include?(cur_instruction.assign)
132
+ last_symbol_table[cur_instruction.assign][cur_instruction.scope] = cur_instruction
133
+
134
+ metadata = {
135
+ last_node_was_conditional_jump: false,
136
+ parent_scope: scope,
137
+ try_assign: nil,
138
+ symbol_table: last_symbol_table
139
+ }
140
+
141
+ # left_child
142
+ tree.set_left_child(plant_trees(scope, rest_of_instructions, from_id: cur_instruction.id,
143
+ indentation:, metadata:))
144
+ end
145
+
146
+ tree
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is the main module for the DTR to Rust gem.
4
+ module SorobanRustBackend
5
+ autoload :LCPBT_Forrest, 'lcpbt_forrest'
6
+ autoload :LeftChildPreferentialBinaryTree, 'left_child_preferential_binary_tree'
7
+ autoload :Silviculturist, 'silviculturist'
8
+ autoload :CodeGenerator, 'code_generator'
9
+ autoload :Condenser, 'condenser'
10
+ autoload :InstructionHandler, 'instruction_handler'
11
+ autoload :UserDefinedTypesHandler, 'user_defined_types_handler'
12
+ autoload :FunctionHandler, 'function_handler'
13
+ autoload :ContractHandler, 'contract_handler'
14
+
15
+ # This module contains all the classes that handle the different types of instructions.
16
+ module Instruction
17
+ autoload :Evaluate, './lib/instruction/evaluate'
18
+ autoload :Field, './lib/instruction/field'
19
+ autoload :Handler, './lib/instruction/handler'
20
+ autoload :Print, './lib/instruction/print'
21
+ autoload :Return, './lib/instruction/return'
22
+ autoload :InstantiateObject, './lib/instruction/instantiate_object'
23
+ autoload :Add, './lib/instruction/add'
24
+ autoload :Subtract, './lib/instruction/subtract'
25
+ autoload :Multiply, './lib/instruction/multiply'
26
+ autoload :Divide, './lib/instruction/divide'
27
+ autoload :Assign, './lib/instruction/assign'
28
+ autoload :Jump, './lib/instruction/jump'
29
+ autoload :Goto, './lib/instruction/goto'
30
+ autoload :ExitWithMessage, './lib/instruction/exit_with_message'
31
+ autoload :And, './lib/instruction/and'
32
+ autoload :Or, './lib/instruction/or'
33
+ autoload :EndOfIterationCheck, './lib/instruction/end_of_iteration_check'
34
+ autoload :Increment, './lib/instruction/increment'
35
+ autoload :TryAssign, './lib/instruction/try_assign'
36
+ autoload :Break, './lib/instruction/break'
37
+ autoload :BinaryInstruction, './lib/instruction/binary_instruction'
38
+ end
39
+
40
+ module Common
41
+ autoload :TypeTranslator, './lib/common/type_translator'
42
+ end
43
+
44
+ module NonTranslatables
45
+ autoload :Handler, './lib/non_translatables/handler'
46
+ end
47
+
48
+ module ContractState
49
+ autoload :Handler, './lib/contract_state/handler'
50
+ end
51
+ end