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,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