diff --git a/lib/crystal.rb b/lib/crystal.rb index 83653551..8bf603e5 100644 --- a/lib/crystal.rb +++ b/lib/crystal.rb @@ -4,4 +4,4 @@ require "elf/object_writer" require 'parser/crystal' require 'parser/transform' require "ast/all" -require "vm/object_machine" +require "virtual/machine" diff --git a/lib/virtual/list.rb b/lib/virtual/list.rb new file mode 100644 index 00000000..d3d97ebb --- /dev/null +++ b/lib/virtual/list.rb @@ -0,0 +1,47 @@ +class List + + def initialize + @next = nil + end + def empty? + @next.nil? + end + + def get(key) + if( @next ) + return @next.get(key) + else + return nil + end + end + + def set(key , value) + if(@next) + @next.set(key,value) + else + @next = Node.new(key,value) + end + value + end +end + +class Node < List + def initialize(key,value) + @key = key + @value = value + end + def get(key) + if(@key == key) + return @value + else + return super(key) + end + end + def set(key,value) + if(@key == key) + @value = value + else + super(key,value) + end + end +end diff --git a/lib/virtual/machine.rb b/lib/virtual/machine.rb index da6e68aa..d4ee3b09 100644 --- a/lib/virtual/machine.rb +++ b/lib/virtual/machine.rb @@ -1,6 +1,8 @@ module Vm - # The ObjectMachine is the object-oriented virtual machine in which ruby is implemented. - # + # The Virtual Machine is a value based virtual machine in which ruby is implemented. While it is value based, + # it resembles oo in basic ways of object encapsulation and method invokation, it is a "closed" / static sytem + # in that all types are know and there is no dynamic dispatch (so we don't bite our tail here). + # # It is minimal and realistic and low level # - minimal means that if one thing can be implemented by another, it is left out. This is quite the opposite from # ruby, which has several loops, many redundant if forms and the like. @@ -9,25 +11,41 @@ module Vm # - low level means it's basic instructions are realively easily implemented in a register machine. ie send is not # a an instruction but a function. # - # A better name may be Value-based machine. Ie all "objects" are values, all passing is value based. - # The illusion of objects is created by a value called object-reference. - # # So the memory model of the machine allows for indexed access into and "object" . A fixed number of objects exist # (ie garbage collection is reclaming, not destroying and recreating) although there may be a way to increase that number. # - # The ast is transformed to object-machine objects, some of which represent code, some data. + # The ast is transformed to virtaul-machine objects, some of which represent code, some data. # # The next step transforms to the register machine layer, which is what actually executes. # - # More concretely, an object machine is a sort of oo turing machine, it has a current instruction, executes the - # instructions, fetches the next one and so on. + # More concretely, an virtual machine is a sort of oo turing machine, it has a current instruction, executes the + # instructions, fetches the next one and so on. # Off course the instructions are not soo simple, but in oo terms quite so. # + # The machine is virtual in the sense that it is completely + # modeled in software, it's complete state explicitly available (not implicitly by walking stacks or something) + # The machine has a no register, but local variables, a scope at each point in time. # Scope changes with calls and blocks, but is saved at each level. In terms of lower level implementation this means - # that the the model is such that what is a variable in ruby, never ends up being just on the cpu stack. + # that the the model is such that what is a variable in ruby, never ends up being just on the pysical stack. # - class ObjectMachine + class Machine + # the main machine is the one that runs on the main thread, if it exists or receives an uncaught exception, that's it. + def self.main + @main || @main = Machine.new + end + + def initialize + # a binding represents the local variables at a point in the program. + # The amount of local variables is assumed to be relatively small, and so the + # storage is a linked list. Has the same api as a ha + @bindings = List.new + end + def run instruction + instruction.execute + end end end + +require_relative "list" \ No newline at end of file diff --git a/test/unit/list.rb b/test/unit/list.rb new file mode 100644 index 00000000..8f95ad3f --- /dev/null +++ b/test/unit/list.rb @@ -0,0 +1,42 @@ +require_relative "../helper" + +class TestLists < MiniTest::Test + + def setup + @list = List.new + end + def test_list_create + assert @list.empty? + end + def test_empty_list_doesnt_return + assert_equal nil , @list.get(3) + assert_equal nil , @list.get(:any) + end + def test_one_set1 + assert_equal 1 , @list.set(1,1) + end + def test_one_set2 + assert_equal :some , @list.set(1,:some) + end + def test_two_sets + assert_equal 1 , @list.set(1,1) + assert_equal :some , @list.set(1,:some) + end + def test_one_get1 + test_one_set1 + assert_equal 1 , @list.get(1) + end + def test_one_get2 + test_one_set2 + assert_equal :some , @list.get(1) + end + def test_many_get + shouldda = { :one => 1 , :two => 2 , :three => 3} + shouldda.each do |k,v| + @list.set(k,v) + end + shouldda.each do |k,v| + assert_equal v , @list.get(k) + end + end +end