check
This commit is contained in:
parent
845a8cab8b
commit
04e4dc872e
@ -9,5 +9,12 @@ module Arm
|
|||||||
def function_call call_value
|
def function_call call_value
|
||||||
"call"
|
"call"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def main_entry
|
||||||
|
e = Vm::Block.new("main_entry")
|
||||||
|
end
|
||||||
|
def main_exit
|
||||||
|
e = Vm::Block.new("main_exit")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -21,21 +21,24 @@ module Vm
|
|||||||
def initialize(name)
|
def initialize(name)
|
||||||
super()
|
super()
|
||||||
@name = name.to_sym
|
@name = name.to_sym
|
||||||
|
@next = nil
|
||||||
|
@previous = nil
|
||||||
|
@codes = []
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :name
|
attr_reader :name , :previous , :next
|
||||||
|
|
||||||
def verify
|
def verify
|
||||||
raise "Empty #{self.inspect}" if @values.empty?
|
|
||||||
end
|
|
||||||
private
|
|
||||||
|
|
||||||
# possibly misguided ??
|
|
||||||
def add_arg value
|
|
||||||
# TODO check
|
|
||||||
@args << value
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# set the next executed block after self.
|
||||||
|
# why is this useful? if it's unconditional, why not merge them:
|
||||||
|
# So the second block can be used as a jump target. You standard loop needs a block to setup
|
||||||
|
# and at least one to do the calculation
|
||||||
|
def next block
|
||||||
|
block.previous = self
|
||||||
|
self.next = block
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
@ -46,7 +46,5 @@ module Vm
|
|||||||
# TODO check
|
# TODO check
|
||||||
@args << value
|
@args << value
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
@ -2,12 +2,15 @@ module Vm
|
|||||||
module Kernel
|
module Kernel
|
||||||
def self.start
|
def self.start
|
||||||
#TODO extract args into array of strings
|
#TODO extract args into array of strings
|
||||||
|
Machine.instance.main_entry
|
||||||
end
|
end
|
||||||
def self.exit
|
def self.exit
|
||||||
# Machine.exit swi 0
|
# Machine.exit swi 0
|
||||||
|
Machine.instance.main_exit
|
||||||
end
|
end
|
||||||
def self.puts
|
def self.puts string
|
||||||
"me"
|
# should unwrap from string to char*
|
||||||
|
Machine.instance.puts
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -16,14 +16,13 @@ module Vm
|
|||||||
|
|
||||||
# throwing in a context for unspecified use (well one is to pass the programm/globals around)
|
# throwing in a context for unspecified use (well one is to pass the programm/globals around)
|
||||||
|
|
||||||
|
|
||||||
class Program < Block
|
class Program < Block
|
||||||
|
|
||||||
# should init for a machine and pass that on to start/exit / register alloc and the like
|
# Initialize with a string for cpu. Naming conventions are: for Machine XXX there exists a module XXX
|
||||||
def initialize
|
# with a XXXMachine in it that derives from Vm::Machine
|
||||||
|
def initialize machine
|
||||||
super("start")
|
super("start")
|
||||||
# this aint pretty. but i'll go soon enough
|
Machine.instance = eval("#{machine}::#{machine}Machine").new
|
||||||
Machine.instance = Arm::ArmMachine.new
|
|
||||||
|
|
||||||
@context = Context.new(self)
|
@context = Context.new(self)
|
||||||
@functions = []
|
@functions = []
|
||||||
@ -60,8 +59,6 @@ module Vm
|
|||||||
|
|
||||||
end
|
end
|
||||||
def verify
|
def verify
|
||||||
main = @functions.find{|f| f.name == "main"}
|
|
||||||
raise "No main in Program" unless main
|
|
||||||
@functions.each do |funct|
|
@functions.each do |funct|
|
||||||
funct.verify
|
funct.verify
|
||||||
end
|
end
|
||||||
|
@ -25,6 +25,11 @@ module Vm
|
|||||||
raise "abstract method called #{self.inspect}"
|
raise "abstract method called #{self.inspect}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# since we convert ast to values in conversion, value itself is responsible for compiling itself
|
||||||
|
# Compile must return a value, usually used in the next level up
|
||||||
|
def compile(context)
|
||||||
|
raise "abstract method called #{self.inspect}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Word < Value
|
class Word < Value
|
||||||
@ -36,19 +41,13 @@ module Vm
|
|||||||
class Unsigned < Word
|
class Unsigned < Word
|
||||||
|
|
||||||
def plus unsigned
|
def plus unsigned
|
||||||
unless unsigned.is_a? Unsigned
|
Machine.instance.unsigned_plus self , unsigned
|
||||||
unsigned = Conversion.new( unsigned , Unsigned )
|
|
||||||
end
|
|
||||||
UnsignedAdd.new( self , unsigned )
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Signed < Word
|
class Signed < Word
|
||||||
def plus signed
|
def plus signed
|
||||||
unless signed.is_a? Signed
|
Machine.instance.signed_plus self , signed
|
||||||
signed = Conversion.new( signed , Signed )
|
|
||||||
end
|
|
||||||
SignedAdd.new( self , signed )
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -20,12 +20,10 @@ class TestRunner < MiniTest::Test
|
|||||||
string = File.read(file)
|
string = File.read(file)
|
||||||
syntax = Parser::Composed.new.parse(string)
|
syntax = Parser::Composed.new.parse(string)
|
||||||
tree = Parser::Transform.new.apply(syntax)
|
tree = Parser::Transform.new.apply(syntax)
|
||||||
#transform
|
|
||||||
# write
|
puts tree.to_yaml
|
||||||
#link
|
|
||||||
# execute
|
program = Vm::Program.new "Arm"
|
||||||
# check result ?
|
|
||||||
program = Vm::Program.new
|
|
||||||
expression = tree.to_value
|
expression = tree.to_value
|
||||||
compiled = expression.compile( program.context )
|
compiled = expression.compile( program.context )
|
||||||
# do some stuff with mains and what not ??
|
# do some stuff with mains and what not ??
|
||||||
|
Loading…
Reference in New Issue
Block a user