first oo program to compile. But no worries, there is still work left to be done
This commit is contained in:
parent
f523d0946d
commit
c59f22f11f
@ -43,7 +43,7 @@ module Arm
|
|||||||
elsif (op_with_rot = calculate_u8_with_rr(right))
|
elsif (op_with_rot = calculate_u8_with_rr(right))
|
||||||
operand = op_with_rot
|
operand = op_with_rot
|
||||||
immediate = 1
|
immediate = 1
|
||||||
raise "hmm"
|
# raise "hmm"
|
||||||
else
|
else
|
||||||
raise "cannot fit numeric literal argument in operand #{right.inspect}"
|
raise "cannot fit numeric literal argument in operand #{right.inspect}"
|
||||||
end
|
end
|
||||||
|
@ -12,10 +12,10 @@ module Arm
|
|||||||
|
|
||||||
@immediate = 0
|
@immediate = 0
|
||||||
@rn = :r0 # register zero = zero bit pattern
|
@rn = :r0 # register zero = zero bit pattern
|
||||||
raise inspect if to.is_a?(Vm::Value) and
|
# raise inspect if to.is_a?(Vm::Value) and
|
||||||
from.is_a?(Vm::Value) and
|
# from.is_a?(Vm::Value) and
|
||||||
!@attributes[:shift_lsr] and
|
# !@attributes[:shift_lsr] and
|
||||||
to.register == from.register
|
# to.register == from.register
|
||||||
end
|
end
|
||||||
|
|
||||||
# arm intrucions are pretty sensible, and always 4 bytes (thumb not supported)
|
# arm intrucions are pretty sensible, and always 4 bytes (thumb not supported)
|
||||||
|
@ -15,14 +15,18 @@ module Ast
|
|||||||
raise "uups #{clazz}.#{c_name}" unless clazz
|
raise "uups #{clazz}.#{c_name}" unless clazz
|
||||||
#class qualifier, means call from metaclass
|
#class qualifier, means call from metaclass
|
||||||
clazz = clazz.meta_class
|
clazz = clazz.meta_class
|
||||||
|
value = clazz
|
||||||
|
puts "CLAZZ #{value}"
|
||||||
function = clazz.get_or_create_function(name)
|
function = clazz.get_or_create_function(name)
|
||||||
elsif receiver.is_a? VariableExpression
|
elsif receiver.is_a? VariableExpression
|
||||||
raise "not implemented instance var:#{receiver}"
|
raise "not implemented instance var:#{receiver}"
|
||||||
else
|
else
|
||||||
raise "not implemented case (dare i say system error):#{receiver}"
|
# should be case switch for basic tyes and dynamic dispatch for objects reference
|
||||||
|
value = context.locals[receiver.name]
|
||||||
|
function = context.current_class.get_or_create_function(name)
|
||||||
end
|
end
|
||||||
raise "No such method error #{clazz.to_s}:#{name}" if function == nil
|
raise "No such method error #{clazz.to_s}:#{name}" if function == nil
|
||||||
call = Vm::CallSite.new( name , params , function)
|
call = Vm::CallSite.new( name , value , params , function)
|
||||||
current_function = context.function
|
current_function = context.function
|
||||||
current_function.save_locals(context , into) if current_function
|
current_function.save_locals(context , into) if current_function
|
||||||
call.load_args into
|
call.load_args into
|
||||||
|
@ -32,17 +32,17 @@ module Boot
|
|||||||
return get_function
|
return get_function
|
||||||
end
|
end
|
||||||
|
|
||||||
def _set_instance_variable(name , value)
|
def _set_instance_variable(context , name , value)
|
||||||
raise name
|
raise name
|
||||||
end
|
end
|
||||||
|
|
||||||
def _get_singleton_method(name )
|
def _get_singleton_method(context , name )
|
||||||
raise name
|
raise name
|
||||||
end
|
end
|
||||||
def _add_singleton_method(method)
|
def _add_singleton_method(context, method)
|
||||||
raise "4"
|
raise "4"
|
||||||
end
|
end
|
||||||
def initialize()
|
def initialize(context)
|
||||||
raise "4"
|
raise "4"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
15
lib/boot/string.rb
Normal file
15
lib/boot/string.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
module Boot
|
||||||
|
class String
|
||||||
|
module ClassMethods
|
||||||
|
def get context , index = Vm::Integer
|
||||||
|
get_function = Vm::Function.new(:get , [Vm::Integer, Vm::Integer] , Vm::Integer )
|
||||||
|
return get_function
|
||||||
|
end
|
||||||
|
def set context , index = Vm::Integer , char = Vm::Integer
|
||||||
|
set_function = Vm::Function.new(:set , [Vm::Integer, Vm::Integer, Vm::Integer] , Vm::Integer )
|
||||||
|
return set_function
|
||||||
|
end
|
||||||
|
end
|
||||||
|
extend ClassMethods
|
||||||
|
end
|
||||||
|
end
|
@ -1,7 +0,0 @@
|
|||||||
module Core
|
|
||||||
class String
|
|
||||||
module ClassMethods
|
|
||||||
end
|
|
||||||
extend ClassMethods
|
|
||||||
end
|
|
||||||
end
|
|
@ -38,7 +38,6 @@ module Vm
|
|||||||
end
|
end
|
||||||
unless fun
|
unless fun
|
||||||
fun = Core::Kernel.send(name , @context)
|
fun = Core::Kernel.send(name , @context)
|
||||||
return nil if fun == nil
|
|
||||||
@functions << fun
|
@functions << fun
|
||||||
end
|
end
|
||||||
fun
|
fun
|
||||||
@ -47,6 +46,9 @@ module Vm
|
|||||||
def inspect
|
def inspect
|
||||||
"BootClass #{@name} , super #{@super_class} #{@functions.length} functions"
|
"BootClass #{@name} , super #{@super_class} #{@functions.length} functions"
|
||||||
end
|
end
|
||||||
|
def to_s
|
||||||
|
inspect
|
||||||
|
end
|
||||||
# Code interface follows. Note position is inheitted as is from Code
|
# Code interface follows. Note position is inheitted as is from Code
|
||||||
|
|
||||||
# length of the class is the length of it's functions
|
# length of the class is the length of it's functions
|
||||||
|
@ -4,6 +4,7 @@ require_relative "call_site"
|
|||||||
require "arm/arm_machine"
|
require "arm/arm_machine"
|
||||||
require "core/kernel"
|
require "core/kernel"
|
||||||
require "boot/object"
|
require "boot/object"
|
||||||
|
require "boot/string"
|
||||||
|
|
||||||
module Vm
|
module Vm
|
||||||
# The BootSpace is contains all objects for a program. In functional terms it is a program, but on oo
|
# The BootSpace is contains all objects for a program. In functional terms it is a program, but on oo
|
||||||
@ -48,6 +49,11 @@ module Vm
|
|||||||
puts "adding #{f}"
|
puts "adding #{f}"
|
||||||
obj.add_function Boot::Object.send(f , @context)
|
obj.add_function Boot::Object.send(f , @context)
|
||||||
end
|
end
|
||||||
|
obj = get_or_create_class :String
|
||||||
|
[:get , :set].each do |f|
|
||||||
|
puts "adding #{f}"
|
||||||
|
obj.add_function Boot::String.send(f , @context)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
def add_object o
|
def add_object o
|
||||||
return if @objects.include? o
|
return if @objects.include? o
|
||||||
|
@ -4,12 +4,13 @@ module Vm
|
|||||||
|
|
||||||
class CallSite < Value
|
class CallSite < Value
|
||||||
|
|
||||||
def initialize(name , args , function )
|
def initialize(name , value , args , function )
|
||||||
@name = name
|
@name = name
|
||||||
|
@value = value
|
||||||
@args = args
|
@args = args
|
||||||
@function = function
|
@function = function
|
||||||
end
|
end
|
||||||
attr_reader :function , :args , :name
|
attr_reader :function , :args , :name , :value
|
||||||
|
|
||||||
def load_args into
|
def load_args into
|
||||||
args.each_with_index do |arg , index|
|
args.each_with_index do |arg , index|
|
||||||
|
@ -15,6 +15,9 @@ module Vm
|
|||||||
@integer = int
|
@integer = int
|
||||||
end
|
end
|
||||||
attr_reader :integer
|
attr_reader :integer
|
||||||
|
def value
|
||||||
|
@integer
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# The name really says it all.
|
# The name really says it all.
|
||||||
|
@ -65,7 +65,8 @@ module Vm
|
|||||||
def new_local type = Vm::Integer
|
def new_local type = Vm::Integer
|
||||||
register = args.length + @locals.length
|
register = args.length + @locals.length
|
||||||
l = type.new(register + 1) # one for the type register 0, TODO add type as arg0 implicitly
|
l = type.new(register + 1) # one for the type register 0, TODO add type as arg0 implicitly
|
||||||
raise "the red flag #{inspect}" if l.register > 6
|
puts "new local #{l.register}"
|
||||||
|
# raise "Register overflow in function #{name}" if l.register > 6
|
||||||
@locals << l
|
@locals << l
|
||||||
l
|
l
|
||||||
end
|
end
|
||||||
|
@ -30,8 +30,22 @@ module Vm
|
|||||||
puts "no function for #{name} in Meta #{@me_self.inspect}" unless f
|
puts "no function for #{name} in Meta #{@me_self.inspect}" unless f
|
||||||
f
|
f
|
||||||
end
|
end
|
||||||
|
# way of creating new functions that have not been parsed.
|
||||||
|
def get_or_create_function name
|
||||||
|
fun = get_function name
|
||||||
|
unless fun or name == :Object
|
||||||
|
supr = @context.object_space.get_or_create_class(@super_class)
|
||||||
|
fun = supr.get_function name
|
||||||
|
puts "#{supr.functions.collect(&:name)} for #{name} GOT #{fun.class}" if name == :index_of
|
||||||
|
end
|
||||||
|
fun
|
||||||
|
end
|
||||||
|
|
||||||
def inspect
|
def inspect
|
||||||
"#{@me_self}, #{@functions.length} functions"
|
"MetaClass on #{@me_self}, #{@functions.length} functions"
|
||||||
|
end
|
||||||
|
def to_s
|
||||||
|
inspect
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -7,13 +7,15 @@ class TestClass < MiniTest::Test
|
|||||||
@string_input = <<HERE
|
@string_input = <<HERE
|
||||||
class Object
|
class Object
|
||||||
def index_of( name )
|
def index_of( name )
|
||||||
return @layout.index_of(name)
|
l = @layout
|
||||||
|
return l.index_of(name)
|
||||||
end
|
end
|
||||||
def layout()
|
def layout()
|
||||||
return @layout
|
return @layout
|
||||||
end
|
end
|
||||||
def class()
|
def class()
|
||||||
return @layout.class()
|
l = @layout
|
||||||
|
return l.class()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
class Class
|
class Class
|
||||||
@ -51,7 +53,7 @@ HERE
|
|||||||
@should = [0x0,0xb0,0xa0,0xe3,0x2a,0x10,0xa0,0xe3,0x13,0x0,0x0,0xeb,0x1,0x70,0xa0,0xe3,0x0,0x0,0x0,0xef,0x0,0x70,0xa0,0xe1,0x0,0x40,0x2d,0xe9,0xa,0x30,0x42,0xe2,0x22,0x21,0x42,0xe0,0x22,0x22,0x82,0xe0,0x22,0x24,0x82,0xe0,0x22,0x28,0x82,0xe0,0xa2,0x21,0xa0,0xe1,0x2,0x41,0x82,0xe0,0x84,0x30,0x53,0xe0,0x1,0x20,0x82,0x52,0xa,0x30,0x83,0x42,0x30,0x30,0x83,0xe2,0x0,0x30,0xc1,0xe5,0x1,0x10,0x41,0xe2,0x0,0x0,0x52,0xe3,0xef,0xff,0xff,0x1b,0x0,0x80,0xbd,0xe8,0x0,0x40,0x2d,0xe9,0x1,0x20,0xa0,0xe1,0x20,0x10,0x8f,0xe2,0x9,0x10,0x81,0xe2,0xe9,0xff,0xff,0xeb,0x14,0x10,0x8f,0xe2,0xc,0x20,0xa0,0xe3,0x1,0x0,0xa0,0xe3,0x4,0x70,0xa0,0xe3,0x0,0x0,0x0,0xef,0x0,0x70,0xa0,0xe1,0x0,0x80,0xbd,0xe8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20]
|
@should = [0x0,0xb0,0xa0,0xe3,0x2a,0x10,0xa0,0xe3,0x13,0x0,0x0,0xeb,0x1,0x70,0xa0,0xe3,0x0,0x0,0x0,0xef,0x0,0x70,0xa0,0xe1,0x0,0x40,0x2d,0xe9,0xa,0x30,0x42,0xe2,0x22,0x21,0x42,0xe0,0x22,0x22,0x82,0xe0,0x22,0x24,0x82,0xe0,0x22,0x28,0x82,0xe0,0xa2,0x21,0xa0,0xe1,0x2,0x41,0x82,0xe0,0x84,0x30,0x53,0xe0,0x1,0x20,0x82,0x52,0xa,0x30,0x83,0x42,0x30,0x30,0x83,0xe2,0x0,0x30,0xc1,0xe5,0x1,0x10,0x41,0xe2,0x0,0x0,0x52,0xe3,0xef,0xff,0xff,0x1b,0x0,0x80,0xbd,0xe8,0x0,0x40,0x2d,0xe9,0x1,0x20,0xa0,0xe1,0x20,0x10,0x8f,0xe2,0x9,0x10,0x81,0xe2,0xe9,0xff,0xff,0xeb,0x14,0x10,0x8f,0xe2,0xc,0x20,0xa0,0xe3,0x1,0x0,0xa0,0xe3,0x4,0x70,0xa0,0xe3,0x0,0x0,0x0,0xef,0x0,0x70,0xa0,0xe1,0x0,0x80,0xbd,0xe8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20]
|
||||||
@output = " 42 "
|
@output = " 42 "
|
||||||
parse
|
parse
|
||||||
@target = [:Object , :foo]
|
@target = [:String , :plus]
|
||||||
write "class"
|
write "class"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user