rlsl 0.1.1 → 1.0.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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -1
  3. data/README.md +2 -0
  4. data/lib/rlsl/base_translator/call_parser.rb +68 -0
  5. data/lib/rlsl/base_translator/code_rewriter.rb +107 -0
  6. data/lib/rlsl/base_translator/code_scanner.rb +102 -0
  7. data/lib/rlsl/base_translator.rb +159 -63
  8. data/lib/rlsl/code_generator/math_prelude.rb +79 -0
  9. data/lib/rlsl/code_generator/ruby_wrapper_generator.rb +97 -0
  10. data/lib/rlsl/code_generator/shader_function_generator.rb +19 -0
  11. data/lib/rlsl/code_generator/template_context.rb +41 -0
  12. data/lib/rlsl/code_generator/uniform_struct_generator.rb +29 -0
  13. data/lib/rlsl/code_generator.rb +26 -201
  14. data/lib/rlsl/compiled_shader.rb +4 -12
  15. data/lib/rlsl/function_context.rb +31 -14
  16. data/lib/rlsl/glsl/translator.rb +19 -38
  17. data/lib/rlsl/msl/shader.rb +8 -38
  18. data/lib/rlsl/msl/translator.rb +19 -36
  19. data/lib/rlsl/msl/uniform_buffer_packer.rb +68 -0
  20. data/lib/rlsl/prism/ast_visitor/control_flow_visiting.rb +96 -0
  21. data/lib/rlsl/prism/ast_visitor/definition_visiting.rb +79 -0
  22. data/lib/rlsl/prism/ast_visitor/expression_visiting.rb +168 -0
  23. data/lib/rlsl/prism/ast_visitor/scope_context.rb +44 -0
  24. data/lib/rlsl/prism/ast_visitor/visitor_registry.rb +21 -0
  25. data/lib/rlsl/prism/ast_visitor.rb +54 -298
  26. data/lib/rlsl/prism/builtins/function_registry.rb +114 -0
  27. data/lib/rlsl/prism/builtins/operator_rules.rb +99 -0
  28. data/lib/rlsl/prism/builtins/swizzle_rules.rb +38 -0
  29. data/lib/rlsl/prism/builtins.rb +31 -148
  30. data/lib/rlsl/prism/compilation_unit.rb +7 -0
  31. data/lib/rlsl/prism/emitters/base_emitter/control_flow_emission.rb +83 -0
  32. data/lib/rlsl/prism/emitters/base_emitter/definition_emission.rb +104 -0
  33. data/lib/rlsl/prism/emitters/base_emitter/expression_emission.rb +92 -0
  34. data/lib/rlsl/prism/emitters/base_emitter/statement_emission.rb +89 -0
  35. data/lib/rlsl/prism/emitters/base_emitter.rb +68 -423
  36. data/lib/rlsl/prism/emitters/c_emitter.rb +78 -121
  37. data/lib/rlsl/prism/emitters/glsl_emitter.rb +30 -65
  38. data/lib/rlsl/prism/emitters/msl_emitter.rb +35 -62
  39. data/lib/rlsl/prism/emitters/target_emitter.rb +77 -0
  40. data/lib/rlsl/prism/emitters/target_profile.rb +34 -0
  41. data/lib/rlsl/prism/emitters/wgsl_emitter.rb +65 -61
  42. data/lib/rlsl/prism/ir/control_flow.rb +83 -0
  43. data/lib/rlsl/prism/ir/definitions.rb +67 -0
  44. data/lib/rlsl/prism/ir/expressions.rb +197 -0
  45. data/lib/rlsl/prism/ir/node.rb +21 -0
  46. data/lib/rlsl/prism/ir/nodes.rb +4 -371
  47. data/lib/rlsl/prism/ir/traversal.rb +62 -0
  48. data/lib/rlsl/prism/source_extractor/block_locator.rb +52 -0
  49. data/lib/rlsl/prism/source_extractor.rb +14 -133
  50. data/lib/rlsl/prism/source_unit/parser.rb +78 -0
  51. data/lib/rlsl/prism/source_unit.rb +42 -0
  52. data/lib/rlsl/prism/target_capability_validator.rb +85 -0
  53. data/lib/rlsl/prism/transpiler.rb +63 -60
  54. data/lib/rlsl/prism/type_inference/call_type_resolver.rb +35 -0
  55. data/lib/rlsl/prism/type_inference/call_validator.rb +71 -0
  56. data/lib/rlsl/prism/type_inference/collection_type_resolver.rb +80 -0
  57. data/lib/rlsl/prism/type_inference/control_flow_inferer.rb +66 -0
  58. data/lib/rlsl/prism/type_inference/definition_inferer.rb +41 -0
  59. data/lib/rlsl/prism/type_inference/expression_inferer.rb +92 -0
  60. data/lib/rlsl/prism/type_inference/field_type_resolver.rb +17 -0
  61. data/lib/rlsl/prism/type_inference/inferer_registry.rb +38 -0
  62. data/lib/rlsl/prism/type_inference/scope_stack.rb +47 -0
  63. data/lib/rlsl/prism/type_inference/type_environment.rb +112 -0
  64. data/lib/rlsl/prism/type_inference/type_shapes.rb +33 -0
  65. data/lib/rlsl/prism/type_inference.rb +114 -248
  66. data/lib/rlsl/runtime_shader.rb +47 -0
  67. data/lib/rlsl/shader_builder/build_service.rb +77 -0
  68. data/lib/rlsl/shader_builder/native_extension_compiler.rb +71 -0
  69. data/lib/rlsl/shader_builder/shader_definition.rb +68 -0
  70. data/lib/rlsl/shader_builder/source_resolver.rb +91 -0
  71. data/lib/rlsl/shader_builder.rb +22 -113
  72. data/lib/rlsl/types/catalog.rb +47 -0
  73. data/lib/rlsl/types/target_resolver.rb +15 -0
  74. data/lib/rlsl/types/type_spec.rb +167 -0
  75. data/lib/rlsl/types/value_normalizer.rb +81 -0
  76. data/lib/rlsl/types.rb +11 -29
  77. data/lib/rlsl/uniform_context.rb +6 -12
  78. data/lib/rlsl/version.rb +1 -1
  79. data/lib/rlsl/wgsl/translator.rb +23 -39
  80. data/lib/rlsl.rb +14 -12
  81. metadata +55 -2
@@ -3,72 +3,46 @@
3
3
  module RLSL
4
4
  module Prism
5
5
  module Emitters
6
- class WGSLEmitter < BaseEmitter
7
- TYPE_MAP = {
8
- float: "f32",
9
- int: "i32",
10
- bool: "bool",
11
- vec2: "vec2<f32>",
12
- vec3: "vec3<f32>",
13
- vec4: "vec4<f32>",
14
- mat2: "mat2x2<f32>",
15
- mat3: "mat3x3<f32>",
16
- mat4: "mat4x4<f32>",
17
- sampler2D: "texture_2d<f32>"
18
- }.freeze
19
-
20
- VECTOR_CONSTRUCTORS = {
21
- vec2: "vec2<f32>",
22
- vec3: "vec3<f32>",
23
- vec4: "vec4<f32>"
24
- }.freeze
25
-
26
- MATRIX_CONSTRUCTORS = {
27
- mat2: "mat2x2<f32>",
28
- mat3: "mat3x3<f32>",
29
- mat4: "mat4x4<f32>"
30
- }.freeze
31
-
32
- TEXTURE_FUNCTIONS = {
33
- texture2D: "textureSample",
34
- texture: "textureSample",
35
- textureLod: "textureSampleLevel"
36
- }.freeze
6
+ class WGSLEmitter < TargetEmitter
7
+ PROFILE = TargetProfile.new(
8
+ type_map: {
9
+ float: "f32",
10
+ int: "i32",
11
+ bool: "bool",
12
+ vec2: "vec2<f32>",
13
+ vec3: "vec3<f32>",
14
+ vec4: "vec4<f32>",
15
+ mat2: "mat2x2<f32>",
16
+ mat3: "mat3x3<f32>",
17
+ mat4: "mat4x4<f32>",
18
+ sampler2D: "texture_2d<f32>"
19
+ },
20
+ vector_constructors: {
21
+ vec2: "vec2<f32>",
22
+ vec3: "vec3<f32>",
23
+ vec4: "vec4<f32>"
24
+ },
25
+ matrix_constructors: {
26
+ mat2: "mat2x2<f32>",
27
+ mat3: "mat3x3<f32>",
28
+ mat4: "mat4x4<f32>"
29
+ },
30
+ texture_functions: {
31
+ texture2D: "textureSample",
32
+ texture: "textureSample",
33
+ textureLod: "textureSampleLevel"
34
+ },
35
+ default_type_name: "f32"
36
+ ).freeze
37
37
 
38
38
  protected
39
39
 
40
- def type_name(type)
41
- TYPE_MAP[type&.to_sym] || "f32"
42
- end
43
-
44
40
  def emit_var_decl(node)
45
41
  type = type_name(node.type || :float)
46
42
  value = emit(node.initializer)
47
43
  "let #{node.name}: #{type} = #{value}"
48
44
  end
49
45
 
50
- def emit_func_call(node)
51
- name = node.name.to_sym
52
-
53
- if VECTOR_CONSTRUCTORS.key?(name)
54
- args = node.args.map { |arg| emit(arg) }.join(", ")
55
- return "#{VECTOR_CONSTRUCTORS[name]}(#{args})"
56
- end
57
-
58
- if MATRIX_CONSTRUCTORS.key?(name)
59
- args = node.args.map { |arg| emit(arg) }.join(", ")
60
- return "#{MATRIX_CONSTRUCTORS[name]}(#{args})"
61
- end
62
-
63
- if TEXTURE_FUNCTIONS.key?(name)
64
- args = node.args.map { |arg| emit(arg) }.join(", ")
65
- return "#{TEXTURE_FUNCTIONS[name]}(#{args})"
66
- end
67
-
68
- args = node.args.map { |arg| emit(arg) }.join(", ")
69
- "#{name}(#{args})"
70
- end
71
-
72
46
  def emit_for_loop(node)
73
47
  var = node.variable
74
48
  start_val = emit(node.range_start)
@@ -78,10 +52,40 @@ module RLSL
78
52
  "for (var #{var}: i32 = #{start_val}; #{var} < #{end_val}; #{var}++) {\n#{body}#{indent}}"
79
53
  end
80
54
 
81
- def emit_binary_op(node)
82
- left = emit_with_precedence(node.left, node.operator)
83
- right = emit_with_precedence(node.right, node.operator)
84
- "#{left} #{node.operator} #{right}"
55
+ def emit_ternary(node)
56
+ condition = emit(node.condition)
57
+ then_expr = emit(node.then_expr)
58
+ else_expr = emit(node.else_expr)
59
+ "select(#{else_expr}, #{then_expr}, #{condition})"
60
+ end
61
+
62
+ def emit_function_definition(node)
63
+ name = node.name
64
+ params = node.params.map do |param|
65
+ param_type = type_name(node.param_types[param] || :float)
66
+ "#{param}: #{param_type}"
67
+ end.join(", ")
68
+
69
+ if node.return_type.is_a?(Array)
70
+ @current_return_struct_name = "#{name}_result"
71
+ struct_def = emit_result_struct(name, node.return_type)
72
+ body = emit_indented_block(node.body, needs_return: true)
73
+ @current_return_struct_name = nil
74
+
75
+ "#{struct_def}fn #{name}(#{params}) -> #{name}_result {\n#{body}\n#{indent}}\n"
76
+ else
77
+ return_type = type_name(node.return_type || :float)
78
+ body = emit_indented_block(node.body, needs_return: true)
79
+
80
+ "fn #{name}(#{params}) -> #{return_type} {\n#{body}\n#{indent}}\n"
81
+ end
82
+ end
83
+
84
+ def emit_result_struct(func_name, types)
85
+ fields = types.each_with_index.map do |type, index|
86
+ "#{indent}v#{index}: #{type_name(type)},"
87
+ end.join("\n")
88
+ "struct #{func_name}_result {\n#{fields}\n};\n"
85
89
  end
86
90
  end
87
91
  end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RLSL
4
+ module Prism
5
+ module IR
6
+ class IfStatement < Node
7
+ attr_reader :condition, :then_branch, :else_branch
8
+
9
+ visits :visit_if_statement
10
+
11
+ def initialize(condition, then_branch, else_branch = nil, type = nil)
12
+ super()
13
+ @condition = condition
14
+ @then_branch = then_branch
15
+ @else_branch = else_branch
16
+ @type = type
17
+ end
18
+ end
19
+
20
+ class Return < Node
21
+ attr_reader :expression
22
+
23
+ visits :visit_return
24
+
25
+ def initialize(expression)
26
+ super()
27
+ @expression = expression
28
+ @type = expression&.type
29
+ end
30
+ end
31
+
32
+ class Assignment < Node
33
+ attr_reader :target, :value
34
+
35
+ visits :visit_assignment
36
+
37
+ def initialize(target, value)
38
+ super()
39
+ @target = target
40
+ @value = value
41
+ @type = value&.type
42
+ end
43
+ end
44
+
45
+ class ForLoop < Node
46
+ attr_reader :variable, :range_start, :range_end, :body
47
+
48
+ visits :visit_for_loop
49
+
50
+ def initialize(variable, range_start, range_end, body)
51
+ super()
52
+ @variable = variable
53
+ @range_start = range_start
54
+ @range_end = range_end
55
+ @body = body
56
+ @type = nil
57
+ end
58
+ end
59
+
60
+ class WhileLoop < Node
61
+ attr_reader :condition, :body
62
+
63
+ visits :visit_while_loop
64
+
65
+ def initialize(condition, body)
66
+ super()
67
+ @condition = condition
68
+ @body = body
69
+ @type = nil
70
+ end
71
+ end
72
+
73
+ class Break < Node
74
+ visits :visit_break
75
+
76
+ def initialize
77
+ super()
78
+ @type = nil
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RLSL
4
+ module Prism
5
+ module IR
6
+ class GlobalDecl < Node
7
+ attr_reader :name, :initializer
8
+ attr_accessor :is_const, :is_static, :array_size, :element_type
9
+
10
+ visits :visit_global_decl
11
+
12
+ def initialize(name, initializer, type: nil, is_const: false, is_static: true, array_size: nil, element_type: nil)
13
+ super()
14
+ @name = name
15
+ @initializer = initializer
16
+ @type = type
17
+ @is_const = is_const
18
+ @is_static = is_static
19
+ @array_size = array_size
20
+ @element_type = element_type
21
+ end
22
+ end
23
+
24
+ class FunctionDefinition < Node
25
+ attr_reader :name, :params, :body
26
+ attr_accessor :return_type, :param_types
27
+
28
+ visits :visit_function_definition
29
+
30
+ def initialize(name, params, body, return_type: nil, param_types: {})
31
+ super()
32
+ @name = name
33
+ @params = params
34
+ @body = body
35
+ @return_type = return_type
36
+ @param_types = param_types
37
+ @type = return_type
38
+ end
39
+ end
40
+
41
+ class MultipleAssignment < Node
42
+ attr_reader :targets, :value
43
+
44
+ visits :visit_multiple_assignment
45
+
46
+ def initialize(targets, value)
47
+ super()
48
+ @targets = targets
49
+ @value = value
50
+ @type = nil
51
+ end
52
+ end
53
+
54
+ class TupleType
55
+ attr_reader :types
56
+
57
+ def initialize(*types)
58
+ @types = types
59
+ end
60
+
61
+ def to_sym
62
+ :"tuple_#{types.map(&:to_s).join('_')}"
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,197 @@
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
+
20
+ visits :visit_var_decl
21
+
22
+ def initialize(name, initializer, type = nil)
23
+ super()
24
+ @name = name
25
+ @initializer = initializer
26
+ @type = type
27
+ end
28
+ end
29
+
30
+ class VarRef < Node
31
+ attr_reader :name
32
+
33
+ visits :visit_var_ref
34
+
35
+ def initialize(name, type = nil)
36
+ super()
37
+ @name = name
38
+ @type = type
39
+ end
40
+ end
41
+
42
+ class Literal < Node
43
+ attr_reader :value
44
+
45
+ visits :visit_literal
46
+
47
+ def initialize(value, type = nil)
48
+ super()
49
+ @value = value
50
+ @type = type || (value.is_a?(Float) ? :float : :int)
51
+ end
52
+ end
53
+
54
+ class BoolLiteral < Node
55
+ attr_reader :value
56
+
57
+ visits :visit_bool_literal
58
+
59
+ def initialize(value)
60
+ super()
61
+ @value = value
62
+ @type = :bool
63
+ end
64
+ end
65
+
66
+ class BinaryOp < Node
67
+ attr_reader :operator, :left, :right
68
+
69
+ visits :visit_binary_op
70
+
71
+ def initialize(operator, left, right, type = nil)
72
+ super()
73
+ @operator = operator
74
+ @left = left
75
+ @right = right
76
+ @type = type
77
+ end
78
+ end
79
+
80
+ class UnaryOp < Node
81
+ attr_reader :operator, :operand
82
+
83
+ visits :visit_unary_op
84
+
85
+ def initialize(operator, operand, type = nil)
86
+ super()
87
+ @operator = operator
88
+ @operand = operand
89
+ @type = type
90
+ end
91
+ end
92
+
93
+ class FuncCall < Node
94
+ attr_reader :name, :args, :receiver
95
+
96
+ visits :visit_func_call
97
+
98
+ def initialize(name, args = [], receiver = nil, type = nil)
99
+ super()
100
+ @name = name
101
+ @args = args
102
+ @receiver = receiver
103
+ @type = type
104
+ end
105
+ end
106
+
107
+ class FieldAccess < Node
108
+ attr_reader :receiver, :field
109
+
110
+ visits :visit_field_access
111
+
112
+ def initialize(receiver, field, type = nil)
113
+ super()
114
+ @receiver = receiver
115
+ @field = field
116
+ @type = type
117
+ end
118
+ end
119
+
120
+ class Swizzle < Node
121
+ attr_reader :receiver, :components
122
+
123
+ visits :visit_swizzle
124
+
125
+ def initialize(receiver, components, type = nil)
126
+ super()
127
+ @receiver = receiver
128
+ @components = components
129
+ @type = type
130
+ end
131
+ end
132
+
133
+ class Ternary < Node
134
+ attr_reader :condition, :then_expr, :else_expr
135
+
136
+ visits :visit_ternary
137
+
138
+ def initialize(condition, then_expr, else_expr, type = nil)
139
+ super()
140
+ @condition = condition
141
+ @then_expr = then_expr
142
+ @else_expr = else_expr
143
+ @type = type
144
+ end
145
+ end
146
+
147
+ class Constant < Node
148
+ attr_reader :name
149
+
150
+ visits :visit_constant
151
+
152
+ def initialize(name, type = :float)
153
+ super()
154
+ @name = name
155
+ @type = type
156
+ end
157
+ end
158
+
159
+ class Parenthesized < Node
160
+ attr_reader :expression
161
+
162
+ visits :visit_parenthesized
163
+
164
+ def initialize(expression)
165
+ super()
166
+ @expression = expression
167
+ @type = expression&.type
168
+ end
169
+ end
170
+
171
+ class ArrayLiteral < Node
172
+ attr_reader :elements
173
+
174
+ visits :visit_array_literal
175
+
176
+ def initialize(elements, type = nil)
177
+ super()
178
+ @elements = elements
179
+ @type = type
180
+ end
181
+ end
182
+
183
+ class ArrayIndex < Node
184
+ attr_reader :array, :index
185
+
186
+ visits :visit_array_index
187
+
188
+ def initialize(array, index, type = nil)
189
+ super()
190
+ @array = array
191
+ @index = index
192
+ @type = type
193
+ end
194
+ end
195
+ end
196
+ end
197
+ 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
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