Programming languages must be implemented in Java or C, everybody knows this. Sure, a prototype in Ruby, but that would be unusable. After all, Ruby is made for web development, right? Hard tasks, like implementing a compiler, have to happen in far more manly languages. But wait, the Rubinius compiler is written completely in Ruby, and it seems to get pretty decent performance, maybe we can use that.
In this talk, we will explore the possibilities of using the Rubinius compiler tool chain to implement our own programming language targeting the Rubinius VM. We get all the hard work that went into Rubinius for free and above all, can do the heavy lifting in Ruby, everyone's favorite programming language.
As an example we'll use Reak, a Smalltalk implementation running on Rubinius.
13. "When you don't create things, you become
defined by your tastes rather than ability. Your
tastes only narrow and exclude people. So
create."
why the lucky stiff
15. About programming languages:
"I don’t like any of them, and I don’t think any of
them are suitable for the real programming
problems of today, whether for systems or for
end-users"
Alan Kay
42. class Object
dynamic_method(:display) do |g|
g.push_self
g.push_local(0) # first argument
g.send(:puts, 1, true)
g.ret
end
end
display "Hello World"
45. class Reak::Compiler < Rubinius::Compiler
class Parser < Stage
stage :parser
next_stage Generator
end
end
46. class CustomNode < Reak::AST::Base
def self.bootstrap_grammar(g)
# grammar definition
end
def bytecode(g)
# bytecode definition
end
end
47. class ConstantAccess < Rubinius::AST::ConstantAccess
include Reak::AST::Node
Reak::AST::Primary.push self
def self.bootstrap_grammar(g)
g.t /[A-Z][a-zA-Z0-9_]*/
end
# no bytecode definition necessary
end
50. Reak.AST.Base subclass: #Cascade [
Reak.AST.Expression push: self.
bytecode: g [
g pushSelf.
cascadedSends do:
[:send |
g dup.
send bytecode: g.
g pop ].
lastSend bytecode: g.
]
]