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,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RLSL
4
+ module Prism
5
+ module Emitters
6
+ class BaseEmitter
7
+ module ExpressionEmission
8
+ def emit_var_decl(node)
9
+ type = type_name(node.type || :float)
10
+ return "#{type} #{node.name}" unless node.initializer
11
+
12
+ if node.initializer.is_a?(IR::ArrayLiteral)
13
+ value = emit(node.initializer)
14
+ element_type = type_name(TypeShapes.element_type(node.type) || :float)
15
+ return "#{element_type} #{node.name}[#{node.initializer.elements.length}] = #{value}"
16
+ end
17
+
18
+ value = emit(node.initializer)
19
+ "#{type} #{node.name} = #{value}"
20
+ end
21
+
22
+ def emit_var_ref(node)
23
+ node.name.to_s
24
+ end
25
+
26
+ def emit_literal(node)
27
+ format_number(node.value, type: node.type)
28
+ end
29
+
30
+ def emit_bool_literal(node)
31
+ node.value.to_s
32
+ end
33
+
34
+ def emit_binary_op(node)
35
+ left = emit_with_precedence(node.left, node.operator, side: :left)
36
+ right = emit_with_precedence(node.right, node.operator, side: :right)
37
+ "#{left} #{node.operator} #{right}"
38
+ end
39
+
40
+ def emit_unary_op(node)
41
+ operand = emit(node.operand)
42
+ operand = "(#{operand})" if node.operand.is_a?(IR::BinaryOp) ||
43
+ node.operand.is_a?(IR::Ternary) ||
44
+ node.operand.is_a?(IR::UnaryOp)
45
+ "#{node.operator}#{operand}"
46
+ end
47
+
48
+ def emit_func_call(node)
49
+ func_name = function_name(node.name)
50
+ args = node.args.map { |arg| emit(arg) }.join(", ")
51
+
52
+ if node.receiver
53
+ receiver = emit(node.receiver)
54
+ "#{func_name}(#{receiver}, #{args})"
55
+ else
56
+ "#{func_name}(#{args})"
57
+ end
58
+ end
59
+
60
+ def emit_field_access(node)
61
+ "#{emit(node.receiver)}.#{node.field}"
62
+ end
63
+
64
+ def emit_swizzle(node)
65
+ "#{emit(node.receiver)}.#{node.components}"
66
+ end
67
+
68
+ def emit_ternary(node)
69
+ "(#{emit(node.condition)} ? #{emit(node.then_expr)} : #{emit(node.else_expr)})"
70
+ end
71
+
72
+ def emit_assignment(node)
73
+ "#{emit(node.target)} = #{emit(node.value)}"
74
+ end
75
+
76
+ def emit_constant(node)
77
+ case node.name
78
+ when :PI
79
+ "3.14159265358979323846"
80
+ when :TAU
81
+ "6.28318530717958647692"
82
+ else
83
+ node.name.to_s
84
+ end
85
+ end
86
+
87
+ def emit_parenthesized(node)
88
+ "(#{emit(node.expression)})"
89
+ end
90
+
91
+ def emit_array_index(node)
92
+ array = emit(node.array)
93
+ index = if node.index.is_a?(IR::Literal) && node.index.value.to_i == node.index.value
94
+ node.index.value.to_i.to_s
95
+ else
96
+ emit(node.index)
97
+ end
98
+ "#{array}[#{index}]"
99
+ end
100
+
101
+ def emit_typed_argument(node, _expected_type)
102
+ emit(node)
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RLSL
4
+ module Prism
5
+ module Emitters
6
+ class BaseEmitter
7
+ module StatementEmission
8
+ def emit_block(node, needs_return = nil)
9
+ statements = node.statements
10
+ return "" if statements.empty?
11
+
12
+ emit_statements(statements, returning: needs_return.nil? ? return_context? : needs_return)
13
+ end
14
+
15
+ def emit_statements(statements, returning:)
16
+ return statements.map { |statement| emit_statement(statement) }.join unless returning
17
+
18
+ leading = statements[0...-1].map { |statement| emit_statement(statement) }.join
19
+ leading + emit_terminal_statement(statements.last)
20
+ end
21
+
22
+ def emit_statement(node, needs_return: false)
23
+ return emit_terminal_statement(node) if needs_return
24
+
25
+ "#{indent}#{emit(node)}#{statement_terminator(node)}"
26
+ end
27
+
28
+ def emit_terminal_statement(node)
29
+ return emit(node, needs_return: true) if node.is_a?(IR::IfStatement)
30
+ if node.is_a?(IR::VarDecl)
31
+ return "#{emit_statement(node)}#{indent}return #{node.name};\n"
32
+ end
33
+ if node.is_a?(IR::Assignment)
34
+ return "#{emit_statement(node)}#{indent}return #{emit(node.target)};\n"
35
+ end
36
+ return emit_statement(node) if terminal_passthrough_node?(node)
37
+ return emit_tuple_return(node) if node.is_a?(IR::ArrayLiteral)
38
+
39
+ "#{indent}return #{emit_return_expression(node)};\n"
40
+ end
41
+
42
+ def emit_branch(node, needs_return:)
43
+ with_indent do
44
+ if node.is_a?(IR::Block)
45
+ emit(node, needs_return: needs_return)
46
+ else
47
+ emit_statement(node, needs_return: needs_return)
48
+ end
49
+ end
50
+ end
51
+
52
+ def emit_indented_block(node, needs_return: false)
53
+ with_indent do
54
+ if node.is_a?(IR::Block)
55
+ emit(node, needs_return: needs_return)
56
+ else
57
+ emit_statement(node, needs_return: needs_return)
58
+ end
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def statement_terminator(node)
65
+ multiline_node?(node) ? "\n" : ";\n"
66
+ end
67
+
68
+ def multiline_node?(node)
69
+ MULTILINE_NODES.any? { |klass| node.is_a?(klass) }
70
+ end
71
+
72
+ def terminal_passthrough_node?(node)
73
+ [
74
+ IR::Return,
75
+ IR::VarDecl,
76
+ IR::Assignment,
77
+ IR::ForLoop,
78
+ IR::WhileLoop,
79
+ IR::FunctionDefinition,
80
+ IR::GlobalDecl,
81
+ IR::MultipleAssignment
82
+ ].any? { |klass| node.is_a?(klass) }
83
+ end
84
+
85
+ def with_indent
86
+ @indent_level += 1
87
+ yield
88
+ ensure
89
+ @indent_level -= 1
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end