Module: RLSL::Prism::Emitters::BaseEmitter::DefinitionEmission

Included in:
RLSL::Prism::Emitters::BaseEmitter
Defined in:
lib/rlsl/prism/emitters/base_emitter/definition_emission.rb

Instance Method Summary collapse

Instance Method Details

#current_return_struct_nameObject



31
32
33
# File 'lib/rlsl/prism/emitters/base_emitter/definition_emission.rb', line 31

def current_return_struct_name
  @current_return_struct_name || "result"
end

#emit_array_literal(node, for_static_init: false) ⇒ Object



35
36
37
38
# File 'lib/rlsl/prism/emitters/base_emitter/definition_emission.rb', line 35

def emit_array_literal(node, for_static_init: false)
  elements = node.elements.map { |elem| emit_for_static_init(elem, for_static_init) }.join(", ")
  "{#{elements}}"
end

#emit_for_static_init(node, for_static_init) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/rlsl/prism/emitters/base_emitter/definition_emission.rb', line 40

def emit_for_static_init(node, for_static_init)
  return emit(node) unless for_static_init

  case node
  when IR::FuncCall
    if %i[vec2 vec3 vec4].include?(node.name)
      args = node.args.map { |arg| emit_for_static_init(arg, true) }.join(", ")
      "{#{args}}"
    else
      emit(node)
    end
  when IR::ArrayLiteral
    emit_array_literal(node, for_static_init: true)
  else
    emit(node)
  end
end

#emit_function_definition(node) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/rlsl/prism/emitters/base_emitter/definition_emission.rb', line 8

def emit_function_definition(node)
  name = node.name
  params = node.params.map do |param|
    "#{type_name(node.param_types[param] || :float)} #{param}"
  end.join(", ")

  if node.return_type.is_a?(Array)
    @current_return_struct_name = "#{name}_result"
    struct_def = emit_result_struct(name, node.return_type)
    body = emit_indented_block(node.body, needs_return: true)
    @current_return_struct_name = nil
    "#{struct_def}static inline #{name}_result #{name}(#{params}) {\n#{body}\n#{indent}}\n"
  else
    body = emit_indented_block(node.body, needs_return: true)
    "static inline #{type_name(node.return_type || :float)} #{name}(#{params}) {\n#{body}\n#{indent}}\n"
  end
end

#emit_global_decl(node) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/rlsl/prism/emitters/base_emitter/definition_emission.rb', line 58

def emit_global_decl(node)
  prefix = ""
  prefix += "static " if node.is_static
  prefix += "const " if node.is_const

  if node.initializer.is_a?(IR::ArrayLiteral)
    elem_type = type_name(node.element_type || :float)
    size = node.array_size || node.initializer.elements.length
    elements = emit_array_literal(node.initializer, for_static_init: true)
    "#{prefix}#{elem_type} #{node.name}[#{size}] = #{elements}"
  else
    value = node.is_const ? emit_for_static_init(node.initializer, true) : emit(node.initializer)
    "#{prefix}#{type_name(node.type || :float)} #{node.name} = #{value}"
  end
end

#emit_multiple_assignment(node) ⇒ Object



74
75
76
77
78
79
80
81
82
# File 'lib/rlsl/prism/emitters/base_emitter/definition_emission.rb', line 74

def emit_multiple_assignment(node)
  value_code = emit(node.value)

  if node.value.is_a?(IR::FuncCall)
    emit_multi_return_assignment(node, value_code)
  else
    emit_indexed_assignment(node, value_code)
  end
end

#emit_result_struct(func_name, types) ⇒ Object



26
27
28
29
# File 'lib/rlsl/prism/emitters/base_emitter/definition_emission.rb', line 26

def emit_result_struct(func_name, types)
  fields = types.each_with_index.map { |type, index| "#{type_name(type)} v#{index};" }.join(" ")
  "typedef struct { #{fields} } #{func_name}_result;\n"
end