Class: CSquare::Generator
- Inherits:
-
Object
- Object
- CSquare::Generator
- Includes:
- Indexable
- Defined in:
- lib/csquare/generator.rb
Defined Under Namespace
Classes: AssignOp, BinaryOp, Blueprint, BooleanOp, Enum, Index, Op, Type
Constant Summary collapse
- DEFAULT_EXTERNS =
{'fprintf' => 'int'}
- OP_RETURN_TYPES =
To use for :inline index functions – need to know return type
{ :'<' => :boolean, :'>' => :boolean, :'<=' => :boolean, :'>=' => :boolean, :'==' => :boolean, :'!=' => :boolean, :'+' => :key, :'-' => :key, :'*' => :key, :'/' => :key, :'%' => :key }
- OP_FUNCTION_NAMES =
To use for :inline index functions that should be automatically generated
{ :'<' => 'lt', :'>' => 'gt', :'<=' => 'lte', :'>=' => 'gte', :'==' => 'eqeq', :'!=' => 'neq', :'+' => 'add', :'-' => 'sub', :'*' => 'mul', :'/' => 'div', :'%' => 'mod' }
- BOOL_CAST_TO_OP =
{ C::Less => :'<', C::More => :'>', C::LessOrEqual => :'<=', C::MoreOrEqual => :'>=', C::Equal => :'==', C::NotEqual => :'!=', C::And => :'&&', C::Or => :'||' }
- UNARY_CAST_TO_OP =
{ C::Negative => :'-@', C::Not => :'!@', C::Arrow => :'->', C::Dereference => :'*@' }
- ASSIGN_CAST_TO_OP =
{ C::Assign => :'=', }
- BINARY_ASSIGN_CAST_TO_OP =
{ C::AddAssign => :'+=', C::SubtractAssign => :'-=', C::MultiplyAssign => :'*=', C::DivideAssign => :'/=', C::ModAssign => :'%=' }
- BINARY_CAST_TO_OP =
{ C::Add => :'+', C::Subtract => :'-', C::Multiply => :'*', C::Divide => :'/', C::Mod => :'%',}
- BIT_CAST_TO_OP =
{ C::BitAnd => :'&', C::BitOr => :'|', C::BitXor => :'^', C::ShiftLeft => :'<<', C::ShiftRight => :'>>' }
- CAST_TO_OP =
BOOL_CAST_TO_OP. merge(UNARY_CAST_TO_OP). merge(ASSIGN_CAST_TO_OP). merge(BINARY_CAST_TO_OP). merge(BIT_CAST_TO_OP). merge(BINARY_ASSIGN_CAST_TO_OP)
Instance Attribute Summary collapse
-
#basename ⇒ Object
readonly
Returns the value of attribute basename.
-
#blueprints ⇒ Object
readonly
Returns the value of attribute blueprints.
-
#enumerators ⇒ Object
readonly
Returns the value of attribute enumerators.
-
#path ⇒ Object
readonly
Returns the value of attribute path.
Instance Method Summary collapse
-
#[](blueprint_id) ⇒ Object
Shorthand for blueprints.
-
#blueprint(id, template_param = 'TYPE', field_params = {}, &block) ⇒ Object
Create a blueprint for a set of types that all behave a certain way.
-
#blueprint_for(type_id) ⇒ Object
Returns the blueprint corresponding to some type_id.
- #c_filename ⇒ Object
- #c_include_guard ⇒ Object
- #default_key(k = nil) ⇒ Object
- #enumerate(name, opts = {}) ⇒ Object
-
#externs(h = nil) ⇒ Object
Register symbols available to all functions, and their types.
- #h_filename ⇒ Object
- #h_include_guard ⇒ Object
- #indices_c_code ⇒ Object
-
#initialize(path, c_output_basename, options = {}) {|_self| ... } ⇒ Generator
constructor
A new instance of Generator.
- #inspect ⇒ Object
-
#keys_for(f_name) ⇒ Object
Return all possible typenames for a given source.
-
#op_symbols ⇒ Object
Get a list of ops used (just the symbols).
-
#params(type_symbol) ⇒ Object
Return a hash giving mappings from template typenames (keys, e.g., ‘TYPE’) to ctypes.
- #read_source(source_filename) ⇒ Object
-
#types ⇒ Object
Get all types stored in the various template types.
Methods included from Indexable
Constructor Details
#initialize(path, c_output_basename, options = {}) {|_self| ... } ⇒ Generator
Returns a new instance of Generator.
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 |
# File 'lib/csquare/generator.rb', line 90 def initialize path, c_output_basename, = {} = { :include_guards => true, :header => true, :include_header => true }.merge() @default_key = 'TYPE' @path = path @basename = c_output_basename @externs = DEFAULT_EXTERNS @blueprints = {} @enumerators = {} yield self # STDERR.puts "GENERATOR EXTERNS: " + @externs.inspect @blueprints.each_key do |id| @blueprints[id]. end mutant_functions = [] blueprints.each_value do |blueprint| blueprint.types.each_pair do |type_symbol,type| mutant_functions = mutant_functions.concat(blueprint.mutate_functions(type_symbol)) end end declarations = write_c_file([:include_guards], [:include_header], mutant_functions) write_h_file([:include_guards], declarations) if [:header] end |
Instance Attribute Details
#basename ⇒ Object (readonly)
Returns the value of attribute basename.
123 124 125 |
# File 'lib/csquare/generator.rb', line 123 def basename @basename end |
#blueprints ⇒ Object (readonly)
Returns the value of attribute blueprints.
123 124 125 |
# File 'lib/csquare/generator.rb', line 123 def blueprints @blueprints end |
#enumerators ⇒ Object (readonly)
Returns the value of attribute enumerators.
123 124 125 |
# File 'lib/csquare/generator.rb', line 123 def enumerators @enumerators end |
#path ⇒ Object (readonly)
Returns the value of attribute path.
123 124 125 |
# File 'lib/csquare/generator.rb', line 123 def path @path end |
Instance Method Details
#[](blueprint_id) ⇒ Object
Shorthand for blueprints
154 155 156 |
# File 'lib/csquare/generator.rb', line 154 def [] blueprint_id blueprints[blueprint_id] end |
#blueprint(id, template_param = 'TYPE', field_params = {}, &block) ⇒ Object
Create a blueprint for a set of types that all behave a certain way.
At minimum, you should provide the name of the blueprint (e.g., blueprint(:integer)
). You may also provide a template parameter name, which defaults to TYPE, and field parameters.
Example (complex):
c.blueprint(:complex, 'TYPE', :r => 'FLOAT', :i => 'FLOAT') do |t|
# ...
end
181 182 183 184 185 186 187 188 189 190 |
# File 'lib/csquare/generator.rb', line 181 def blueprint id, template_param = 'TYPE', field_params = {}, &block raise(ArgumentError, "id #{id} already declared") if @blueprints.has_key?(id) # Clear cache of blueprints by type_id @blueprint_for = nil @blueprints[id] = Blueprint.new(self, id, template_param, field_params, &block) self end |
#blueprint_for(type_id) ⇒ Object
Returns the blueprint corresponding to some type_id. Caches types for faster lookup.
209 210 211 212 |
# File 'lib/csquare/generator.rb', line 209 def blueprint_for type_id @blueprint_for ||= types @blueprint_for[type_id].blueprint end |
#c_filename ⇒ Object
145 146 147 |
# File 'lib/csquare/generator.rb', line 145 def c_filename "#{@basename}.c" end |
#c_include_guard ⇒ Object
136 137 138 |
# File 'lib/csquare/generator.rb', line 136 def c_include_guard "#{@basename.upcase}_C" end |
#default_key(k = nil) ⇒ Object
130 131 132 133 |
# File 'lib/csquare/generator.rb', line 130 def default_key k=nil return @default_key if k.nil? @default_key = k end |
#enumerate(name, opts = {}) ⇒ Object
215 216 217 |
# File 'lib/csquare/generator.rb', line 215 def enumerate name, opts = {} @enumerators[name] = CSquare::Generator::Enum.new(name, opts) end |
#externs(h = nil) ⇒ Object
Register symbols available to all functions, and their types. Takes a hash as only argument.
Example:
c.externs 'NM_MAX' => :integer, 'CblasNoTrans' => 'char', 'fprintf' => 'int'
165 166 167 168 |
# File 'lib/csquare/generator.rb', line 165 def externs h=nil return @externs if h.nil? @externs.merge!(h) end |
#h_filename ⇒ Object
149 150 151 |
# File 'lib/csquare/generator.rb', line 149 def h_filename "#{@basename}.h" end |
#h_include_guard ⇒ Object
140 141 142 |
# File 'lib/csquare/generator.rb', line 140 def h_include_guard "#{@basename.upcase}_H" end |
#indices_c_code ⇒ Object
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/csquare/generator.rb', line 228 def indices_c_code ary = [] # Blueprint-scoped indices @blueprints.each_value do |blueprint| blueprint.indices.values.flatten.each do |index| blueprint.types.each_key do |type_id| ary << index.to_c(type_id) end end end # Add generator-scoped indices @indices.values.flatten.each do |index| ary << index.to_c end ary end |
#inspect ⇒ Object
125 126 127 128 |
# File 'lib/csquare/generator.rb', line 125 def inspect obj_id = "0x#{(self.object_id << 1).to_s(16)}" "#<#{self.class.to_s}:#{obj_id} basename=#{@basename.inspect} blueprint_ids=#{@blueprints.keys.inspect} path=#{@path.inspect}>" end |
#keys_for(f_name) ⇒ Object
Return all possible typenames for a given source
285 286 287 288 289 290 291 292 |
# File 'lib/csquare/generator.rb', line 285 def keys_for f_name ary = self.template_keys(f_name) @blueprints.each_value do |blueprint| next unless blueprint.has_source?(f_name) ary << blueprint.template_keys(f_name) end ary.flatten.compact.uniq end |
#op_symbols ⇒ Object
Get a list of ops used (just the symbols)
220 221 222 223 224 225 226 |
# File 'lib/csquare/generator.rb', line 220 def op_symbols ary = [] @blueprints.each_value do |blueprint| ary = ary.concat blueprint.op_symbols end ary.sort.uniq end |
#params(type_symbol) ⇒ Object
Return a hash giving mappings from template typenames (keys, e.g., ‘TYPE’) to ctypes.
270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/csquare/generator.rb', line 270 def params type_symbol types_ = types[type_symbol] k = types_.ctype_keys # hash of typenames to type ids begin k[@default_key] = types_.ctype rescue NoMethodError STDERR.puts "NoMethodError: @default_key=#{@default_key}, type_symbol = #{type_symbol}" end k["LONG_#{@default_key}"] = (types_.long || types_).ctype k end |
#read_source(source_filename) ⇒ Object
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/csquare/generator.rb', line 249 def read_source source_filename begin g = self.is_a?(CSquare::Generator) ? self : self.generator Dir.chdir(g.path) do if File.exists?(source_filename) preprocess_source File.new(source_filename, "r") else raise IOError, "file '#{source_filename}' not found in '#{g.path}' or '#{File.join(g.path, self.id.to_s)}'" end end rescue Errno::ENOENT => e # This is really helpful for people who are using rake compile and don't know what # the template directory should be, since they don't know their current location. STDERR.puts "CSquare: Exception thrown: #{e.inspect}" STDERR.puts "CSquare: Current directory: #{Dir.pwd.inspect}" raise e end end |
#types ⇒ Object
Get all types stored in the various template types
194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/csquare/generator.rb', line 194 def types h = {} @blueprints.each_value do |blueprint| blueprint.types.each_pair do |id, type| if h.has_key?(id) raise(StandardError, "two types with same id: #{id}") else h[id] = type end end end h end |