Skip to content

Yadriggy C

chibash edited this page Jun 14, 2018 · 13 revisions

An embedded DSL similar to the C language.

Overview

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.

Example

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.

Types

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.

Literals

Only numbers and simple strings are valid literals. Either symbols, arrays, or hashes are not valid.

Type declaration

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.

Operators

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.

Statements

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.

Array

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.

Builtin functions

native: and foreign:

Object orientation

Object orientation is not supported. The object creation by new, instance variables such as @field, or class variables such as @@cvar are not supported.

Compile and run

Clone this wiki locally