diff --git a/README.md b/README.md index c9b96bbf..e8f0ee39 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,21 @@ -#Salama +# Salama -Salama is about native code generation in and of ruby. In is done. +Salama is about native code generation in and of ruby. -### Step 1 - Assembly +It is probably best to read the book first. + +Currently the work is to get the styetm to bootstrap, ie produce and executable that does what the ruby code says. + +Later that executable nneds to extend itself, but to do so cwill be able to use the same code. + +## Done + +### Assembly Produce binary that represents code. Traditionally called assembling, but there is no need for an external file representation. -Ie only in ruby code do i want to create machine code. - Most instructions are in fact assembling correctly. Meaning i have tests, and i can use objbump to verify the correct assembler code is disasembled I even polished the dsl and so (from the tests), this is a valid hello world: @@ -26,25 +32,27 @@ I even polished the dsl and so (from the tests), this is a valid hello world: end write(7 + hello.length/4 + 1 , 'hello') -### Step 2 -Link to system +### Linking -Package the code into an executable. Run that and verify it's output. But full elf support (including externs) is eluding me for now. - -Still, this has proven to be a good review point for the arcitecture and means no libc for now. -Full rationale on the web pages, but it means starting an extra step. +Package the code into an executable, currently elf, and very simple at that. Above Hello World can be linked and run. And will say its thing. -### Step 3 - syscalls +There is no way to link c code currently and not planned either, for some time (see next) -Start implementing some syscalls and add the functionality we actually need from c (basic io only really) +### Syscalls -This is surprisingly easy, framework is done. As said, "Hello world" comes out and does use syscall 4. -Also the program stops by syscall exit. The full list is ont the net and involves mostly grunt work. +Some small portion of what libc usually provides is needed even right at the beginning. +Mainly file open and read, exit, that kind of thing. Looking at libc implementations and +kernel "api" docs, this is quite simple to do. -### Step 4 -Parse ruby +As said, "Hello world" comes out and does use syscall 4. +Also the program stops by syscall exit. +The full list is on the net and involves mostly just work. -Parse simple code, using Parslet. +### Parse ruby + +Parse simple code, using Parslet. This has been seperated out as it's own gem, salama-reader. Parsing is a surprisingly fiddly process, very space and order sensitive. But Parslet is great and simple expressions (including function definitions and calls) are starting to work. @@ -52,10 +60,10 @@ expressions (including function definitions and calls) are starting to work. I spent some time on the parse testing framework, so it is safe to fiddle and add. In fact it is very modular and so ot is easy to add. -### Step 5 - Virtual: Compile the Ast +### Virtual: Compile the Ast Since we now have an Abstact syntax tree, it needs to be compiled to a virtual machine Instruction format. -For the parsed subset that's done. +For the parsed subset that's almost done. It took me a while to come up with a decent but simple machine model. I had tried to map straight to hardware but failed. The current Virtual directory represent a machine with basic oo features. @@ -65,16 +73,8 @@ and modify it. This allows optimisation after every pass as we have a data structure at every point in time. -### Step 6 - Compound types -Arrays and Hash parse. Good. But this means The Actual datastructures should be implemented. AWIP ( a work in progress) - -Implement Core library of arrays/hash/string , memory definition and access - -Also compound data needs to find it's way into the executable, needs to be assembled. This is done. (though there is -very little to be done with it at runtime) - -### Step 7 - Dynmic function lookup +## Status - Dynmic function lookup It proved to be quite a big step to go from static function calling to oo method lookup. Also ruby is very introspective and that means much of the compiled code needs to be accessible in the runtime (not just present, @@ -90,12 +90,14 @@ So the current staus is that i can - assemle and link the code and objects (strings/arrays/hashes) into an executable - run the executable and debug :-( -### Step x + 1 +## Future + +#### Blocks Implement ruby Blocks, and make new vm classes to deal with that. This is in fact a little open, but i have a general notion that blocks are "just" methods with even more implicit arguments. -### Step +2 +#### Exceptions Implement Exceptions. Conceptionally this is not so difficult in an oo machine as it would be in c. @@ -104,7 +106,7 @@ I have a post about it http://salama.github.io/2014/06/27/an-exceptional-though. which boild down to the fact that we can treat the address to return to in an exception quite like a return address from a function. Ie just another implicit parameter (as return is really an implicit parameter, a little like self for oo) -### Step +3 +### C linking Implement a way to call libc and other c libraries. I am not placing a large emphasis on this personally, but excpect somebody will come along and have library they want to use so much they can't stop themselves. @@ -112,9 +114,9 @@ Personally i think a fresh start is what we need much more. I once counted the c printf to the actual kernel invocation in some libc once and it was getting to 10! I hope with dynamic (re)compiling we can do better than that. -### Step +4 +### Stary sky -Iterate from one: +Iterate: 1. more cpus (ie intel) 2. more systems (ie mac) @@ -131,10 +133,6 @@ Iterate from one: And generally optimize and work towards that perfect world (we never seem to be able to attain). -### Step 30 - -Celebrate New year 2030 - Contributing to salama diff --git a/Rakefile b/Rakefile index 9b870bde..fcb8c7f8 100644 --- a/Rakefile +++ b/Rakefile @@ -38,11 +38,11 @@ task :simplecov do Rake::Task['test'].execute end -require 'roodi' -require 'roodi_task' -RoodiTask.new do |t| - t.verbose = false -end +#require 'roodi' +#require 'roodi_task' +#RoodiTask.new do |t| +# t.verbose = false +#end task :default => :test diff --git a/test/virtual/hello.rb b/test/virtual/hello.rb index ededa05c..92cd5a2a 100644 --- a/test/virtual/hello.rb +++ b/test/virtual/hello.rb @@ -10,7 +10,7 @@ class HelloTest < MiniTest::Test writer = Elf::ObjectWriter.new(Virtual::BootSpace.space) writer.save "hello.o" # puts Sof::Writer.write(expressions) -# puts Sof::Writer.write(Virtual::BootSpace.space) + puts Sof::Writer.write(Virtual::BootSpace.space) end def qtest_simplest_function