Module: Idl::PruneHelpers
- Extended by:
- T::Sig
- Defined in:
- lib/idlc/passes/prune.rb
Class Method Summary collapse
- .coerce_ary_element_widths(symtab, elements, max_element_width) ⇒ Object
- .create_bool_literal(value) ⇒ Object
- .create_int_literal(value, forced_type: nil) ⇒ Object
- .create_literal(symtab, value, type, forced_type: nil) ⇒ Object
- .find_max_element_width(symtab, node, max = nil) ⇒ Object
Class Method Details
.coerce_ary_element_widths(symtab, elements, max_element_width) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/idlc/passes/prune.rb', line 55 def self.coerce_ary_element_widths(symtab, elements, max_element_width) if elements.is_a?(Array) && elements.empty? Idl::ArrayLiteralAst.new("pruned_literal_ary", 0..18, []) elsif elements.fetch(0).is_a?(Idl::ArrayLiteralAst) # Recursively coerce nested arrays - pass e.entries, not e Idl::ArrayLiteralAst.new("pruned_literal_ary", 0..18, elements.map { |e| coerce_ary_element_widths(symtab, e.entries, max_element_width) }) else # Base case: elements is an array of leaf nodes, coerce each to max_element_width coerced = elements.map { |node| create_int_literal(node.value(symtab), forced_type: Idl::Type.new(:bits, width: max_element_width)) } Idl::ArrayLiteralAst.new("pruned_literal_ary", 0..18, coerced) end end |
.create_bool_literal(value) ⇒ Object
28 29 30 31 32 33 34 |
# File 'lib/idlc/passes/prune.rb', line 28 def self.create_bool_literal(value) if value Idl::TrueExpressionAst.new("true", 0..4) else Idl::FalseExpressionAst.new("false", 0..5) end end |
.create_int_literal(value, forced_type: nil) ⇒ Object
19 20 21 22 23 24 25 26 |
# File 'lib/idlc/passes/prune.rb', line 19 def self.create_int_literal(value, forced_type: nil) width = forced_type ? forced_type.width : value.bit_length raise "pruning error: attempting to prune an integer with unknown width" unless width.is_a?(Integer) width = 1 if width == 0 v = value <= 512 ? value.to_s : "h#{value.to_s(16)}" str = "#{width}'#{v}" Idl::IntLiteralAst.new(str, 0...str.size, str) end |
.create_literal(symtab, value, type, forced_type: nil) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/idlc/passes/prune.rb', line 69 def self.create_literal(symtab, value, type, forced_type: nil) case type.kind when :enum_ref member_name = type.enum_class.element_names[type.enum_class.element_values.index(value)] str = "#{type.enum_class.name}::#{member_name}" Idl::EnumRefAst.new(str, 0...str.size, type.enum_class.name, member_name) when :bits create_int_literal(value, forced_type:) when :boolean create_bool_literal(value) when :array elements = value.map { |e| create_literal(symtab, e, type.sub_type) } # array elements MUST have the same type, so we need to coerce them # find the leaf level, and get the bit widths if needed ary = Idl::ArrayLiteralAst.new("pruned_literal_ary", 0..18, elements) max_element_width = find_max_element_width(symtab, ary) if max_element_width.nil? ary else coerce_ary_element_widths(symtab, elements, max_element_width) end else raise "TODO: #{type}" end end |
.find_max_element_width(symtab, node, max = nil) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/idlc/passes/prune.rb', line 39 def self.find_max_element_width(symtab, node, max = nil) if node.is_a?(Idl::ArrayLiteralAst) node.entries.map do |e| e_max = find_max_element_width(symtab, e) max.nil? ? e_max : [max, e_max].max end.max else if node.is_a?(Idl::TrueExpressionAst) || node.is_a?(Idl::FalseExpressionAst) nil else node_width = node.type(symtab).width max.nil? ? node_width : [max, node_width].max end end end |