bit of refactoring

This commit is contained in:
Torsten Ruger 2018-06-27 17:09:50 +03:00
parent f0ba863721
commit 2e086a78e2
6 changed files with 39 additions and 30 deletions

View File

@ -25,7 +25,7 @@ module Parfait
end end
def add_instance_method( method ) def add_instance_method( method )
raise "not implemented #{method.class} #{method.inspect}" unless method.is_a? RubyMethod raise "not implemented #{method.class} #{method.inspect}" unless method.is_a? VoolMethod
method method
end end

View File

@ -1,17 +1,18 @@
# Class is mainly a list of methods with a name. The methods are untyped, sis Vool. # Class is mainly a list of methods with a name.
# The methods are untyped, sis VoolMethod.
# The memory layout of an object is determined by the Type (see there). # The memory layout of an object is determined by the Type (see there).
# The class carries the "current" type, ie the type an object would be if you created an instance # The class carries the "current" type, ie the type an object would be if you
# of the class. Note that this changes over time and so many types share the same class. # created an instance of the class.
# Note that this changes over time and so many types share the same class.
# For dynamic OO it is essential that the class (the object defining the class) # For dynamic OO it is essential that the class (the object defining the class)
# can carry methods. It does so as instance variables. # can carry methods. It does so in an instance variable methods.
# In fact this property is implemented in the Type, as methods
# may be added to any object at run-time.
# An Object carries the data for the instance variables it has. # An Object carries the data for the instance variables it has.
# The Type lists the names of the instance variables # The Type lists the names of the instance variables
# The Class keeps a list of instance methods, these have a name and code # The Class keeps a list of instance methods, these have a name and (vool) code
# Each type in turn has a list of TypedMethods that hold binary code
module Parfait module Parfait
class Class < Object class Class < Object
@ -35,6 +36,12 @@ module Parfait
"Class(#{name})" "Class(#{name})"
end end
def add_method_for(name , type , frame , body )
method = Parfait::VoolMethod.new(name , type , frame , body )
add_method( method )
method
end
def add_method(method) def add_method(method)
raise "Must be untyped method #{method}" unless method.is_a? Parfait::VoolMethod raise "Must be untyped method #{method}" unless method.is_a? Parfait::VoolMethod
@methods[method.name] = method @methods[method.name] = method

View File

@ -1,19 +1,22 @@
# A TypedMethod is static object that primarily holds the executable code. # A TypedMethod is static object that primarily holds the executable code.
# It is called typed, because all arguments and variables it uses are typed. # It is called typed, because all arguments and variables it uses are "typed",
# that is to say the names are known and form a type (not that the types of the
# variables are known). The objects type is known too, which means all instances
# variable names are known (not their respective type).
# It's relation to the method a ruby programmer knows (called RubyMethod) is many to one, # It's relation to the method a ruby programmer knows (called VoolMethod) is many to one,
# meaning one RubyMethod (untyped) has many TypedMethod implementations. # meaning one VoolMethod (untyped) has many TypedMethod implementations.
# The RubyMethod only holds ruby code, no binary. # The VoolMethod only holds vool code, no binary.
# The Typed method has the following instance variables # The Typed method has the following instance variables
# - name : This is the same as the ruby method name it implements # - name : This is the same as the ruby method name it implements
# - source: is currently the ast (or string) that represents the "code". This is historic # - risc_instructions: The sequence of risc level instructions that mom was compiled to
# and will change to the RubyMethod that it implements # - cpu_instructions: The sequence of cpu specific instructions that the
# - instructions: The sequence of instructions the source (ast) was compiled to # risc_instructions was compiled to
# Instructions derive from class Instruction and form a linked list # Instructions derive from class Instruction and form a linked list
# - binary: The binary (jumpable) code that the instructions get assembled into # - binary: The binary (jumpable) code that the instructions get assembled into
# - arguments: A type object describing the arguments (name+types) to be passed # - arguments_type: A type object describing the arguments (name+types) to be passed
# - frame: A type object describing the local variables that the method has # - frame_type: A type object describing the local variables that the method has
# - for_type: The Type the Method is for # - for_type: The Type the Method is for
@ -24,8 +27,6 @@ module Parfait
attr_reader :name , :risc_instructions , :for_type , :cpu_instructions attr_reader :name , :risc_instructions , :for_type , :cpu_instructions
attr_reader :arguments_type , :frame_type , :binary , :next_method attr_reader :arguments_type , :frame_type , :binary , :next_method
attr_accessor :source
def initialize( type , name , arguments_type , frame_type) def initialize( type , name , arguments_type , frame_type)
super() super()
raise "No class #{name}" unless type raise "No class #{name}" unless type

View File

@ -27,5 +27,12 @@ module Parfait
type.create_method( @name , @args_type , @frame_type) type.create_method( @name , @args_type , @frame_type)
end end
def compile_to_risc(for_type)
typed_method = create_typed_method(for_type)
head = source.to_mom( typed_method )
compiler = Risc::MethodCompiler.new( typed_method )
compiler.add_mom(head)
head # return for testing
end
end end
end end

View File

@ -9,15 +9,9 @@ module Vool
end end
def to_mom(clazz) def to_mom(clazz)
@clazz = clazz @clazz = clazz || raise( "no class in #{self}")
raise "no class" unless clazz method = @clazz.add_method_for(name , make_arg_type , make_frame , body )
method = Parfait::VoolMethod.new(name , make_type , make_frame , body ) method.compile_to_risc(clazz.instance_type)
@clazz.add_method( method )
typed_method = method.create_typed_method(clazz.instance_type)
head = @body.to_mom( typed_method )
compiler = Risc::MethodCompiler.new( typed_method )
compiler.add_mom(head)
head # return for testing
end end
def each(&block) def each(&block)
@ -31,7 +25,7 @@ module Vool
private private
def make_type( ) def make_arg_type( )
type_hash = {} type_hash = {}
@args.each {|arg| type_hash[arg] = :Object } @args.each {|arg| type_hash[arg] = :Object }
Parfait::NamedList.type_for( type_hash ) Parfait::NamedList.type_for( type_hash )

View File

@ -5,7 +5,7 @@ module Vool
# Return a Name, and a possible rest that has a hoisted part of the statement # Return a Name, and a possible rest that has a hoisted part of the statement
# #
# eg if( @var % 5) is not normalized # eg if( @var % 5) is not normalized
# but if(tmp_123) is with tmp_123 = @var % 5 hoited above the if # but if(tmp_123) is with tmp_123 = @var % 5 hoisted above the if
# #
# also constants count, though they may not be so useful in ifs, but returns # also constants count, though they may not be so useful in ifs, but returns
def normalize_name( condition ) def normalize_name( condition )