# Stumped

**URL:** <https://www.ruby-forum.com/t/stumped/133268>\
**Category:** Ruby\
**Created:** [March 29, 2008, 3:35pm UTC](https://www.ruby-forum.com/t/stumped/133268 "2008-03-29T15:35:18Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jeffpritchard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/43a26b/32.png) [@jeffpritchard](https://www.ruby-forum.com/u/jeffpritchard)\
**Post date:** [March 29, 2008, 3:35pm UTC](https://www.ruby-forum.com/t/stumped/133268/1 "2008-03-29T15:35:18Z")

</div>

# I’m learning ruby by writing a hardware simulator. Since the users will be first year EE majors with no software skills, it is important that the syntax they will use to describe circuits be as clean and intuitive as possible. With some helpful hints obtained in an earlier post on this forum, I’ve got the netlist description down to this

class Top \< NetList

def initialize(name);super

```
    #instantiate the blocks
    create 'Nco', NCO

```

create ‘clk’, Clk  
create ‘fifo1’,ShiftReg,4

```
    #provide a control interface
    create 'nCnfg', CtrlInfc, { # :field =>length (lsb ->

```

msb)  
:AngMod =\> 1,  
:AngModTyp =\> 1,  
:AngModScl =\> 5,  
:PhsRnd =\> 1,  
:AmpRnd =\> 1,  
:SpurElim =\> 1,  
:SwpTyp =\> 1,  
:Swp =\> 1,  
:BbSrc =\> 1,  
:MrkSrc =\> 1,  
:PnPolySel =\> 1  
}

```
    #wire 'em up

```

@clk.bind(@Nco[:Clk\_in])  
@clk.bind(@fifo1[:Clk])  
@nCnfg[:ANGMOD].bind(@Nco[:freq])  
@nCnfg[:BV].bind(@fifo1[:D])  
end  
#read control cmds from stdin

#run method inherited from Netlist super class  
def run()  
cmd=’’  
print “ready\>”  
while((cmd=gets) !~ /^.$/)  
begin  
eval cmd,binding()  
rescue Exception=\>e  
puts e.message  
end  
print “ready\>”  
end  
end  
end

sim=Simulation.new(Top.new(“DDS”))  
sim.run()

=======================

The simulation can be controlled either interactively or from a file  
that might look like:

@Nco[:Rst].set(true)  
@nCnfg[:bv]=0  
yield 1  
@Nco[:Rst].set(false)  
@nCnfg[:AngMod]=1  
yield 10  
@nCnfg.set(:AngMod =\>0.01,:ModType =\>0)  
yield 10

these command are read in the run method above which pass them to eval  
to set certain nodes in the simulation to certain values. A yield  
command advances the simulation by yielding to the simulator’s run  
method which advances the indicated number of steps.

So far so good. But eval seems to barf if I give it more than one  
command per line. I.e. what I want to be able to do pass in a command  
something like

10.times{ some\_node.set(some\_value);yield 1;n+=1}

and have it work as expected. Instead the eval gives  
./systemR.rb:24: warning: multiple values for a block parameter (0 for  
1)

and the simulation does not advance.

In case it helps, here’s the simulators run method that is being yielded  
to:

@sim.run{|cyc|  
while (cyc\>0)  
puts “\n#@cycles”  
#update the system clocks-causes scheduled clock outputs to update  
@clks.each{|x| x.update}  
#update asynchronous elements-causes their listners to schedule an  
update  
@elements.each{|x| x.update}  
#empty the scheduler queue  
@elements=[]  
@cycles += 1  
cyc -= 1  
end  
}  
end

I think the basic problem boils down to this: I need the method and  
block to cooperate like

block statement #1  
block block statement #1  
block block yield  
\<---- method returns here  
block block end  
block statement #2  
block yield  
\<----- method returns here

when blocks are nested  
Any ideas?

Thanks in advance  
Jeff

---

<div class="post-metadata">

**Author:** ![jeffpritchard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/43a26b/32.png) [@jeffpritchard](https://www.ruby-forum.com/u/jeffpritchard)\
**Post date:** [March 29, 2008, 5:58pm UTC](https://www.ruby-forum.com/t/stumped/133268/2 "2008-03-29T17:58:31Z")

</div>

Jeff Patterson wrote:

> ```
> print "ready>"
> end
> end
> 
> ```
> 
> end

One suggestion: use readline. It’s more user friendly.

A minimal example is:

require “readline”  
while line=Readline.readline("\> ", true)  
puts line  
end

The above, though simple, has cmdline history and editing. For command  
completion, you can do something like this:

require “readline”  
require “abbrev”

commands = %w{foo bar baz quux}  
abbrevs = commands.abbrev

Readline.completion\_proc = proc {|str| abbrevs[str]}

puts “Commands are #{commands.join(” “)}. Use ^D to quit.”

while line=Readline.readline("\> ", true)  
puts line  
end

(But note that this doesn’t handle the “bar”/“baz” amibiguity. The  
completion proc would have to be smarter for that.)

---

<div class="post-metadata">

**Author:** ![jeffpritchard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/43a26b/32.png) [@jeffpritchard](https://www.ruby-forum.com/u/jeffpritchard)\
**Post date:** [March 29, 2008, 6:15pm UTC](https://www.ruby-forum.com/t/stumped/133268/3 "2008-03-29T18:15:44Z")

</div>

Joel VanderWerf wrote:

> > ```
> > end
> > print "ready>"
> > end
> > end
> > 
> > ```
> > 
> > end
> 
> One suggestion: use readline. It’s more user friendly.

On second thought, since you’re evaling the input, you might want to  
hook your simulation engine up to irb. This uses readline, too, but has  
the advantage of maintaining program state between lines, so that you  
can define local vars, methods, etc. Also, it accepts multiline inputs.

This is the snippet I start from when I want to do that:

require ‘irb’  
require ‘irb/completion’

module IRB  
def IRB.parse\_opts  
# Don’t touch ARGV, which belongs to the app which called this  
module.  
end

def IRB.start\_session(\*args)  
unless $irb  
IRB.setup nil  
## maybe set some opts here, as in parse\_opts in irb/init.rb?  
end

```
 workspace = WorkSpace.new(*args)

 if @CONF[:SCRIPT] ## normally, set by parse_opts
   $irb = Irb.new(workspace, @CONF[:SCRIPT])
 else
   $irb = Irb.new(workspace)
 end

 @CONF[:IRB_RC].call($irb.context) if @CONF[:IRB_RC]
 @CONF[:MAIN_CONTEXT] = $irb.context

 trap 'INT' do
   $irb.signal_handle
 end

 custom_configuration if defined?(IRB.custom_configuration)

 catch :IRB_EXIT do
   $irb.eval_input
 end

 ## might want to reset your app's interrupt handler here

```

end  
end

class Object  
include IRB::ExtendCommandBundle # so that Marshal.dump works  
end

if **FILE** == $0  
x = Object.new  
puts “\nStarted irb shell for x”  
IRB.start\_session(x)  
puts “\nStarted irb shell for x with current binding”  
IRB.start\_session(binding, x)  
puts “\nRestarted irb shell for x with current binding”  
$irb.eval\_input  
puts “\nExited irb shell”  
p x  
end

---

<div class="post-metadata">

**Author:** ![jeffpritchard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/43a26b/32.png) [@jeffpritchard](https://www.ruby-forum.com/u/jeffpritchard)\
**Post date:** [March 30, 2008, 4:45pm UTC](https://www.ruby-forum.com/t/stumped/133268/4 "2008-03-30T16:45:42Z")

</div>

Joel VanderWerf wrote:

> Joel VanderWerf wrote:

> On second thought, since you’re evaling the input, you might want to  
> hook your simulation engine up to irb. This uses readline, too, but has  
> the advantage of maintaining program state between lines, so that you  
> can define local vars, methods, etc. Also, it accepts multiline inputs.

Thanks for your suggestions. I tried the irb approach and while command  
history is very nice.

The error I am (still) getting turns out to stem from the fact that in  
the loop I was trying to execute, I said “yield” instead of “yield 1”.  
Is there a way to default a parameter passed to a block the same way you  
can default arguments passed to a method? i.e if @sim is my netlist  
whose run method reads in the commands, I want to do something like

@sim.run{|cyc =1| # ERROR  
while (cyc\>0)  
…advance the simulator cyc cycles  
end  
}

I tried  
@sim.run{|cyc|  
cyc ||= 1  
…

which keeps the program from bombing but I still get the warning

Thanks for your help!

Jeff

---

<div class="post-metadata">

**Author:** ![jeffpritchard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/43a26b/32.png) [@jeffpritchard](https://www.ruby-forum.com/u/jeffpritchard)\
**Post date:** [March 30, 2008, 5:18pm UTC](https://www.ruby-forum.com/t/stumped/133268/5 "2008-03-30T17:18:35Z")

</div>

Jeff Patterson wrote:

> I tried  
> @sim.run{|cyc|  
> cyc ||= 1  
> …
> 
> which keeps the program from bombing but I still get the warning

@sim.run{|\*c|  
cyc=c[0] || 1

works but seems a little klunky.
