renamed info to MethodSource

This commit is contained in:
Torsten Ruger
2015-07-03 20:13:03 +03:00
parent e959c5b0f5
commit b61c73acdd
24 changed files with 103 additions and 103 deletions

View File

@ -14,24 +14,24 @@ All the headache comes from mixing those two up.*
Similarly, the result of compiling is two-fold: a static and a dynamic part.
- the static part are objects like the constants, but also defined classes and their methods
- the dynamic part is the code, which is stored as streams of instructions in the CompiledMethod
- the dynamic part is the code, which is stored as streams of instructions in the MethodSource
Too make things a little simpler, we create a very high level instruction stream at first and then
run transformation and optimization passes on the stream to improve it.
Each ast class gets a compile method that does the compilation.
#### Compiled Method and Instructions
#### MethodSource and Instructions
The first argument to the compile method is the CompiledMethod.
All code is encoded as a stream of Instructions in the CompiledMethod.
The first argument to the compile method is the MethodSource.
All code is encoded as a stream of Instructions in the MethodSource.
Instructions are stored as a list of Blocks, and Blocks are the smallest unit of code,
which is always linear.
Code is added to the method (using add_code), rather than working with the actual instructions.
This is so each compiling method can just do it's bit and be unaware of the larger structure
that is being created.
The genearal structure of the instructions is a graph
The general structure of the instructions is a graph
(with if's and whiles and breaks and what), but we build it to have one start and *one* end (return).

View File

@ -15,25 +15,25 @@ module Virtual
def self.compile_integer expression , method
int = expression.value
to = Return.new(Integer , int)
method.info.add_code Set.new( int , to )
method.source.add_code Set.new( int , to )
to
end
def self.compile_true expression , method
to = Return.new(Reference , true )
method.info.add_code Set.new( true , to )
method.source.add_code Set.new( true , to )
to
end
def self.compile_false expression , method
to = Return.new(Reference , false)
method.info.add_code Set.new( false , to )
method.source.add_code Set.new( false , to )
to
end
def self.compile_nil expression , method
to = Return.new(Reference , nil)
method.info.add_code Set.new( nil , to )
method.source.add_code Set.new( nil , to )
to
end
@ -47,9 +47,9 @@ module Virtual
if method.has_var(name)
# either an argument, so it's stored in message
if( index = method.has_arg(name))
method.info.add_code MessageGet.new(expression.name , index)
method.source.add_code MessageGet.new(expression.name , index)
else # or a local so it is in the frame
method.info.add_code FrameGet.new(expression.name , index)
method.source.add_code FrameGet.new(expression.name , index)
end
else
call = Ast::CallSiteExpression.new(expression.name , [] ) #receiver self is implicit
@ -62,7 +62,7 @@ module Virtual
clazz = Space.space.get_class_by_name name
raise "uups #{clazz}.#{name}" unless clazz
to = Return.new(Reference , clazz )
method.info.add_code Set.new( clazz , to )
method.source.add_code Set.new( clazz , to )
to
end
@ -71,8 +71,8 @@ module Virtual
# Clearly a TODO here to implement strings rather than reusing symbols
value = expression.string.to_sym
to = Return.new(Reference , value)
method.info.constants << value
method.info.add_code Set.new( value , to )
method.source.constants << value
method.source.add_code Set.new( value , to )
to
end
@ -85,16 +85,16 @@ module Virtual
raise "oh noo, nil from where #{expression.right.inspect}" unless r
index = method.has_arg(expression.left.name.to_sym)
if index
method.info.add_code Set.new(MessageSlot.new(index , r,type , r ) , Return.new)
method.source.add_code Set.new(MessageSlot.new(index , r,type , r ) , Return.new)
else
index = method.ensure_local(expression.left.name.to_sym)
method.info.add_code Set.new(FrameSlot.new(index , r.type , r ) , Return.new)
method.source.add_code Set.new(FrameSlot.new(index , r.type , r ) , Return.new)
end
r
end
def self.compile_variable expression, method
method.info.add_code InstanceGet.new(expression.name)
method.source.add_code InstanceGet.new(expression.name)
Return.new( Unknown )
end
end

View File

@ -6,9 +6,9 @@ module Virtual
def self.compile_callsite expession , method
me = Compiler.compile( expession.receiver , method )
method.info.add_code NewMessage.new
method.info.add_code Set.new( me , NewSelf.new(me.type))
method.info.add_code Set.new( expession.name.to_sym , NewMessageName.new())
method.source.add_code NewMessage.new
method.source.add_code Set.new( me , NewSelf.new(me.type))
method.source.add_code Set.new( expession.name.to_sym , NewMessageName.new())
compiled_args = []
expession.args.each_with_index do |arg , i|
#compile in the running method, ie before passing control
@ -18,13 +18,13 @@ module Virtual
# so the next free is +1
to = NewArgSlot.new(i + 1 ,val.type , val)
# (doing this immediately, not after the loop, so if it's a return it won't get overwritten)
method.info.add_code Set.new( val , to )
method.source.add_code Set.new( val , to )
compiled_args << to
end
method.info.add_code MessageSend.new(expession.name , me , compiled_args) #and pass control
method.source.add_code MessageSend.new(expession.name , me , compiled_args) #and pass control
# the effect of the method is that the NewMessage Return slot will be filled, return it
# (this is what is moved _inside_ above loop for such expressions that are calls (or constants))
Return.new( method.info.return_type )
Return.new( method.source.return_type )
end
end
end

View File

@ -18,8 +18,8 @@ module Virtual
r = Self.new()
class_name = method.for_class.name
end
new_method = CompiledMethodInfo.create_method(class_name, expression.name , args )
new_method.info.receiver = r
new_method = MethodSource.create_method(class_name, expression.name , args )
new_method.source.receiver = r
new_method.for_class.add_instance_method new_method
#frame = frame.new_frame
@ -28,7 +28,7 @@ module Virtual
return_type = Compiler.compile(ex,new_method )
raise return_type.inspect if return_type.is_a? Instruction
end
new_method.info.return_type = return_type
new_method.source.return_type = return_type
new_method
end
def scratch

View File

@ -6,18 +6,18 @@ module Virtual
# to execute the logic as the if states it, the blocks are the other way around
# so we can the jump over the else if true ,
# and the else joins unconditionally after the true_block
merge_block = method.info.new_block "if_merge" # last one, created first
true_block = method.info.new_block "if_true" # second, linked in after current, before merge
false_block = method.info.new_block "if_false" # directly next in order, ie if we don't jump we land here
merge_block = method.source.new_block "if_merge" # last one, created first
true_block = method.source.new_block "if_true" # second, linked in after current, before merge
false_block = method.source.new_block "if_false" # directly next in order, ie if we don't jump we land here
is = Compiler.compile(expression.cond, method )
# TODO should/will use different branches for different conditions.
# just a scetch : cond_val = cond_val.is_true?(method) unless cond_val.is_a? BranchCondition
method.info.add_code IsTrueBranch.new( true_block )
method.source.add_code IsTrueBranch.new( true_block )
# compile the true block (as we think of it first, even it is second in sequential order)
method.info.current true_block
method.source.current true_block
last = is
expression.if_true.each do |part|
last = Compiler.compile(part,method )
@ -25,16 +25,16 @@ module Virtual
end
# compile the false block
method.info.current false_block
method.source.current false_block
expression.if_false.each do |part|
#puts "compiling in if false #{part}"
last = Compiler.compile(part,method )
raise part.inspect if last.nil?
end
method.info.add_code UnconditionalBranch.new( merge_block )
method.source.add_code UnconditionalBranch.new( merge_block )
#puts "compiled if: end"
method.info.current merge_block
method.source.current merge_block
#TODO should return the union of the true and false types
last