introduce constant class and add block to compile signature(wip, work in progress)

This commit is contained in:
Torsten Ruger
2014-05-13 16:24:19 +03:00
parent dd05b30230
commit d7f31e7f39
15 changed files with 145 additions and 140 deletions

51
lib/vm/constants.rb Normal file
View File

@ -0,0 +1,51 @@
module Vm
# constants are the stuff that you embedd in the program as numbers or strings.
# Another way to think about them is as Operands, they have no seperate "identity"
# and usually end up embedded in the instructions. ie your basic foo + 4 will encode
# the 4 in the instruction opcode. The 4 is not accessible anywhere else.
# When it should be usable in other forms, the constant must become a Value first
class Constant < Value
end
class IntegerConstant < Constant
def init int
@integer = int
end
attr_reader :integer
end
# The name really says it all.
# The only interesting thing is storage.
# Currently string are stored "inline" , ie in the code segment.
# Mainly because that works an i aint no elf expert.
class StringConstant < Constant
attr_reader :string
# currently aligned to 4 (ie padded with 0) and off course 0 at the end
def initialize str
length = str.length
# rounding up to the next 4 (always adding one for zero pad)
pad = ((length / 4 ) + 1 ) * 4 - length
raise "#{pad} #{self}" unless pad >= 1
@string = str + "\x00" * pad
end
def load reg_num
Machine.instance.string_load self , reg_num
end
# the strings length plus padding
def length
string.length
end
# just writing the string
def assemble(io)
io << string
end
end
end

View File

@ -2,31 +2,23 @@ module Vm
# name and args , return
class FunctionCall < Block
class FunctionCall < Value
def initialize(name , args)
super(name)
@name = name
@args = args
@function = nil
end
attr_reader :function , :args
attr_reader :function , :args , :name
def assign_function context
@function = context.program.get_function @name
if @function
raise "error #{self} , #{@function.args.length} != #{args.length}" if @function.arity != args.length
else
@function = context.program.get_or_create_function @name
end
end
def load_args
def load_args into
args.each_with_index do |arg , index|
add_code arg.load("r#{index}".to_sym)
into.add_code arg.load("r#{index}".to_sym)
end
end
def do_call
add_code Machine.instance.function_call self
def do_call into
into.add_code Machine.instance.function_call self
end
end
end

View File

@ -14,7 +14,7 @@ module Vm
# A Machines main responsibility in the framework is to instantiate Instruction
# Value functions are mapped to machines by concatenating the values class name + the methd name
# Example: SignedValue.plus( value ) -> Machine.signed_plus (value )
# Example: IntegerValue.plus( value ) -> Machine.signed_plus (value )
# Also, shortcuts are created to easily instantiate Instruction objects. The "standard" set of instructions
# (arm-influenced) provides for normal operations on a register machine,

View File

@ -21,27 +21,23 @@ module Vm
# just a base class for data. not sure how this will be usefull (may just have read too much llvm)
class Value < Code
def initialize value
@value = value
end
attr_reader :value
#naming convention to infer types in kernel functions. Kernel types are basic types, ie see below
#
def self.type name
parts = name.split("_")
t = "Basic"
if parts[1]
t = parts[1]
end
t
def type
self.class
end
end
# This is what it is when we don't know what it is.
# Must be promoted to A Word-Value to to anything
# remembering that our oo machine is typed, no overloading or stuff
class Word < Value
def load reg
Machine.instance.word_load self , reg
attr_accessor :register
def initialize reg
register = reg
end
def length
4
end
@ -54,59 +50,15 @@ module Vm
end
end
class Signed < Word
def plus signed
Machine.instance.signed_plus self , signed
end
end
class Integer < Word
class Variable < Value
attr_reader :name , :register
def initialize name , register = nil , val = nil
super(val)
@register = register
@name = name
end
def length
@value.length
end
def assemble io
@value.load @register
end
end
# The name really says it all.
# The only interesting thing is storage.
# Currently string are stored "inline" , ie in the code segment.
# Mainly because that works an i aint no elf expert.
class StringLiteral < Value
# currently aligned to 4 (ie padded with 0) and off course 0 at the end
def initialize(str)
super(str)
length = str.length
# rounding up to the next 4 (always adding one for zero pad)
pad = ((length / 4 ) + 1 ) * 4 - length
raise "#{pad} #{self}" unless pad >= 1
@value = str + "\x00" * pad
end
def string
@value
def less_or_equal right
Machine.instance.integer_less_or_equal self , right
end
def load reg_num
Machine.instance.string_load self , reg_num
end
# the strings length plus padding
def length
string.length
end
# just writing the string
def assemble(io)
io << string
def plus right
Machine.instance.integer_plus self , right
end
end
end
require_relative "constants"