deprecating ruby package
to be replaced by vool and mom
This commit is contained in:
25
stash/rubyx/passes/locals_collector.rb
Normal file
25
stash/rubyx/passes/locals_collector.rb
Normal file
@ -0,0 +1,25 @@
|
||||
module Rubyx
|
||||
module Passes
|
||||
class LocalsCollector < TotalProcessor
|
||||
|
||||
def initialize
|
||||
@locals = {}
|
||||
end
|
||||
|
||||
def collect(statement)
|
||||
process statement
|
||||
@locals
|
||||
end
|
||||
|
||||
def on_lvasgn statement
|
||||
add_local( statement )
|
||||
end
|
||||
|
||||
def add_local(statement)
|
||||
var = statement.children[0]
|
||||
@locals[var] = :Object #not really used right now
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
38
stash/rubyx/passes/method_collector.rb
Normal file
38
stash/rubyx/passes/method_collector.rb
Normal file
@ -0,0 +1,38 @@
|
||||
module Rubyx
|
||||
module Passes
|
||||
|
||||
class MethodCollector < TotalProcessor
|
||||
|
||||
def initialize
|
||||
@methods = []
|
||||
end
|
||||
|
||||
def collect(statement)
|
||||
process statement
|
||||
@methods
|
||||
end
|
||||
|
||||
def on_def(statement)
|
||||
name , args , body = *statement
|
||||
args_type = make_type(args)
|
||||
locals_type = make_locals(body)
|
||||
@methods << Vool::VoolMethod.new(name , args_type , locals_type , body )
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def make_type( statement )
|
||||
type_hash = {}
|
||||
statement.children.each do |arg|
|
||||
type_hash[arg.children[0]] = :Object
|
||||
end
|
||||
Parfait::NamedList.type_for( type_hash )
|
||||
end
|
||||
|
||||
def make_locals(body)
|
||||
type_hash = LocalsCollector.new.collect(body)
|
||||
Parfait::NamedList.type_for( type_hash )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
61
stash/rubyx/passes/method_compiler.rb
Normal file
61
stash/rubyx/passes/method_compiler.rb
Normal file
@ -0,0 +1,61 @@
|
||||
module Rubyx
|
||||
module Passes
|
||||
|
||||
class MethodCompiler < AST::Processor
|
||||
|
||||
def initialize( ruby_method )
|
||||
@ruby_method = ruby_method
|
||||
end
|
||||
|
||||
def get_code
|
||||
process(@ruby_method.source)
|
||||
end
|
||||
|
||||
def on_ivasgn(statement)
|
||||
name , value = *statement
|
||||
w = Vm::Tree::Assignment.new()
|
||||
w.name = Vm::Tree::InstanceName.new( name[1..-1].to_sym)
|
||||
w.value = process(value)
|
||||
w
|
||||
end
|
||||
|
||||
def on_ivar( var )
|
||||
name = var.children.first
|
||||
w = Vm::Tree::FieldAccess.new()
|
||||
w.receiver = Vm::Tree::KnownName.new(:self)
|
||||
w.field = Vm::Tree::InstanceName.new( name[1..-1].to_sym)
|
||||
w
|
||||
end
|
||||
|
||||
def on_send( statement )
|
||||
receiver , name , args = *statement
|
||||
w = Vm::Tree::CallSite.new()
|
||||
w.name = name
|
||||
w.arguments = process(args) || []
|
||||
w.receiver = process(receiver)
|
||||
w
|
||||
end
|
||||
|
||||
def on_lvar(statement)
|
||||
name = statement.children.first.to_sym
|
||||
if(@ruby_method.args_type.variable_index(name))
|
||||
return Vm::Tree::ArgumentName.new(name)
|
||||
end
|
||||
raise "Not found #{name}"
|
||||
end
|
||||
|
||||
def on_str( string )
|
||||
Vm::Tree::StringExpression.new(string.children.first)
|
||||
end
|
||||
|
||||
def on_int( expression)
|
||||
Vm::Tree::IntegerExpression.new(expression.children.first)
|
||||
end
|
||||
|
||||
def handler_missing(node)
|
||||
raise "No handler for #{node}"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
12
stash/rubyx/passes/normalizer.rb
Normal file
12
stash/rubyx/passes/normalizer.rb
Normal file
@ -0,0 +1,12 @@
|
||||
module Rubyx
|
||||
module Passes
|
||||
|
||||
class Normalizer < AST::Processor
|
||||
|
||||
def initialize( ruby_method )
|
||||
@ruby_method
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
14
stash/rubyx/passes/total_processor.rb
Normal file
14
stash/rubyx/passes/total_processor.rb
Normal file
@ -0,0 +1,14 @@
|
||||
module Rubyx
|
||||
|
||||
module Passes
|
||||
class TotalProcessor < AST::Processor
|
||||
|
||||
def handler_missing(node)
|
||||
node.children.each do |kid |
|
||||
process(kid) if kid.is_a?(AST::Node)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
29
stash/rubyx/passes/type_collector.rb
Normal file
29
stash/rubyx/passes/type_collector.rb
Normal file
@ -0,0 +1,29 @@
|
||||
module Rubyx
|
||||
module Passes
|
||||
class TypeCollector < TotalProcessor
|
||||
|
||||
def initialize
|
||||
@ivars = {}
|
||||
end
|
||||
|
||||
def collect(statement)
|
||||
process statement
|
||||
@ivars
|
||||
end
|
||||
|
||||
def on_ivar(statement)
|
||||
add_ivar(statement)
|
||||
end
|
||||
|
||||
def on_ivasgn( statement )
|
||||
add_ivar(statement)
|
||||
end
|
||||
|
||||
def add_ivar(statement)
|
||||
var = statement.children[0].to_s[1..-1].to_sym
|
||||
@ivars[var] = :Object #guess, can maybe guess better
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
64
stash/rubyx/ruby_compiler.rb
Normal file
64
stash/rubyx/ruby_compiler.rb
Normal file
@ -0,0 +1,64 @@
|
||||
require "parser/ruby22"
|
||||
|
||||
require_relative "passes/total_processor"
|
||||
require_relative "passes/type_collector"
|
||||
require_relative "passes/method_collector"
|
||||
require_relative "passes/method_compiler"
|
||||
require_relative "passes/locals_collector"
|
||||
require_relative "passes/normalizer"
|
||||
require "vool/vool_method"
|
||||
|
||||
|
||||
module Rubyx
|
||||
class RubyxCompiler < Passes::TotalProcessor
|
||||
|
||||
def self.compile( input )
|
||||
ast = Parser::Ruby22.parse( input )
|
||||
self.new.process( ast )
|
||||
end
|
||||
|
||||
def on_class statement
|
||||
name , sup , body = *statement
|
||||
class_name = get_name(name)
|
||||
clazz = Parfait.object_space.get_class_by_name(class_name )
|
||||
if(clazz)
|
||||
#FIXME super class check with "sup"
|
||||
else #existing class, don't overwrite type (parfait only?)
|
||||
clazz = Parfait.object_space.create_class(class_name , get_name(sup) )
|
||||
ivar_hash = Passes::TypeCollector.new.collect(body)
|
||||
clazz.set_instance_type( Parfait::Type.for_hash( clazz , ivar_hash ) )
|
||||
end
|
||||
methods = create_methods(clazz , body)
|
||||
compile_methods(clazz,methods)
|
||||
end
|
||||
|
||||
def create_methods(clazz , body)
|
||||
methods = Passes::MethodCollector.new.collect(body)
|
||||
methods.each do |method|
|
||||
clazz.add_method( method )
|
||||
normalizer = Passes::Normalizer.new(method)
|
||||
method.normalize_source { |sourc| normalizer.process( sourc ) }
|
||||
end
|
||||
methods
|
||||
end
|
||||
|
||||
def compile_methods(clazz , methods)
|
||||
methods.each do |method|
|
||||
code = Passes::MethodCompiler.new(method).get_code
|
||||
typed_method = method.create_vm_method(clazz.instance_type)
|
||||
Vm::MethodCompiler.new( typed_method ).init_method.process( code )
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_name( statement )
|
||||
return nil unless statement
|
||||
raise "Not const #{statement}" unless statement.type == :const
|
||||
name = statement.children[1]
|
||||
raise "Not symbol #{name}" unless name.is_a? Symbol
|
||||
name
|
||||
end
|
||||
|
||||
end
|
||||
end
|
101
stash/test_rubyx/fragments/collector.rb
Normal file
101
stash/test_rubyx/fragments/collector.rb
Normal file
@ -0,0 +1,101 @@
|
||||
require_relative '../helper'
|
||||
require "risc/interpreter"
|
||||
require "parser/ruby22"
|
||||
require "yaml"
|
||||
|
||||
# An experiment to find out how much ruby there is to achieve bootstrap
|
||||
#
|
||||
# currently (jan/2017) just under 150 classes, 1.5k methods , 10k sends, only 10 yields
|
||||
# 1 retry and redo (to be avoided), 4 ensure , 5 rescue
|
||||
#
|
||||
class Walker < AST::Processor
|
||||
def initialize collector
|
||||
@collector = collector
|
||||
end
|
||||
|
||||
def on_send node
|
||||
_ , method , file_node = *node
|
||||
if method == :require
|
||||
file = file_node.children[0]
|
||||
@collector.load("#{file}.rb") unless file.include?("parslet")
|
||||
end
|
||||
if method == :require_relative
|
||||
@collector.load File.dirname(@collector.current) + "/" + file_node.children[0] + ".rb"
|
||||
end
|
||||
if method.to_s.include?("eval")
|
||||
@collector.evals << method
|
||||
end
|
||||
handler_missing(node)
|
||||
end
|
||||
|
||||
def on_class node
|
||||
@collector.class_defs << node.children[0].children[1]
|
||||
handler_missing(node)
|
||||
end
|
||||
def on_const node
|
||||
@collector.const_uses[node.children[1]] += 1
|
||||
handler_missing(node)
|
||||
end
|
||||
def handler_missing node
|
||||
type = node.type
|
||||
@collector.types[type] += 1
|
||||
node.children.each do |kid|
|
||||
process(kid) if kid.is_a? AST::Node
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Collector
|
||||
|
||||
def initialize
|
||||
@parser = Parser::Ruby22
|
||||
@paths = Bundler.load.specs.collect { |s| s.gem_dir + "/lib/" }
|
||||
@class_defs = []
|
||||
@const_uses = Hash.new(0)
|
||||
@types = Hash.new(0)
|
||||
@not_found = []
|
||||
@walker = Walker.new(self)
|
||||
@files = []
|
||||
@evals = []
|
||||
@current = nil
|
||||
end
|
||||
attr_reader :class_defs , :const_uses , :types , :current , :evals
|
||||
|
||||
def file_content file_name
|
||||
return nil if @files.include? file_name
|
||||
@paths.each do |name|
|
||||
next unless File.exist? name + file_name
|
||||
@files << file_name
|
||||
return File.open(name + file_name).read
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def run
|
||||
load "rubyx.rb"
|
||||
load "parser/ruby22.rb"
|
||||
# load "../../../.rbenv/versions/2.2.3/lib/ruby/2.2.0/racc/parser.rb"
|
||||
print
|
||||
end
|
||||
|
||||
def load file
|
||||
str = file_content(file)
|
||||
return @not_found.push(file) unless str
|
||||
ast = @parser.parse str
|
||||
was = @current
|
||||
@current = file
|
||||
@walker.process ast
|
||||
@current = was
|
||||
end
|
||||
def print
|
||||
@class_defs.uniq!
|
||||
@files.uniq!
|
||||
puts "Types #{@types.to_yaml}"
|
||||
puts "Class defs #{@class_defs.length}"
|
||||
puts "Class defs #{@class_defs}"
|
||||
puts "evals=#{@evals.length} #{@evals.uniq}"
|
||||
puts "Not found #{@not_found.length} #{@not_found}"
|
||||
end
|
||||
end
|
||||
|
||||
Collector.new.run
|
17
stash/test_rubyx/fragments/helper.rb
Normal file
17
stash/test_rubyx/fragments/helper.rb
Normal file
@ -0,0 +1,17 @@
|
||||
require_relative '../helper'
|
||||
require "risc/interpreter"
|
||||
require "parser/ruby22"
|
||||
|
||||
module Rubyx
|
||||
module RubyxTests
|
||||
include CompilerHelper
|
||||
include Risc::InterpreterHelpers
|
||||
subs = ObjectSpace.each_object(Class).select { |klass| klass < Risc::Instruction }
|
||||
subs.each do |clazz|
|
||||
name = clazz.to_s
|
||||
next if name.include?("Arm")
|
||||
scoped = name.split("::").last
|
||||
module_eval "#{scoped} = #{name}"
|
||||
end
|
||||
end
|
||||
end
|
26
stash/test_rubyx/fragments/test_adds.rb
Normal file
26
stash/test_rubyx/fragments/test_adds.rb
Normal file
@ -0,0 +1,26 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Rubyx
|
||||
class TestRubyAdds < MiniTest::Test
|
||||
include RubyxTests
|
||||
|
||||
def pest_ruby_adds
|
||||
@string_input = <<HERE
|
||||
def fibo( n)
|
||||
a = 0
|
||||
b = 1
|
||||
i = 1
|
||||
while( i < n ) do
|
||||
result = a + b
|
||||
a = b
|
||||
b = result
|
||||
i+= 1
|
||||
end
|
||||
return result
|
||||
end
|
||||
HERE
|
||||
@stdout = "Hello there"
|
||||
check
|
||||
end
|
||||
end
|
||||
end
|
24
stash/test_rubyx/fragments/test_calls.rb
Normal file
24
stash/test_rubyx/fragments/test_calls.rb
Normal file
@ -0,0 +1,24 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Rubyx
|
||||
class TestRubyCalls < MiniTest::Test
|
||||
include RubyxTests
|
||||
|
||||
def pest_ruby_calls
|
||||
@string_input = <<HERE
|
||||
|
||||
def fibo_r( n )
|
||||
if( n < 2 )
|
||||
return n
|
||||
else
|
||||
return fibo_r(n - 1) + fibo_r(n - 2)
|
||||
end
|
||||
end
|
||||
|
||||
fibo 40
|
||||
HERE
|
||||
@stdout = "Hello there"
|
||||
check
|
||||
end
|
||||
end
|
||||
end
|
45
stash/test_rubyx/fragments/test_hello.rb
Normal file
45
stash/test_rubyx/fragments/test_hello.rb
Normal file
@ -0,0 +1,45 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Rubyx
|
||||
class TestRubyHello #< MiniTest::Test
|
||||
include RubyxTests
|
||||
Branch = Risc::Branch
|
||||
Label = Risc::Label
|
||||
|
||||
def setup
|
||||
@string_input = as_main '"Hello there".putstring'
|
||||
Risc.machine.boot
|
||||
# do_clean_compile
|
||||
RubyxCompiler.compile @string_input
|
||||
Risc::Collector.collect_space
|
||||
@interpreter = Risc::Interpreter.new
|
||||
@interpreter.start Risc.machine.init
|
||||
end
|
||||
|
||||
def test_chain
|
||||
#show_ticks
|
||||
check_chain [Branch, Label, LoadConstant, SlotToReg, RegToSlot,
|
||||
LoadConstant, RegToSlot, FunctionCall, Label, LoadConstant,
|
||||
SlotToReg, RegToSlot, SlotToReg, LoadConstant, RegToSlot,
|
||||
LoadConstant, RegToSlot, LoadConstant, SlotToReg, RegToSlot,
|
||||
LoadConstant, RegToSlot, RiscTransfer, FunctionCall, Label,
|
||||
LoadConstant, SlotToReg, RegToSlot, SlotToReg, SlotToReg,
|
||||
RiscTransfer, Syscall, RiscTransfer, RiscTransfer, RegToSlot,
|
||||
Label, FunctionReturn, RiscTransfer, SlotToReg, SlotToReg,
|
||||
Label, FunctionReturn, RiscTransfer, Syscall, NilClass]
|
||||
end
|
||||
|
||||
def test_overflow
|
||||
instruction = ticks( 24 )
|
||||
assert_equal Risc::FunctionCall , instruction.class
|
||||
assert_equal :putstring , instruction.method.name
|
||||
end
|
||||
|
||||
def test_ruby_hello
|
||||
done = ticks(45)
|
||||
assert_equal NilClass , done.class
|
||||
assert_equal "Hello there" , @interpreter.stdout
|
||||
end
|
||||
|
||||
end
|
||||
end
|
16
stash/test_rubyx/fragments/test_itos.rb
Normal file
16
stash/test_rubyx/fragments/test_itos.rb
Normal file
@ -0,0 +1,16 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Rubyx
|
||||
class TestRubyItos < MiniTest::Test
|
||||
include RubyxTests
|
||||
|
||||
def pest_ruby_itos
|
||||
@string_input = <<HERE
|
||||
100000.to_s
|
||||
HERE
|
||||
@stdout = "Hello there"
|
||||
check
|
||||
end
|
||||
|
||||
end
|
||||
end
|
19
stash/test_rubyx/fragments/test_loop.rb
Normal file
19
stash/test_rubyx/fragments/test_loop.rb
Normal file
@ -0,0 +1,19 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Rubyx
|
||||
class TestRubyLoop < MiniTest::Test
|
||||
include RubyxTests
|
||||
|
||||
def pest_ruby_loop
|
||||
@string_input = <<HERE
|
||||
counter = 100000
|
||||
while(counter > 0) do
|
||||
counter -= 1
|
||||
end
|
||||
HERE
|
||||
@stdout = "Hello there"
|
||||
check
|
||||
end
|
||||
|
||||
end
|
||||
end
|
34
stash/test_rubyx/fragments/test_many_adds.rb
Normal file
34
stash/test_rubyx/fragments/test_many_adds.rb
Normal file
@ -0,0 +1,34 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Rubyx
|
||||
class TestManyAdds < MiniTest::Test
|
||||
include RubyxTests
|
||||
|
||||
def pest_ruby_adds_looping
|
||||
@string_input = <<HERE
|
||||
def fibo( n)
|
||||
a = 0
|
||||
b = 1
|
||||
i = 1
|
||||
while( i < n ) do
|
||||
result = a + b
|
||||
a = b
|
||||
b = result
|
||||
i+= 1
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
counter = 100000
|
||||
|
||||
while(counter > 0) do
|
||||
fibo(40)
|
||||
counter -= 1
|
||||
end
|
||||
HERE
|
||||
@length = 37
|
||||
@stdout = "Hello there"
|
||||
check
|
||||
end
|
||||
end
|
||||
end
|
30
stash/test_rubyx/fragments/test_many_calls.rb
Normal file
30
stash/test_rubyx/fragments/test_many_calls.rb
Normal file
@ -0,0 +1,30 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Rubyx
|
||||
class TestManyCalls < MiniTest::Test
|
||||
include RubyxTests
|
||||
|
||||
def pest_ruby_calls_looping
|
||||
@string_input = <<HERE
|
||||
|
||||
def fibo_r( n )
|
||||
if( n < 2 )
|
||||
return n
|
||||
else
|
||||
return fibo_r(n - 1) + fibo_r(n - 2)
|
||||
end
|
||||
end
|
||||
|
||||
counter = 1000
|
||||
|
||||
while(counter > 0) do
|
||||
fibo_r(20)
|
||||
counter -= 1
|
||||
end
|
||||
HERE
|
||||
@length = 37
|
||||
@stdout = ""
|
||||
check
|
||||
end
|
||||
end
|
||||
end
|
21
stash/test_rubyx/fragments/test_many_hello.rb
Normal file
21
stash/test_rubyx/fragments/test_many_hello.rb
Normal file
@ -0,0 +1,21 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Rubyx
|
||||
class TestManyHello < MiniTest::Test
|
||||
include RubyxTests
|
||||
|
||||
def pest_ruby_hello_looping
|
||||
@string_input = <<HERE
|
||||
counter = 100000;
|
||||
while(counter > 0) do
|
||||
puts "Hello there"
|
||||
STDOUT.flush
|
||||
counter = counter - 1
|
||||
end
|
||||
HERE
|
||||
@length = 37
|
||||
@stdout = "Hello there"
|
||||
check
|
||||
end
|
||||
end
|
||||
end
|
22
stash/test_rubyx/fragments/test_many_itos.rb
Normal file
22
stash/test_rubyx/fragments/test_many_itos.rb
Normal file
@ -0,0 +1,22 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Rubyx
|
||||
class TestManyItos < MiniTest::Test
|
||||
include RubyxTests
|
||||
|
||||
def pest_ruby_itos_looping
|
||||
@string_input = <<HERE
|
||||
counter = 100000
|
||||
|
||||
while(counter > 0) do
|
||||
str = counter.to_s
|
||||
counter = counter - 1
|
||||
end
|
||||
str
|
||||
HERE
|
||||
@length = 37
|
||||
@stdout = "Hello Raisa, I am rubyx"
|
||||
check
|
||||
end
|
||||
end
|
||||
end
|
1
stash/test_rubyx/helper.rb
Normal file
1
stash/test_rubyx/helper.rb
Normal file
@ -0,0 +1 @@
|
||||
require_relative '../helper'
|
1
stash/test_rubyx/passes/helper.rb
Normal file
1
stash/test_rubyx/passes/helper.rb
Normal file
@ -0,0 +1 @@
|
||||
require_relative '../helper'
|
37
stash/test_rubyx/passes/test_locals_collector.rb
Normal file
37
stash/test_rubyx/passes/test_locals_collector.rb
Normal file
@ -0,0 +1,37 @@
|
||||
require_relative "helper"
|
||||
|
||||
module Rubyx
|
||||
module Passes
|
||||
class TestLocalsCollector #< MiniTest::Test
|
||||
|
||||
def setup
|
||||
Risc.machine.boot unless Risc.machine.booted
|
||||
end
|
||||
|
||||
def parse_collect( input )
|
||||
ast = Parser::Ruby22.parse input
|
||||
LocalsCollector.new.collect(ast)
|
||||
end
|
||||
|
||||
def test_no_locals
|
||||
locals = parse_collect "def meth; end"
|
||||
assert locals.empty?
|
||||
end
|
||||
|
||||
def test_method_is_not_local
|
||||
locals = parse_collect("def meth2(arg1); foo ;end")
|
||||
assert locals.empty?
|
||||
end
|
||||
|
||||
def test_local_assign_one
|
||||
locals = parse_collect("def meth2(arg1); foo = bar ;end")
|
||||
assert locals[:foo] , locals.inspect
|
||||
end
|
||||
def test_local_assign_two
|
||||
locals = parse_collect("def meth2(arg1); foo = bar ; groove = 1 + 2 ;end")
|
||||
assert locals.length == 2 , locals.inspect
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
39
stash/test_rubyx/passes/test_method_collector.rb
Normal file
39
stash/test_rubyx/passes/test_method_collector.rb
Normal file
@ -0,0 +1,39 @@
|
||||
require_relative "helper"
|
||||
|
||||
module Rubyx
|
||||
module Passes
|
||||
class TestMethodCollector #< MiniTest::Test
|
||||
|
||||
def setup
|
||||
Risc.machine.boot unless Risc.machine.booted
|
||||
end
|
||||
|
||||
def parse_collect( input )
|
||||
ast = Parser::Ruby22.parse input
|
||||
MethodCollector.new.collect(ast)
|
||||
end
|
||||
|
||||
def test_no_args
|
||||
methods = parse_collect "def meth; @ivar;end"
|
||||
assert methods.find{|m| m.name == :meth }
|
||||
end
|
||||
|
||||
def test_one_arg
|
||||
method = parse_collect("def meth2(arg1); 1;end").first
|
||||
assert method.name == :meth2
|
||||
assert_equal 2 , method.args_type.variable_index(:arg1) , method.args_type.inspect
|
||||
end
|
||||
|
||||
def test_three_args
|
||||
method = parse_collect("def meth3(yksi,kaksi,kolme); 1;end").first
|
||||
assert method.args_type.variable_index(:kolme) , method.args_type.inspect
|
||||
end
|
||||
|
||||
def test_one_local
|
||||
method = parse_collect("def meth2(arg1); foo = 2 ;end").first
|
||||
assert method.locals_type.variable_index(:foo) , method.locals_type.inspect
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
16
stash/test_rubyx/passes/test_normalizer.rb
Normal file
16
stash/test_rubyx/passes/test_normalizer.rb
Normal file
@ -0,0 +1,16 @@
|
||||
require_relative "helper"
|
||||
|
||||
module Rubyx
|
||||
module Passes
|
||||
class TestNormalizer < MiniTest::Test
|
||||
|
||||
def setup
|
||||
Risc.machine.boot unless Risc.machine.booted
|
||||
end
|
||||
|
||||
def test_no_thing
|
||||
assert true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
40
stash/test_rubyx/passes/test_type_collector.rb
Normal file
40
stash/test_rubyx/passes/test_type_collector.rb
Normal file
@ -0,0 +1,40 @@
|
||||
require_relative "helper"
|
||||
|
||||
module Rubyx
|
||||
module Passes
|
||||
class TestTypeCollector #< MiniTest::Test
|
||||
|
||||
def setup
|
||||
Risc.machine.boot
|
||||
end
|
||||
|
||||
def parse_collect( input )
|
||||
ast = Parser::Ruby22.parse input
|
||||
TypeCollector.new.collect(ast)
|
||||
end
|
||||
|
||||
def test_ivar_name
|
||||
hash = parse_collect "def meth; @ivar;end"
|
||||
assert hash[:ivar] , hash
|
||||
end
|
||||
|
||||
def test_ivar_assign
|
||||
hash = parse_collect "def meth; @ivar = 5;end"
|
||||
assert hash[:ivar] , hash
|
||||
end
|
||||
|
||||
def test_ivar_operator_assign
|
||||
hash = parse_collect "def meth; @ivar += 5;end"
|
||||
assert hash[:ivar] , hash
|
||||
end
|
||||
|
||||
def test_compile_class
|
||||
RubyxCompiler.compile "class TestIvar < Object ; def meth; @ivar;end; end"
|
||||
itest = Parfait.object_space.get_class_by_name(:TestIvar)
|
||||
assert itest
|
||||
assert itest.instance_type.names.include?(:ivar) , itest.instance_type.names.inspect
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
46
stash/test_rubyx/test_ruby_compiler.rb
Normal file
46
stash/test_rubyx/test_ruby_compiler.rb
Normal file
@ -0,0 +1,46 @@
|
||||
require_relative "helper"
|
||||
|
||||
module Rubyx
|
||||
class TestCompiler #< MiniTest::Test
|
||||
|
||||
def setup
|
||||
Risc.machine.boot
|
||||
end
|
||||
|
||||
def test_doesnt_create_existing_clas
|
||||
space_class = Parfait.object_space.get_class_by_name(:Space)
|
||||
RubyxCompiler.compile "class Space ; end"
|
||||
clazz = Parfait.object_space.get_class_by_name(:Space)
|
||||
assert_equal clazz , space_class
|
||||
end
|
||||
|
||||
def test_creates_class_without_deriviation
|
||||
RubyxCompiler.compile "class Testing ; end"
|
||||
clazz = Parfait.object_space.get_class_by_name(:Testing)
|
||||
assert clazz , "No classes created"
|
||||
assert_equal :Object , clazz.super_class_name
|
||||
end
|
||||
|
||||
def test_creates_class_with_deriviation
|
||||
RubyxCompiler.compile "class Test2 < List ;end"
|
||||
clazz = Parfait.object_space.get_class_by_name(:Test2)
|
||||
assert clazz, "No classes created"
|
||||
assert_equal :List , clazz.super_class_name
|
||||
end
|
||||
|
||||
def test_space_is_unchanged_by_compile
|
||||
space1 = Parfait.object_space.get_class_by_name(:Space)
|
||||
RubyxCompiler.compile "class Space ;end"
|
||||
space2 = Parfait.object_space.get_class_by_name(:Space)
|
||||
assert_equal space1 , space2
|
||||
end
|
||||
|
||||
def test_space_type_is_unchanged_by_compile
|
||||
space1 = Parfait.object_space.get_class_by_name(:Space).instance_type
|
||||
RubyxCompiler.compile "class Space ;end"
|
||||
space2 = Parfait.object_space.get_class_by_name(:Space).instance_type
|
||||
assert_equal space1 , space2
|
||||
end
|
||||
|
||||
end
|
||||
end
|
72
stash/test_rubyx/test_ruby_method.rb
Normal file
72
stash/test_rubyx/test_ruby_method.rb
Normal file
@ -0,0 +1,72 @@
|
||||
require_relative "helper"
|
||||
|
||||
module Rubyx
|
||||
class TestRubyMethod < MiniTest::Test
|
||||
include CompilerHelper
|
||||
|
||||
def setup
|
||||
Risc.machine.boot
|
||||
end
|
||||
|
||||
def create_method
|
||||
Vool::VoolCompiler.compile in_Test("def meth; @ivar ;end")
|
||||
test = Parfait.object_space.get_class_by_name(:Test)
|
||||
test.get_method(:meth)
|
||||
end
|
||||
|
||||
def create_method_arg
|
||||
Vool::VoolCompiler.compile in_Test("def meth_arg(arg); arg ;end")
|
||||
test = Parfait.object_space.get_class_by_name(:Test)
|
||||
test.get_method(:meth_arg)
|
||||
end
|
||||
|
||||
def create_method_local
|
||||
Vool::VoolCompiler.compile in_Test("def meth_local(arg); local = 5 ;end")
|
||||
test = Parfait.object_space.get_class_by_name(:Test)
|
||||
test.get_method(:meth_local)
|
||||
end
|
||||
|
||||
def test_creates_method_in_class
|
||||
method = create_method
|
||||
assert method , "No method created"
|
||||
end
|
||||
|
||||
def test_method_has_source
|
||||
method = create_method
|
||||
assert_equal Vool::ScopeStatement, method.source.class
|
||||
assert_equal Vool::InstanceVariable, method.source.first.class
|
||||
end
|
||||
|
||||
def test_method_has_no_args
|
||||
method = create_method
|
||||
assert_equal 1 , method.args_type.instance_length
|
||||
end
|
||||
|
||||
def test_method_has_no_locals
|
||||
method = create_method
|
||||
assert_equal 1 , method.locals_type.instance_length
|
||||
end
|
||||
|
||||
def test_method_has_args
|
||||
method = create_method_arg
|
||||
assert_equal 2 , method.args_type.instance_length
|
||||
end
|
||||
|
||||
def test_method_has_locals
|
||||
method = create_method_local
|
||||
assert_equal 2 , method.locals_type.instance_length
|
||||
end
|
||||
|
||||
def test_method_create_tmp
|
||||
name = create_method.create_tmp
|
||||
assert_equal :tmp_1 , name
|
||||
end
|
||||
|
||||
def test_method_add_tmp
|
||||
method = create_method_local
|
||||
method.create_tmp
|
||||
assert_equal 3 , method.locals_type.instance_length
|
||||
end
|
||||
|
||||
end
|
||||
end
|
Reference in New Issue
Block a user