refactor name expression for compiler
This commit is contained in:
parent
ca4bdcc528
commit
224670e449
@ -18,10 +18,10 @@ module Register
|
|||||||
def div10 context
|
def div10 context
|
||||||
s = "div_10"
|
s = "div_10"
|
||||||
compiler = Typed::Compiler.new.create_method(:Integer,:div10 ).init_method
|
compiler = Typed::Compiler.new.create_method(:Integer,:div10 ).init_method
|
||||||
me = compiler.process( Typed::NameExpression.new( :self) )
|
me = compiler.process( Typed::Tree::NameExpression.new( :self) )
|
||||||
tmp = compiler.process( Typed::NameExpression.new( :self) )
|
tmp = compiler.process( Typed::Tree::NameExpression.new( :self) )
|
||||||
q = compiler.process( Typed::NameExpression.new( :self) )
|
q = compiler.process( Typed::Tree::NameExpression.new( :self) )
|
||||||
const = compiler.process( Typed::IntegerExpression.new(1) )
|
const = compiler.process( Typed::Tree::IntegerExpression.new(1) )
|
||||||
# int tmp = self >> 1
|
# int tmp = self >> 1
|
||||||
compiler.add_code Register.op( s , ">>" , tmp , const)
|
compiler.add_code Register.op( s , ">>" , tmp , const)
|
||||||
# int q = self >> 2
|
# int q = self >> 2
|
||||||
|
@ -13,7 +13,7 @@ module Register
|
|||||||
compiler = Typed::Compiler.new.create_method(:Object , :get_internal_word , {:index => :Integer}).init_method
|
compiler = Typed::Compiler.new.create_method(:Object , :get_internal_word , {:index => :Integer}).init_method
|
||||||
source = "get_internal_word"
|
source = "get_internal_word"
|
||||||
#Load self by "calling" on_name
|
#Load self by "calling" on_name
|
||||||
me = compiler.process( Typed::NameExpression.new( :self) )
|
me = compiler.process( Typed::Tree::NameExpression.new( :self) )
|
||||||
# Load the argument
|
# Load the argument
|
||||||
index = compiler.use_reg :Integer
|
index = compiler.use_reg :Integer
|
||||||
compiler.add_code Register.get_slot(source , :message , Parfait::Message.get_indexed(1), index )
|
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
|
{:index => :Integer, :value => :Object} ).init_method
|
||||||
source = "set_internal_word"
|
source = "set_internal_word"
|
||||||
#Load self by "calling" on_name
|
#Load self by "calling" on_name
|
||||||
me = compiler.process( Typed::NameExpression.new( :self) )
|
me = compiler.process( Typed::Tree::NameExpression.new( :self) )
|
||||||
# Load the index
|
# Load the index
|
||||||
index = compiler.use_reg :Integer
|
index = compiler.use_reg :Integer
|
||||||
compiler.add_code Register.get_slot(source , :message , Parfait::Message.get_indexed(1), index )
|
compiler.add_code Register.get_slot(source , :message , Parfait::Message.get_indexed(1), index )
|
||||||
|
@ -20,7 +20,7 @@ module Register
|
|||||||
compiler = Typed::Compiler.new.create_method(:Word , :get_internal_byte , {:index => :Integer }).init_method
|
compiler = Typed::Compiler.new.create_method(:Word , :get_internal_byte , {:index => :Integer }).init_method
|
||||||
source = "get_internal_word"
|
source = "get_internal_word"
|
||||||
#Load self by "calling" on_name
|
#Load self by "calling" on_name
|
||||||
me = compiler.process( Typed::NameExpression.new( :self) )
|
me = compiler.process( Typed::Tree::NameExpression.new( :self) )
|
||||||
# Load the argument
|
# Load the argument
|
||||||
index = compiler.use_reg :Integer
|
index = compiler.use_reg :Integer
|
||||||
compiler.add_code Register.get_slot(source , :message , Parfait::Message.get_indexed(1), index )
|
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
|
{:index => :Integer, :value => :Integer } ).init_method
|
||||||
source = "set_internal_word"
|
source = "set_internal_word"
|
||||||
#Load self by "calling" on_name
|
#Load self by "calling" on_name
|
||||||
me = compiler.process( Typed::NameExpression.new( :self) )
|
me = compiler.process( Typed::Tree::NameExpression.new( :self) )
|
||||||
# Load the index
|
# Load the index
|
||||||
index = compiler.use_reg :Integer
|
index = compiler.use_reg :Integer
|
||||||
compiler.add_code Register.get_slot(source , :message , Parfait::Message.get_indexed(1), index )
|
compiler.add_code Register.get_slot(source , :message , Parfait::Message.get_indexed(1), index )
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
module Typed
|
module Typed
|
||||||
|
module Tree
|
||||||
class IntegerExpression < Expression
|
class IntegerExpression < Expression
|
||||||
attr_accessor :value
|
attr_accessor :value
|
||||||
def initialize(value)
|
def initialize(value)
|
||||||
@ -37,3 +38,4 @@ module Typed
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
@ -125,26 +125,26 @@ module Typed
|
|||||||
end
|
end
|
||||||
|
|
||||||
def on_int expression
|
def on_int expression
|
||||||
IntegerExpression.new(expression.children.first)
|
Tree::IntegerExpression.new(expression.children.first)
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_true expression
|
def on_true expression
|
||||||
TrueExpression.new
|
Tree::TrueExpression.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_false expression
|
def on_false expression
|
||||||
FalseExpression.new
|
Tree::FalseExpression.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_nil expression
|
def on_nil expression
|
||||||
NilExpression.new
|
Tree::NilExpression.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_name statement
|
def on_name statement
|
||||||
NameExpression.new(statement.children.first)
|
Tree::NameExpression.new(statement.children.first)
|
||||||
end
|
end
|
||||||
def on_string expression
|
def on_string expression
|
||||||
StringExpression.new(expression.children.first)
|
Tree::StringExpression.new(expression.children.first)
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_class_name expression
|
def on_class_name expression
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
require_relative "compiler/name_expression"
|
||||||
|
|
||||||
module Typed
|
module Typed
|
||||||
# Compiling is the conversion of the AST into 2 things:
|
# Compiling is the conversion of the AST into 2 things:
|
||||||
# - code (ie sequences of Instructions inside Methods)
|
# - code (ie sequences of Instructions inside Methods)
|
||||||
@ -37,6 +39,7 @@ module Typed
|
|||||||
end
|
end
|
||||||
|
|
||||||
class Compiler
|
class Compiler
|
||||||
|
include NameExpression
|
||||||
|
|
||||||
def initialize( method = nil )
|
def initialize( method = nil )
|
||||||
@regs = []
|
@regs = []
|
||||||
@ -188,7 +191,6 @@ require_relative "compiler/field_def"
|
|||||||
require_relative "compiler/field_access"
|
require_relative "compiler/field_access"
|
||||||
require_relative "compiler/function_definition"
|
require_relative "compiler/function_definition"
|
||||||
require_relative "compiler/if_statement"
|
require_relative "compiler/if_statement"
|
||||||
require_relative "compiler/name_expression"
|
|
||||||
require_relative "compiler/operator_value"
|
require_relative "compiler/operator_value"
|
||||||
require_relative "compiler/return_statement"
|
require_relative "compiler/return_statement"
|
||||||
require_relative "compiler/statement_list"
|
require_relative "compiler/statement_list"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
module Typed
|
module Typed
|
||||||
Compiler.class_eval do
|
module NameExpression
|
||||||
|
|
||||||
# attr_reader :name
|
# attr_reader :name
|
||||||
# compiling name needs to check if it's a local variable
|
# 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)
|
# whichever way this goes the result is stored in the return slot (as all compiles)
|
||||||
def on_NameExpression statement
|
def on_NameExpression statement
|
||||||
name = statement.name
|
name = statement.name
|
||||||
if( name == :self)
|
[:self , :space , :message].each do |special|
|
||||||
ret = use_reg @clazz.name
|
return send(:"handle_special_#{special}" , statement ) if name == special
|
||||||
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
|
|
||||||
end
|
end
|
||||||
# either an argument, so it's stored in message
|
# either an argument, so it's stored in message
|
||||||
if( index = @method.has_arg(name))
|
if( index = @method.has_arg(name))
|
||||||
ret = use_reg @method.arguments[index].value_type
|
ret = use_reg @method.arguments[index].value_type
|
||||||
add_code Register.get_slot(statement , :message , Parfait::Message.get_indexed(index), ret )
|
add_code Register.get_slot(statement , :message , Parfait::Message.get_indexed(index), ret )
|
||||||
return ret
|
return ret
|
||||||
else # or a local so it is in the frame
|
end
|
||||||
|
# or a local so it is in the frame
|
||||||
|
handle_local(statement)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def handle_local statement
|
||||||
index = @method.has_local( name )
|
index = @method.has_local( name )
|
||||||
if(index)
|
raise "must define variable '#{name}' before using it" unless index
|
||||||
frame = use_reg :Frame
|
frame = use_reg :Frame
|
||||||
add_code Register.get_slot(statement , :message , :frame , frame )
|
add_code Register.get_slot(statement , :message , :frame , frame )
|
||||||
ret = use_reg @method.locals[index].value_type
|
ret = use_reg @method.locals[index].value_type
|
||||||
add_code Register.get_slot(statement , frame , Parfait::Frame.get_indexed(index), ret )
|
add_code Register.get_slot(statement , frame , Parfait::Frame.get_indexed(index), ret )
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
end
|
|
||||||
raise "must define variable '#{name}' before using it"
|
def handle_special_self(statement)
|
||||||
|
ret = use_reg @clazz.name
|
||||||
|
add_code Register.get_slot(statement , :message , :receiver , ret )
|
||||||
|
return ret
|
||||||
end
|
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 #module
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user