bit of documentation
This commit is contained in:
parent
fb54d68020
commit
0bf008b351
39
README.md
39
README.md
@ -14,9 +14,12 @@ of the system, see below. The overhaul is done and rubyx produces working binari
|
||||
|
||||
Processing goes through layers: Ruby --> Vool --> Mom --> Risc --> Arm --> binary .
|
||||
|
||||
Currently most functional constructs work to some (usable) degree, ie if, while,
|
||||
assignment, ivars, calling and dynamic dispatch all work. Work continues
|
||||
on blocks currently, see below.
|
||||
Currently most basic constructs work to some (usable) degree, ie if, while,
|
||||
assignment, ivars, calling and dynamic dispatch all work. Simple blocks, those
|
||||
that ruby passes implicitly also work (lambdas not).
|
||||
|
||||
Work continues on memory management, which turns out to be pretty basic to do just about
|
||||
anything, even counting to a million.
|
||||
|
||||
## Layers
|
||||
|
||||
@ -149,38 +152,22 @@ Specifically here is a list of what works:
|
||||
- assignment (local/args/ivar)
|
||||
- static calling (where method is determined at compile time)
|
||||
- dynamic dispatch with caching
|
||||
- implicit blocks, ie the ones that ruby passes implicitly and are used in enumerating
|
||||
|
||||
Current work is on implicit blocks, which are surprisingly like static method calls
|
||||
and lambdas like dynamic dispatch.
|
||||
|
||||
## Contributing to rubyx
|
||||
|
||||
Probably best to talk to me, if it's not a typo or so.
|
||||
|
||||
There is a todo, for inspiration, though actual tasks that result in pulls, should start
|
||||
their live as a github issue. There we can discuss details so that no work is done
|
||||
in vain. There are some small issues there already, just comment if you're interested.
|
||||
I've started to put some github issues out, some basic some not so. Also there is a todo
|
||||
for the adventurous (bigger things, no BIG things).
|
||||
|
||||
Actual tasks that result in pulls, should start their life as a github issue.
|
||||
There we can discuss details so that no work is done
|
||||
in vain. If you're interested in an existing issues, just comment on it.
|
||||
|
||||
Fork and create a branch before sending pulls.
|
||||
|
||||
### Stary sky
|
||||
|
||||
Iterate:
|
||||
|
||||
1. more cpus (ie intel)
|
||||
2. more systems (ie mac)
|
||||
3. more syscalls, there are after all some hundreds
|
||||
5. A lot of modern cpu's functionality has to be mapped to ruby and implemented in assembler to be useful
|
||||
6. Different sized machines, with different register types ?
|
||||
7. on 64bit, there would be 8 bits for types and thus allow for rational, complex, and whatnot
|
||||
8. Housekeeping (the superset of gc) is abundant
|
||||
9. Any amount of time could be spent on a decent digital tree (see judy). Or possibly Dr.Cliffs hash.
|
||||
10. Also better string/arrays would be good.
|
||||
11. The minor point of threads and hopefully lock free primitives to deal with that.
|
||||
12. Other languages, python at least, maybe others
|
||||
|
||||
And generally optimise and work towards that perfect world (we never seem to be able to attain).
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright (c) 2014-8 Torsten Ruger.
|
||||
|
35
ToDo.md
35
ToDo.md
@ -10,8 +10,7 @@ Some things that would be nice . .
|
||||
- utf8 support (string improvements generally)
|
||||
|
||||
|
||||
Platforms
|
||||
---------
|
||||
## Platforms
|
||||
|
||||
x86 is up for grabs. I have intentionally started on arm (the most sold cpu) because i do
|
||||
this for fun. And my pi is fun.
|
||||
@ -19,24 +18,40 @@ this for fun. And my pi is fun.
|
||||
There is a ruby intel assembler called wilson out there. Or then there is Metasm, with
|
||||
good support for many other cpu's (and a lot more code)
|
||||
|
||||
Compliance
|
||||
----------
|
||||
## Compliance
|
||||
|
||||
Is admittedly a little more fun, but also not really my goal in the near future.
|
||||
Is admittedly a little more fun, but also not really my personal goal in the near future.
|
||||
|
||||
If i am really honest about this, i think ruby is a little quirky around the edges and i
|
||||
think a lot of that can/should be done as a compatibility layer. Keeping the core clean (and shiny).
|
||||
|
||||
Stdlib
|
||||
------
|
||||
## Stdlib
|
||||
|
||||
Stdlib is not clean. More like a layer that accumulated over the years.
|
||||
|
||||
Very nice solutions exist for most of the important things. Like celluloid for concurrency. Celluloid-io for
|
||||
Very nice solutions exist for most of the important things.
|
||||
Like celluloid for concurrency. Celluloid-io for
|
||||
good performance io with or without zero-mq. Fiddle looks nice admittedly.
|
||||
|
||||
Interesting
|
||||
-----------
|
||||
## Concurrency
|
||||
|
||||
Solving concurrency is up for grabs. Any solution is a start, channels ala go are nice and
|
||||
lock free stuff is the ultimate goal.
|
||||
|
||||
## Stary sky
|
||||
|
||||
Iterate:
|
||||
|
||||
1. more cpus (ie intel)
|
||||
2. more systems (ie mac)
|
||||
3. more syscalls, there are after all some hundreds (most as external gems)
|
||||
5. A lot of modern cpu's functionality has to be mapped to ruby and implemented in assembler to be useful
|
||||
6. Different sized machines, with different register types ?
|
||||
7. on 64bit, there would be 8 bits for types and thus allow for rational, complex, and whatnot
|
||||
8. Housekeeping (the superset of gc) is abundant
|
||||
9. Any amount of time could be spent on a decent digital tree (see judy). Or possibly Dr.Cliffs hash.
|
||||
10. Also better string/arrays would be good.
|
||||
11. The minor point of threads and hopefully lock free primitives to deal with that.
|
||||
12. Other languages, python at least, maybe others
|
||||
|
||||
And generally optimise and work towards that perfect world (we never seem to be able to attain).
|
||||
|
@ -1,10 +1,16 @@
|
||||
#integer related kernel functions
|
||||
module Risc
|
||||
module Builtin
|
||||
# integer related kernel functions
|
||||
# all these functions (return the functione they implement) assume interger input
|
||||
#
|
||||
# This means they will have to be renamed at some point and wrapped
|
||||
module Integer
|
||||
module ClassMethods
|
||||
include CompileHelper
|
||||
|
||||
# div by 4, ie shift two left
|
||||
# Mostly created for testing at this point, as it is short
|
||||
# return new int with result
|
||||
def div4(context)
|
||||
compiler = compiler_for(:Integer,:div4 ,{})
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
@ -18,18 +24,30 @@ module Risc
|
||||
compiler.add_mom( Mom::ReturnSequence.new)
|
||||
return compiler
|
||||
end
|
||||
# implemented by the comparison
|
||||
def >( context )
|
||||
comparison( :> )
|
||||
end
|
||||
# implemented by the comparison
|
||||
def <( context )
|
||||
comparison( :< )
|
||||
end
|
||||
# implemented by the comparison
|
||||
def <=( context )
|
||||
comparison( :<= )
|
||||
end
|
||||
# implemented by the comparison
|
||||
def >=( context )
|
||||
comparison( :>= )
|
||||
end
|
||||
|
||||
# all (four) comparison operation are quite similar and implemented here
|
||||
# - reduce the ints (assume int as input)
|
||||
# - subtract the fixnums
|
||||
# - check for minus ( < and > )
|
||||
# - also check for zero (<= and >=)
|
||||
# - load true or false object into return, depending on check
|
||||
# - return
|
||||
def comparison( operator )
|
||||
compiler = compiler_for(:Integer, operator ,{other: :Integer})
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
@ -54,11 +72,19 @@ module Risc
|
||||
return compiler
|
||||
end
|
||||
|
||||
# not implemented, would need a itos and that needs "new" (wip)
|
||||
def putint(context)
|
||||
compiler = compiler_for(:Integer,:putint ,{})
|
||||
compiler.add_mom( Mom::ReturnSequence.new)
|
||||
return compiler
|
||||
end
|
||||
|
||||
# implemented all known binary operators that map straight to machine codes
|
||||
# this function (similar to comparison):
|
||||
# - unpacks the intergers to fixnum
|
||||
# - applies the operator (at a risc level)
|
||||
# - gets a new integer and stores the result
|
||||
# - returns the new int
|
||||
def operator_method( op_sym )
|
||||
compiler = compiler_for(:Integer, op_sym ,{other: :Integer})
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
@ -76,6 +102,7 @@ module Risc
|
||||
return compiler
|
||||
end
|
||||
|
||||
# old helper function for div10 (which doesn't use builder yet)
|
||||
def add_receiver(builder)
|
||||
message = Risc.message_reg
|
||||
ret_type = builder.compiler.receiver_type
|
||||
|
@ -6,7 +6,6 @@ module Risc
|
||||
|
||||
# self[index] basically. Index is the first arg
|
||||
# return is stored in return_value
|
||||
# (this method returns a new method off course, like all builtin)
|
||||
def get_internal_word( context )
|
||||
compiler = compiler_for(:Object , :get_internal_word ,{at: :Integer})
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
@ -22,7 +21,7 @@ module Risc
|
||||
end
|
||||
|
||||
# self[index] = val basically. Index is the first arg , value the second
|
||||
# no return
|
||||
# return the value passed in
|
||||
def set_internal_word( context )
|
||||
compiler = compiler_for(:Object , :set_internal_word , {at: :Integer, :value => :Object} )
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
@ -48,8 +47,11 @@ module Risc
|
||||
|
||||
# this is the really really first place the machine starts (apart from the jump here)
|
||||
# it isn't really a function, ie it is jumped to (not called), exits and may not return
|
||||
# so it is responsible for initial setup
|
||||
def __init__ context
|
||||
# so it is responsible for initial setup:
|
||||
# - load fist message, set up Space as receiver
|
||||
# - call main, ie set up message for that etc
|
||||
# - exit (exit_sequence) which passes a machine int out to c
|
||||
def __init__( context )
|
||||
compiler = MethodCompiler.compiler_for_class(:Object,:__init__ ,
|
||||
Parfait::NamedList.type_for({}) , Parfait::NamedList.type_for({}))
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
@ -82,6 +84,7 @@ module Risc
|
||||
|
||||
# a sort of inline version of exit method.
|
||||
# Used by exit and __init__ (so it doesn't have to call it)
|
||||
# Assumes int return value and extracts the fixnum for process exit code
|
||||
def exit_sequence(builder)
|
||||
save_message( builder )
|
||||
message = Risc.message_reg
|
||||
@ -90,6 +93,8 @@ module Risc
|
||||
builder.add_code Syscall.new("emit_syscall(exit)", :exit )
|
||||
end
|
||||
|
||||
# the exit function
|
||||
# mainly calls exit_sequence
|
||||
def exit( context )
|
||||
compiler = compiler_for(:Object,:exit ,{})
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
@ -97,6 +102,8 @@ module Risc
|
||||
return compiler
|
||||
end
|
||||
|
||||
# emit the syscall with given name
|
||||
# there is a Syscall instruction, but the message has to be saved and restored
|
||||
def emit_syscall( builder , name )
|
||||
save_message( builder )
|
||||
builder.add_code Syscall.new("emit_syscall(#{name})", name )
|
||||
@ -114,6 +121,9 @@ module Risc
|
||||
builder.add_transfer("save_message", Risc.message_reg , r8 )
|
||||
end
|
||||
|
||||
# restore the message that we save in r8
|
||||
# get a new int and save the c return into it
|
||||
# tht int gets retured, ie is the return_value of the message
|
||||
def restore_message(builder)
|
||||
r8 = RegisterValue.new( :r8 , :Message)
|
||||
int = builder.compiler.use_reg(:Integer)
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
module Risc
|
||||
module Builtin
|
||||
class Space
|
||||
|
@ -4,6 +4,12 @@ module Risc
|
||||
module ClassMethods
|
||||
include CompileHelper
|
||||
|
||||
# wrapper for the syscall
|
||||
# io/file currently hardcoded to stdout
|
||||
# set up registers for syscall, ie
|
||||
# - pointer in r1
|
||||
# - length in r2
|
||||
# - emit_syscall (which does the return of an integer, see there)
|
||||
def putstring( context)
|
||||
compiler = compiler_for(:Word , :putstring ,{})
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
@ -18,7 +24,7 @@ module Risc
|
||||
end
|
||||
|
||||
# self[index] basically. Index is the first arg > 0
|
||||
# return (and word sized int) is stored in return_value
|
||||
# return a word sized new int, in return_value
|
||||
def get_internal_byte( context)
|
||||
compiler = compiler_for(:Word , :get_internal_byte , {at: :Integer})
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
@ -30,14 +36,13 @@ module Risc
|
||||
add_new_int("get_internal_byte", object , integer)
|
||||
message[:return_value] << integer
|
||||
end
|
||||
|
||||
compiler.add_mom( Mom::ReturnSequence.new)
|
||||
return compiler
|
||||
end
|
||||
|
||||
# self[index] = val basically. Index is the first arg ( >0),
|
||||
# value the second
|
||||
# return self
|
||||
# return value
|
||||
def set_internal_byte( context )
|
||||
compiler = compiler_for(:Word, :set_internal_byte , {at: :Integer , :value => :Integer} )
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
|
Loading…
Reference in New Issue
Block a user