rubyx/lib/virtual/method_definition.rb

76 lines
2.1 KiB
Ruby
Raw Normal View History

2014-07-14 10:29:38 +02:00
require_relative "object"
2014-07-14 13:06:09 +02:00
2014-07-10 16:14:38 +02:00
module Virtual
# static description of a method
# name
# args (with defaults)
# code
# return arg (usually mystery, but for coded ones can be more specific)
# known local variable names
# temp variables (numbered)
#
2014-07-16 18:24:41 +02:00
class MethodDefinition < Virtual::Object
2014-07-10 16:14:38 +02:00
#return the main function (the top level) into which code is compiled
2014-07-16 18:24:41 +02:00
def MethodDefinition.main
MethodDefinition.new(:main , [] , Virtual::SelfReference )
2014-07-10 16:14:38 +02:00
end
2014-07-14 10:29:38 +02:00
def attributes
2014-07-14 15:19:47 +02:00
[:name , :args , :receiver , :return_type , :start]
2014-07-14 10:29:38 +02:00
end
def initialize name , args , receiver = Virtual::SelfReference.new , return_type = Virtual::Mystery , start = MethodEnter.new(MethodReturn.new)
2014-07-14 10:29:38 +02:00
@name = name.to_sym
2014-07-10 16:14:38 +02:00
@args = args
@locals = []
2014-07-14 23:00:00 +02:00
@tmps = []
@receiver = receiver
@return_type = return_type
2014-07-14 15:19:47 +02:00
@start = start
2014-07-10 16:14:38 +02:00
@current = @start
end
attr_reader :name , :args , :receiver , :start
2014-07-16 19:16:10 +02:00
attr_accessor :return_type , :current
2014-07-10 16:14:38 +02:00
# add an instruction after the current (insertion point)
# the added instruction will become the new insertion point
2014-07-10 16:14:38 +02:00
def add instruction
2014-07-14 23:00:00 +02:00
raise instruction.inspect unless instruction.is_a? Instruction
@current.insert(instruction) #insert after current
2014-07-10 16:14:38 +02:00
@current = instruction
end
# determine whether this method has a variable by the given name
# variables are locals and and arguments
# used to determine if a send must be issued
def has_var name
2014-07-16 12:20:47 +02:00
name = name.to_sym
var = @args.find {|a| a.name == name }
var = @locals.find {|a| a.name == name } unless var
var = @tmps.find {|a| a.name == name } unless var
var
end
def set_var name , var
v = has_var name
if( v )
puts "resetting local #{v.inspect}"
2014-07-16 12:20:47 +02:00
else
v = Local.new(name , var)
@locals << v
end
v
end
def get_var name
var = has_var name
raise "no var #{name} in method #{self.name} , #{@locals} #{@args}" unless var
2014-07-10 16:14:38 +02:00
var
end
2014-07-15 09:35:29 +02:00
2014-07-14 23:00:00 +02:00
def get_tmp
name = "__tmp__#{@tmps.length}"
@tmps << name
Ast::NameExpression.new(name)
end
2014-07-10 16:14:38 +02:00
end
end