introducing class variable and typed arguments

This commit is contained in:
Torsten Ruger 2015-09-27 14:30:41 +03:00
parent 94c08f7129
commit 18935366fe
8 changed files with 37 additions and 15 deletions

View File

@ -7,7 +7,7 @@ module Bosl
name = name.to_a.first name = name.to_a.first
args = parameters.to_a.collect do |p| args = parameters.to_a.collect do |p|
raise "error, argument must be a identifier, not #{p}" unless p.type == :parameter raise "error, argument must be a identifier, not #{p}" unless p.type == :parameter
p[2] Parfait::Variable.new( p.first , p[1])
end end
if receiver if receiver

View File

@ -8,6 +8,7 @@ require "parfait/list"
require "parfait/word" require "parfait/word"
require "parfait/binary_code" require "parfait/binary_code"
require "parfait/method" require "parfait/method"
require "parfait/variable"
require "parfait/dictionary" require "parfait/dictionary"
require "parfait/layout" require "parfait/layout"
require "parfait/message" require "parfait/message"

View File

@ -9,7 +9,7 @@ module Parfait
# static description of a method # static description of a method
# name # name
# arg_names # arguments
# known local variable names # known local variable names
# executable code # executable code
@ -18,17 +18,20 @@ module Parfait
class Method < Object class Method < Object
def initialize clazz , name , arg_names def initialize clazz , name , arguments
super() super()
raise "No class #{name}" unless clazz raise "No class #{name}" unless clazz
self.for_class = clazz self.for_class = clazz
self.name = name self.name = name
self.code = BinaryCode.new name self.code = BinaryCode.new name
raise "Wrong type, expect List not #{arg_names.class}" unless arg_names.is_a? List raise "Wrong type, expect List not #{arguments.class}" unless arguments.is_a? List
self.arg_names = arg_names arguments.each do |var|
raise "Must be variable argument, not #{var}" unless var.is_a? Variable
end
self.arguments = arguments
self.locals = List.new self.locals = List.new
end end
attributes [:name , :arg_names , :for_class , :code , :locals ] attributes [:name , :arguments , :for_class , :code , :locals ]
# determine whether this method has a variable by the given name # determine whether this method has a variable by the given name
@ -45,7 +48,7 @@ module Parfait
# determine whether this method has an argument by the name # determine whether this method has an argument by the name
def has_arg name def has_arg name
raise "has_arg #{name}.#{name.class}" unless name.is_a? Symbol raise "has_arg #{name}.#{name.class}" unless name.is_a? Symbol
self.arg_names.index_of name self.arguments.index_of name
end end
# determine if method has a local variable or tmp (anonymous local) by given name # determine if method has a local variable or tmp (anonymous local) by given name
@ -64,7 +67,7 @@ module Parfait
def get_var name def get_var name
var = has_var name var = has_var name
raise "no var #{name} in method #{self.name} , #{self.locals} #{self.arg_names}" unless var raise "no var #{name} in method #{self.name} , #{self.locals} #{self.arguments}" unless var
var var
end end

View File

@ -58,12 +58,12 @@ module Parfait
self.instance_methods.delete found self.instance_methods.delete found
end end
def create_instance_method method_name , arg_names def create_instance_method method_name , arguments
raise "create_instance_method #{method_name}.#{method_name.class}" unless method_name.is_a?(Symbol) raise "create_instance_method #{method_name}.#{method_name.class}" unless method_name.is_a?(Symbol)
clazz = object_layout().object_class() clazz = object_layout().object_class()
raise "??? #{method_name}" unless clazz raise "??? #{method_name}" unless clazz
#puts "Self: #{self.class} clazz: #{clazz.name}" #puts "Self: #{self.class} clazz: #{clazz.name}"
Method.new( clazz , method_name , arg_names ) Method.new( clazz , method_name , arguments )
end end
# this needs to be done during booting as we can't have all the classes and superclassses # this needs to be done during booting as we can't have all the classes and superclassses

9
lib/parfait/variable.rb Normal file
View File

@ -0,0 +1,9 @@
module Parfait
class Variable < Object
def initialize type , name , value = nil
@type , @name , @value = type , name , value
@value = 0 if @type == :int and value == nil
end
attributes [:type , :name, :value]
end
end

View File

@ -4,7 +4,7 @@ module Register
module Integer module Integer
module ClassMethods module ClassMethods
def plus c def plus c
plus_function = Virtual::MethodSource.create_method(:Integer,:int,:plus , [:Integer] ) plus_function = Virtual::MethodSource.create_method(:Integer,:int,:plus , [:int] )
plus_function.source.return_type = Virtual::Integer plus_function.source.return_type = Virtual::Integer
plus_function.source.receiver = Virtual::Integer plus_function.source.receiver = Virtual::Integer

View File

@ -130,7 +130,8 @@ module Virtual
# instances are copied (shame on you) # instances are copied (shame on you)
:Class => [:object_layout , :name , :instance_methods , :super_class , :meta_class], :Class => [:object_layout , :name , :instance_methods , :super_class , :meta_class],
:Dictionary => [:keys , :values ] , :Dictionary => [:keys , :values ] ,
:Method => [:name , :code ,:arg_names , :for_class, :locals ] , :Method => [:name , :code ,:arguments , :for_class, :locals ] ,
:Variable => [:type , :name , :value ] ,
:Module => [:name , :instance_methods , :super_class , :meta_class ] :Module => [:name , :instance_methods , :super_class , :meta_class ]
} }
end end

View File

@ -38,7 +38,15 @@ module Virtual
clazz = Virtual.machine.space.get_class_by_name class_name clazz = Virtual.machine.space.get_class_by_name class_name
raise "No such class #{class_name}" unless clazz raise "No such class #{class_name}" unless clazz
return_type = Virtual::Type.from_sym return_type return_type = Virtual::Type.from_sym return_type
method = clazz.create_instance_method( method_name , Virtual.new_list(args)) arguemnts = []
args.each_with_index do | arg , index |
unless arg.is_a? Parfait::Variable
raise "not type #{arg}:#{arg.class}" unless arg == :int || arg == :ref
arg = Parfait::Variable.new arg , "arg#{index}".to_sym
end
arguemnts << arg
end
method = clazz.create_instance_method( method_name , Virtual.new_list(arguemnts))
method.source = MethodSource.new(method , return_type) method.source = MethodSource.new(method , return_type)
method method
end end
@ -125,8 +133,8 @@ module Virtual
# mov and add will be called on Machine and generate Instructions that are then added # mov and add will be called on Machine and generate Instructions that are then added
# to the current block # to the current block
# also symbols are supported and wrapped as register usages (for bare metal programming) # also symbols are supported and wrapped as register usages (for bare metal programming)
# def method_missing(meth, *arg_names, &block) # def method_missing(meth, *arguments, &block)
# add_code ::Arm::ArmMachine.send(meth , *arg_names) # add_code ::Arm::ArmMachine.send(meth , *arguments)
# end # end
def byte_length def byte_length