refactor name expression for compiler

This commit is contained in:
Torsten Ruger 2016-12-09 12:13:33 +02:00
parent ca4bdcc528
commit 224670e449
7 changed files with 84 additions and 72 deletions

View File

@ -18,10 +18,10 @@ module Register
def div10 context
s = "div_10"
compiler = Typed::Compiler.new.create_method(:Integer,:div10 ).init_method
me = compiler.process( Typed::NameExpression.new( :self) )
tmp = compiler.process( Typed::NameExpression.new( :self) )
q = compiler.process( Typed::NameExpression.new( :self) )
const = compiler.process( Typed::IntegerExpression.new(1) )
me = compiler.process( Typed::Tree::NameExpression.new( :self) )
tmp = compiler.process( Typed::Tree::NameExpression.new( :self) )
q = compiler.process( Typed::Tree::NameExpression.new( :self) )
const = compiler.process( Typed::Tree::IntegerExpression.new(1) )
# int tmp = self >> 1
compiler.add_code Register.op( s , ">>" , tmp , const)
# int q = self >> 2

View File

@ -13,7 +13,7 @@ module Register
compiler = Typed::Compiler.new.create_method(:Object , :get_internal_word , {:index => :Integer}).init_method
source = "get_internal_word"
#Load self by "calling" on_name
me = compiler.process( Typed::NameExpression.new( :self) )
me = compiler.process( Typed::Tree::NameExpression.new( :self) )
# Load the argument
index = compiler.use_reg :Integer
compiler.add_code Register.get_slot(source , :message , Parfait::Message.get_indexed(1), index )
@ -31,7 +31,7 @@ module Register
{:index => :Integer, :value => :Object} ).init_method
source = "set_internal_word"
#Load self by "calling" on_name
me = compiler.process( Typed::NameExpression.new( :self) )
me = compiler.process( Typed::Tree::NameExpression.new( :self) )
# Load the index
index = compiler.use_reg :Integer
compiler.add_code Register.get_slot(source , :message , Parfait::Message.get_indexed(1), index )

View File

@ -20,7 +20,7 @@ module Register
compiler = Typed::Compiler.new.create_method(:Word , :get_internal_byte , {:index => :Integer }).init_method
source = "get_internal_word"
#Load self by "calling" on_name
me = compiler.process( Typed::NameExpression.new( :self) )
me = compiler.process( Typed::Tree::NameExpression.new( :self) )
# Load the argument
index = compiler.use_reg :Integer
compiler.add_code Register.get_slot(source , :message , Parfait::Message.get_indexed(1), index )
@ -39,7 +39,7 @@ module Register
{:index => :Integer, :value => :Integer } ).init_method
source = "set_internal_word"
#Load self by "calling" on_name
me = compiler.process( Typed::NameExpression.new( :self) )
me = compiler.process( Typed::Tree::NameExpression.new( :self) )
# Load the index
index = compiler.use_reg :Integer
compiler.add_code Register.get_slot(source , :message , Parfait::Message.get_indexed(1), index )

View File

@ -1,39 +1,41 @@
module Typed
class IntegerExpression < Expression
attr_accessor :value
def initialize(value)
@value = value
module Tree
class IntegerExpression < Expression
attr_accessor :value
def initialize(value)
@value = value
end
end
end
class FloatExpression < Expression
attr_accessor :value
def initialize(value)
@value = value
class FloatExpression < Expression
attr_accessor :value
def initialize(value)
@value = value
end
end
end
class TrueExpression < Expression
end
class FalseExpression < Expression
end
class NilExpression < Expression
end
class StringExpression < Expression
attr_accessor :value
def initialize(value)
@value = value
class TrueExpression < Expression
end
end
class NameExpression < Expression
attr_accessor :value
alias :name :value
def initialize(value)
@value = value
class FalseExpression < Expression
end
end
class ClassExpression < Expression
attr_accessor :value
def initialize(value)
@value = value
class NilExpression < Expression
end
class StringExpression < Expression
attr_accessor :value
def initialize(value)
@value = value
end
end
class NameExpression < Expression
attr_accessor :value
alias :name :value
def initialize(value)
@value = value
end
end
class ClassExpression < Expression
attr_accessor :value
def initialize(value)
@value = value
end
end
end
end

View File

@ -125,26 +125,26 @@ module Typed
end
def on_int expression
IntegerExpression.new(expression.children.first)
Tree::IntegerExpression.new(expression.children.first)
end
def on_true expression
TrueExpression.new
Tree::TrueExpression.new
end
def on_false expression
FalseExpression.new
Tree::FalseExpression.new
end
def on_nil expression
NilExpression.new
Tree::NilExpression.new
end
def on_name statement
NameExpression.new(statement.children.first)
Tree::NameExpression.new(statement.children.first)
end
def on_string expression
StringExpression.new(expression.children.first)
Tree::StringExpression.new(expression.children.first)
end
def on_class_name expression

View File

@ -1,3 +1,5 @@
require_relative "compiler/name_expression"
module Typed
# Compiling is the conversion of the AST into 2 things:
# - code (ie sequences of Instructions inside Methods)
@ -37,6 +39,7 @@ module Typed
end
class Compiler
include NameExpression
def initialize( method = nil )
@regs = []
@ -188,7 +191,6 @@ require_relative "compiler/field_def"
require_relative "compiler/field_access"
require_relative "compiler/function_definition"
require_relative "compiler/if_statement"
require_relative "compiler/name_expression"
require_relative "compiler/operator_value"
require_relative "compiler/return_statement"
require_relative "compiler/statement_list"

View File

@ -1,5 +1,5 @@
module Typed
Compiler.class_eval do
module NameExpression
# attr_reader :name
# compiling name needs to check if it's a local variable
@ -7,39 +7,47 @@ module Typed
# whichever way this goes the result is stored in the return slot (as all compiles)
def on_NameExpression statement
name = statement.name
if( name == :self)
ret = use_reg @clazz.name
add_code Register.get_slot(statement , :message , :receiver , ret )
return ret
end
if(name == :space)
space = Parfait::Space.object_space
reg = use_reg :Space , space
add_code Register::LoadConstant.new( statement, space , reg )
return reg
end
if(name == :message)
reg = use_reg :Message
add_code Register::RegisterTransfer.new( statement, Register.message_reg , reg )
return reg
[:self , :space , :message].each do |special|
return send(:"handle_special_#{special}" , statement ) if name == special
end
# either an argument, so it's stored in message
if( index = @method.has_arg(name))
ret = use_reg @method.arguments[index].value_type
add_code Register.get_slot(statement , :message , Parfait::Message.get_indexed(index), ret )
return ret
else # or a local so it is in the frame
index = @method.has_local( name )
if(index)
frame = use_reg :Frame
add_code Register.get_slot(statement , :message , :frame , frame )
ret = use_reg @method.locals[index].value_type
add_code Register.get_slot(statement , frame , Parfait::Frame.get_indexed(index), ret )
return ret
end
end
raise "must define variable '#{name}' before using it"
# or a local so it is in the frame
handle_local(statement)
end
private
def handle_local statement
index = @method.has_local( name )
raise "must define variable '#{name}' before using it" unless index
frame = use_reg :Frame
add_code Register.get_slot(statement , :message , :frame , frame )
ret = use_reg @method.locals[index].value_type
add_code Register.get_slot(statement , frame , Parfait::Frame.get_indexed(index), ret )
return ret
end
def handle_special_self(statement)
ret = use_reg @clazz.name
add_code Register.get_slot(statement , :message , :receiver , ret )
return ret
end
def handle_special_space(statement)
space = Parfait::Space.object_space
reg = use_reg :Space , space
add_code Register::LoadConstant.new( statement, space , reg )
return reg
end
def handle_special_message(statement)
reg = use_reg :Message
add_code Register::RegisterTransfer.new( statement, Register.message_reg , reg )
return reg
end
end #module
end