项目作者: csg-tokyo

项目描述 :
A framework for embedded DSLs in Ruby
高级语言: Ruby
项目地址: git://github.com/csg-tokyo/yadriggy.git
创建时间: 2018-06-05T08:34:07Z
项目社区:https://github.com/csg-tokyo/yadriggy

开源协议:MIT License

下载


Yadriggy

Yadriggy (mistletoe in English) is a library for building a
domain-specific language (DSL) embedded in Ruby. It was developed for
a particular kind of embedded DSLs.
These DSLs borrow the syntax from the host language, Ruby, and the
code written in the DSLs is embedded in normal Ruby code. However,
the execution of the DSL code is independent of Ruby. Its semantics
can be totally different from Ruby and the code can be run out of the
Ruby VM. These DSLs look like Ruby but they are different
languages except their syntax.
They are embedded in Ruby by borrowing the syntax but their embedding is
outward; their execution engines are their own.

For details, the documentation is available from Wiki.

An example

Computation offloading from Ruby is a typical example of the DSLs
implemented by Yadriggy.
For example, Yadriggy provides a simple DSL to offload
from Ruby to native C language.

  1. require 'yadriggy/c'
  2. include Yadriggy::C::CType
  3. def fib(n) ! Integer
  4. typedecl n: Integer
  5. if n > 1
  6. return fib(n - 1) + fib(n - 2)
  7. else
  8. return n
  9. end
  10. end
  11. 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.

An external variable is accessible from the compiled block:

  1. n = 32
  2. 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.

Note that the definition of fib contains type declarations
since this DSL is not Ruby.
This DSL looks like Ruby but it is a different language.
! Integer following def fib(n) specifies the return type.
typedecl specifies the types of the parameters (and local variables
if any). In this DSL, most types have to be statically given
although the DSL performs simple type inference and some types
can be omitted.

Library

Yadriggy provides a method for obtaining the abstract syntax tree (AST)
of the given method, lambda, or Proc.
It also provides a syntax checker that determines whether or not an AST
satisfies the syntax described in the BNF-like language, which is
a DSL embedded in Ruby by Yadriggy.

You can even obtain the AST of a piece of source code:

  1. require 'yadriggy'
  2. ast = Yadriggy.reify {|a| a + 1 }

reify returns the AST of the given block {|a| a + 1 }.
It takes not only a block but also a Method or Proc object.

Yadriggy works with Pry and IRuby unless a syntax error occurs.

The idea of reify was proposed in the following paper:

  • Shigeru Chiba, YungYu Zhuang, Maximilian Scherr, “Deeply Reifying Running Code for Constructing a Domain-Specific Language”, PPPJ’16, Article No. 1, ACM, August 2016.

Yadriggy-Py was presented in the following paper:

  • Shigeru Chiba, Foreign language interfaces by code migration, Proc. of the 18th ACM SIGPLAN International Conference on Generative Programming: Concepts and Experiences (GPCE 2019), pp. 1-13, ACM, 2019.

Installation

To install, run:

  1. $ gem install yadriggy

or, download this repository and run:

  1. $ bundle exec rake install

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/csg-tokyo/yadriggy.

License

The gem is available as open source under the terms of the MIT License.