rlsl 0.1.0 → 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 +14 -1
  3. data/README.md +18 -1
  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 -16
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RLSL
4
+ module Prism
5
+ class ExpressionInferer
6
+ def initialize(infer:, lookup:, call_type_resolver:, field_type_resolver:, collection_type_resolver:)
7
+ @infer = infer
8
+ @lookup = lookup
9
+ @call_type_resolver = call_type_resolver
10
+ @field_type_resolver = field_type_resolver
11
+ @collection_type_resolver = collection_type_resolver
12
+ end
13
+
14
+ def infer_var_ref(node)
15
+ node.type ||= @lookup.call(node.name)
16
+ node
17
+ end
18
+
19
+ def infer_literal(node)
20
+ node
21
+ end
22
+
23
+ def infer_bool_literal(node)
24
+ node.type = :bool
25
+ node
26
+ end
27
+
28
+ def infer_binary_op(node)
29
+ @infer.call(node.left)
30
+ @infer.call(node.right)
31
+
32
+ node.type = Builtins.binary_op_result_type(
33
+ node.operator,
34
+ node.left.type,
35
+ node.right.type
36
+ )
37
+ node
38
+ end
39
+
40
+ def infer_unary_op(node)
41
+ @infer.call(node.operand)
42
+
43
+ case node.operator.to_s
44
+ when "-"
45
+ node.type = node.operand.type
46
+ when "!"
47
+ node.type = :bool
48
+ end
49
+ node
50
+ end
51
+
52
+ def infer_func_call(node)
53
+ node.args.each { |arg| @infer.call(arg) }
54
+ @infer.call(node.receiver) if node.receiver
55
+
56
+ node.type = @call_type_resolver.resolve(node)
57
+ node
58
+ end
59
+
60
+ def infer_field_access(node)
61
+ @infer.call(node.receiver)
62
+ node.type = @field_type_resolver.resolve(node)
63
+ node
64
+ end
65
+
66
+ def infer_swizzle(node)
67
+ @infer.call(node.receiver)
68
+ node.type = Builtins.swizzle_type(node.components)
69
+ node
70
+ end
71
+
72
+ def infer_parenthesized(node)
73
+ @infer.call(node.expression)
74
+ node.type = node.expression.type
75
+ node
76
+ end
77
+
78
+ def infer_array_literal(node)
79
+ node.elements.each { |element| @infer.call(element) }
80
+ node.type = @collection_type_resolver.resolve_array_literal(node)
81
+ node
82
+ end
83
+
84
+ def infer_array_index(node)
85
+ @infer.call(node.array)
86
+ @infer.call(node.index)
87
+ node.type = @collection_type_resolver.resolve_array_index(node)
88
+ node
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RLSL
4
+ module Prism
5
+ class FieldTypeResolver
6
+ def initialize(uniforms:)
7
+ @uniforms = uniforms
8
+ end
9
+
10
+ def resolve(node)
11
+ return :float if Builtins.single_component_field?(node.field)
12
+
13
+ @uniforms[node.field.to_sym] || :float
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RLSL
4
+ module Prism
5
+ class InfererRegistry
6
+ def initialize
7
+ @handlers = {}
8
+ end
9
+
10
+ def register(node_class, target = nil, method_name = nil, &block)
11
+ @handlers[node_class] = block || build_handler(target, method_name)
12
+ end
13
+
14
+ def register_methods(target, mapping)
15
+ mapping.each do |node_class, method_name|
16
+ register(node_class, target, method_name)
17
+ end
18
+ end
19
+
20
+ def infer(node, **options)
21
+ handler = @handlers[node.class]
22
+ return unless handler
23
+
24
+ handler.call(node, **options)
25
+ end
26
+
27
+ private
28
+
29
+ def build_handler(target, method_name)
30
+ lambda do |node, **options|
31
+ return target.send(method_name, node) if options.empty?
32
+
33
+ target.send(method_name, node, **options)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RLSL
4
+ module Prism
5
+ class ScopeStack
6
+ def initialize
7
+ @scopes = [{}]
8
+ end
9
+
10
+ def push(initial_scope = {})
11
+ @scopes << normalize(initial_scope)
12
+ end
13
+
14
+ def pop
15
+ raise "Cannot pop the global scope" if @scopes.length == 1
16
+
17
+ @scopes.pop
18
+ end
19
+
20
+ def register(name, type)
21
+ @scopes.last[name.to_sym] = type
22
+ end
23
+
24
+ def lookup(name)
25
+ @scopes.reverse_each do |scope|
26
+ return scope[name.to_sym] if scope.key?(name.to_sym)
27
+ end
28
+
29
+ nil
30
+ end
31
+
32
+ def to_h
33
+ @scopes.each_with_object({}) do |scope, merged|
34
+ merged.merge!(scope)
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def normalize(scope)
41
+ scope.each_with_object({}) do |(name, type), normalized|
42
+ normalized[name.to_sym] = type
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RLSL
4
+ module Prism
5
+ class TypeEnvironment
6
+ include TypeShapes
7
+
8
+ ARRAY_ELEMENT_SUFFIX = "_element_type"
9
+
10
+ def initialize
11
+ @value_scopes = ScopeStack.new
12
+ @array_element_scopes = ScopeStack.new
13
+ end
14
+
15
+ def push(initial_scope = {})
16
+ value_scope = {}
17
+ array_scope = {}
18
+
19
+ normalize(initial_scope).each do |name, type|
20
+ register_in_scopes(value_scope, array_scope, name, type)
21
+ end
22
+
23
+ @value_scopes.push(value_scope)
24
+ @array_element_scopes.push(array_scope)
25
+ end
26
+
27
+ def pop
28
+ @value_scopes.pop
29
+ @array_element_scopes.pop
30
+ end
31
+
32
+ def register(name, type)
33
+ register_in_scopes(@value_scopes, @array_element_scopes, name, type)
34
+ end
35
+
36
+ def lookup(name)
37
+ normalized_name = name.to_sym
38
+ return array_element_type(metadata_base_name(normalized_name)) if metadata_name?(normalized_name)
39
+
40
+ @value_scopes.lookup(normalized_name)
41
+ end
42
+
43
+ def array_element_type(name)
44
+ normalized_name = name.to_sym
45
+ explicit_type = @array_element_scopes.lookup(normalized_name)
46
+ return explicit_type if explicit_type
47
+
48
+ value_type = @value_scopes.lookup(normalized_name)
49
+ return TypeShapes.element_type(value_type) if TypeShapes.array?(value_type)
50
+
51
+ nil
52
+ end
53
+
54
+ def to_h
55
+ values = @value_scopes.to_h
56
+ elements = @array_element_scopes.to_h.each_with_object({}) do |(name, type), memo|
57
+ memo[metadata_name(name)] = type
58
+ end
59
+
60
+ values.each do |name, type|
61
+ next unless TypeShapes.array?(type)
62
+
63
+ elements[metadata_name(name)] ||= TypeShapes.element_type(type)
64
+ end
65
+
66
+ values.merge(elements)
67
+ end
68
+
69
+ private
70
+
71
+ def register_in_scopes(value_scope, array_scope, name, type)
72
+ normalized_name = name.to_sym
73
+
74
+ if metadata_name?(normalized_name)
75
+ write_scope(array_scope, metadata_base_name(normalized_name), type)
76
+ return
77
+ end
78
+
79
+ write_scope(value_scope, normalized_name, type)
80
+ return unless TypeShapes.array?(type)
81
+
82
+ write_scope(array_scope, normalized_name, TypeShapes.element_type(type))
83
+ end
84
+
85
+ def normalize(scope)
86
+ scope.each_with_object({}) do |(name, type), normalized|
87
+ normalized[name.to_sym] = type
88
+ end
89
+ end
90
+
91
+ def metadata_name?(name)
92
+ name.to_s.end_with?(ARRAY_ELEMENT_SUFFIX)
93
+ end
94
+
95
+ def metadata_name(name)
96
+ :"#{name}#{ARRAY_ELEMENT_SUFFIX}"
97
+ end
98
+
99
+ def metadata_base_name(name)
100
+ name.to_s.delete_suffix(ARRAY_ELEMENT_SUFFIX).to_sym
101
+ end
102
+
103
+ def write_scope(scope, name, type)
104
+ if scope.respond_to?(:register)
105
+ scope.register(name, type)
106
+ else
107
+ scope[name.to_sym] = type
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RLSL
4
+ module Prism
5
+ module TypeShapes
6
+ ArrayType = Struct.new(:element_type) do
7
+ def to_sym
8
+ :"array_#{element_type}"
9
+ end
10
+
11
+ def to_s
12
+ to_sym.to_s
13
+ end
14
+ end
15
+
16
+ module_function
17
+
18
+ def array(element_type)
19
+ ArrayType.new(element_type)
20
+ end
21
+
22
+ def array?(type)
23
+ type.is_a?(ArrayType)
24
+ end
25
+
26
+ def element_type(type)
27
+ return type.element_type if array?(type)
28
+
29
+ nil
30
+ end
31
+ end
32
+ end
33
+ end