dtr_to_rust 0.2.10 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/common/input_interpreter.rb +11 -0
- data/lib/common/reference_appender.rb +56 -0
- data/lib/common/type_translator.rb +20 -0
- data/lib/dtr_to_rust.rb +25 -4
- data/lib/generator.rb +78 -32
- data/lib/instruction/add.rb +13 -0
- data/lib/instruction/and.rb +19 -0
- data/lib/instruction/assign.rb +12 -0
- data/lib/instruction/divide.rb +13 -0
- data/lib/instruction/evaluate.rb +57 -17
- data/lib/instruction/exit_with_message.rb +18 -0
- data/lib/instruction/field.rb +3 -3
- data/lib/instruction/goto.rb +12 -0
- data/lib/instruction/handler.rb +7 -4
- data/lib/instruction/instantiate_object.rb +67 -0
- data/lib/instruction/jump.rb +26 -0
- data/lib/instruction/label.rb +12 -0
- data/lib/instruction/multiply.rb +13 -0
- data/lib/instruction/or.rb +19 -0
- data/lib/instruction/{log_string.rb → print.rb} +2 -2
- data/lib/instruction/return.rb +1 -1
- data/lib/instruction/subtract.rb +13 -0
- data/lib/instruction_handler.rb +31 -18
- data/lib/optimization/chained_invocation_assignment_reduction.rb +113 -0
- data/lib/user_defined_types/handler.rb +55 -0
- metadata +20 -7
- data/lib/instruction/add_and_assign.rb +0 -12
- data/lib/instruction/create_list.rb +0 -31
- data/lib/instruction/initialize_udt.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b42b05c23f4f6cd523b03895ef4e41734d83d836f768143379b12d996415038d
|
4
|
+
data.tar.gz: d23996a0656a9ee252065f4f36d68646d18c42a9b9a05fe9897574ca4453dfb8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4238874b6d9be9f31090673903cf2d265b0aa5bcf4eb69056eb642b8750b73724a46bb005ad0e5fad7e22a98ca6e6ae95de9c401e8533bd6aa334622bc1002f
|
7
|
+
data.tar.gz: baebd2c976094cc88714c008f93ce5fd048fb0b5eb8a3c174d2ec899b612606a837d7c9bc7da1b12319d79d141793768c17336d5c82126226f24af7e491d3652
|
@@ -17,6 +17,8 @@ module DTRToRust
|
|
17
17
|
number_return(@input)
|
18
18
|
elsif string?(@input)
|
19
19
|
string_return(@input)
|
20
|
+
elsif boolean?(@input)
|
21
|
+
boolean_return(@input)
|
20
22
|
else
|
21
23
|
variable_return(@input)
|
22
24
|
end
|
@@ -58,6 +60,15 @@ module DTRToRust
|
|
58
60
|
# Check if the string matches the pattern
|
59
61
|
!!(str =~ decimal_pattern)
|
60
62
|
end
|
63
|
+
|
64
|
+
## Boolean ##
|
65
|
+
def boolean?(input)
|
66
|
+
input.is_a?(TrueClass) || input.is_a?(FalseClass) || input&.match?(/true|false/)
|
67
|
+
end
|
68
|
+
|
69
|
+
def boolean_return(_input)
|
70
|
+
{ value: @input, type: 'boolean', needs_reference: false }
|
71
|
+
end
|
61
72
|
end
|
62
73
|
end
|
63
74
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DTRToRust
|
4
|
+
module Common
|
5
|
+
# This module appends references to variables.
|
6
|
+
module ReferenceAppender
|
7
|
+
def self.call(input, ref_nums: false)
|
8
|
+
decorated_input = Common::InputInterpreter.interpret(input)
|
9
|
+
|
10
|
+
# HACK: is likely chain of method calls
|
11
|
+
# ex: env.storage().instance().get(COUNTER).unwrap_or(0);
|
12
|
+
# --> env.storage().instance().get(&COUNTER).unwrap_or(0);
|
13
|
+
if decorated_input[:type] != 'number' &&
|
14
|
+
decorated_input[:value].include?('.') &&
|
15
|
+
decorated_input[:value].include?('(') && decorated_input[:value].include?(')')
|
16
|
+
more_complex_ref_appender(input, decorated_input)
|
17
|
+
elsif decorated_input[:needs_reference]
|
18
|
+
"&#{decorated_input[:value]}"
|
19
|
+
elsif decorated_input[:type] == 'number'
|
20
|
+
ref_nums ? "&#{decorated_input[:value]}" : decorated_input[:value]
|
21
|
+
else
|
22
|
+
decorated_input[:value]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.more_complex_ref_appender(_input, decorated_input)
|
27
|
+
decorated_input[:value].split('.').map do |x|
|
28
|
+
x = x.strip
|
29
|
+
if call_with_input?(x)
|
30
|
+
matches = x.scan(/\((.*?)\)/)
|
31
|
+
things = matches
|
32
|
+
.flatten
|
33
|
+
.filter(&method(:not_empty_string?))
|
34
|
+
.map(&method(:wild_stuff))
|
35
|
+
.join(', ')
|
36
|
+
"#{x.split('(')[0]}(#{things})"
|
37
|
+
else
|
38
|
+
x
|
39
|
+
end
|
40
|
+
end.join('.')
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.not_empty_string?(input)
|
44
|
+
input != ''
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.wild_stuff(input)
|
48
|
+
input.split(',').map { |x| ReferenceAppender.call(x.strip) }.join(', ')
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.call_with_input?(input)
|
52
|
+
input.include?('(') && input.end_with?(')') && !input.end_with?('()')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DTRToRust
|
4
|
+
module Common
|
5
|
+
# TypeTranslator translates DTR types to Rust types
|
6
|
+
module TypeTranslator
|
7
|
+
def self.translate_type(type)
|
8
|
+
# TODO: fix this, it is incorrect
|
9
|
+
type
|
10
|
+
.gsub('List<', 'Vec<')
|
11
|
+
.gsub('Dictionary<', 'HashMap<')
|
12
|
+
.gsub('BigInteger', 'i128')
|
13
|
+
.gsub('Integer', 'i64')
|
14
|
+
.gsub('String', 'Symbol')
|
15
|
+
.gsub('Boolean', 'bool')
|
16
|
+
.gsub('Float', 'f64')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/dtr_to_rust.rb
CHANGED
@@ -7,18 +7,39 @@ module DTRToRust
|
|
7
7
|
|
8
8
|
# This module contains all the classes that handle the different types of instructions.
|
9
9
|
module Instruction
|
10
|
-
autoload :AddAndAssign, 'instruction/add_and_assign'
|
11
|
-
autoload :CreateList, 'instruction/create_list'
|
12
10
|
autoload :Evaluate, 'instruction/evaluate'
|
13
11
|
autoload :Field, 'instruction/field'
|
14
12
|
autoload :Handler, 'instruction/handler'
|
15
|
-
autoload :
|
16
|
-
autoload :LogString, 'instruction/log_string'
|
13
|
+
autoload :Print, 'instruction/print'
|
17
14
|
autoload :Return, 'instruction/return'
|
15
|
+
autoload :InstantiateObject, 'instruction/instantiate_object'
|
16
|
+
autoload :Add, 'instruction/add'
|
17
|
+
autoload :Subtract, 'instruction/subtract'
|
18
|
+
autoload :Multiply, 'instruction/multiply'
|
19
|
+
autoload :Divide, 'instruction/divide'
|
20
|
+
autoload :Assign, 'instruction/assign'
|
21
|
+
autoload :Jump, 'instruction/jump'
|
22
|
+
autoload :Goto, 'instruction/goto'
|
23
|
+
autoload :ExitWithMessage, 'instruction/exit_with_message'
|
24
|
+
autoload :And, 'instruction/and'
|
25
|
+
autoload :Or, 'instruction/or'
|
26
|
+
autoload :Label, 'instruction/label'
|
18
27
|
end
|
19
28
|
|
20
29
|
# This module contains all the classes that handle common logic.
|
21
30
|
module Common
|
22
31
|
autoload :InputInterpreter, 'common/input_interpreter'
|
32
|
+
autoload :ReferenceAppender, 'common/reference_appender'
|
33
|
+
autoload :TypeTranslator, 'common/type_translator'
|
34
|
+
end
|
35
|
+
|
36
|
+
# This module contains all the classes that handle optimization.
|
37
|
+
module Optimization
|
38
|
+
autoload :ChainedInvocationAssignmentReduction, 'optimization/chained_invocation_assignment_reduction'
|
39
|
+
end
|
40
|
+
|
41
|
+
# This module contains all the classes that handle user defined types.
|
42
|
+
module UserDefinedTypes
|
43
|
+
autoload :Handler, 'user_defined_types/handler'
|
23
44
|
end
|
24
45
|
end
|
data/lib/generator.rb
CHANGED
@@ -12,11 +12,13 @@ module DTRToRust
|
|
12
12
|
def generate
|
13
13
|
@content = ''
|
14
14
|
|
15
|
-
generate_contract_header
|
16
15
|
generate_user_defined_types
|
17
16
|
generate_state
|
18
17
|
generate_contract_name
|
19
|
-
|
18
|
+
generate_interface
|
19
|
+
generate_helpers
|
20
|
+
|
21
|
+
generate_contract_header
|
20
22
|
|
21
23
|
@content
|
22
24
|
end
|
@@ -34,8 +36,30 @@ module DTRToRust
|
|
34
36
|
attr_reader :dtr_contract
|
35
37
|
|
36
38
|
def generate_contract_header
|
39
|
+
imports_super_set = %w[
|
40
|
+
contract
|
41
|
+
contractimpl
|
42
|
+
contracttype
|
43
|
+
symbol_short
|
44
|
+
vec
|
45
|
+
Env
|
46
|
+
Symbol
|
47
|
+
Vec
|
48
|
+
log
|
49
|
+
]
|
50
|
+
|
51
|
+
used_imports = []
|
52
|
+
|
53
|
+
@content.split.each do |word|
|
54
|
+
imports_super_set.each do |import|
|
55
|
+
used_imports << import if word.include?(import)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
used_imports.uniq!
|
60
|
+
|
37
61
|
# TODO: don't hardcode imports
|
38
|
-
@content
|
62
|
+
@content = "#![no_std]\nuse soroban_sdk::{#{used_imports.join(', ')}};\n\n" + @content
|
39
63
|
end
|
40
64
|
|
41
65
|
def generate_contract_name
|
@@ -47,22 +71,44 @@ module DTRToRust
|
|
47
71
|
|
48
72
|
dtr_contract.state.each do |state_value|
|
49
73
|
if state_value.type == 'String'
|
50
|
-
@content += "const #{state_value.name}: Symbol = symbol_short!(
|
74
|
+
@content += "const #{state_value.name}: Symbol = symbol_short!(#{state_value.initial_value});\n"
|
75
|
+
else
|
76
|
+
@content += "const #{state_value.name}: #{Common::TypeTranslator.translate_type(state_value.type)} = #{state_value.initial_value};\n"
|
51
77
|
end
|
52
78
|
end
|
53
79
|
|
54
80
|
@content += "\n"
|
55
81
|
end
|
56
82
|
|
57
|
-
def
|
58
|
-
@content += "#[contractimpl]\nimpl #{dtr_contract.name} {#{generate_functions_each(dtr_contract.
|
83
|
+
def generate_interface
|
84
|
+
@content += "#[contractimpl]\nimpl #{dtr_contract.name} {#{generate_functions_each(dtr_contract.interface,
|
85
|
+
false)}}\n"
|
86
|
+
end
|
87
|
+
|
88
|
+
def generate_helpers
|
89
|
+
@content += "#{generate_functions_each(dtr_contract.helpers, true)}\n"
|
59
90
|
end
|
60
91
|
|
61
|
-
def generate_functions_each(functions)
|
92
|
+
def generate_functions_each(functions, is_helper)
|
93
|
+
function_names = functions&.map(&:name)
|
94
|
+
|
62
95
|
functions&.map do |function|
|
63
|
-
|
96
|
+
@last_scope = nil
|
97
|
+
optimized_instructions =
|
98
|
+
Optimization::ChainedInvocationAssignmentReduction.apply(function.instructions)
|
99
|
+
|
100
|
+
return_string = "\n#{is_helper ? '' : ' '}pub fn #{function.name}(#{generate_function_args(function)}) "
|
64
101
|
return_string += generate_function_output(function)
|
65
|
-
return_string += " {\n#{generate_instructions_each(
|
102
|
+
return_string += " {\n#{generate_instructions_each(optimized_instructions, function_names,
|
103
|
+
is_helper)}"
|
104
|
+
unless @last_scope.nil?
|
105
|
+
while @last_scope.positive?
|
106
|
+
return_string += "\n#{form_rust_string('}', @last_scope,
|
107
|
+
is_helper)}"
|
108
|
+
@last_scope -= 1
|
109
|
+
end
|
110
|
+
end
|
111
|
+
return_string += "\n#{is_helper ? '' : ' '}}\n"
|
66
112
|
|
67
113
|
return_string
|
68
114
|
end&.join("\n")
|
@@ -71,49 +117,49 @@ module DTRToRust
|
|
71
117
|
def generate_function_output(function)
|
72
118
|
return '' if function.output.nil?
|
73
119
|
|
74
|
-
"-> #{translate_type(function.output)}"
|
120
|
+
"-> #{Common::TypeTranslator.translate_type(function.output)}"
|
75
121
|
end
|
76
122
|
|
77
123
|
def generate_function_args(function)
|
78
124
|
all_inputs = [] + function.inputs
|
79
125
|
|
80
|
-
all_inputs.map { |x| "#{x[:name]}: #{translate_type(x[:type_name])}" }.join(', ')
|
126
|
+
all_inputs.map { |x| "#{x[:name]}: #{Common::TypeTranslator.translate_type(x[:type_name])}" }.join(', ')
|
81
127
|
end
|
82
128
|
|
83
|
-
def generate_instructions_each(instructions)
|
129
|
+
def generate_instructions_each(instructions, function_names, is_helper)
|
84
130
|
instructions.map do |instruction|
|
85
|
-
|
131
|
+
content = ''
|
132
|
+
if @last_scope.nil?
|
133
|
+
@last_scope = instruction.scope
|
134
|
+
elsif @last_scope != instruction.scope
|
135
|
+
content += form_rust_string("}\n", instruction.scope, is_helper) if @last_scope > instruction.scope
|
136
|
+
@last_scope = instruction.scope
|
137
|
+
end
|
138
|
+
content += generate_instruction(instruction, function_names, is_helper)
|
139
|
+
|
140
|
+
content
|
86
141
|
end.join("\n")
|
87
142
|
end
|
88
143
|
|
89
|
-
def
|
90
|
-
|
91
|
-
handler.generate_rust
|
144
|
+
def form_rust_string(instruction_string, scope, is_helper)
|
145
|
+
"#{spacing(scope, is_helper)}#{instruction_string}"
|
92
146
|
end
|
93
147
|
|
94
|
-
def
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
'Vec<Symbol>'
|
102
|
-
else
|
103
|
-
type
|
104
|
-
end
|
148
|
+
def spacing(scope, is_helper)
|
149
|
+
' ' * (is_helper ? 0 : scope + 1)
|
150
|
+
end
|
151
|
+
|
152
|
+
def generate_instruction(instruction, function_names, is_helper)
|
153
|
+
handler = InstructionHandler.new(instruction, function_names, dtr_contract.user_defined_types || [], is_helper)
|
154
|
+
handler.generate_rust
|
105
155
|
end
|
106
156
|
|
107
157
|
def generate_user_defined_types
|
108
158
|
return if dtr_contract.user_defined_types.nil?
|
109
159
|
|
110
160
|
dtr_contract.user_defined_types.each do |udt|
|
111
|
-
@content +=
|
161
|
+
@content += DTRToRust::UserDefinedTypes::Handler.generate(udt)
|
112
162
|
end
|
113
163
|
end
|
114
|
-
|
115
|
-
def derives
|
116
|
-
"#[contracttype]\n#[derive(Clone, Debug, Eq, PartialEq)]\n"
|
117
|
-
end
|
118
164
|
end
|
119
165
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DTRToRust
|
4
|
+
module Instruction
|
5
|
+
# This class handles the add instruction.
|
6
|
+
class Add < Handler
|
7
|
+
def handle
|
8
|
+
form_rust_string("#{@instruction.assign} = #{@instruction.inputs[0]} + #{@instruction.inputs[1]};",
|
9
|
+
@instruction.scope)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DTRToRust
|
4
|
+
module Instruction
|
5
|
+
# This class handles the and instruction.
|
6
|
+
class And < Handler
|
7
|
+
def handle
|
8
|
+
inputs = @instruction.inputs
|
9
|
+
assignment = @instruction.assign
|
10
|
+
|
11
|
+
assignment_rust = "let #{assignment} = "
|
12
|
+
body_rust = "#{inputs[0]} && #{inputs[1]};"
|
13
|
+
rust_string = "#{assignment.nil? ? '' : assignment_rust}#{body_rust}"
|
14
|
+
|
15
|
+
form_rust_string(rust_string, @instruction.scope)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DTRToRust
|
4
|
+
module Instruction
|
5
|
+
# This class handles the assign instruction.
|
6
|
+
class Assign < Handler
|
7
|
+
def handle
|
8
|
+
form_rust_string("let mut #{@instruction.assign} = #{@instruction.inputs[0]};", @instruction.scope)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DTRToRust
|
4
|
+
module Instruction
|
5
|
+
# This class handles the add instruction.
|
6
|
+
class Divide < Handler
|
7
|
+
def handle
|
8
|
+
form_rust_string("#{@instruction.assign} = #{@instruction.inputs[0]} / #{@instruction.inputs[1]};",
|
9
|
+
@instruction.scope)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/instruction/evaluate.rb
CHANGED
@@ -5,34 +5,74 @@ module DTRToRust
|
|
5
5
|
# This class is responsible for generating Rust code for the Evaluate instruction.
|
6
6
|
class Evaluate < Handler
|
7
7
|
def handle
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
rust_string = handle_keyword_method_invocation
|
9
|
+
form_rust_string(rust_string, @instruction.scope)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def handle_keyword_method_invocation
|
15
|
+
case @instruction.inputs[0]
|
16
|
+
when 'equal_to'
|
17
|
+
handle_equal_to
|
18
|
+
when '!'
|
19
|
+
handle_unary_negation
|
20
|
+
else
|
21
|
+
handle_non_keyword_method_invocation
|
22
|
+
end
|
23
|
+
end
|
11
24
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
25
|
+
def handle_non_keyword_method_invocation
|
26
|
+
inputs = @instruction.inputs[1..]
|
27
|
+
evaluated_method_name = @instruction.inputs[0]
|
28
|
+
assignment = @instruction.assign
|
17
29
|
|
18
|
-
|
30
|
+
assignment_rust = "let mut #{assignment} = "
|
31
|
+
# TODO: make this less hacky evaluated_method_name.end_with?('set')
|
32
|
+
body_rust = "#{invocation_name(evaluated_method_name)}(#{inputs_to_rust_string(inputs,
|
33
|
+
don_t_append_ref)});"
|
34
|
+
"#{assignment.nil? ? '' : assignment_rust}#{body_rust}"
|
19
35
|
end
|
20
36
|
|
21
|
-
|
37
|
+
def handle_equal_to
|
38
|
+
inputs = @instruction.inputs[1..]
|
39
|
+
@instruction.inputs[0]
|
40
|
+
assignment = @instruction.assign
|
22
41
|
|
23
|
-
|
24
|
-
|
42
|
+
assignment_rust = "let #{assignment} = "
|
43
|
+
lhs = Common::ReferenceAppender.call(inputs[0])
|
44
|
+
rhs = Common::ReferenceAppender.call(inputs[1])
|
45
|
+
body_rust = "#{lhs} == #{rhs};"
|
46
|
+
|
47
|
+
"#{assignment.nil? ? '' : assignment_rust}#{body_rust}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def handle_unary_negation
|
51
|
+
inputs = @instruction.inputs[1..]
|
52
|
+
@instruction.inputs[0]
|
53
|
+
assignment = @instruction.assign
|
54
|
+
|
55
|
+
assignment_rust = "let #{assignment} = "
|
56
|
+
body_rust = "!(#{inputs[0]});"
|
57
|
+
|
58
|
+
"#{assignment.nil? ? '' : assignment_rust}#{body_rust}"
|
25
59
|
end
|
26
60
|
|
27
|
-
def
|
28
|
-
|
61
|
+
def don_t_append_ref
|
62
|
+
@instruction.inputs[0].end_with?('set') || @instruction.inputs[0].end_with?('unwrap_or')
|
63
|
+
end
|
29
64
|
|
30
|
-
|
31
|
-
|
65
|
+
def invocation_name(evaluated_method_name)
|
66
|
+
if @function_names.include?(evaluated_method_name)
|
67
|
+
"Self::#{evaluated_method_name}"
|
32
68
|
else
|
33
|
-
|
69
|
+
evaluated_method_name
|
34
70
|
end
|
35
71
|
end
|
72
|
+
|
73
|
+
def inputs_to_rust_string(inputs, ref_nums)
|
74
|
+
inputs.map { |input| Common::ReferenceAppender.call(input, ref_nums:) }.join(', ')
|
75
|
+
end
|
36
76
|
end
|
37
77
|
end
|
38
78
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DTRToRust
|
4
|
+
module Instruction
|
5
|
+
# This class handles the exit_with_message instruction.
|
6
|
+
class ExitWithMessage < Handler
|
7
|
+
def handle
|
8
|
+
form_rust_string("panic! #{inputs_to_rust_string(@instruction.inputs)};", @instruction.scope)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def inputs_to_rust_string(inputs)
|
14
|
+
inputs.map { |input| Common::ReferenceAppender.call(input) }.join(', ')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/instruction/field.rb
CHANGED
@@ -5,17 +5,17 @@ module DTRToRust
|
|
5
5
|
# This class is responsible for generating Rust code for the Field instruction.
|
6
6
|
class Field < Handler
|
7
7
|
def handle
|
8
|
-
form_rust_string("#{handle_field_assign}#{handle_field_call}", @instruction
|
8
|
+
form_rust_string("#{handle_field_assign}#{handle_field_call}", @instruction.scope)
|
9
9
|
end
|
10
10
|
|
11
11
|
private
|
12
12
|
|
13
13
|
def handle_field_call
|
14
|
-
"#{@instruction
|
14
|
+
"#{@instruction.inputs[0]}.#{@instruction.inputs[1]};"
|
15
15
|
end
|
16
16
|
|
17
17
|
def handle_field_assign
|
18
|
-
"let mut #{@instruction
|
18
|
+
"let mut #{@instruction.assign} = " if @instruction.assign
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
data/lib/instruction/handler.rb
CHANGED
@@ -4,16 +4,19 @@ module DTRToRust
|
|
4
4
|
module Instruction
|
5
5
|
# This class is responsible for generating Rust code for the AddAndAssign instruction.
|
6
6
|
class Handler
|
7
|
-
def initialize(instruction)
|
7
|
+
def initialize(instruction, function_names, user_defined_types, is_helper)
|
8
8
|
@instruction = instruction
|
9
|
+
@function_names = function_names
|
10
|
+
@user_defined_types = user_defined_types
|
11
|
+
@is_helper = is_helper
|
9
12
|
end
|
10
13
|
|
11
|
-
def self.handle(instruction)
|
12
|
-
new(instruction).handle
|
14
|
+
def self.handle(instruction, function_names, user_defined_types, is_helper)
|
15
|
+
new(instruction, function_names, user_defined_types, is_helper).handle
|
13
16
|
end
|
14
17
|
|
15
18
|
def spacing(scope)
|
16
|
-
'
|
19
|
+
' ' * (@is_helper ? 1 : scope + 2)
|
17
20
|
end
|
18
21
|
|
19
22
|
def form_rust_string(instruction_string, scope)
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DTRToRust
|
4
|
+
module Instruction
|
5
|
+
# This class is responsible for generating Rust code for the LogString instruction.
|
6
|
+
class InstantiateObject < Handler
|
7
|
+
def handle
|
8
|
+
case @instruction.inputs[0]
|
9
|
+
when 'List'
|
10
|
+
handle_list
|
11
|
+
when 'UDT'
|
12
|
+
handle_udt
|
13
|
+
else
|
14
|
+
raise "Unknown object type: #{@instruction.inputs[0]}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def handle_list
|
21
|
+
form_rust_string("let mut #{@instruction.assign} = vec![#{inputs_to_rust_string(@instruction.inputs[1..])}];",
|
22
|
+
@instruction.scope)
|
23
|
+
end
|
24
|
+
|
25
|
+
def udt_name_fix(udt)
|
26
|
+
if udt.name.end_with?('_STRUCT') || udt.name.end_with?('_ENUM')
|
27
|
+
udt.name.split('_')[0..-2].join('_')
|
28
|
+
else
|
29
|
+
udt.name
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def handle_udt
|
34
|
+
udt_found = @user_defined_types.filter { |udt| udt_name_fix(udt) == @instruction.inputs[1] }
|
35
|
+
|
36
|
+
assignment = "let mut #{@instruction.assign} = "
|
37
|
+
udt = "#{@instruction.inputs[1]}{"
|
38
|
+
inputs = inputs_to_rust_string(@instruction.inputs[2..], udt_found[0].attributes.map { |x| x[:name] })
|
39
|
+
end_ = '};'
|
40
|
+
form_rust_string("#{assignment}#{udt}#{inputs}#{end_}", @instruction.scope)
|
41
|
+
end
|
42
|
+
|
43
|
+
def inputs_to_rust_string(inputs, udt_type_names)
|
44
|
+
inputs_to_return = []
|
45
|
+
inputs.each_with_index do |input, index|
|
46
|
+
inputs_to_return << handle_input(input, udt_type_names[index])
|
47
|
+
end
|
48
|
+
|
49
|
+
inputs_to_return.join(', ')
|
50
|
+
end
|
51
|
+
|
52
|
+
def handle_input(input, udt_type_name)
|
53
|
+
decorated_input = Common::InputInterpreter.interpret(input)
|
54
|
+
|
55
|
+
value = if decorated_input[:type] == 'string'
|
56
|
+
"symbol_short!(#{input})"
|
57
|
+
elsif decorated_input[:needs_reference] && input == 'env'
|
58
|
+
"&#{input}"
|
59
|
+
else
|
60
|
+
input
|
61
|
+
end
|
62
|
+
|
63
|
+
"#{udt_type_name}: #{value}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DTRToRust
|
4
|
+
module Instruction
|
5
|
+
# This class handles the jump instruction.
|
6
|
+
class Jump < Handler
|
7
|
+
def handle
|
8
|
+
if @instruction.inputs[0].nil?
|
9
|
+
handle_unconditional_jump
|
10
|
+
else
|
11
|
+
handle_conditional_jump
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def handle_conditional_jump
|
18
|
+
form_rust_string("if #{@instruction.inputs[0]} {", @instruction.scope)
|
19
|
+
end
|
20
|
+
|
21
|
+
def handle_unconditional_jump
|
22
|
+
form_rust_string('if true {', @instruction.scope)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DTRToRust
|
4
|
+
module Instruction
|
5
|
+
# This class handles the add instruction.
|
6
|
+
class Multiply < Handler
|
7
|
+
def handle
|
8
|
+
form_rust_string("#{@instruction.assign} = #{@instruction.inputs[0]} * #{@instruction.inputs[1]};",
|
9
|
+
@instruction.scope)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DTRToRust
|
4
|
+
module Instruction
|
5
|
+
# This class handles the or instruction.
|
6
|
+
class Or < Handler
|
7
|
+
def handle
|
8
|
+
inputs = @instruction.inputs
|
9
|
+
assignment = @instruction.assign
|
10
|
+
|
11
|
+
assignment_rust = "let #{assignment} = "
|
12
|
+
body_rust = "#{inputs[0]} || #{inputs[1]};"
|
13
|
+
rust_string = "#{assignment.nil? ? '' : assignment_rust}#{body_rust}"
|
14
|
+
|
15
|
+
form_rust_string(rust_string, @instruction.scope)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -3,9 +3,9 @@
|
|
3
3
|
module DTRToRust
|
4
4
|
module Instruction
|
5
5
|
# This class is responsible for generating Rust code for the LogString instruction.
|
6
|
-
class
|
6
|
+
class Print < Handler
|
7
7
|
def handle
|
8
|
-
form_rust_string("log!(#{inputs_to_rust_string(@instruction
|
8
|
+
form_rust_string("log!(#{inputs_to_rust_string(@instruction.inputs)});", @instruction.scope)
|
9
9
|
end
|
10
10
|
|
11
11
|
private
|
data/lib/instruction/return.rb
CHANGED
@@ -5,7 +5,7 @@ module DTRToRust
|
|
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
|
8
|
+
form_rust_string(@instruction.inputs[0], @instruction.scope)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DTRToRust
|
4
|
+
module Instruction
|
5
|
+
# This class handles the add instruction.
|
6
|
+
class Subtract < Handler
|
7
|
+
def handle
|
8
|
+
form_rust_string("#{@instruction.assign} = #{@instruction.inputs[0]} - #{@instruction.inputs[1]};",
|
9
|
+
@instruction.scope)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/instruction_handler.rb
CHANGED
@@ -3,33 +3,46 @@
|
|
3
3
|
module DTRToRust
|
4
4
|
# This class is responsible for generating Rust code for a single instruction.
|
5
5
|
class InstructionHandler
|
6
|
-
def initialize(instruction)
|
6
|
+
def initialize(instruction, function_names, user_defined_types, is_helper)
|
7
7
|
@instruction = instruction
|
8
|
+
@function_names = function_names
|
9
|
+
@user_defined_types = user_defined_types
|
10
|
+
@is_helper = is_helper
|
8
11
|
end
|
9
12
|
|
10
13
|
def generate_rust
|
11
|
-
|
12
|
-
|
13
|
-
Instruction::Return.handle(@instruction)
|
14
|
-
when 'log_string'
|
15
|
-
Instruction::LogString.handle(@instruction)
|
16
|
-
when 'add_and_assign'
|
17
|
-
Instruction::AddAndAssign.handle(@instruction)
|
18
|
-
when 'evaluate'
|
19
|
-
Instruction::Evaluate.handle(@instruction)
|
20
|
-
when 'create_list'
|
21
|
-
Instruction::CreateList.handle(@instruction)
|
22
|
-
when 'field'
|
23
|
-
Instruction::Field.handle(@instruction)
|
24
|
-
when 'initialize_udt'
|
25
|
-
Instruction::InitializeUDT.handle(@instruction)
|
26
|
-
else
|
27
|
-
raise "Unknown instruction type: #{@instruction[:instruction]}"
|
14
|
+
unless EXPRESSION_FOOBAR.key?(@instruction.instruction.strip)
|
15
|
+
raise "Unknown instruction type: #{@instruction.instruction}"
|
28
16
|
end
|
17
|
+
|
18
|
+
EXPRESSION_FOOBAR[@instruction.instruction.strip].send(:handle, @instruction, @function_names,
|
19
|
+
@user_defined_types, @is_helper)
|
29
20
|
end
|
30
21
|
|
31
22
|
private
|
32
23
|
|
24
|
+
EXPRESSION_FOOBAR = {
|
25
|
+
'assign' => Instruction::Assign,
|
26
|
+
'jump' => Instruction::Jump,
|
27
|
+
'goto' => Instruction::Goto,
|
28
|
+
'exit_with_message' => Instruction::ExitWithMessage,
|
29
|
+
'and' => Instruction::And,
|
30
|
+
'or' => Instruction::Or,
|
31
|
+
'label' => Instruction::Label,
|
32
|
+
'add' => Instruction::Add,
|
33
|
+
'subtract' => Instruction::Subtract,
|
34
|
+
'multiply' => Instruction::Multiply,
|
35
|
+
'divide' => Instruction::Divide,
|
36
|
+
'instantiate_object' => Instruction::InstantiateObject,
|
37
|
+
'print' => Instruction::Print,
|
38
|
+
'return' => Instruction::Return,
|
39
|
+
'evaluate' => Instruction::Evaluate,
|
40
|
+
'field' => Instruction::Field
|
41
|
+
}.freeze
|
42
|
+
|
43
|
+
def handle_empty_instruction
|
44
|
+
''
|
45
|
+
end
|
33
46
|
attr_reader :instruction
|
34
47
|
end
|
35
48
|
end
|
@@ -0,0 +1,113 @@
|
|
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
|
+
@memoize_assigns[@cur_instruction.assign] = {
|
54
|
+
inputs: @optimized_inputs,
|
55
|
+
index:
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def clear_memoize?
|
60
|
+
if @last_was_eavluate.nil?
|
61
|
+
@last_was_eavluate = @cur_instruction.instruction == 'evaluate'
|
62
|
+
return false
|
63
|
+
end
|
64
|
+
|
65
|
+
if @cur_instruction.instruction == 'evaluate'
|
66
|
+
if @last_was_eavluate
|
67
|
+
false
|
68
|
+
else
|
69
|
+
@last_was_eavluate = true
|
70
|
+
true
|
71
|
+
end
|
72
|
+
elsif @last_was_eavluate
|
73
|
+
@last_was_eavluate = false
|
74
|
+
true
|
75
|
+
else
|
76
|
+
false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def apply_to_instruction_input(_instruction, input)
|
81
|
+
done_a_thing = false
|
82
|
+
@memoize_assigns.each do |key, value|
|
83
|
+
next unless do_a_thing?(input, key, input.split('.')[0])
|
84
|
+
|
85
|
+
# input = input.gsub(key, "#{value[:inputs][0]}(#{value[:inputs][1..].join(', ')})")
|
86
|
+
|
87
|
+
input = input.gsub(key, "#{evaluate_input(key, value)}")
|
88
|
+
@optimized_inputs << input # evaluate_input(key, value)
|
89
|
+
done_a_thing = true
|
90
|
+
@to_remove[value[:index]] = true
|
91
|
+
next
|
92
|
+
end
|
93
|
+
|
94
|
+
@optimized_inputs << input unless done_a_thing
|
95
|
+
end
|
96
|
+
|
97
|
+
def evaluate_input(_key, input)
|
98
|
+
InstructionHandler.new(DTRCore::Instruction.new('evaluate', input[:inputs], nil, 0), [], [],
|
99
|
+
false).generate_rust.strip.gsub(';', '')
|
100
|
+
end
|
101
|
+
|
102
|
+
def do_a_thing?(input, key, input_beginning)
|
103
|
+
input &&
|
104
|
+
key &&
|
105
|
+
input_beginning == key &&
|
106
|
+
!(input.start_with?('"') &&
|
107
|
+
input.end_with?('"')) &&
|
108
|
+
@cur_instruction.instruction == 'evaluate' &&
|
109
|
+
!['equal_to', '!'].include?(@cur_instruction)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,55 @@
|
|
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
|
+
" #{x[:name]},"
|
39
|
+
end.join("\n")
|
40
|
+
end
|
41
|
+
|
42
|
+
def derives
|
43
|
+
"#[contracttype]\n#[derive(Clone, Debug, Eq, PartialEq)]\n"
|
44
|
+
end
|
45
|
+
|
46
|
+
def struct?
|
47
|
+
@user_defined_type.name.end_with? '_STRUCT'
|
48
|
+
end
|
49
|
+
|
50
|
+
def enum?
|
51
|
+
@user_defined_type.name.end_with? '_ENUM'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dtr_to_rust
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Durst
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-06-
|
11
|
+
date: 2024-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Rust to DTR translator (Digicus Textual Representation).
|
14
14
|
email:
|
@@ -18,17 +18,30 @@ extensions: []
|
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
20
|
- lib/common/input_interpreter.rb
|
21
|
+
- lib/common/reference_appender.rb
|
22
|
+
- lib/common/type_translator.rb
|
21
23
|
- lib/dtr_to_rust.rb
|
22
24
|
- lib/generator.rb
|
23
|
-
- lib/instruction/
|
24
|
-
- lib/instruction/
|
25
|
+
- lib/instruction/add.rb
|
26
|
+
- lib/instruction/and.rb
|
27
|
+
- lib/instruction/assign.rb
|
28
|
+
- lib/instruction/divide.rb
|
25
29
|
- lib/instruction/evaluate.rb
|
30
|
+
- lib/instruction/exit_with_message.rb
|
26
31
|
- lib/instruction/field.rb
|
32
|
+
- lib/instruction/goto.rb
|
27
33
|
- lib/instruction/handler.rb
|
28
|
-
- lib/instruction/
|
29
|
-
- lib/instruction/
|
34
|
+
- lib/instruction/instantiate_object.rb
|
35
|
+
- lib/instruction/jump.rb
|
36
|
+
- lib/instruction/label.rb
|
37
|
+
- lib/instruction/multiply.rb
|
38
|
+
- lib/instruction/or.rb
|
39
|
+
- lib/instruction/print.rb
|
30
40
|
- lib/instruction/return.rb
|
41
|
+
- lib/instruction/subtract.rb
|
31
42
|
- lib/instruction_handler.rb
|
43
|
+
- lib/optimization/chained_invocation_assignment_reduction.rb
|
44
|
+
- lib/user_defined_types/handler.rb
|
32
45
|
homepage: https://spaced-out-thoughts-dev-foundation.github.io/digicus/
|
33
46
|
licenses:
|
34
47
|
- MIT
|
@@ -49,7 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
49
62
|
- !ruby/object:Gem::Version
|
50
63
|
version: '0'
|
51
64
|
requirements: []
|
52
|
-
rubygems_version: 3.
|
65
|
+
rubygems_version: 3.5.13
|
53
66
|
signing_key:
|
54
67
|
specification_version: 4
|
55
68
|
summary: Rust to DTR translator (Digicus Textual Representation).
|
@@ -1,12 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DTRToRust
|
4
|
-
module Instruction
|
5
|
-
# This class is responsible for generating Rust code for the AddAndAssign instruction.
|
6
|
-
class AddAndAssign < Handler
|
7
|
-
def handle
|
8
|
-
form_rust_string("#{@instruction[:inputs][0]} += #{@instruction[:inputs][1]};", @instruction[:scope])
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DTRToRust
|
4
|
-
module Instruction
|
5
|
-
# This class is responsible for generating Rust code for the AddAndAssign instruction.
|
6
|
-
class CreateList < Handler
|
7
|
-
def handle
|
8
|
-
form_rust_string("let #{@instruction[:assign]} = vec![#{handle_inputs}];",
|
9
|
-
@instruction[:scope])
|
10
|
-
end
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
def handle_inputs
|
15
|
-
@instruction[:inputs].map { |input| handle_input(input) }.join(', ')
|
16
|
-
end
|
17
|
-
|
18
|
-
def handle_input(input)
|
19
|
-
decorated_input = Common::InputInterpreter.interpret(input)
|
20
|
-
|
21
|
-
if decorated_input[:type] == 'string'
|
22
|
-
"symbol_short!(#{input})"
|
23
|
-
elsif decorated_input[:needs_reference] && input == 'env'
|
24
|
-
"&#{input}"
|
25
|
-
else
|
26
|
-
input
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DTRToRust
|
4
|
-
module Instruction
|
5
|
-
# This class is responsible for generating Rust code for the Field instruction.
|
6
|
-
class InitializeUDT < Handler
|
7
|
-
def handle
|
8
|
-
form_rust_string("#{handle_assign}#{handle_udt_part}", @instruction[:scope])
|
9
|
-
end
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
def handle_udt_part
|
14
|
-
"#{@instruction[:inputs][0]} { #{@instruction[:inputs][1..].join(' ')} };"
|
15
|
-
end
|
16
|
-
|
17
|
-
def handle_assign
|
18
|
-
"let mut #{@instruction[:assign]} = " if @instruction[:assign]
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|