refactor name expression for compiler
This commit is contained in:
parent
ca4bdcc528
commit
224670e449
@ -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
|
||||
|
@ -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 )
|
||||
|
@ -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 )
|
||||
|
@ -1,4 +1,5 @@
|
||||
module Typed
|
||||
module Tree
|
||||
class IntegerExpression < Expression
|
||||
attr_accessor :value
|
||||
def initialize(value)
|
||||
@ -37,3 +38,4 @@ module Typed
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
end
|
||||
# or a local so it is in the frame
|
||||
handle_local(statement)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def handle_local statement
|
||||
index = @method.has_local( name )
|
||||
if(index)
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user