Class: CSquare::Generator::Index

Inherits:
Object
  • Object
show all
Defined in:
lib/csquare/generator/index.rb

Instance Method Summary collapse

Constructor Details

#initialize(parent, index_name, options_and_mappings = {}) ⇒ Index

Returns a new instance of Index.



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/csquare/generator/index.rb', line 3

def initialize parent, index_name, options_and_mappings = {}
  @parent   = parent
  @basename = index_name
  @inline_sources = {}

  on        = options_and_mappings.delete(:on) # which enums
  @with     = options_and_mappings.delete(:with) # which function template to call
  @default  = options_and_mappings.delete(:default) # error function to call
  @on       = {}

  # STDERR.puts "@with=#{@with.inspect}, name=#{name.inspect}"

  # Find enumerators
  if on.is_a?(Array)
    on.each do |enum_id|
      @on[enum_id]  = generator.enumerators[enum_id]
    end
  else
    @on[on || @basename] = generator.enumerators[on || @basename]
  end

  @signatures = map_from_index_options(options_and_mappings).merge(map_from_enums(options_and_mappings))
  @mappings   = options_and_mappings # save what remains
end

Instance Method Details

#common_signature(type_id = nil, enumeree_stack = [], on = nil) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/csquare/generator/index.rb', line 76

def common_signature type_id=nil, enumeree_stack=[], on=nil
  on ||= @on

  ary = []

  if on.values.first.on == :ops # index by ops instead of by type
    ary = @signatures.values.compact
  else

    dim_enum_id, dim_enum = on.first
    next_dim_on           = on.select { |k,v| k != dim_enum_id }
    next_dim_enum         = next_dim_on.first.last unless next_dim_on.size == 0

    if next_dim_on.size == 0

      dim_enum.enumerees.each do |enumeree|
        next if enumeree.nil?
        curr_enumeree_stack = stacked_enumerees(enumeree_stack, enumeree)
        ary << decorated_signature(type_id, curr_enumeree_stack)
      end

    else

      dim_enum.enumerees.each do |enumeree|
        next if enumeree.nil?
        curr_enumeree_stack = stacked_enumerees(enumeree_stack, enumeree)
        ary << common_signature(type_id, curr_enumeree_stack, next_dim_on)
      end
    end

    ary = ary.compact
  end

  common_sig = nil

  ary.each do |sig|
    common_sig = sig.clone if common_sig.nil? || sig.params.size > common_sig.params.size
  end

  # Second pass: walk through arguments of common sig and see if the current
  # sig is simpler.
  ary.each do |sig|

    # Start with return type
    common_sig.type = simplify_type common_sig.type, sig.type

    # Now do params
    sig.params.each_index do |i|
      common_sig.params[i] = simplify_type common_sig.params[i], sig.params[i]
    end
  end

  common_sig.replace_types!(@parent.params(type_id)) unless type_id.nil?

  common_sig
end

#declaration(type_id = nil) ⇒ Object

Return the function pointer array declaration. Count is optional.



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/csquare/generator/index.rb', line 149

def declaration type_id=nil
  # Figure out the function pointer type
  sig            = common_signature(type_id)

  unnamed_params = sig.params.map { |p| p.name = nil; p.to_s }.join(", ")

  # Figure out how many [][][] to include and what values to enclose in them
  array_portion = begin
    str = ""
    @on.each_pair do |enum_id, enum_obj|
      str += "[#{enum_obj.enumerees.size}]"
    end
    str
  end

  "#{sig.type.to_s} (*#{decorated_basename(type_id)}#{array_portion})(#{unnamed_params.to_s})"
end

#decorated_basename(type_id = nil) ⇒ Object



187
188
189
# File 'lib/csquare/generator/index.rb', line 187

def decorated_basename type_id=nil
  type_id.nil? ? @basename : "#{@basename}_#{type_id}"
end

#decorated_calls(universal_type_id, enumeree_stack = [], on = nil) ⇒ Object



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/csquare/generator/index.rb', line 204

def decorated_calls universal_type_id, enumeree_stack=[], on=nil
  on ||= @on

  ary = []
  count = 0

  dim_enum_id, dim_enum = on.first
  next_dim_on           = on.select { |k,v| k != dim_enum_id }
  next_dim_enum         = next_dim_on.first.last unless next_dim_on.size == 0

  if next_dim_on.size == 0

    dim_enum.enumerate_for_index.each do |enumeree, c_value|

      while c_value > count
        ary << default_name
        count += 1
      end

      if use_decorated?(enumeree_stack, enumeree)
        curr_enumeree_stack = stacked_enumerees(enumeree_stack, enumeree)
        ary << [@mappings[enumeree], universal_type_id].concat(curr_enumeree_stack).compact.map{|i| i.to_s}.join('_')
      else
        ary << default_name
      end

      count += 1
    end

  else

    dim_enum.enumerate_for_index.each do |enumeree, c_value|

      while c_value > count
        ary << (next_dim_enum.nil? ? default_name : "{ #{[default_name]*next_dim_enum.enumerate_for_index.size} }")
        count += 1
      end

      curr_enumeree_stack = stacked_enumerees(enumeree_stack, enumeree)

      ary << decorated_calls(universal_type_id, curr_enumeree_stack, next_dim_on)
      count += 1
    end
  end

  ary
end

#decorated_name(type_ids = []) ⇒ Object



176
177
178
179
# File 'lib/csquare/generator/index.rb', line 176

def decorated_name type_ids=[]
  type_ids = [type_ids] unless type_ids.is_a?(Array)
  type_ids.empty? ? name : [name].concat(type_ids).compact.join('_')
end

#decorated_signature(type_id, enumeree_stack = []) ⇒ Object

def common_signature type_id=nil

common_sig = nil

# First pass: Find the longest, make that the common sig
@signatures.each_value do |sig|
  common_sig = sig.clone if common_sig.nil? || sig.params.size > common_sig.params.size
end

# Second pass: walk through arguments of common sig and see if the current
# sig is simpler.
@signatures.each_value do |sig|
  # Start with return type
  common_sig.type = simplify_type common_sig.type, sig.type

  # Now do params
  sig.params.each_index do |i|
    common_sig.params[i] = simplify_type common_sig.params[i], sig.params[i]
  end
end

if @signatures.size == 1
  common_sig.params.each_index do |i|
    common_sig.params[i] = simplify_type common_sig.params[i], common_sig.params[i]
  end
end

common_sig.replace_types!(@parent.params(type_id)) unless type_id.nil?

common_sig

end



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/csquare/generator/index.rb', line 60

def decorated_signature type_id, enumeree_stack=[]
  stack = [type_id].concat(enumeree_stack).compact
  name  = @mappings[type_id || enumeree_stack.first]
  sig   = @signatures[name].clone

  blueprint = @parent.is_a?(CSquare::Generator::Blueprint) ? @parent : @parent.blueprint_for(stack.first)

  require 'pry'
  binding.pry if sig.nil? || blueprint.nil?

  sig.replace_types!(blueprint.params(stack.first))

  sig
end

#default_name(type_ids = []) ⇒ Object



168
169
170
171
172
173
# File 'lib/csquare/generator/index.rb', line 168

def default_name type_ids=[]
  type_ids ||= []
  type_ids   = [type_ids] unless type_ids.is_a?(Array)
  return 'NULL' if @default.nil?
  decorated_name(@default, type_ids)
end

#nameObject



182
183
184
# File 'lib/csquare/generator/index.rb', line 182

def name
  @with || @basename
end

#return_typenameObject

Returns the template typename (e.g., TYPE) for this function pointer array.



136
137
138
139
140
141
142
143
144
145
# File 'lib/csquare/generator/index.rb', line 136

def return_typename
  common_rtn = nil

  @signatures.each_value do |sig|
    common_rtn ||= sig.type.clone
    simplify_type common_rtn, sig.type
  end

  common_rtn
end

#stacked_enumerees(stack, enumeree) ⇒ Object



192
193
194
# File 'lib/csquare/generator/index.rb', line 192

def stacked_enumerees stack, enumeree
  @parent.is_a?(CSquare::Generator::Blueprint) ? stack : stack.clone.push(enumeree)
end

#to_c(type_id = nil) ⇒ Object

arg only gets used when type_ids are constant (not set by enum)



253
254
255
# File 'lib/csquare/generator/index.rb', line 253

def to_c type_id=nil # arg only gets used when type_ids are constant (not set by enum)
  "#{declaration(type_id)} = {\n  #{to_c_internal(decorated_calls(type_id))}\n};\n"
end

#use_decorated?(stack, enumeree) ⇒ Boolean

Returns:

  • (Boolean)


197
198
199
200
201
# File 'lib/csquare/generator/index.rb', line 197

def use_decorated? stack, enumeree
  return false if !@mappings.has_key?(enumeree) || enumeree.nil?
  return false if stack.include?(nil)
  true
end