Module: HDLRuby::High
- Defined in:
- lib/HDLRuby/hruby_high.rb,
lib/HDLRuby/hruby_rsim.rb,
lib/HDLRuby/hruby_error.rb,
lib/HDLRuby/hruby_rcsim.rb,
lib/HDLRuby/hruby_rsim_vcd.rb,
lib/HDLRuby/hruby_rsim_mute.rb,
lib/HDLRuby/hruby_high_fullname.rb
Overview
Library for enhancing the Ruby simulator with muted output support
Defined Under Namespace
Modules: BlockHierarchy, HArrow, HBlock, HExpression, HRef, HScope_missing, HStatement, HbasicType, High2C, Hinner, Hmissing, Hmux, Htype, HvectorType, RCSimBehavior, RCSimBlock, SimSignal, SingletonExtend, Soft, Std, WithFullname Classes: AnyError, Behavior, Binary, Block, Case, Cast, Chunk, Code, Concat, Configure, Connection, Delay, Event, Expression, If, Namespace, NotDefinedError, Operation, Print, Ref, RefConcat, RefIndex, RefName, RefObject, RefRange, RefThis, Scope, Select, SignalC, SignalI, Statement, StringE, SystemI, SystemT, TimeBehavior, TimeBlock, TimeRepeat, TimeTerminate, TimeWait, Transmit, Type, TypeDef, TypeFloat, TypeGen, TypeSigned, TypeStruct, TypeTuple, TypeUnsigned, TypeVector, Unary, Value, When
Constant Summary collapse
- Low =
Base = HDLRuby::Base
HDLRuby::Low
- Void =
The void type
define_type(:void)
- Bit =
The bit type.
define_type(:bit)
- Signed =
The signed bit type.
define_type(:signed)
- Unsigned =
The unsigned bit type.
define_type(:unsigned)
- Float =
The float bit type
define_type(:float)
- StringT =
The string type
define_type(:string)
- Universe =
The universe, i.e., the top system type.
SystemT.new(:"") {}
- NameStack =
The stack of names for creating new names without conflicts.
[ Set.new ]
- Integer =
Standard vector types.
TypeSigned.new(:integer,63..0)
- Char =
TypeSigned.new(:char,7..0)
- Natural =
TypeUnsigned.new(:natural,63..0)
- Bignum =
TypeSigned.new(:bignum,HDLRuby::Infinity..0)
- Real =
TypeFloat.new(:float)
- RCSim =
RCSimCinterface
- @@rsim_object_idstr =
Converts a HDLRuby object to a VCD id string.
{ }
- @@rsim_object_idstr_count =
0
Class Method Summary collapse
-
.booting? ⇒ Boolean
Tells HDLRuby is currently booting.
-
.cur_behavior ⇒ Object
Gets the enclosing behavior if any.
-
.cur_block(level = 0) ⇒ Object
Gets the enclosing block if any.
-
.cur_scope(level = 0) ⇒ Object
Gets the enclosing scope if any.
-
.cur_system ⇒ Object
Gets the enclosing system type if any.
-
.define_type(name) ⇒ Object
Defines a basic type +name+.
-
.from_users(method) ⇒ Object
Gather the result of the execution of +method+ from all the users of the namespaces.
-
.in_behavior? ⇒ Boolean
Tell if we are in a behavior.
-
.in_system? ⇒ Boolean
Tells if within a system type.
-
.make_block(mode = nil, name = :"", &ruby_block) ⇒ Object
Creates a block executed in +mode+, with possible +name+, that can be timed or not depending on the enclosing object and build it by executing the enclosing +ruby_block+.
-
.make_time_block(mode = nil, name = :"", &ruby_block) ⇒ Object
Creates a specifically timed block in +mode+, with possible +name+ and build it by executing the enclosing +ruby_block+.
-
.names_add(name) ⇒ Object
Adds a +name+ to the top of the stack.
-
.names_create(base) ⇒ Object
Creates and adds the new name from +base+ that do not collides with the exisiting names.
-
.names_has?(name) ⇒ Boolean
Checks if a +name+ is present in the stack.
-
.names_pop ⇒ Object
Pops from the name stack.
-
.names_push ⇒ Object
Pushes on the name stack.
-
.rcsim(top, name, outpath, outmode) ⇒ Object
Starts the simulation for top system +top+.
-
.space_call(name, *args, &ruby_block) ⇒ Object
Looks up and calls method +name+ from the namespace stack with arguments +args+ and block +ruby_block+.
-
.space_each(&ruby_block) ⇒ Object
Iterates over each namespace.
-
.space_include?(namespace) ⇒ Boolean
Tells if +namespace+ in included within the stack.
-
.space_index(namespace) ⇒ Object
Gets the index of a +namespace+ within the stack.
-
.space_insert(index, namespace) ⇒ Object
Inserts +namespace+ at +index+.
-
.space_pop ⇒ Object
Pops a namespace.
-
.space_push(namespace) ⇒ Object
Pushes +namespace+.
-
.space_reg(name, &ruby_block) ⇒ Object
Registers hardware referencing method +name+ to the current namespace.
-
.space_top ⇒ Object
Gets the top of the namespaces stack.
-
.space_top=(top) ⇒ Object
sets the top namespace.
-
.top_block(level = 0) ⇒ Object
Gets the top enclosing block if any.
-
.top_user ⇒ Object
Gets construct whose namespace is the top of the namespaces stack.
-
.vcd_bitstr(str) ⇒ Object
Converts a bit string to a vcd format.
- .vcd_idstr(obj) ⇒ Object
-
.vcd_name(name) ⇒ Object
Converts a HDLRuby name to a VCD name.
Instance Method Summary collapse
-
#curry_with_context(*args, &ruby_block) ⇒ Object
Reimplementation of the Proc's curry that transmit the context for execution.
-
#function(name, &ruby_block) ⇒ Object
Declares a function named +name+ using +ruby_block+ as body.
-
#hdef(name, &ruby_block) ⇒ Object
Declares a function named +name+ using +ruby_block+ as body.
-
#infinity ⇒ Object
Gets the infinity.
-
#instance(name, *includes, &ruby_block) ⇒ Object
Declares a high-level system instance named +name+, with +includes+ mixins system types and using +ruby_block+ for instantiating.
-
#set_this(obj = proc { RefThis.new }) ⇒ Object
Sets the current this to +obj+.
-
#struct(content) ⇒ Object
Creates an unnamed structure type from a +content+.
-
#system(name = :"", *includes, &ruby_block) ⇒ Object
Declares a high-level system type named +name+, with +includes+ mixins system types and using +ruby_block+ for instantiating.
-
#this ⇒ Object
Gives access to the this reference.
-
#typedef(name, &ruby_block) ⇒ Object
Declares a high-level generic type named +name+, and using +ruby_block+ for construction.
Class Method Details
.booting? ⇒ Boolean
Tells HDLRuby is currently booting.
17 18 19 |
# File 'lib/HDLRuby/hruby_high.rb', line 17 def self.booting? true end |
.cur_behavior ⇒ Object
Gets the enclosing behavior if any.
4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 |
# File 'lib/HDLRuby/hruby_high.rb', line 4621 def self.cur_behavior # return @@cur_behavior if in_behavior? then user = top_user while(user && !user.is_a?(Behavior)) do user = user.parent end return user else return nil end end |
.cur_block(level = 0) ⇒ Object
Gets the enclosing block if any.
NOTE: +level+ allows to get an upper block of the currently enclosing block.
4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 |
# File 'lib/HDLRuby/hruby_high.rb', line 4658 def self.cur_block(level = 0) if Namespaces[-1-level].user.is_a?(Scope) then raise AnyError, "Not within a block: #{Namespaces[-1-level].user.class}" elsif Namespaces[-1-level].user.is_a?(Block) then return Namespaces[-1-level].user else return cur_block(level+1) end end |
.cur_scope(level = 0) ⇒ Object
Gets the enclosing scope if any.
NOTE: +level+ allows to get an upper scope of the currently enclosing scope.
4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 |
# File 'lib/HDLRuby/hruby_high.rb', line 4643 def self.cur_scope(level = 0) if level < 0 then raise AnyError, "Not within a scope: #{Namespaces[-1].user.class}" end if Namespaces[-1-level].user.is_a?(Scope) then return Namespaces[-1-level].user else return cur_scope(level+1) end end |
.cur_system ⇒ Object
Gets the enclosing system type if any.
4607 4608 4609 4610 4611 4612 4613 4614 4615 |
# File 'lib/HDLRuby/hruby_high.rb', line 4607 def self.cur_system if Namespaces.size <= 1 then raise AnyError, "Not within a system type." else return Namespaces.reverse_each.find do |space| space.user.is_a?(Scope) and space.user.parent.is_a?(SystemT) end.user.parent end end |
.define_type(name) ⇒ Object
Defines a basic type +name+.
1812 1813 1814 1815 1816 1817 |
# File 'lib/HDLRuby/hruby_high.rb', line 1812 def self.define_type(name) name = name.to_sym type = Type.new(name) self.send(:define_method,name) { type } return type end |
.from_users(method) ⇒ Object
Gather the result of the execution of +method+ from all the users of the namespaces.
4582 4583 4584 4585 4586 4587 4588 4589 |
# File 'lib/HDLRuby/hruby_high.rb', line 4582 def self.from_users(method) Namespaces.reverse_each.reduce([]) do |res,space| user = space.user if user.respond_to?(method) then res += [*user.send(method)] end end end |
.in_behavior? ⇒ Boolean
Tell if we are in a behavior.
4635 4636 4637 |
# File 'lib/HDLRuby/hruby_high.rb', line 4635 def self.in_behavior? top_user.is_a?(Block) end |
.in_system? ⇒ Boolean
Tells if within a system type.
4602 4603 4604 |
# File 'lib/HDLRuby/hruby_high.rb', line 4602 def self.in_system? return Namespaces.size > 1 end |
.make_block(mode = nil, name = :"", &ruby_block) ⇒ Object
Creates a block executed in +mode+, with possible +name+, that can be timed or not depending on the enclosing object and build it by executing the enclosing +ruby_block+.
NOTE: not a method to include since it can only be used with a behavior or a block. Hence set as module method.
4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 |
# File 'lib/HDLRuby/hruby_high.rb', line 4392 def self.make_block(mode = nil, name = :"", &ruby_block) unless mode then # No type of block given, get a default one. if top_user.is_a?(Block) then # There is an upper block, use its mode. mode = top_user.mode else # There is no upper block, use :par as default. mode = :par end end if top_user.is_a?(TimeBlock) then return TimeBlock.new(mode,name,&ruby_block) else return Block.new(mode,name,&ruby_block) end end |
.make_time_block(mode = nil, name = :"", &ruby_block) ⇒ Object
Creates a specifically timed block in +mode+, with possible +name+ and build it by executing the enclosing +ruby_block+.
NOTE: not a method to include since it can only be used with a behavior or a block. Hence set as module method.
4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 |
# File 'lib/HDLRuby/hruby_high.rb', line 4415 def self.make_time_block(mode = nil, name = :"", &ruby_block) unless mode then # No type of block given, get a default one. if top_user.is_a?(Block) then # There is an upper block, use its mode. mode = block.mode else # There is no upper block, use :par as default. mode = :par end end return TimeBlock.new(mode,name,&ruby_block) end |
.names_add(name) ⇒ Object
Adds a +name+ to the top of the stack.
5265 5266 5267 |
# File 'lib/HDLRuby/hruby_high.rb', line 5265 def self.names_add(name) NameStack[-1].add(name.to_s) end |
.names_create(base) ⇒ Object
Creates and adds the new name from +base+ that do not collides with the exisiting names.
5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 |
# File 'lib/HDLRuby/hruby_high.rb', line 5278 def self.names_create(base) base = base.to_s.clone # Create a non-conflicting name if self.names_has?(base) then count = 0 while (self.names_has?(base + count.to_s)) do count += 1 end base << count.to_s end # Add and return it self.names_add(base) # puts "created name: #{base}" return base.to_sym end |
.names_has?(name) ⇒ Boolean
Checks if a +name+ is present in the stack.
5270 5271 5272 5273 5274 |
# File 'lib/HDLRuby/hruby_high.rb', line 5270 def self.names_has?(name) NameStack.find do |names| names.include?(name) end end |
.names_pop ⇒ Object
Pops from the name stack.
5260 5261 5262 |
# File 'lib/HDLRuby/hruby_high.rb', line 5260 def self.names_pop NameStack.pop end |
.names_push ⇒ Object
Pushes on the name stack.
5255 5256 5257 |
# File 'lib/HDLRuby/hruby_high.rb', line 5255 def self.names_push NameStack.push(Set.new) end |
.rcsim(top, name, outpath, outmode) ⇒ Object
Starts the simulation for top system +top+. NOTE: +name+ is the name of the simulation, +outpath+ is the path where the output is to save, and +outmode+ is the output mode as follows: 0: standard 1: mute 2: vcd
85 86 87 |
# File 'lib/HDLRuby/hruby_rcsim.rb', line 85 def self.rcsim(top,name,outpath,outmode) RCSim.rcsim_main(top.rcsystemT,outpath +"/" + name,outmode) end |
.space_call(name, *args, &ruby_block) ⇒ Object
Looks up and calls method +name+ from the namespace stack with arguments +args+ and block +ruby_block+.
4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 |
# File 'lib/HDLRuby/hruby_high.rb', line 4691 def self.space_call(name,*args,&ruby_block) # print "space_call with name=#{name}\n" # Ensures name is a symbol. name = name.to_sym # Look from the top of the namespace stack. Namespaces.reverse_each do |space| # puts "space=#{space.singleton_methods}" if space.respond_to?(name) then # print "Found is space user with class=#{space.user.class}\n" # The method is found, call it. return space.send(name,*args,&ruby_block) elsif space.user.respond_to?(name) then # The method is found in the user, call it. return space.user.send(name,*args,&ruby_block) end end # Look in the global methods. if HDLRuby::High.respond_to?(name) then # Found. return HDLRuby::High.send(name,*args,&ruby_block) end # Not found. raise NotDefinedError, "undefined HDLRuby construct, local variable or method `#{name}'." end |
.space_each(&ruby_block) ⇒ Object
Iterates over each namespace.
Returns an enumerator if no ruby block is given.
4594 4595 4596 4597 4598 4599 |
# File 'lib/HDLRuby/hruby_high.rb', line 4594 def self.space_each(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:space_each) unless ruby_block # A block? Apply it on each system instance. Namespaces.each(&ruby_block) end |
.space_include?(namespace) ⇒ Boolean
Tells if +namespace+ in included within the stack.
4552 4553 4554 |
# File 'lib/HDLRuby/hruby_high.rb', line 4552 def self.space_include?(namespace) return Namespaces.include?(namespace) end |
.space_index(namespace) ⇒ Object
Gets the index of a +namespace+ within the stack.
4557 4558 4559 |
# File 'lib/HDLRuby/hruby_high.rb', line 4557 def self.space_index(namespace) return Namespaces.index(namespace) end |
.space_insert(index, namespace) ⇒ Object
Inserts +namespace+ at +index+.
4539 4540 4541 |
# File 'lib/HDLRuby/hruby_high.rb', line 4539 def self.space_insert(index,namespace) Namespaces.insert(index.to_i,namespace.to_namespace) end |
.space_pop ⇒ Object
Pops a namespace.
4544 4545 4546 4547 4548 4549 |
# File 'lib/HDLRuby/hruby_high.rb', line 4544 def self.space_pop if Namespaces.size <= 1 then raise AnyError, "Internal error: cannot pop further namespaces." end Namespaces.pop end |
.space_push(namespace) ⇒ Object
Pushes +namespace+.
4531 4532 4533 4534 4535 4536 |
# File 'lib/HDLRuby/hruby_high.rb', line 4531 def self.space_push(namespace) # Emsure namespace is really a namespace. namespace = namespace.to_namespace # Adds the namespace to the top. Namespaces.push(namespace) end |
.space_reg(name, &ruby_block) ⇒ Object
Registers hardware referencing method +name+ to the current namespace.
4684 4685 4686 4687 |
# File 'lib/HDLRuby/hruby_high.rb', line 4684 def self.space_reg(name,&ruby_block) # print "registering #{name} in #{Namespaces[-1]}\n" Namespaces[-1].add_method(name,&ruby_block) end |
.space_top ⇒ Object
Gets the top of the namespaces stack.
4562 4563 4564 |
# File 'lib/HDLRuby/hruby_high.rb', line 4562 def self.space_top Namespaces[-1] end |
.space_top=(top) ⇒ Object
sets the top namespace.
4567 4568 4569 4570 4571 4572 |
# File 'lib/HDLRuby/hruby_high.rb', line 4567 def self.space_top=(top) unless top.is_a?(Namespace) then raise "Invalid class for a Namspace: #{top.class}" end Namespaces[-1] = top end |
.top_block(level = 0) ⇒ Object
Gets the top enclosing block if any.
4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 |
# File 'lib/HDLRuby/hruby_high.rb', line 4670 def self.top_block(level = 0) blk = cur_block(level) unless blk.is_a?(Block) raise AnyError, "Not within a block: #{blk.user.class}" end if Namespaces[-1-level-1].user.is_a?(Scope) then return blk else return top_block(level+1) end end |
.top_user ⇒ Object
Gets construct whose namespace is the top of the namespaces stack.
4576 4577 4578 |
# File 'lib/HDLRuby/hruby_high.rb', line 4576 def self.top_user self.space_top.user end |
.vcd_bitstr(str) ⇒ Object
Converts a bit string to a vcd format.
15 16 17 18 19 20 21 |
# File 'lib/HDLRuby/hruby_rsim_vcd.rb', line 15 def self.vcd_bitstr(str) if str.length > 1 then return "b" + str + " " else return str end end |
.vcd_idstr(obj) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/HDLRuby/hruby_rsim_vcd.rb', line 26 def self.vcd_idstr(obj) idstr = @@rsim_object_idstr[obj] unless idstr then # Must generate a new id string. chars = [] id = @@rsim_object_idstr_count @@rsim_object_idstr_count += 1 loop do chars << ((id % (127-33)) + 33).chr break if ((id=id/(127-33)) == 0) end idstr = chars.join @@rsim_object_idstr[obj] = idstr end return idstr end |
.vcd_name(name) ⇒ Object
Converts a HDLRuby name to a VCD name.
10 11 12 |
# File 'lib/HDLRuby/hruby_rsim_vcd.rb', line 10 def self.vcd_name(name) return name.to_s.gsub(/[^a-zA-Z0-9_$]/,"$") end |
Instance Method Details
#curry_with_context(*args, &ruby_block) ⇒ Object
Reimplementation of the Proc's curry that transmit the context for execution.
31 32 33 34 35 |
# File 'lib/HDLRuby/hruby_high.rb', line 31 def curry_with_context(*args,&ruby_block) return proc do |cxt,*new_args| cxt.instance_exec(*(args+new_args),&ruby_block) end end |
#function(name, &ruby_block) ⇒ Object
Declares a function named +name+ using +ruby_block+ as body.
NOTE: a function is a short-cut for a method that creates a scope.
2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 |
# File 'lib/HDLRuby/hruby_high.rb', line 2200 def function(name, &ruby_block) warn("Construct 'function' is deprecated, use 'hdef' instead.") # Ensure there is a block. ruby_block = proc {} unless block_given? if HDLRuby::High.in_system? then define_singleton_method(name.to_sym) do |*args,&other_block| sub(HDLRuby.uniq_name(name)) do HDLRuby::High.top_user.instance_exec(*args,*other_block, &ruby_block) end end else define_method(name.to_sym) do |*args,&other_block| sub(HDLRuby.uniq_name(name)) do HDLRuby::High.top_user.instance_exec(*args,*other_block, &ruby_block) end end end end |
#hdef(name, &ruby_block) ⇒ Object
Declares a function named +name+ using +ruby_block+ as body.
NOTE: a function is a short-cut for a method that creates a scope.
2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 |
# File 'lib/HDLRuby/hruby_high.rb', line 2224 def hdef(name, &ruby_block) # Ensure there is a block. ruby_block = proc {} unless block_given? if HDLRuby::High.in_system? then define_singleton_method(name.to_sym) do |*args,&other_block| sub(HDLRuby.uniq_name(name)) do HDLRuby::High.top_user.instance_exec(*args,*other_block, &ruby_block) end end else define_method(name.to_sym) do |*args,&other_block| sub(HDLRuby.uniq_name(name)) do HDLRuby::High.top_user.instance_exec(*args,*other_block, &ruby_block) end end end end |
#infinity ⇒ Object
Gets the infinity.
25 26 27 |
# File 'lib/HDLRuby/hruby_high.rb', line 25 def infinity return HDLRuby::Infinity end |
#instance(name, *includes, &ruby_block) ⇒ Object
Declares a high-level system instance named +name+, with +includes+ mixins system types and using +ruby_block+ for instantiating.
NOTE: this is for generating directly an instance without declaring it system type.
2186 2187 2188 2189 2190 2191 2192 2193 |
# File 'lib/HDLRuby/hruby_high.rb', line 2186 def instance(name, *includes, &ruby_block) # Ensure there is a block. ruby_block = proc {} unless block_given? # Creates the system type. systemT = system(:"",*includes,&ruby_block) # Instantiate it with +name+. return systemT.instantiate(name) end |
#set_this(obj = proc { RefThis.new }) ⇒ Object
Sets the current this to +obj+.
NOTE: do not use a this= style to avoid confusion.
3639 3640 3641 3642 3643 3644 3645 |
# File 'lib/HDLRuby/hruby_high.rb', line 3639 def set_this(obj = proc { RefThis.new }) if (obj.is_a?(Proc)) then @@this = obj else @@this = proc { RefObject.new(RefThis.new,obj) } end end |
#struct(content) ⇒ Object
Creates an unnamed structure type from a +content+.
2127 2128 2129 |
# File 'lib/HDLRuby/hruby_high.rb', line 2127 def struct(content) return TypeStruct.new(:"",:little,content) end |
#system(name = :"", *includes, &ruby_block) ⇒ Object
Declares a high-level system type named +name+, with +includes+ mixins system types and using +ruby_block+ for instantiating.
2173 2174 2175 2176 2177 2178 2179 |
# File 'lib/HDLRuby/hruby_high.rb', line 2173 def system(name = :"", *includes, &ruby_block) # Ensure there is a block. ruby_block = proc {} unless block_given? # print "system ruby_block=#{ruby_block}\n" # Creates the resulting system. return SystemT.new(name,*includes,&ruby_block) end |
#this ⇒ Object
Gives access to the this reference.
3649 3650 3651 3652 |
# File 'lib/HDLRuby/hruby_high.rb', line 3649 def this # RefThis.new @@this.call end |
#typedef(name, &ruby_block) ⇒ Object
Declares a high-level generic type named +name+, and using +ruby_block+ for construction.
2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 |
# File 'lib/HDLRuby/hruby_high.rb', line 2135 def typedef(name, &ruby_block) # Ensure there is a block. ruby_block = proc {} unless block_given? type = TypeGen.new(name,&ruby_block) if HDLRuby::High.in_system? then # Must be inside a scope. unless HDLRuby::High.top_user.is_a?(Scope) then raise AnyError, "A local type cannot be declared within a #{HDLRuby::High.top_user.class}." end define_singleton_method(name.to_sym) do |*args| if (args.size < ruby_block.arity) then # Not enough arguments get generic type as is. type else # There are arguments, specialize the type. gtype = type.generate(*args) # And add it as a local type of the system. HDLRuby::High.top_user.add_type(gtype) gtype end end else define_method(name.to_sym) do |*args| if (args.size < ruby_block.arity) then # Not enough arguments, get generic type as is. type else # There are arguments, specialize the type. type.generate(*args) end end end end |