Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
This paste will be private.
require 'compiler/duby' module Duby module Compiler class C class MathCompiler def call(compiler, name, recv, args) recv.call compiler.src << " #{name} " args.call end end attr_accessor :filename, :src def initialize(filename) @filename = filename @src = "" self.type_mapper[AST::TypeReference.new(:fixnum)] = "int" self.call_compilers[AST::TypeReference.new(:fixnum)] = MathCompiler.new end def compile(ast) ast.compile(this) end def define_method(name, signature, args, body) @src << "#{type_mapper[signature[:return]]} #{name}(" args.call @src << ") {" body.call @src << "}\n\n" end def declare_argument(name, type) @src << "#{type_mapper[type]} #{name}" end def branch(condition, body_proc, else_proc) @src << "if (" condition.call @src << ") {" body_proc.call if else_proc @src << "} else {" else_proc.call end @src << "}" end def call(name, recv_type, recv, args) call_compilers[recv_type].call(self, name, recv, args) end def call_compilers @call_compilers ||= {} end def self_call(name, args) @src << "#{name}(" args.call @src << ")" end def local(name) @src << name end def fixnum(value) @src << value.to_s end def newline @src << ";\n" end def ret @src << "return " yield end def generate @src end def type_mapper @type_mapper ||= {} end end end module AST class Script def compile(compiler) # preparations for the .c file would go here body.compile(compiler) end end class Body def compile(compiler) last = children[-1] children.each do |child| child.compile(compiler) compiler.newline end end end class MethodDefinition def compile(compiler) args_callback = proc {arguments.compile(compiler)} body_callback = proc {body.compile(compiler)} compiler.define_method(name, signature, args_callback, body_callback) end end class Arguments def compile(compiler) args.each {|arg| compiler.declare_argument(arg.name, arg.inferred_type)} if args end end class Noop def compile(compiler) # nothing end end class Fixnum def compile(compiler) compiler.fixnum(literal) end end class If def compile(compiler) cond_callback = proc { condition.compile(compiler) } body_callback = proc { body.compile(compiler) } else_callback = proc { self.else.compile(compiler)} compiler.branch(cond_callback, body_callback, else_callback) end end class Condition def compile(compiler) predicate.compile(compiler) end end class FunctionalCall def compile(compiler) args_callback = proc { parameters.each {|param| param.compile(compiler)}} compiler.self_call(name, args_callback) end end class Call def compile(compiler) recv_callback = proc { target.compile(compiler) } args_callback = proc { parameters.each {|param| param.compile(compiler)}} compiler.call(name, target.inferred_type, recv_callback, args_callback) end end class Local def compile(compiler) compiler.local(name) end end end end if __FILE__ == $0 ast = Duby::AST.parse(File.read(ARGV[0])) typer = Duby::Typer::Simple.new(:script) ast.infer(typer) typer.resolve(true) compiler = Duby::Compiler::C.new("#{ARGV[0]}.c") ast.compile(compiler) File.open(compiler.filename, "w") {|file| file.write(compiler.generate)} end
Pasted March 24, 2008 7:08PM EDT
by headius
Channel #rubinius on irc.freenode.com
Embed