more random code

This commit is contained in:
Torsten Ruger 2014-05-02 08:02:25 +03:00
parent e019f10e19
commit 990b4726ba
8 changed files with 155 additions and 13 deletions

View File

@ -4,4 +4,4 @@ require "asm/program"
require "elf/object_writer"
require 'parser/composed'
require 'parser/transform'
require "vm/context"

53
lib/vm/context.rb Normal file
View File

@ -0,0 +1,53 @@
require_relative "kernel"
module Vm
class Context
def initialize
@locals = {}
end
def get name
@locals[name]
end
end
end
# ast classes
module Parser
Expression.class_eval do
def compile builder , context
raise "abstract #{self.inspect}"
end
end
IntegerExpression.class_eval do
end
NameExpression.class_eval do
end
StringExpression.class_eval do
def compile builder , context
return string
end
end
FuncallExpression.class_eval do
def compile builder , context
arguments = args.collect{|arg| arg.compile(builder , context) }
function = context.get(name)
unless function
function = Vm::Kernel.send(name)
context.add_function( name , function )
end
end
end
ConditionalExpression.class_eval do
end
AssignmentExpression.class_eval do
end
FunctionExpression.class_eval do
end
end

6
lib/vm/instruction.rb Normal file
View File

@ -0,0 +1,6 @@
module Vm
class Instruction
end
end

7
lib/vm/kernel.rb Normal file
View File

@ -0,0 +1,7 @@
module Vm
module Kernel
def self.puts
"me"
end
end
end

View File

@ -1,7 +1,27 @@
module Vm
# the vm machine is what does things. The only one that does things
# all things must go through the machine to actually happen
# Our virtual machine has a number of registers of a given size and uses a stack
# So much so standard
# But our machine is oo, meaning that the register contents is typed.
# Off course current hardware does not have that (a perceived issue), but for our machine we pretend.
# So internally we have at least 8 word registers, one of which is used to keep track of types*
# and any number of scratch registers
# but externally it's all Values (see there)
# * Note that register content is typed externally. Not as in mri, where int's are tagged. Floats can's
# be tagged and lambda should be it's own type, so tagging does not work
# Note: subclasses should/will be used once we have the basic architecture clear and working
class Machine
attr_reader :registers
attr_reader :scratch
attr_reader :pc
attr_reader :stack
# is often a pseudo register (ie doesn't support move or other operations).
# Still, using if to express tests makes sense, not just for
# consistency in this code, but also because that is what is actually done
attr_reader :status
end
end

View File

@ -1,17 +1,70 @@
module Vm
# Values represent the information as it is processed. Different subclasses for different types,
# each type with different operations.
# The oprerations on values is what makes a machine do things.
# For compilation, values are mopped to the machines registers and the functions (on values) map
# to machine instructions
# Values are immutable! (that's why they are called values)
# Operations on values _always_ produce new values (conceptionally)
# Values are a way to reason about (create/validate) instructions. The final executable is mostly
# instrucions.
# Word Values are what fits in a register. Derived classes
# Float, Reference , Integer(s) must fit the same registers
class Value
def bit_size
8 * byte_size
end
def byte_size
raise "abstract method called #{self.inspect}"
end
attr :register
def initialize reg = nil
@register = nil
end
end
class Word < Value
end
class Reference < Value
class Unsigned < Word
def + unsigned
unless unsigned.is_a? Unsigned
unsigned = Conversion.new( unsigned , Unsigned )
end
UnsignedAdd.new( self , unsigned )
end
end
class Signed < Word
def + signed
unless signed.is_a? Signed
signed = Conversion.new( signed , Signed )
end
SignedAdd.new( self , signed )
end
end
class Float < Word
end
class Reference < Word
end
class MemoryReference < Reference
end
class ObjectReference < Reference
end
end
class Byte < Value
end
end

View File

@ -1,3 +1,5 @@
def foo(x)
a = 5
end
end
foo( 3 )

View File

@ -25,9 +25,10 @@ class TestRunner < MiniTest::Test
#link
# execute
# check result ?
puts string
puts " "
puts tree.inspect
context = Vm::Context.new
builder = Asm::Program.new
compiled = tree.compile( builder , context )
puts compiled.inspect
end
end