-
Notifications
You must be signed in to change notification settings - Fork 2
Yadriggy C Examples
The source code of the following examples are under yadriggy/examples.
When the DSL code refers to a variable out of the DSL code, the value of the variable is copied during the translation into C code. For example,
require 'yadriggy/c'
include Yadriggy::C::CType
def fib(n) ! Integer
typedecl n: Integer
if n > 1
return fib(n - 1) + fib(n - 2)
else
return n
end
end
n = 32
puts Yadriggy::C.run { return fib(n) }
The argument to fib
is take from the variable n
that exists
outside of the block. n
is passed to the compiled block by copying.
It is not passed by reference. Thus, when a new value is assigned to
n
within the compiled block, it is not visible from the Ruby code.
The variable n
in the Ruby code keeps the old value.
A compiled method can be repeatedly invoked. To do so, first define
a subclass of Yadriggy::C::Program
:
require 'yadriggy/c'
class Fib < Yadriggy::C::Program
def fib(n) ! Integer
typedecl n: Integer
if n > 1
return fib(n - 1) + fib(n - 2)
else
return n
end
end
end
Then compile all the public methods in Fib
:
m = Fib.compile
The compile
method returns a module that contains a stub method
invoking the compiled fib
method. To invoke it, simply do:
puts m.fib(32)
puts m.fib(30)
It is also possible to generate a Ruby script to load the generated binary later. For example,
m = Fib.compile('FastFib')
This generates yadriggy_tmp/fastfib.rb
. It loads the FastFib
module
with the compiled method fib
.
require 'yadriggy_tmp/fastfib'
puts FastFib.fib(31)
Passing an array to a compiled method is supported.
The type of array is either arrayof(Int)
or arrayof(Float)
.
The length of array has to be also passed.
require 'yadriggy/c'
class ArrayToC < Yadriggy::C::Program
def inc(a, b, n) ! Void
typedecl a: arrayof(Int), b: arrayof(Int), n: Int
for i in 0...n
b[i] = a[i] + 1
end
end
end
To call inc
, first, special array objects are created;
they are instances of Yadriggy::C::CType::IntArray
or FloatArray
and they are accessible from both the Ruby code and the
offloaded inc
method.
Regular Ruby arrays are not available in the method.
include Yadriggy::C::CType
a_in = IntArray.new(5) # an array object that can be passed to C code.
a_in.set_values {|i| i } # a_in[i] = i
a_in[0] = 7
a_out = IntArray.new(5)
ArrayToC.compile.inc(a_in, a_out, a_in.size) # compile and run
puts a_out.to_a # convert a_out into a Ruby array and print it.
In the compiled method written in the DSL,
control structures such as for
and if
are available.
Moreover, the times
method is available on an integer.
The inc
method above can be rewritten as follows:
def inc(a, b, n) ! Void
typedecl a: arrayof(Int), b: arrayof(Int), n: Int
n.times do |i|
b[i] = a[i] + 1
end
end
The block parameter i
is a loop counter. Note that a block
argument is only available for times
in the DSL. times
in the DSL
is not a method but a special syntax form provided
for Ruby-like programming experience.
Currently, IntArray
or FloatArray
does not accept times
.