Created
October 13, 2014 00:20
-
-
Save asterite/370389c5e61f810c398a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require "compiler/crystal/**" | |
| include Crystal | |
| class MyVisitor < Visitor | |
| def initialize | |
| @str = StringIO.new | |
| end | |
| def visit(node : ClassDef) | |
| @str << %(_class = Ruby::Class.new "#{node.name}"\n) | |
| end | |
| def visit(node : Def) | |
| @str << %(_class.def "#{node.name}", #{node.args.length}, ) | |
| @str << %[->(self : LibRuby::VALUE, ] | |
| node.args.each do |arg| | |
| @str << %(#{arg.name} : LibRuby::VALUE, ) | |
| end | |
| @str << %[) do\n] | |
| @str << node.body | |
| @str << %(\nend) | |
| false | |
| end | |
| def visit(node : Nop) | |
| end | |
| def visit(node : ASTNode) | |
| raise "Unexpected node: #{node}" | |
| end | |
| def to_s(io : IO) | |
| io << @str | |
| end | |
| end | |
| node = Parser.parse(ARGV[0].gsub(/\\n/, "\n")) | |
| visitor = MyVisitor.new | |
| node.accept visitor | |
| visitor.to_s(STDOUT) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| lib LibRuby | |
| type VALUE = Void* | |
| type ID = Void* | |
| $rb_cObject : VALUE | |
| fun rb_define_global_function(name : UInt8*, f : Void*, args : Int32) | |
| fun rb_eval_string(str : UInt8*) : VALUE | |
| fun rb_str_new_cstr(str : UInt8*) : VALUE | |
| fun rb_define_class(name : UInt8*, parent : VALUE) : VALUE | |
| fun rb_define_method(clazz : VALUE, name : UInt8*, f : Void*, args : Int32) | |
| fun rb_any_to_s(v : VALUE) : VALUE | |
| fun rb_string_value_cstr(v : VALUE*) : UInt8* | |
| fun rb_intern(name : UInt8*) : ID | |
| fun rb_funcall(obj : VALUE, func : ID, args : Int32, ...) : VALUE | |
| end | |
| struct Nil | |
| def to_ruby | |
| Pointer(Void).new(8_u64) as LibRuby::VALUE | |
| end | |
| end | |
| struct Bool | |
| def to_ruby | |
| Pointer(Void).new(self ? 0_u64 : 20_u64) as LibRuby::VALUE | |
| end | |
| end | |
| class String | |
| def to_ruby | |
| LibRuby.rb_str_new_cstr(self) | |
| end | |
| end | |
| module Ruby | |
| ID_TO_S = LibRuby.rb_intern("to_s") | |
| struct Class | |
| def initialize(name) | |
| @class = LibRuby.rb_define_class(name, LibRuby.rb_cObject) | |
| end | |
| def def(name, args, f) | |
| LibRuby.rb_define_method(@class, name, f.pointer, args) | |
| end | |
| end | |
| struct Value | |
| @value :: LibRuby::VALUE | |
| def initialize(@value : LibRuby::VALUE) | |
| end | |
| def to_unsafe | |
| @value | |
| end | |
| def to_s | |
| str = LibRuby.rb_funcall(self, ID_TO_S, 0) | |
| String.new(LibRuby.rb_string_value_cstr(pointerof(str))) | |
| end | |
| end | |
| def self.global_def(name, args, f) | |
| LibRuby.rb_define_global_function(name, f.pointer, args) | |
| end | |
| end | |
| macro ruby(code) | |
| {{ run "ruby_processor", code }} | |
| end | |
| ruby( | |
| class Foo | |
| def foo(a) | |
| a = Ruby::Value.new(a) | |
| "From Crystal!! #{a.to_s}".to_ruby | |
| end | |
| end | |
| ) | |
| redefine_main("Init_testruby") do |main| | |
| {{main}} | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment