introduce constant class and add block to compile signature(wip, work in progress)
This commit is contained in:
51
lib/vm/constants.rb
Normal file
51
lib/vm/constants.rb
Normal 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
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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"
|
Reference in New Issue
Block a user