diff --git a/lib/melon/compiler.rb b/lib/melon/compiler.rb index 2bd1722d..3da7e267 100644 --- a/lib/melon/compiler.rb +++ b/lib/melon/compiler.rb @@ -8,33 +8,39 @@ require_relative "compiler/ruby_method" module Melon class Compiler < AST::Processor - def self.compile input - ast = Parser::Ruby22.parse input - compiler = self.new - compiler.process ast - end - - def get_name( statement ) - return nil unless statement - statement.children[1] + 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.create_class(class_name , get_name(sup) ) + clazz = Parfait.object_space.get_class_by_name!(class_name , get_name(sup) ) ivar_hash = TypeCollector.new.collect(body) clazz.set_instance_type( Parfait::Type.for_hash( clazz , ivar_hash ) ) + create_methods(clazz , body) + end - MethodCollector.new.collect(body) - + def create_methods(clazz , body) + methods = MethodCollector.new.collect(body) + methods.each do |method| + clazz.add_method( method ) + end end def handler_missing(node) +# raise "Oh" node.children.each do |kid | process(kid) if kid.is_a?(AST::Node) end end + private + def get_name( statement ) + return nil unless statement + statement.children[1] + end + end end diff --git a/lib/typed/parfait/class.rb b/lib/typed/parfait/class.rb index e72b84c7..fd06bd97 100644 --- a/lib/typed/parfait/class.rb +++ b/lib/typed/parfait/class.rb @@ -23,6 +23,7 @@ module Parfait super() @name = name @super_class_name = superclass + @methods = {} set_instance_type( instance_type ) end @@ -34,6 +35,14 @@ module Parfait "Class(#{name})" end + def add_method(method) + @methods[method.name] = method + end + + def get_method(name) + @methods[name] + end + # setting the type generates all methods for this type # (or will do, once we store the methods code to do that) def set_instance_type( type ) diff --git a/lib/typed/parfait/space.rb b/lib/typed/parfait/space.rb index 0271dcc7..07975253 100644 --- a/lib/typed/parfait/space.rb +++ b/lib/typed/parfait/space.rb @@ -29,7 +29,7 @@ module Parfait # While data ususally would live in a .data section, we may also "inline" it into the code # in an oo system all data is represented as objects - class Space < Object + class Space < Object def initialize(classes ) @classes = classes @@ -99,10 +99,10 @@ module Parfait # get or create the class by the (symbol) name # notice that this method of creating classes implies Object superclass - def get_class_by_name! name + def get_class_by_name!(name , super_class = :Object) c = get_class_by_name(name) return c if c - create_class name + create_class( name ,super_class) end # this is the way to instantiate classes (not Parfait::Class.new) diff --git a/test/melon/compiler/helper.rb b/test/melon/compiler/helper.rb index 3f91a123..4b370847 100644 --- a/test/melon/compiler/helper.rb +++ b/test/melon/compiler/helper.rb @@ -1 +1,13 @@ require_relative '../helper' + +module Melon + module CompilerHelper + def in_Space(statements) + "class Space ; #{statements} ; end" + end + + def as_main(statements) + in_Space("def main ; #{statements}; end") + end + end +end diff --git a/test/melon/compiler/test_all.rb b/test/melon/compiler/test_all.rb index e0604a89..544c2946 100644 --- a/test/melon/compiler/test_all.rb +++ b/test/melon/compiler/test_all.rb @@ -1,3 +1,4 @@ require_relative "test_type_collector" require_relative "test_method_collector" require_relative "test_locals_collector" +require_relative "test_class_creation" diff --git a/test/melon/test_compiler.rb b/test/melon/compiler/test_class_creation.rb similarity index 100% rename from test/melon/test_compiler.rb rename to test/melon/compiler/test_class_creation.rb diff --git a/test/melon/compiler/test_method_creation.rb b/test/melon/compiler/test_method_creation.rb new file mode 100644 index 00000000..a764b25b --- /dev/null +++ b/test/melon/compiler/test_method_creation.rb @@ -0,0 +1,19 @@ +require_relative "helper" + +module Melon + class TestMethod < MiniTest::Test + include CompilerHelper + + def setup + Register.machine.boot + end + + def test_creates_method_in_class + Compiler.compile in_Space("def meth; @ivar;end") + space = Parfait.object_space.get_class + method = space.get_method(:meth) + assert method , "No method created" + end + + end +end diff --git a/test/melon/fragments/helper.rb b/test/melon/fragments/helper.rb index e5abb691..a51b2237 100644 --- a/test/melon/fragments/helper.rb +++ b/test/melon/fragments/helper.rb @@ -6,12 +6,15 @@ module Melon module MelonTests def setup - @parser = Parser::Ruby22 + Register.machine.boot end def check - assert true - #puts @parser.parse @string_input + Compiler.compile @string_input + Register::Collector.collect_space + @interpreter = Register::Interpreter.new + @interpreter.start Register.machine.init + nil end end end diff --git a/test/melon/fragments/test_all.rb b/test/melon/fragments/test_all.rb index 3a38b6c5..5005ce52 100644 --- a/test/melon/fragments/test_all.rb +++ b/test/melon/fragments/test_all.rb @@ -3,3 +3,8 @@ require_relative "test_calls" require_relative "test_hello" require_relative "test_itos" require_relative "test_loop" + +require_relative "test_many_adds" +require_relative "test_many_hello" +require_relative "test_many_calls" +require_relative "test_many_itos" diff --git a/test/melon/fragments/test_hello.rb b/test/melon/fragments/test_hello.rb index 299021cd..5f30eab2 100644 --- a/test/melon/fragments/test_hello.rb +++ b/test/melon/fragments/test_hello.rb @@ -6,11 +6,9 @@ module Melon def test_ruby_hello - @string_input = <