-
Notifications
You must be signed in to change notification settings - Fork 2
Yadriggy C
An embedded DSL similar to the C language.
This DSL is used to offload computation from the Ruby VM. The code for the offloaded computation is written in this DSL but embedded in Ruby code. At runtime, the DSL processor locates the DSl code in the Ruby source code. It is parsed, translated into C code, compiled into binary on the fly by an external C compiler, and run through ruby-ffi.
Since the DSL is not Ruby, only the syntax is shared among this DSL and Ruby. In the DSL, only limited kinds of language constructs are available and the DSL code is statically typed. Neither classes or hash maps are available. The code has to be written with C-like language constructs such as functions and arrays but pointers are not supported.
The following program is an 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 1
end
end
puts Yadriggy::C.run { return fib(32) }
When this code is run, the block given to Yadriggy::C.run
is
translated into C code with the definition of fib
method.
Then the C code is compiled into a dynamic library, loaded the
library through ruby-ffi, and executed. Since the block given to
run
calls fib
, the definition of fib
is also translated
into C.
Although the fib
method looks like a normal Ruby method
(and it is normal Ruby code with respect to the syntax),
it is the DSL code.
! Integer
, which follows def
, specifies the return type and
typedecl n: Integer
specifies the type of the parameter n
. Since the DSL is a C-like
language, the resulting value of the method invocation has to be
explicitly returned by the return
statement.
Note that the DSL performs simple type inference. Thus, you do not have to explicitly specify all the types.
For more examples, see this page.
The types available in the DSL code are as follows:
DSL Type | C type |
---|---|
Integer | int32_t |
Int | int32_t |
Float | double |
Float32 | float |
Void | void |
String | char* |
IntArray | int32_t[] |
FloatArray | double[] |
Float32Array | float[] |
arrayof(Integer)
, arrayof(Float)
, and arrayof(Float32)
are
aliases of IntArray
, FloatArray
, and Float32Array
, respectively.
Only numbers and simple strings are valid literals. Either symbols, arrays, or hashes are not valid.
The return type is specified by !
followed by a type name.
It has to be written at the same line as def
's.
The parameter types has to be declared in the next line by typedecl
.
typedecl a: Int, b: Float
This declares that the variable a
has type Int
and the variable b
has type Float
.
A local variable type has to be declared in another typedecl
, which
may be at the third line or later.
The binary operators available in the DSL code are +
, -
, *
, /
, %
,
<
, >
, <=
, >=
, ==
, &&
, and ||
.
-@
(unary minus) is the only unary operator available.
=
, +=
, -=
, and so on are also available for assignment.
an array access such as a[i]
and assignment to an array such as
a[i] = 3
are also supported.
if-elsif-else
and while
statements are available.
Ternary if (?:
) and if
modifier are also available.
for
statement is also supported but the range has to be a range literal in integer. For example,
for i in 0...n
b[i] = a[i] + 1
end
is valid. ...
and ..
are supported. The operands have to be
an integer literal or variable. An array cannot be used as a range.
For looping, the times
method is available when the receiver is
an integer literal or variable. The example above can be
also written as follows:
n.times do |i|
b[i] = a[i] + 1
end
Althoguh it seems that the block is passed to times
as in Ruby,
times
is a special form in this DSL;
yield
or Proc
is not available.
The call to the times
method is translated into a for
statement
in C.
An array object cannot be created in the DSL. All the array objects used in the DSL code have to be created in Ruby code and explicitly passed as an argument to a function written in the DSL.
native: and foreign:
Object orientation is not supported.
The object creation by new
, instance variables such as @field
,
or class variables such as @@cvar
are not supported.