rlsl 0.1.1 → 1.0.1

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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +8 -0
  3. data/CHANGELOG.md +13 -2
  4. data/README.md +101 -26
  5. data/Rakefile +7 -0
  6. data/lib/rlsl/base_translator/call_parser.rb +79 -0
  7. data/lib/rlsl/base_translator/code_rewriter.rb +107 -0
  8. data/lib/rlsl/base_translator/code_scanner.rb +140 -0
  9. data/lib/rlsl/base_translator.rb +182 -64
  10. data/lib/rlsl/code_generator/math_prelude.rb +172 -0
  11. data/lib/rlsl/code_generator/ruby_wrapper_generator.rb +137 -0
  12. data/lib/rlsl/code_generator/shader_function_generator.rb +19 -0
  13. data/lib/rlsl/code_generator/template_context.rb +44 -0
  14. data/lib/rlsl/code_generator/uniform_struct_generator.rb +29 -0
  15. data/lib/rlsl/code_generator.rb +30 -202
  16. data/lib/rlsl/compiled_shader.rb +5 -13
  17. data/lib/rlsl/errors.rb +29 -0
  18. data/lib/rlsl/function_context.rb +31 -14
  19. data/lib/rlsl/glsl/translator.rb +35 -41
  20. data/lib/rlsl/msl/shader.rb +34 -46
  21. data/lib/rlsl/msl/translator.rb +38 -34
  22. data/lib/rlsl/msl/uniform_buffer_packer.rb +72 -0
  23. data/lib/rlsl/prism/ast_visitor/control_flow_visiting.rb +137 -0
  24. data/lib/rlsl/prism/ast_visitor/definition_visiting.rb +92 -0
  25. data/lib/rlsl/prism/ast_visitor/expression_visiting.rb +172 -0
  26. data/lib/rlsl/prism/ast_visitor/scope_context.rb +48 -0
  27. data/lib/rlsl/prism/ast_visitor/visitor_registry.rb +21 -0
  28. data/lib/rlsl/prism/ast_visitor.rb +100 -286
  29. data/lib/rlsl/prism/builtins/function_registry.rb +131 -0
  30. data/lib/rlsl/prism/builtins/operator_rules.rb +123 -0
  31. data/lib/rlsl/prism/builtins/swizzle_rules.rb +47 -0
  32. data/lib/rlsl/prism/builtins.rb +39 -148
  33. data/lib/rlsl/prism/compilation_unit.rb +7 -0
  34. data/lib/rlsl/prism/emitters/base_emitter/control_flow_emission.rb +126 -0
  35. data/lib/rlsl/prism/emitters/base_emitter/definition_emission.rb +134 -0
  36. data/lib/rlsl/prism/emitters/base_emitter/expression_emission.rb +108 -0
  37. data/lib/rlsl/prism/emitters/base_emitter/statement_emission.rb +95 -0
  38. data/lib/rlsl/prism/emitters/base_emitter.rb +120 -414
  39. data/lib/rlsl/prism/emitters/c_emitter.rb +165 -112
  40. data/lib/rlsl/prism/emitters/glsl_emitter.rb +63 -50
  41. data/lib/rlsl/prism/emitters/msl_emitter.rb +67 -52
  42. data/lib/rlsl/prism/emitters/target_emitter.rb +124 -0
  43. data/lib/rlsl/prism/emitters/target_profile.rb +34 -0
  44. data/lib/rlsl/prism/emitters/wgsl_emitter.rb +217 -58
  45. data/lib/rlsl/prism/errors.rb +9 -0
  46. data/lib/rlsl/prism/ir/control_flow.rb +85 -0
  47. data/lib/rlsl/prism/ir/definitions.rb +82 -0
  48. data/lib/rlsl/prism/ir/expressions.rb +201 -0
  49. data/lib/rlsl/prism/ir/node.rb +21 -0
  50. data/lib/rlsl/prism/ir/nodes.rb +4 -371
  51. data/lib/rlsl/prism/ir/traversal.rb +66 -0
  52. data/lib/rlsl/prism/mutation_analyzer.rb +30 -0
  53. data/lib/rlsl/prism/node_traversal.rb +41 -0
  54. data/lib/rlsl/prism/parameter_list.rb +46 -0
  55. data/lib/rlsl/prism/return_flow_validator.rb +73 -0
  56. data/lib/rlsl/prism/source_extractor/block_locator.rb +50 -0
  57. data/lib/rlsl/prism/source_extractor.rb +19 -137
  58. data/lib/rlsl/prism/source_unit/parser.rb +88 -0
  59. data/lib/rlsl/prism/source_unit.rb +42 -0
  60. data/lib/rlsl/prism/target_capability_validator.rb +110 -0
  61. data/lib/rlsl/prism/transpiler.rb +99 -59
  62. data/lib/rlsl/prism/type_inference/call_type_resolver.rb +59 -0
  63. data/lib/rlsl/prism/type_inference/call_validator.rb +75 -0
  64. data/lib/rlsl/prism/type_inference/collection_type_resolver.rb +106 -0
  65. data/lib/rlsl/prism/type_inference/control_flow_inferer.rb +147 -0
  66. data/lib/rlsl/prism/type_inference/definition_inferer.rb +56 -0
  67. data/lib/rlsl/prism/type_inference/expression_inferer.rb +96 -0
  68. data/lib/rlsl/prism/type_inference/field_type_resolver.rb +38 -0
  69. data/lib/rlsl/prism/type_inference/inferer_registry.rb +38 -0
  70. data/lib/rlsl/prism/type_inference/scope_stack.rb +47 -0
  71. data/lib/rlsl/prism/type_inference/type_environment.rb +112 -0
  72. data/lib/rlsl/prism/type_inference/type_shapes.rb +33 -0
  73. data/lib/rlsl/prism/type_inference.rb +120 -249
  74. data/lib/rlsl/runtime_shader.rb +47 -0
  75. data/lib/rlsl/shader_builder/build_service.rb +104 -0
  76. data/lib/rlsl/shader_builder/native_extension_compiler.rb +97 -0
  77. data/lib/rlsl/shader_builder/shader_definition.rb +68 -0
  78. data/lib/rlsl/shader_builder/source_resolver.rb +109 -0
  79. data/lib/rlsl/shader_builder.rb +60 -111
  80. data/lib/rlsl/shader_name.rb +18 -0
  81. data/lib/rlsl/types/catalog.rb +47 -0
  82. data/lib/rlsl/types/target_resolver.rb +15 -0
  83. data/lib/rlsl/types/type_spec.rb +167 -0
  84. data/lib/rlsl/types/value_normalizer.rb +86 -0
  85. data/lib/rlsl/types.rb +9 -31
  86. data/lib/rlsl/uniform_context.rb +22 -11
  87. data/lib/rlsl/version.rb +1 -1
  88. data/lib/rlsl/wgsl/translator.rb +46 -39
  89. data/lib/rlsl/wgsl/uniform_layout.rb +25 -0
  90. data/lib/rlsl.rb +38 -15
  91. metadata +76 -11
@@ -0,0 +1,201 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RLSL
4
+ module Prism
5
+ module IR
6
+ class Block < Node
7
+ attr_reader :statements
8
+
9
+ visits :visit_block
10
+
11
+ def initialize(statements = [])
12
+ super()
13
+ @statements = statements
14
+ end
15
+ end
16
+
17
+ class VarDecl < Node
18
+ attr_reader :name, :initializer
19
+ attr_accessor :mutable
20
+
21
+ visits :visit_var_decl
22
+
23
+ def initialize(name, initializer, type = nil, mutable: false)
24
+ super()
25
+ @name = name
26
+ @initializer = initializer
27
+ @type = type
28
+ @mutable = mutable
29
+ end
30
+ end
31
+
32
+ class VarRef < Node
33
+ attr_reader :name
34
+
35
+ visits :visit_var_ref
36
+
37
+ def initialize(name, type = nil)
38
+ super()
39
+ @name = name
40
+ @type = type
41
+ end
42
+ end
43
+
44
+ class Literal < Node
45
+ attr_reader :value
46
+
47
+ visits :visit_literal
48
+
49
+ def initialize(value, type = nil)
50
+ super()
51
+ @value = value
52
+ @type = type || (value.is_a?(Float) ? :float : :int)
53
+ end
54
+ end
55
+
56
+ class BoolLiteral < Node
57
+ attr_reader :value
58
+
59
+ visits :visit_bool_literal
60
+
61
+ def initialize(value)
62
+ super()
63
+ @value = value
64
+ @type = :bool
65
+ end
66
+ end
67
+
68
+ class BinaryOp < Node
69
+ attr_reader :operator, :left, :right
70
+
71
+ visits :visit_binary_op
72
+
73
+ def initialize(operator, left, right, type = nil)
74
+ super()
75
+ @operator = operator
76
+ @left = left
77
+ @right = right
78
+ @type = type
79
+ end
80
+ end
81
+
82
+ class UnaryOp < Node
83
+ attr_reader :operator, :operand
84
+
85
+ visits :visit_unary_op
86
+
87
+ def initialize(operator, operand, type = nil)
88
+ super()
89
+ @operator = operator
90
+ @operand = operand
91
+ @type = type
92
+ end
93
+ end
94
+
95
+ class FuncCall < Node
96
+ attr_reader :name, :args, :receiver
97
+ attr_accessor :expected_arg_types
98
+
99
+ visits :visit_func_call
100
+
101
+ def initialize(name, args = [], receiver = nil, type = nil)
102
+ super()
103
+ @name = name
104
+ @args = args
105
+ @receiver = receiver
106
+ @expected_arg_types = []
107
+ @type = type
108
+ end
109
+ end
110
+
111
+ class FieldAccess < Node
112
+ attr_reader :receiver, :field
113
+
114
+ visits :visit_field_access
115
+
116
+ def initialize(receiver, field, type = nil)
117
+ super()
118
+ @receiver = receiver
119
+ @field = field
120
+ @type = type
121
+ end
122
+ end
123
+
124
+ class Swizzle < Node
125
+ attr_reader :receiver, :components
126
+
127
+ visits :visit_swizzle
128
+
129
+ def initialize(receiver, components, type = nil)
130
+ super()
131
+ @receiver = receiver
132
+ @components = components
133
+ @type = type
134
+ end
135
+ end
136
+
137
+ class Ternary < Node
138
+ attr_reader :condition, :then_expr, :else_expr
139
+
140
+ visits :visit_ternary
141
+
142
+ def initialize(condition, then_expr, else_expr, type = nil)
143
+ super()
144
+ @condition = condition
145
+ @then_expr = then_expr
146
+ @else_expr = else_expr
147
+ @type = type
148
+ end
149
+ end
150
+
151
+ class Constant < Node
152
+ attr_reader :name
153
+
154
+ visits :visit_constant
155
+
156
+ def initialize(name, type = :float)
157
+ super()
158
+ @name = name
159
+ @type = type
160
+ end
161
+ end
162
+
163
+ class Parenthesized < Node
164
+ attr_reader :expression
165
+
166
+ visits :visit_parenthesized
167
+
168
+ def initialize(expression)
169
+ super()
170
+ @expression = expression
171
+ @type = expression&.type
172
+ end
173
+ end
174
+
175
+ class ArrayLiteral < Node
176
+ attr_reader :elements
177
+
178
+ visits :visit_array_literal
179
+
180
+ def initialize(elements, type = nil)
181
+ super()
182
+ @elements = elements
183
+ @type = type
184
+ end
185
+ end
186
+
187
+ class ArrayIndex < Node
188
+ attr_reader :array, :index
189
+
190
+ visits :visit_array_index
191
+
192
+ def initialize(array, index, type = nil)
193
+ super()
194
+ @array = array
195
+ @index = index
196
+ @type = type
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RLSL
4
+ module Prism
5
+ module IR
6
+ class Node
7
+ attr_accessor :type, :location
8
+
9
+ def self.visits(method_name)
10
+ define_method(:accept) do |visitor|
11
+ visitor.public_send(method_name, self)
12
+ end
13
+ end
14
+
15
+ def accept(_visitor)
16
+ raise NotImplementedError
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,373 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RLSL
4
- module Prism
5
- module IR
6
- class Node
7
- attr_accessor :type
8
-
9
- def accept(visitor)
10
- raise NotImplementedError
11
- end
12
- end
13
-
14
- class Block < Node
15
- attr_reader :statements
16
-
17
- def initialize(statements = [])
18
- super()
19
- @statements = statements
20
- end
21
-
22
- def accept(visitor)
23
- visitor.visit_block(self)
24
- end
25
- end
26
-
27
- class VarDecl < Node
28
- attr_reader :name, :initializer
29
-
30
- def initialize(name, initializer, type = nil)
31
- super()
32
- @name = name
33
- @initializer = initializer
34
- @type = type
35
- end
36
-
37
- def accept(visitor)
38
- visitor.visit_var_decl(self)
39
- end
40
- end
41
-
42
- class VarRef < Node
43
- attr_reader :name
44
-
45
- def initialize(name, type = nil)
46
- super()
47
- @name = name
48
- @type = type
49
- end
50
-
51
- def accept(visitor)
52
- visitor.visit_var_ref(self)
53
- end
54
- end
55
-
56
- class Literal < Node
57
- attr_reader :value
58
-
59
- def initialize(value, type = nil)
60
- super()
61
- @value = value
62
- @type = type || (value.is_a?(Float) ? :float : :int)
63
- end
64
-
65
- def accept(visitor)
66
- visitor.visit_literal(self)
67
- end
68
- end
69
-
70
- class BoolLiteral < Node
71
- attr_reader :value
72
-
73
- def initialize(value)
74
- super()
75
- @value = value
76
- @type = :bool
77
- end
78
-
79
- def accept(visitor)
80
- visitor.visit_bool_literal(self)
81
- end
82
- end
83
-
84
- class BinaryOp < Node
85
- attr_reader :operator, :left, :right
86
-
87
- def initialize(operator, left, right, type = nil)
88
- super()
89
- @operator = operator
90
- @left = left
91
- @right = right
92
- @type = type
93
- end
94
-
95
- def accept(visitor)
96
- visitor.visit_binary_op(self)
97
- end
98
- end
99
-
100
- class UnaryOp < Node
101
- attr_reader :operator, :operand
102
-
103
- def initialize(operator, operand, type = nil)
104
- super()
105
- @operator = operator
106
- @operand = operand
107
- @type = type
108
- end
109
-
110
- def accept(visitor)
111
- visitor.visit_unary_op(self)
112
- end
113
- end
114
-
115
- class FuncCall < Node
116
- attr_reader :name, :args, :receiver
117
-
118
- def initialize(name, args = [], receiver = nil, type = nil)
119
- super()
120
- @name = name
121
- @args = args
122
- @receiver = receiver
123
- @type = type
124
- end
125
-
126
- def accept(visitor)
127
- visitor.visit_func_call(self)
128
- end
129
- end
130
-
131
- class FieldAccess < Node
132
- attr_reader :receiver, :field
133
-
134
- def initialize(receiver, field, type = nil)
135
- super()
136
- @receiver = receiver
137
- @field = field
138
- @type = type
139
- end
140
-
141
- def accept(visitor)
142
- visitor.visit_field_access(self)
143
- end
144
- end
145
-
146
- class Swizzle < Node
147
- attr_reader :receiver, :components
148
-
149
- def initialize(receiver, components, type = nil)
150
- super()
151
- @receiver = receiver
152
- @components = components
153
- @type = type
154
- end
155
-
156
- def accept(visitor)
157
- visitor.visit_swizzle(self)
158
- end
159
- end
160
-
161
- class IfStatement < Node
162
- attr_reader :condition, :then_branch, :else_branch
163
-
164
- def initialize(condition, then_branch, else_branch = nil, type = nil)
165
- super()
166
- @condition = condition
167
- @then_branch = then_branch
168
- @else_branch = else_branch
169
- @type = type
170
- end
171
-
172
- def accept(visitor)
173
- visitor.visit_if_statement(self)
174
- end
175
- end
176
-
177
- class Return < Node
178
- attr_reader :expression
179
-
180
- def initialize(expression)
181
- super()
182
- @expression = expression
183
- @type = expression&.type
184
- end
185
-
186
- def accept(visitor)
187
- visitor.visit_return(self)
188
- end
189
- end
190
-
191
- class Assignment < Node
192
- attr_reader :target, :value
193
-
194
- def initialize(target, value)
195
- super()
196
- @target = target
197
- @value = value
198
- @type = value&.type
199
- end
200
-
201
- def accept(visitor)
202
- visitor.visit_assignment(self)
203
- end
204
- end
205
-
206
- class ForLoop < Node
207
- attr_reader :variable, :range_start, :range_end, :body
208
-
209
- def initialize(variable, range_start, range_end, body)
210
- super()
211
- @variable = variable
212
- @range_start = range_start
213
- @range_end = range_end
214
- @body = body
215
- @type = nil
216
- end
217
-
218
- def accept(visitor)
219
- visitor.visit_for_loop(self)
220
- end
221
- end
222
-
223
- class WhileLoop < Node
224
- attr_reader :condition, :body
225
-
226
- def initialize(condition, body)
227
- super()
228
- @condition = condition
229
- @body = body
230
- @type = nil
231
- end
232
-
233
- def accept(visitor)
234
- visitor.visit_while_loop(self)
235
- end
236
- end
237
-
238
- class Break < Node
239
- def initialize
240
- super()
241
- @type = nil
242
- end
243
-
244
- def accept(visitor)
245
- visitor.visit_break(self)
246
- end
247
- end
248
-
249
- class Constant < Node
250
- attr_reader :name
251
-
252
- def initialize(name, type = :float)
253
- super()
254
- @name = name
255
- @type = type
256
- end
257
-
258
- def accept(visitor)
259
- visitor.visit_constant(self)
260
- end
261
- end
262
-
263
- class Parenthesized < Node
264
- attr_reader :expression
265
-
266
- def initialize(expression)
267
- super()
268
- @expression = expression
269
- @type = expression&.type
270
- end
271
-
272
- def accept(visitor)
273
- visitor.visit_parenthesized(self)
274
- end
275
- end
276
-
277
- class ArrayLiteral < Node
278
- attr_reader :elements
279
-
280
- def initialize(elements, type = nil)
281
- super()
282
- @elements = elements
283
- @type = type
284
- end
285
-
286
- def accept(visitor)
287
- visitor.visit_array_literal(self)
288
- end
289
- end
290
-
291
- class ArrayIndex < Node
292
- attr_reader :array, :index
293
-
294
- def initialize(array, index, type = nil)
295
- super()
296
- @array = array
297
- @index = index
298
- @type = type
299
- end
300
-
301
- def accept(visitor)
302
- visitor.visit_array_index(self)
303
- end
304
- end
305
-
306
- class GlobalDecl < Node
307
- attr_reader :name, :initializer
308
- attr_accessor :is_const, :is_static, :array_size, :element_type
309
-
310
- def initialize(name, initializer, type: nil, is_const: false, is_static: true, array_size: nil, element_type: nil)
311
- super()
312
- @name = name
313
- @initializer = initializer
314
- @type = type
315
- @is_const = is_const
316
- @is_static = is_static
317
- @array_size = array_size
318
- @element_type = element_type
319
- end
320
-
321
- def accept(visitor)
322
- visitor.visit_global_decl(self)
323
- end
324
- end
325
-
326
- class FunctionDefinition < Node
327
- attr_reader :name, :params, :body
328
- attr_accessor :return_type, :param_types
329
-
330
- def initialize(name, params, body, return_type: nil, param_types: {})
331
- super()
332
- @name = name
333
- @params = params
334
- @body = body
335
- @return_type = return_type
336
- @param_types = param_types
337
- @type = return_type
338
- end
339
-
340
- def accept(visitor)
341
- visitor.visit_function_definition(self)
342
- end
343
- end
344
-
345
- class MultipleAssignment < Node
346
- attr_reader :targets, :value
347
-
348
- def initialize(targets, value)
349
- super()
350
- @targets = targets
351
- @value = value
352
- @type = nil
353
- end
354
-
355
- def accept(visitor)
356
- visitor.visit_multiple_assignment(self)
357
- end
358
- end
359
-
360
- class TupleType
361
- attr_reader :types
362
-
363
- def initialize(*types)
364
- @types = types
365
- end
366
-
367
- def to_sym
368
- :"tuple_#{types.map(&:to_s).join('_')}"
369
- end
370
- end
371
- end
372
- end
373
- end
3
+ require_relative "node"
4
+ require_relative "expressions"
5
+ require_relative "control_flow"
6
+ require_relative "definitions"
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RLSL
4
+ module Prism
5
+ module IR
6
+ module Traversal
7
+ module_function
8
+
9
+ def each(node, &block)
10
+ return enum_for(:each, node) unless block_given?
11
+ return if node.nil?
12
+
13
+ stack = [node]
14
+ until stack.empty?
15
+ current = stack.pop
16
+ yield current
17
+ stack.concat(child_nodes(current).reverse)
18
+ end
19
+ end
20
+
21
+ def child_nodes(node)
22
+ case node
23
+ when Block
24
+ node.statements
25
+ when VarDecl
26
+ [node.initializer]
27
+ when BinaryOp
28
+ [node.left, node.right]
29
+ when UnaryOp
30
+ [node.operand]
31
+ when FuncCall
32
+ [node.receiver, *node.args]
33
+ when FieldAccess, Swizzle
34
+ [node.receiver]
35
+ when IfStatement
36
+ [node.condition, node.then_branch, node.else_branch]
37
+ when Ternary
38
+ [node.condition, node.then_expr, node.else_expr]
39
+ when Return
40
+ [node.expression]
41
+ when Assignment
42
+ [node.target, node.value]
43
+ when ForLoop
44
+ [node.range_start, node.range_end, node.body]
45
+ when WhileLoop
46
+ [node.condition, node.body]
47
+ when Parenthesized
48
+ [node.expression]
49
+ when ArrayLiteral
50
+ node.elements
51
+ when ArrayIndex
52
+ [node.array, node.index]
53
+ when GlobalDecl
54
+ [node.initializer]
55
+ when FunctionDefinition
56
+ [node.body]
57
+ when MultipleAssignment
58
+ [*node.targets, node.value]
59
+ else
60
+ []
61
+ end.compact
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+
5
+ require_relative "ir/traversal"
6
+
7
+ module RLSL
8
+ module Prism
9
+ class MutationAnalyzer
10
+ def analyze(node)
11
+ assigned_names = IR::Traversal.each(node).filter_map do |current|
12
+ case current
13
+ when IR::Assignment
14
+ current.target.name if current.target.is_a?(IR::VarRef)
15
+ when IR::MultipleAssignment
16
+ current.targets.select { |target| target.is_a?(IR::VarRef) }.map(&:name)
17
+ end
18
+ end.flatten.to_set
19
+
20
+ IR::Traversal.each(node) do |current|
21
+ next unless current.is_a?(IR::VarDecl)
22
+
23
+ current.mutable = assigned_names.include?(current.name)
24
+ end
25
+
26
+ node
27
+ end
28
+ end
29
+ end
30
+ end