introducing class variable and typed arguments
This commit is contained in:
parent
94c08f7129
commit
18935366fe
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
9
lib/parfait/variable.rb
Normal 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
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user